// Mini Game Template by g.c. // win32: g++ szesciany.cpp -o szesciany.exe -Wall -pedantic -lSDL -lopengl32 -lglu32 -lSDL_image -lm // linux: g++ szesciany.c -o szesciany -Wall -pedantic -lSDL -lGL -lGLU -lSDL_image -lm #include #include #include #include #include #include #include // Sometimes this needs to be changed to just and // When in doubt, use sdl-config to find out #include #include #ifdef _WIN32 # include #endif //using namespace std; // Remove SDL main hook on Windows #ifdef _WIN32 # undef main #endif // Macros. #define UNUSED(a) ((void)(a)) // Globals. static int screen_width; static int screen_height; bool keys[SDLK_LAST]; float ratio; // Functions. static bool InitSDL(bool fullscreen, int width, int height); static bool InitOpenGL(); unsigned int ImgToTexture(const char *filename); void DrawQuad(float x, float y, float w, float h); void DrawQuadRGBA(float x, float y, float w, float h, float r, float g, float b, float a); void DrawQuadTexture(float x, float y, float w, float h, unsigned int texture_id); void DrawCube(float x, float y, float z, float w, float h, float d); void DrawCubeRGBA(float x, float y, float z, float w, float h, float d, float r, float g, float b, float a); static bool Events(); static void Logic(); static void Scene(); // ------------------------------------------------------------------ // EVENTS // ------------------------------------------------------------------ // Events static bool Events() { SDL_Event ev; memset(&ev, 0, sizeof(ev)); while(SDL_PollEvent(&ev)) { switch(ev.type) { case SDL_KEYUP: keys[ev.key.keysym.sym] = false; break; case SDL_KEYDOWN: if(ev.key.keysym.sym == SDLK_ESCAPE) return false; keys[ev.key.keysym.sym] = true; break; case SDL_QUIT: return false; } } return true; } // ------------------------------------------------------------------ // LOGIC // ------------------------------------------------------------------ // Logic static void Logic() { } // ------------------------------------------------------------------ // SCENE // ------------------------------------------------------------------ // Scene static void Scene() { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glScalef(1.0f, -1.0f, 1.0f); glTranslatef(0.0f, 0.0f, -15.0f); glRotatef(25.0f, -1.0f, 0.0f, 0.0f); // draw sth here // -- EXAMPLE -- static float rotx; //DrawQuadRGBA(0.0f, 0.0f, 1.0f, 2.0f, 1.0f, 1.0f, 0.0f, 0.0f); //DrawQuadTexture(0.0f, 0.0f, 1.0f, 1.0f, textures[TEX_TLO]); // -- EXAMPLE -- // for(int z=-1; z<2; z++) // for(int x=-1; x<2; x++) // for(int y=-1; y<2; y++) // { // glPushMatrix(); // glRotatef(rotx -= 1.0f*ratio, 0.0f, 1.0f, 0.0f); // DrawCubeRGBA(3.0f * x, 3.0f * y, 3.0f * z, 1.5f, 1.5f, 1.5f, 0.5f, 1.0f, 1.0f, 0.5f); // glPopMatrix(); // } for(int z=-1; z<2; z++) for(int x=-1; x<2; x++) for(int y=-1; y<2; y++) { if(z == -1) { switch(x) { case -1: { glPushMatrix(); glTranslatef(-3.0, -1.5, -3.0); glRotatef(rotx -= 1.0f*ratio, 0.0f, -1.0f, 0.0f); glTranslatef(3.0f, 1.5, 3.0f); DrawCubeRGBA(3.0f * x, 3.0f * y, 3.0f * z, 1.5f, 1.5f, 1.5f, 0.5f, 1.0f, 1.0f, 0.5f); glPopMatrix(); break; } case 0: { glPushMatrix(); glTranslatef(0,0,-3.0); glRotatef(rotx -= 1.0f*ratio, 0.0f, -1.0f, 0.0f); glTranslatef(0,0,3.0); DrawCubeRGBA(3.0f * x, 3.0f * y, 3.0f * z, 1.5f, 1.5f, 1.5f, 0.5f, 1.0f, 1.0f, 0.5f); glPopMatrix(); break; } case 1: { glPushMatrix(); glTranslatef(3,0,-3.0); glRotatef(rotx -= 1.0f*ratio, 0.0f, -1.0f, 0.0f); glTranslatef(-3,0,3.0); DrawCubeRGBA(3.0f * x, 3.0f * y, 3.0f * z, 1.5f, 1.5f, 1.5f, 0.5f, 1.0f, 1.0f, 0.5f); glPopMatrix(); break; } } } else if (z == 0) { switch(x) { case -1: { glPushMatrix(); glTranslatef(-3.0, -1.5, 0.0); glRotatef(rotx -= 1.0f*ratio, 0.0f, -1.0f, 0.0f); glTranslatef(3.0f, 1.5, 0.0f); DrawCubeRGBA(3.0f * x, 3.0f * y, 3.0f * z, 1.5f, 1.5f, 1.5f, 0.5f, 1.0f, 1.0f, 0.5f); glPopMatrix(); break; } case 0: { glPushMatrix(); glTranslatef(0,0,0); glRotatef(rotx -= 1.0f*ratio, 0.0f, -1.0f, 0.0f); glTranslatef(0,0,0); DrawCubeRGBA(3.0f * x, 3.0f * y, 3.0f * z, 1.5f, 1.5f, 1.5f, 0.5f, 1.0f, 1.0f, 0.5f); glPopMatrix(); break; } case 1: { glPushMatrix(); glTranslatef(3,0,0); glRotatef(rotx -= 1.0f*ratio, 0.0f, -1.0f, 0.0f); glTranslatef(-3,0,0); DrawCubeRGBA(3.0f * x, 3.0f * y, 3.0f * z, 1.5f, 1.5f, 1.5f, 0.5f, 1.0f, 1.0f, 0.5f); glPopMatrix(); break; } } } else if (z == 1) { switch(x) { case -1: { glPushMatrix(); glTranslatef(-3.0, -1.5, 3.0); glRotatef(rotx -= 1.0f*ratio, 0.0f, -1.0f, 0.0f); glTranslatef(3.0f, 1.5, -3.0f); DrawCubeRGBA(3.0f * x, 3.0f * y, 3.0f * z, 1.5f, 1.5f, 1.5f, 0.5f, 1.0f, 1.0f, 0.5f); glPopMatrix(); break; } case 0: { glPushMatrix(); glTranslatef(0,0,3); glRotatef(rotx -= 1.0f*ratio, 0.0f, -1.0f, 0.0f); glTranslatef(0,0,-3); DrawCubeRGBA(3.0f * x, 3.0f * y, 3.0f * z, 1.5f, 1.5f, 1.5f, 0.5f, 1.0f, 1.0f, 0.5f); glPopMatrix(); break; } case 1: { glPushMatrix(); glTranslatef(3,0,3); glRotatef(rotx -= 1.0f*ratio, 0.0f, -1.0f, 0.0f); glTranslatef(-3,0,-3); DrawCubeRGBA(3.0f * x, 3.0f * y, 3.0f * z, 1.5f, 1.5f, 1.5f, 0.5f, 1.0f, 1.0f, 0.5f); glPopMatrix(); break; } } } } /* Use depth buffering for hidden surface elimination. */ SDL_GL_SwapBuffers(); } // ------------------------------------------------------------------ // Init & utils // ------------------------------------------------------------------ // main int main(int argc, char **argv, char **envp) { // Unused. UNUSED(argc); UNUSED(argv); UNUSED(envp); // Init SDL. if(!InitSDL(false, 640, 480)) return 1; // Init OpenGL. if(!InitOpenGL()) return 2; // Title SDL_WM_SetCaption("Szesciany", "Szesciany"); // Main loop: unsigned int last_time = SDL_GetTicks(); ratio = 0.0f; for(;;) { // Main stuff. if(!Events()) break; Logic(); Scene(); // Calc time. unsigned int curr_time = SDL_GetTicks(); ratio = (float)(curr_time - last_time) / 1000.0f; last_time = curr_time; } // Done. SDL_Quit(); return 0; } // InitSDL static bool InitSDL(bool fullscreen, int width, int height) { int screen_bpp; int screen_flag = SDL_OPENGL; if(fullscreen) screen_flag |= SDL_FULLSCREEN; screen_width = width; screen_height = height; const SDL_VideoInfo *info; SDL_Surface *surface; if(SDL_Init(SDL_INIT_VIDEO) < 0) return false; info = SDL_GetVideoInfo(); if(info == NULL) goto err; screen_bpp = info->vfmt->BitsPerPixel; 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_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_putenv("SDL_VIDEO_CENTERED=center"); surface = SDL_SetVideoMode( screen_width, screen_height, screen_bpp, screen_flag); if(surface == NULL) goto err; SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); return true; err: SDL_Quit(); return false; } // InitOpenGL static bool InitOpenGL() { float ratio; ratio = (float)screen_width / (float)screen_height; glShadeModel(GL_SMOOTH); glClearColor(0, 0, 0, 0); glViewport(0, 0, screen_width, screen_height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective( 60.0, ratio, 1.0, 1024.0 ); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); return true; } // Note: older version of opengl required image width and height // to be a power of 2 (e.g. 16x32 or 512x128 or 256x256, etc). unsigned int ImgToTexture(const char *filename) { // Load image. SDL_Surface *img = IMG_Load(filename); if(!img) { fprintf(stderr, "error: ImgToTexture could not load image \"%s\"\n", filename); return ~0; } // Image type? Only 24 and 32 supported, rest must be converted. unsigned int img_type = 0; if(img->format->BitsPerPixel == 32) { img_type = GL_RGBA; } else if(img->format->BitsPerPixel == 24) { img_type = GL_RGB; } else { // Convert to 32 bits. SDL_PixelFormat fmt = { NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, 0xff, 0xff00, 0xff0000, 0xff000000, 0, 0xff }; SDL_Surface *nimg = SDL_ConvertSurface(img, &fmt, SDL_SWSURFACE); SDL_FreeSurface(img); if(!nimg) { fprintf(stderr, "error: ImgToTexture could not convert image \"%s\" to 32-bit\n", filename); return ~0; } // Done converting. img = nimg; img_type = GL_RGBA; } // Create texture. unsigned int texture_id = ~0; glGenTextures(1, &texture_id); glBindTexture(GL_TEXTURE_2D, texture_id); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // You might want to play with these parameters. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Gen texture. glTexImage2D(GL_TEXTURE_2D, 0, img_type, img->w, img->h, 0, img_type, GL_UNSIGNED_BYTE, img->pixels); printf("info: ImgToTexture loaded texture \"%s\" as %u\n", filename, texture_id); // Done SDL_FreeSurface(img); return texture_id; } void DrawQuad(float x, float y, float w, float h) { w /= 2.0f; h /= 2.0f; glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f(x - w, y - h); glTexCoord2f(1.0f, 0.0f); glVertex2f(x + w, y - h); glTexCoord2f(1.0f, 1.0f); glVertex2f(x + w, y + h); glTexCoord2f(0.0f, 1.0f); glVertex2f(x - w, y + h); glEnd(); } void DrawQuadRGBA(float x, float y, float w, float h, float r, float g, float b, float a) { // Get old color. float current_color[4]; glGetFloatv(GL_CURRENT_COLOR, current_color); // Set new color and draw quad. glColor4f(r, g, b, a); DrawQuad(x, y, w, h); // Set old color. glColor4fv(current_color); } void DrawQuadTexture(float x, float y, float w, float h, unsigned int texture_id) { // Enable texturing if needed. bool texturing_enabled = glIsEnabled(GL_TEXTURE_2D); if(!texturing_enabled) glEnable(GL_TEXTURE_2D); // Bind texture and draw. glBindTexture(GL_TEXTURE_2D, texture_id); DrawQuad(x, y, w, h); // Disable if was disable. if(!texturing_enabled) glDisable(GL_TEXTURE_2D); } void DrawCube(float x, float y, float z, float w, float h, float d) { w /= 2.0f; h /= 2.0f; d /= 2.0f; glBegin(GL_QUADS); //top glNormal3f( 0.0F, 1.0F, 0.0F); glVertex3f(x + w, y + h, z - d); glVertex3f(x - w, y + h, z - d); glVertex3f(x - w, y + h, z + d); glVertex3f(x + w, y + h, z + d); glNormal3f( 0.0F, -1.0F, 0.0F); glVertex3f(x + w, y - h, z + d); // Top Right Of The Quad (Bottom) glVertex3f(x - w, y - h, z + d); // Top Left Of The Quad (Bottom) glVertex3f(x - w, y - h, z - d); // Bottom Left Of The Quad (Bottom) glVertex3f(x + w, y - h, z - d); // Bottom Right Of The Quad (Bottom) glNormal3f( 0.0F, 0.0F, 1.0F); glVertex3f(x + w, y + h, z + d); //front glVertex3f(x - w, y + h, z + d); glVertex3f(x - w, y - h, z + d); glVertex3f(x + w, y - h, z + d); glNormal3f( 0.0F, 0.0F, -1.0F); glVertex3f(x + w, y - h, z - d); //back glVertex3f(x - w, y - h, z - d); glVertex3f(x - w, y + h, z - d); glVertex3f(x + w, y + h, z - d); glNormal3f( -1.0F, 0.0F, 0.0F); glVertex3f(x - w, y + h, z + d); //left glVertex3f(x - w, y + h, z - d); glVertex3f(x - w, y - h, z - d); glVertex3f(x - w, y - h, z + d); glNormal3f( 1.0F, 0.0F, 0.0F); glVertex3f(x + w, y + h, z - d); //right glVertex3f(x + w, y + h, z + d); glVertex3f(x + w, y - h, z + d); glVertex3f(x + w, y - h, z - d); glEnd(); } void DrawCubeRGBA(float x, float y, float z, float w, float h, float d, float r, float g, float b, float a) { // Get old color. float current_color[4]; glGetFloatv(GL_CURRENT_COLOR, current_color); // Set new color and draw quad. glColor4f(r, g, b, a); DrawCube(x, y, z, w, h, d); // Set old color. glColor4fv(current_color); }