/* sdl.c * * @2011 Kamil Kaminski * * Skeleton for SDL * */ #include <SDL/SDL.h> #include <SDL/SDL_image.h> #include <GL/glew.h> #include <GL/freeglut.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> /* function prototypes */ static void resize(int, int); static void setup_opengl(void); static void keys(SDL_keysym *, unsigned int *); static void process_events(void); static void render(void); /* global */ int program_running = 1; /* few arrays, they could make into the header at some point */ GLfloat fNoLight[] = { 0.0f, 0.0f, 0.0f, 0.0f }; GLfloat fLowLight[] = { 0.25f, 0.25f, 0.25f, 1.0f }; GLfloat fBrightLight[] = { 1.0f, 1.0f, 1.0f, 1.0f }; static void resize(int w, int h) { printf("window: resizing to %dx%d\n", w, h); GLfloat fAspect = (GLfloat) w / (GLfloat) h; if (h == 0) h = 1; glViewport(0, 0, w, h); /* reset coordinate system */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* produce the perspective projection */ /* void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) */ gluPerspective(40.0f, fAspect, 1.0, 40.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* this needs to be ran again, glut does it for you I suppose */ SDL_SetVideoMode(w, h, 32, SDL_OPENGL | SDL_RESIZABLE); } static void setup_opengl(void) { /* light values and coordinates */ GLfloat whiteLight[] = { 0.05f, 0.05f, 0.05f, 1.0f }; GLfloat sourceLight[] = { 0.75f, 0.75f, 0.75f, 1.0f }; GLfloat lightPos[] = { -10.f, 5.0f, 5.0f, 1.0f }; /* setup fog */ glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, fLowLight); /* set fog color to match background */ glFogf(GL_FOG_START, 4.0f); glFogf(GL_FOG_END, 20.0f); glFogi(GL_FOG_MODE, GL_LINEAR); /* fog equation */ glEnable(GL_DEPTH_TEST); /* hidden surface removal */ glFrontFace(GL_CCW); /* counter clock-wise polygons face out */ glEnable(GL_CULL_FACE); /* do not calculate inside of a pyramid */ /* setup and enable light 0 */ /* ambient RGBA intensity of the entire scene */ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, whiteLight); glLightfv(GL_LIGHT0, GL_AMBIENT, sourceLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, fBrightLight); glLightfv(GL_LIGHT0, GL_SPECULAR, fBrightLight); glLightfv(GL_LIGHT0, GL_POSITION, lightPos); /* enable lighting */ glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); /* enable color tracking */ glEnable(GL_COLOR_MATERIAL); /* set Material properties to follow glColor values */ glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMaterialfv(GL_FRONT, GL_SPECULAR, fBrightLight); glMateriali(GL_FRONT, GL_SHININESS, 128); /* turn on anti aliasing for points, lines, and polygons */ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glEnable(GL_POINT_SMOOTH); glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); /* gray background */ glClearColor(0.5f, 0.5f, 0.5f, 1.0f); } static void keys(SDL_keysym *keysym, unsigned int *keys_held) { switch (keysym->sym) { case SDLK_ESCAPE: program_running = 0; break; default: break; } } /* process SDL events */ static void process_events(void) { SDL_Event event; unsigned static int keys_held[323]; SDLKey sym; while (SDL_PollEvent(&event)) { sym = event.key.keysym.sym; switch (event.type) { case SDL_KEYUP: { /* reset the key to 0 */ keys_held[sym] = 0; break; } case SDL_KEYDOWN: { keys_held[sym] = 1; keys(&event.key.keysym, keys_held); break; } case SDL_VIDEORESIZE: { resize(event.resize.w, event.resize.h); break; } case SDL_QUIT: { program_running = 0; break; } default: break; } } } static void render(void) { /* clear the window with current clearing color */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* save the matrix state and do the rotations */ glPushMatrix(); GLfloat fExtent = 20.0f; GLfloat fStep = 0.5f; GLfloat y = -0.4f; GLfloat iLine; glLineWidth(1.0f); glBegin(GL_LINES); for (iLine = -fExtent; iLine <= fExtent; iLine += fStep) { glVertex3f(iLine, y, fExtent); glVertex3f(iLine, y, -fExtent); glVertex3f(fExtent, y, iLine); glVertex3f(-fExtent, y, iLine); } glEnd(); /* restore the matrix state */ glPopMatrix(); /* buffer swap */ SDL_GL_SwapBuffers(); } int main(int argc, char **argv) { SDL_Surface *screen; if (SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "unable to init SDL: %s\n", SDL_GetError()); exit(-1); } atexit(SDL_Quit); SDL_WM_SetCaption("SDL", NULL); 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, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if ((screen = SDL_SetVideoMode(640, 480, 32, SDL_OPENGL | SDL_RESIZABLE)) == NULL) { fprintf(stderr, "unable to set video mode: %s\n", SDL_GetError()); exit(-1); } SDL_EnableUNICODE(1); /* SDL doesn't trigger off a ResizeEvent at startup, but as we need this * for OpenGL, we do this ourselves */ SDL_Event resizeEvent; resizeEvent.type = SDL_VIDEORESIZE; resizeEvent.resize.w = 640; resizeEvent.resize.h = 480; SDL_PushEvent(&resizeEvent); /* initalize glew */ GLenum glewerr = glewInit(); if (GLEW_OK != glewerr) { fprintf(stderr, "error: %s\n", glewGetErrorString(glewerr)); return -1; } else fprintf(stdout, "status: using GLEW %s\n", glewGetString(GLEW_VERSION)); /* display OpenGL version */ GLint major; GLint minor; glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MINOR_VERSION, &minor); fprintf(stdout, "version: OpenGL %d.%d\n", major, minor); setup_opengl(); while (program_running) { process_events(); render(); } puts("bye!"); return 0; }