#include #include #include #include "SDL.h" #include "SDL_opengl.h" #include "SDL_image.h" #include "SDL_net.h" #include #include "glpong3d.h" GLuint box; int main(int argc, char * argv[]) { clock_t now, last = 0; unsigned int frames = 0; if (argc) { if (argv) {} } GLPong_Init(); while ( !GLPong.done ) { GLPong_HandleEvents(); GLPong_Move(); now = clock(); frames++; if (now - last > CLK_TCK * 2) { GLPong.fps = (frames * CLK_TCK) / (now - last); last = now; frames = 0; } printf("now: %ld, last %ld, frames: %u, fps: %u\n", now, last, frames, GLPong.fps); GLPong_Draw(); SDL_Delay(10); } GLPong_CleanUp(); return 0; } void GLPong_Init() { SDL_Surface * temp = NULL; int i; int count; GLPong.done = 0; GLPong.w = 800; GLPong.h = 600; GLPong.Ball.w = 0.5f; GLPong.Ball.h = 0.5f; GLPong.Ball.x = -(GLPong.Ball.w / 2); GLPong.Ball.y = -(GLPong.Ball.h / 2); GLPong.Ball.z = -3.0f; GLPong.Ball.xv = 0.02f; GLPong.Ball.yv = 0.01f; GLPong.Ball.zv = -0.03f; GLPong.Front.w = 0.66f; GLPong.Front.h = 0.5f; GLPong.Front.x = -(GLPong.Front.w / 2); GLPong.Front.y = -(GLPong.Front.h / 2); GLPong.Front.z = -3.0f; GLPong.Back.w = 0.66f; GLPong.Back.h = 0.5f; GLPong.Back.x = -(GLPong.Front.w / 2); GLPong.Back.y = -(GLPong.Front.h / 2); GLPong.Back.z = -9.0f; SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE); atexit(SDL_Quit); GLPong.GLC.context = glcGenContext(); glcContext(GLPong.GLC.context); #ifdef _WIN32 glcAppendCatalog("C:\\WINDOWS\\Fonts"); #endif count = glcGeti(GLC_CATALOG_COUNT); for (i = 0; i < count; i++) { printf("%s\n", (char *)glcGetListc(GLC_CATALOG_LIST, i)); } GLPong.GLC.font = glcGenFontID(); glcNewFontFromFamily(GLPong.GLC.font, "DejaVu Sans"); glcFontFace(GLPong.GLC.font, "Normal"); glcRenderStyle(GLC_TEXTURE); glcFont(GLPong.GLC.font); SDLNet_Init(); atexit(SDLNet_Quit); SDL_WM_SetCaption("glpong3d", "glpong3d"); temp = IMG_Load("ball.png"); SDL_WM_SetIcon(temp, NULL); SDL_FreeSurface(temp); 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(); gluPerspective(45.0f, GLPong.w / GLPong.h, 0.1f, 50.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glShadeModel(GL_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 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)); temp = IMG_Load("background.jpg"); if (temp != NULL) { background = SDL_GL_SurfaceToTexture(temp); } SDL_FreeSurface(temp); temp = IMG_Load("128x128.png"); ball_texture = SDL_GL_SurfaceToTexture(temp); SDL_FreeSurface(temp); temp = IMG_Load("paddle-skyos.png"); paddle_texture = SDL_GL_SurfaceToTexture(temp); SDL_FreeSurface(temp); box = glGenLists(1); glNewList(box, GL_COMPILE); glBegin(GL_LINE_LOOP); glVertex3f(-1.5f, -1.0f, 0.0f); /* Lower Left */ glVertex3f( 1.5f, -1.0f, 0.0f); /* Lower Right */ glVertex3f( 1.5f, 1.0f, 0.0f); /* Upper Right */ glVertex3f(-1.5f, 1.0f, 0.0f); /* Upper Left */ glEnd(); glEndList(); } void GLPong_HandleEvents() { Uint8 * key; int x = 0, y = 0; 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_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; } } } } } } } key = SDL_GetKeyState(NULL); SDL_GetMouseState(&x, &y); GLPong.Mouse.x = ((float) x / GLPong.w) * 3.3f - 1.65f; if (GLPong.Mouse.x <= -1.5 + (GLPong.Front.w / 2)) GLPong.Mouse.x = -1.5 + (GLPong.Front.w / 2); else if (GLPong.Mouse.x >= 1.5 - (GLPong.Front.w / 2)) GLPong.Mouse.x = 1.5 - (GLPong.Front.w / 2); GLPong.Mouse.y = ((float) y / GLPong.h) * 2.5f - 1.25f; if (GLPong.Mouse.y <= -1.0 + (GLPong.Front.h / 2)) GLPong.Mouse.y = -1.0 + (GLPong.Front.h / 2); else if (GLPong.Mouse.y >= 1.0 - (GLPong.Front.h / 2)) GLPong.Mouse.y = 1.0 - (GLPong.Front.h / 2); /*printf("SDL x,y: %d,%d; OpenGL x,y: %f,%f\n", x, y, GLPong.Mouse.x, GLPong.Mouse.y);*/ } void GLPong_Draw() { char buffer[10]; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); if (background) { glBindTexture(GL_TEXTURE_2D, background); glEnable(GL_TEXTURE_2D); } else { glColor3f(0.0f, 0.0f, 0.0f); } glTranslatef(0.0f, 0.0f, -9.0f); glBegin(GL_QUADS); glTexCoord2f(0.875f, 0.0f); glVertex2f( 1.5f, 1.0f); /* Upper Right */ glTexCoord2f(0.125f, 0.0f); glVertex2f(-1.5f, 1.0f); /* Upper Left */ glTexCoord2f(0.125f, 1.0f); glVertex2f(-1.5f, -1.0f); /* Lower Left */ glTexCoord2f(0.875f, 1.0f); glVertex2f( 1.5f, -1.0f); /* Lower Right */ glEnd(); glDisable(GL_TEXTURE_2D); glLoadIdentity(); glColor3f(0.0f, 1.0f, 0.0f); glTranslatef(0.0f, 0.0f, -3.0f); glCallList(box); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -4.0f); glCallList(box); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -5.0f); glCallList(box); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -6.0f); glCallList(box); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -7.0f); glCallList(box); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -8.0f); glCallList(box); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -9.0f); glCallList(box); glLoadIdentity(); glTranslatef(0.0f, 0.0f, 0.0f); glBegin(GL_LINES); glVertex3f(-1.5f, -1.0f, -3.0f); /* Lower Left */ glVertex3f(-1.5f, -1.0f, -9.0f); glEnd(); glBegin(GL_LINES); glVertex3f( 1.5f, -1.0f, -3.0f); /* Lower Right */ glVertex3f( 1.5f, -1.0f, -9.0f); glEnd(); glBegin(GL_LINES); glVertex3f( 1.5f, 1.0f, -3.0f); /* Upper Right */ glVertex3f( 1.5f, 1.0f, -9.0f); glEnd(); glBegin(GL_LINES); glVertex3f(-1.5f, 1.0f, -3.0f); /* Upper Left */ glVertex3f(-1.5f, 1.0f, -9.0f); glEnd(); glLoadIdentity(); glBindTexture(GL_TEXTURE_2D, paddle_texture); glEnable(GL_TEXTURE_2D); glColor3f(1.0f, 1.0f, 1.0f); glTranslatef(0.0f, 0.0f, GLPong.Back.z); glBegin(GL_QUADS); glTexCoord2f(0.832f, 1.0f); glVertex2f(GLPong.Back.w / 2, GLPong.Back.h / 2); /* Upper Right */ glTexCoord2f(0.168f, 1.0f); glVertex2f(-GLPong.Back.w / 2, GLPong.Back.h / 2); /* Upper Left */ glTexCoord2f(0.168f, 0.0f); glVertex2f(-GLPong.Back.w / 2, -GLPong.Back.h / 2); /* Lower Left */ glTexCoord2f(0.832f, 0.0f); glVertex2f(GLPong.Back.w / 2, -GLPong.Back.h / 2); /* Lower Right */ glEnd(); glDisable(GL_TEXTURE_2D); glLoadIdentity(); glBindTexture(GL_TEXTURE_2D, ball_texture); glEnable(GL_TEXTURE_2D); glTranslatef(GLPong.Ball.x, GLPong.Ball.y, GLPong.Ball.z); glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex2f(GLPong.Ball.w, GLPong.Ball.h); /* Lower Left */ glTexCoord2f(1.0f, 1.0f); glVertex2f(0.0f, GLPong.Ball.h); /* Lower Right */ glTexCoord2f(1.0f, 0.0f); glVertex2f(0.0f, 0.0f); /* Upper Right */ glTexCoord2f(0.0f, 0.0f); glVertex2f(GLPong.Ball.w, 0.0f); /* Upper Left */ glEnd(); glDisable(GL_TEXTURE_2D); glLoadIdentity(); glTranslatef(0.0f, 0.0f, GLPong.Ball.z); glCallList(box); glLoadIdentity(); glBindTexture(GL_TEXTURE_2D, paddle_texture); glEnable(GL_TEXTURE_2D); glTranslatef(GLPong.Mouse.x, -GLPong.Mouse.y, GLPong.Front.z); glBegin(GL_QUADS); glTexCoord2f(0.168f, 1.0f); glVertex2f(GLPong.Front.w / 2, GLPong.Front.h / 2); /* Upper Right */ glTexCoord2f(0.832f, 1.0f); glVertex2f(-GLPong.Front.w / 2, GLPong.Front.h / 2); /* Upper Left */ glTexCoord2f(0.832f, 0.0f); glVertex2f(-GLPong.Front.w / 2, -GLPong.Front.h / 2); /* Lower Left */ glTexCoord2f(0.168f, 0.0f); glVertex2f(GLPong.Front.w / 2, -GLPong.Front.h / 2); /* Lower Right */ glEnd(); glDisable(GL_TEXTURE_2D); sprintf(buffer, "%u FPS", GLPong.fps); glLoadIdentity(); glTranslatef(-1.5f, 1.1f, -3.0f); glColor3f(1.0f, 1.0f, 1.0f); glScalef(0.1f, 0.1f, 0.0f); glcRenderString(buffer); SDL_GL_SwapBuffers(); } void GLPong_CleanUp() { } void GLPong_Move() { GLPong.Ball.x += GLPong.Ball.xv; GLPong.Ball.y += GLPong.Ball.yv; GLPong.Ball.z += GLPong.Ball.zv; if ((GLPong.Ball.x > 1.0f) || (GLPong.Ball.x + GLPong.Ball.w < -1.0f)) { GLPong.Ball.xv = -GLPong.Ball.xv; } if ((GLPong.Ball.y > 0.5f) || (GLPong.Ball.y + GLPong.Ball.h < -0.5f)) { GLPong.Ball.yv = -GLPong.Ball.yv; } if ((GLPong.Ball.z < -9.0f) || (GLPong.Ball.z > -3.0f)) { GLPong.Ball.zv = -GLPong.Ball.zv; } } __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; } GLuint SDL_GL_SurfaceToTexture(SDL_Surface * surface) { Uint32 rmask, gmask, bmask, amask; GLuint texture; GLenum format = GL_RGB; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif if (surface->format->Rmask & rmask) { format = GL_RGB; if (surface->format->BitsPerPixel == 32) { format = GL_RGBA; } } else if (surface->format->Rmask & bmask) { format = GL_BGR; if (surface->format->BitsPerPixel == 32) { format = GL_BGRA; } } glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); SDL_LockSurface(surface); glTexImage2D(GL_TEXTURE_2D, 0, surface->format->BytesPerPixel, surface->w, surface->h, 0, format, GL_UNSIGNED_BYTE, surface->pixels); SDL_UnlockSurface(surface); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); return texture; } void glEnable2D() { int vPort[4]; glGetIntegerv(GL_VIEWPORT, vPort); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, vPort[2], vPort[3], 0, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); } void glDisable2D() { glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); }