summaryrefslogtreecommitdiff
path: root/glpong.c
diff options
context:
space:
mode:
Diffstat (limited to 'glpong.c')
-rw-r--r--glpong.c276
1 files changed, 276 insertions, 0 deletions
diff --git a/glpong.c b/glpong.c
new file mode 100644
index 0000000..6779a79
--- /dev/null
+++ b/glpong.c
@@ -0,0 +1,276 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "SDL.h"
+#include "SDL_opengl.h"
+#include "SDL_image.h"
+
+#include "glpong.h"
+
+int main(int argc, char * argv[]) {
+ if (argc) {
+ if (argv) {}
+ }
+
+ GLPong_Init();
+
+ GLPong_PaddlesCreate();
+
+ GLPong_BallAdd();
+
+ while ( !GLPong.done ) {
+ GLPong_HandleEvents();
+ GLPong_Move();
+ GLPong_Draw();
+ SDL_Delay(10);
+ }
+ GLPong_CleanUp();
+
+ return 0;
+}
+
+void GLPong_Init() {
+ SDL_Surface * temp = NULL;
+ Uint8 i;
+ GLPong.done = 0;
+
+ GLPong.w = 800;
+ GLPong.h = 600;
+
+ for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i++) {
+ GLPong.Balls[i] = NULL;
+ }
+
+ srand(time(NULL));
+
+ SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
+ atexit(SDL_Quit);
+
+ SDL_WM_SetCaption("glPong", "glPong");
+ temp = IMG_Load("ball.png");
+ SDL_WM_SetIcon(temp, NULL);
+ SDL_ShowCursor(SDL_DISABLE);
+
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ GLPong.Surface = SDL_SetVideoMode(GLPong.w, GLPong.h, 32, SDL_OPENGL);
+ glViewport(0, 0, GLPong.w, GLPong.h);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0f, GLPong.w, GLPong.h, 0.0f, -1.0f, 1.0f);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glShadeModel(GL_SMOOTH);
+ glClearDepth(2.0f);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+
+ GLPong.Event.type = SDL_NOEVENT;
+
+ printf("OpenGL Vendor: %s\n", glGetString(GL_VENDOR));
+ printf("OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
+ printf("OpenGL Version: %s\n", glGetString(GL_VERSION));
+ printf("OpenGL Extensions: %s\n", glGetString(GL_EXTENSIONS));
+
+ ball_texture = SDL_GL_SurfaceToTexture(temp);
+ SDL_FreeSurface(temp);
+}
+
+void GLPong_HandleEvents() {
+ if (SDL_PollEvent(&GLPong.Event) != 0) {
+ if (GLPong.Event.type == SDL_QUIT) {
+ GLPong.done = 1;
+ return;
+ }
+ if (GLPong.Event.type == SDL_KEYDOWN) {
+ if (GLPong.Event.key.keysym.sym == SDLK_ESCAPE) {
+ GLPong.done = 1;
+ return;
+ } else if (GLPong.Event.key.keysym.sym == SDLK_SPACE) {
+ GLPong_BallAdd();
+ } else if (GLPong.Event.key.keysym.sym == SDLK_p) {
+ for (;;) {
+ SDL_Delay(10);
+ if (SDL_PollEvent(&GLPong.Event) != 0) {
+ if (GLPong.Event.type == SDL_QUIT) {
+ GLPong.done = 1;
+ return;
+ } else if (GLPong.Event.type == SDL_KEYDOWN){
+ if (GLPong.Event.key.keysym.sym == SDLK_ESCAPE) {
+ GLPong.done = 1;
+ return;
+ } else if (GLPong.Event.key.keysym.sym == SDLK_p) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void GLPong_Draw() {
+ Uint8 i;
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindTexture(GL_TEXTURE_2D, ball_texture);
+ glEnable(GL_TEXTURE_2D);
+ for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i++) {
+ if (GLPong.Balls[i] != NULL) {
+ glLoadIdentity();
+ glTranslatef(GLPong.Balls[i]->x, GLPong.Balls[i]->y, 0);
+ glColor4f(GLPong.Balls[i]->r, GLPong.Balls[i]->g, GLPong.Balls[i]->b, GLPong.Balls[i]->a);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, 1.0f); glVertex2f(GLPong.Balls[i]->w, GLPong.Balls[i]->h); /* Lower Left */
+ glTexCoord2f(1.0f, 1.0f); glVertex2f(0.0f, GLPong.Balls[i]->h); /* Lower Right */
+ glTexCoord2f(1.0f, 0.0f); glVertex2f(0.0f, 0.0f); /* Upper Right */
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(GLPong.Balls[i]->w, 0.0f); /* Upper Left */
+ glEnd();
+ }
+ }
+ glDisable(GL_TEXTURE_2D);
+
+ SDL_GL_SwapBuffers();
+}
+
+void GLPong_CleanUp() {
+ Uint8 i;
+ for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i++) {
+ if (GLPong.Balls[i] != NULL) {
+ free(GLPong.Balls[i]);
+ GLPong.Balls[i] = NULL;
+ }
+ }
+}
+
+void GLPong_Move() {
+ Uint8 i;
+ Uint8 j;
+ for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i++) {
+ if (GLPong.Balls[i] != NULL) {
+ GLPong.Balls[i]->x += GLPong.Balls[i]->xv;
+ GLPong.Balls[i]->y += GLPong.Balls[i]->yv;
+ if ( GLPong.Balls[i]->y > (GLPong.h - GLPong.Balls[i]->h) || GLPong.Balls[i]->y < 0.0f ) {
+ GLPong.Balls[i]->yv = -GLPong.Balls[i]->yv;
+ }
+ if ( GLPong.Balls[i]->x > (GLPong.w - GLPong.Balls[i]->w) || GLPong.Balls[i]->x < 0.0f ) {
+ GLPong.Balls[i]->xv = -GLPong.Balls[i]->xv;
+ }
+ }
+ }
+ /*if (GLPong.Balls[1] != NULL) {
+ if (GLPong_BallCollide(GLPong.Balls[0], GLPong.Balls[1])) {
+ GLPong.Balls[0]->xv = -GLPong.Balls[0]->xv;
+ GLPong.Balls[0]->yv = -GLPong.Balls[0]->yv;
+ GLPong.Balls[1]->xv = -GLPong.Balls[1]->xv;
+ GLPong.Balls[1]->yv = -GLPong.Balls[1]->yv;
+ }
+ }*/
+
+ /*
+ for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *) - 1; i++) {
+ if (GLPong.Balls[i] != NULL) {
+ for (j = i + i; j < sizeof(GLPong.Balls) / sizeof(void *); j++) {
+ if (j != i && GLPong.Balls[j] != NULL) {
+ if (GLPong_BallCollide(GLPong.Balls[i], GLPong.Balls[j])) {
+ printf("%d - %d\n", i, j);
+ GLPong.Balls[i]->xv *= -1;
+ GLPong.Balls[i]->yv *= -1;
+ GLPong.Balls[j]->xv *= -1;
+ GLPong.Balls[j]->yv *= -1;
+ }
+ }
+ }
+ }
+ }*/
+ /*for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i++) {
+ if (GLPong.Balls[i] != NULL) {
+ for (j = 0; j < sizeof(GLPong.Balls) / sizeof(void *); i++) {
+ if (GLPong.Balls[j] != NULL && i != j) {
+ if (GLPong_BallCollide(GLPong.Balls[i], GLPong.Balls[j])) {
+ GLPong.Balls[i]->xv *= -1;
+ GLPong.Balls[i]->yv *= -1;
+ }
+ }
+ }
+ }
+ }*/
+}
+
+GLuint SDL_GL_SurfaceToTexture(SDL_Surface * surface) {
+ Uint32 rmask, gmask, bmask, amask;
+ SDL_Surface * temp = NULL;
+ SDL_Surface * tempalpha = NULL;
+ GLuint texture;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ rmask = 0xff000000;
+ gmask = 0x00ff0000;
+ bmask = 0x0000ff00;
+ amask = 0x000000ff;
+#else
+ rmask = 0x000000ff;
+ gmask = 0x0000ff00;
+ bmask = 0x00ff0000;
+ amask = 0xff000000;
+#endif
+ tempalpha = SDL_DisplayFormatAlpha(surface);
+ SDL_SetAlpha(tempalpha, 0, SDL_ALPHA_TRANSPARENT);
+ temp = SDL_CreateRGBSurface(SDL_SWSURFACE, surface->w, surface->h, 32, bmask, gmask, rmask, amask);
+ SDL_FreeSurface(surface);
+ SDL_BlitSurface(tempalpha, NULL, temp, NULL);
+
+ SDL_FreeSurface(tempalpha);
+
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ SDL_LockSurface(temp);
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, temp->w, temp->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, temp->pixels);
+ SDL_UnlockSurface(temp);
+ SDL_FreeSurface(temp);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ return texture;
+}
+
+GLuint SDL_GL_NPOTSurfaceToTexture(SDL_Surface * surface, GLfloat * wratio, GLfloat * hratio) {
+ SDL_Surface * pow2 = NULL;
+ unsigned int w = NextPow2(surface->w);
+ unsigned int h = NextPow2(surface->h);
+ if (wratio) {
+ *wratio = (GLfloat)surface->w / (GLfloat)h;
+ }
+ if (hratio) {
+ *hratio = (GLfloat)surface->h/(GLfloat)h;
+ }
+
+ pow2 = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
+ SDL_BlitSurface(surface, NULL, pow2, NULL);
+ SDL_FreeSurface(surface);
+
+ return SDL_GL_SurfaceToTexture(pow2);
+}
+
+__inline__ unsigned int NextPow2(unsigned int value) {
+ unsigned int x;
+ __asm("dec %1\n\t"
+ "movl $2,%0\n\t"
+ "bsr %1,%1\n\t"
+ "shl %b1,%0\n\t"
+ : "=r" (x)
+ : "c" (value)
+ );
+ return x;
+}