diff options
Diffstat (limited to 'sdl.c')
-rw-r--r-- | sdl.c | 241 |
1 files changed, 241 insertions, 0 deletions
@@ -0,0 +1,241 @@ +/* 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; +} + |