OpenGL minimal app

Sorry for disturbing the list yet again, but hopefully this will help others
as well as myself.

This is a thoroughly minimal OpenGL application I’ve written, that loads an
image, and displays it, and waits for the user to press ‘q’ to quit.
Nothing more.

It is truly short and simple. Can ‘those who know’ take a quick glance and
determine whether it is appropriate as a minimal Windows based SDL OpenGL
app? If so, perhaps I could post it somewhere for other new users to use,
or something?

If there’s something wrong with the construction process, I can correct it,
and help others not make the same mistakes,

Rob

ps: I use SDL_Image and the helper function that Sam wrote for converting
images for OpenGL (in SDLGL_Util.h).

#include
#include
#include <SDL.h>
#include <SDL_Image.h>
#include “SDLGL_Util.h”

SDL_Surface *display;

int createDisplay(int p_width, int p_height, int p_depth);
int showTexture(unsigned int texID, GLfloat coord[4], unsigned int width,
unsigned int height, int x, int y);
int loadTexture(unsigned int &rTexID, unsigned int &width, unsigned int
&height, GLfloat coord[4]);

int main(int argc, char *argv[])
{
//Init SDL base
if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0 )
{
fprintf(stderr, “Couldn’t create video display\n”);
exit(1);
}

atexit(SDL_Quit);
signal(SIGINT, exit);
signal(SIGTERM, exit);

createDisplay(640,480,32);

// Load texture
GLfloat coord[4];
unsigned int rTexID, width, height;
loadTexture(rTexID, width, height, coord);

bool appRunning=true;
glClearColor(0.0,0.0,0.0,1.0);
int loop_time=0, oldtime=0, newtime;
while(appRunning)
{
glClear(GL_COLOR_BUFFER_BIT);
showTexture(rTexID, coord, width, height, 320-width/2, 240-height/2);
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
appRunning=false;
break;

case SDL_KEYDOWN:
 SDLKey sym = event.key.keysym.sym;
 if( sym == SDLK_q )
  appRunning=false;
break;

}
}
SDL_GL_SwapBuffers();
SDL_Delay(1);
newtime=SDL_GetTicks();
if(oldtime==0) oldtime=newtime;
loop_time=newtime-oldtime;
if(loop_time > 300) loop_time = 300;
oldtime=newtime;
}
return 0;
}

int loadTexture(unsigned int &rTexID, unsigned int &width, unsigned int
&height, GLfloat coord[4])
{
SDL_Surface *temptex = IMG_Load(“game_over.png”), *texture;
if(!temptex)
{
fprintf(stderr, “failed to load game_over.png\n”);
exit(1);
}
texture = SDL_DisplayFormatAlpha(temptex);
SDL_FreeSurface(temptex);

rTexID = SDL_GL_LoadTexture(texture, coord);
width=texture->w;
height=texture->h;
SDL_FreeSurface(texture);

return 1;
}

int showTexture(unsigned int texID, GLfloat coord[4], unsigned int width,
unsigned int height, int x, int y)
{
if( !glIsTexture(texID) )
{
loadTexture(texID, width, height, coord);
fprintf(stderr, “reloaded texture\n”);
}
else
{
float cX = width/2, cY = height/2;
glBindTexture(GL_TEXTURE_2D, texID);
glPushMatrix();
glTranslatef(cX+x,cY+y,0);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(coord[0],coord[1]); glVertex2f(-cX,-cY);
glTexCoord2f(coord[2],coord[1]); glVertex2f(-cX+width,-cY);
glTexCoord2f(coord[0],coord[3]); glVertex2f(-cX,-cY+height);
glTexCoord2f(coord[2],coord[3]); glVertex2f(-cX+width,-cY+height);
glEnd();

glPopMatrix();
}
return 1;
}

int createDisplay(int p_width, int p_height, int p_depth)
{
Uint32 SDLFlags = SDL_OPENGL|SDL_FULLSCREEN;
int rgb_size[3];
switch (p_depth)
{
case 8:
rgb_size[0] = 3;
rgb_size[1] = 3;
rgb_size[2] = 2;
break;
case 15:
case 16:
rgb_size[0] = 5;
rgb_size[1] = 5;
rgb_size[2] = 5;
break;
default:
rgb_size[0] = 8;
rgb_size[1] = 8;
rgb_size[2] = 8;
break;

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, rgb_size[0]);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, rgb_size[1]);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, rgb_size[2]);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, p_depth);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 0);
}
// Create the video display and return the video surface
display=SDL_SetVideoMode(p_width, p_height, 32, SDLFlags);
if ( display == NULL )
{
fprintf(stderr, “Unable to allocate surface\n”);
exit(1);
}

glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);

// This allows alpha blending of 2D textures with the scene
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

glViewport(0, 0, p_width, p_height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluOrtho2D(0.0, (GLdouble)p_width, (GLdouble)p_height, 0.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

return 1;
}