#include #include #include #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; }