diff options
Diffstat (limited to 'sdl/platform.c')
-rw-r--r-- | sdl/platform.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/sdl/platform.c b/sdl/platform.c new file mode 100644 index 0000000..55f6555 --- /dev/null +++ b/sdl/platform.c @@ -0,0 +1,169 @@ +/* platform.c + * + * Platform + * + * + */ + +#include <SDL/SDL.h> +#include <SDL/SDL_image.h> +#include <GL/glew.h> +#include "platform.h" + +/* few light arrays */ +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 }; + +/* 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 }; + +/* variables that should be already defined and declared for us by main program */ +extern const unsigned int xres; +extern const unsigned int yres; +extern const unsigned int bpp; +extern const char *window_caption; +extern const char *window_icon_path; + +void setup_opengl(void) +{ + /* 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); + /* screws up snowman */ + //glEnable(GL_POLYGON_SMOOTH); + //glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + + /* gray background */ + glClearColor(0.5f, 0.5f, 0.5f, 1.0f); + + /* original texture loading used to be here */ + + /* texture filtering, we modify default values since we don't have mipmaps */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + /* how OpenGL combines the colors from texels with the color of the underlying + * geometry is controlled by the texture environment mode */ + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + /* once texture is loaded and enabled, it will applied to every primitive + * that specifies coordinates */ + glEnable(GL_TEXTURE_2D); + + /* multisampling for polygons, conflicts with anti-aliasing */ + //glEnable(GL_MULTISAMPLE); + + /* don't know about this, but why not */ + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); +} + +void setup_sdl(void) +{ + SDL_Surface *screen; + + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0 ) + { + fprintf(stderr, "unable to init SDL: %s\n", SDL_GetError()); + exit(-1); + } + atexit(SDL_Quit); + SDL_WM_SetCaption(window_caption, NULL); + SDL_WM_SetIcon(IMG_Load(window_icon_path), 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_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + + if ((screen = SDL_SetVideoMode(xres, yres, bpp, 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 = xres; + resizeEvent.resize.h = yres; + SDL_PushEvent(&resizeEvent); +} + +void setup_glew(void) +{ + /* initalize glew */ + GLenum glewerr = glewInit(); + if (GLEW_OK != glewerr) + { + fprintf(stderr, "error: %s\n", glewGetErrorString(glewerr)); + exit(-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 detected\n", major, minor); +} + +inline void fps_control(const unsigned int startclock) +{ + unsigned int deltaclock = SDL_GetTicks() - startclock; + if (deltaclock < 1000 / FRAMES_PER_SECOND) + SDL_Delay((1000 / FRAMES_PER_SECOND) - deltaclock); + +#ifdef STAT_FPS + char buffer[30] = { 0 }; + sprintf(buffer, "%s: %4d fps", window_caption, + 1000 / (SDL_GetTicks() - startclock)); + SDL_WM_SetCaption(buffer, NULL); +#endif +} + |