openGL rendering of SDL-retrieved image

This problem is probably due more to my unfamiliarity with openGL than
with my unfamiliarity with SDL. However, since I’m reading the image
using SDL functions, this is the best place I can think of to post.

I’ve modified the SDL demo program “testgl” to attempt to display an
image on each side of the rotating cube. When I run the program, I
get an error in glEnd():

    error 1282 (GL_INVALID_OPERATION)

The image I’m attempting to texture the cube with (test.gif) is:

    test.gif 128x128+0+0 PseudoClass 256c 18kb GIF 0.0u 0:01

Any help would be greatly appreciated!

This is my modified version of testgl.c…

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include “SDL.h”
#include “SDL_image.h”

#ifdef WIN32
#include <windows.h>
#endif
#include <GL/gl.h>

#define CHECKERROR
{
GLenum gl_error;
gl_error = glGetError();

if (gl_error != GL_NO_ERROR)
{
fprintf(stderr,
“testgl:%d: OpenGL error: %d\n”,
LINE, gl_error);
}
}

int HandleEvent(SDL_Event *event)
{
int done;

done = 0;
switch(event->type) 
{
case SDL_ACTIVEEVENT:
/* See what happened */
printf("app %s ", event->active.gain ? "gained" : "lost");
if (event->active.state & SDL_APPACTIVE) 
{
    printf("active ");
}
else if (event->active.state & SDL_APPMOUSEFOCUS) 
{
    printf("mouse ");
}
else if (event->active.state & SDL_APPINPUTFOCUS) 
{
    printf("input ");
}
printf("focus\n");
break;


case SDL_QUIT:
done = 1;
break;
}
return(done);

}

int RunGLTest(int argc, char* argv[])
{
int i;
int bpp;
int rgb_size[3];
int w = 640;
int h = 480;
int done = 0;
int frames;
SDL_Surface *image;
static GLuint texName;
Uint32 start_time, this_time;
float cube[8][3]= {{ 0.5, 0.5, -0.5},
{ 0.5, -0.5, -0.5},
{-0.5, -0.5, -0.5},
{-0.5, 0.5, -0.5},
{-0.5, 0.5, 0.5},
{ 0.5, 0.5, 0.5},
{ 0.5, -0.5, 0.5},
{-0.5, -0.5, 0.5}};
Uint32 video_flags;

if(SDL_Init(SDL_INIT_VIDEO) < 0) 
{
fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError());
exit(1);
}

if (SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 8) 
{
bpp = 8;
}
else 
{
bpp = 16;  /* More doesn't seem to work */
}

/* Set the flags we want to use for setting the video mode */
video_flags = SDL_OPENGL;

for (i=1; argv[i]; ++i) 
{
if (strcmp(argv[1], "-fullscreen") == 0) 
{
    video_flags |= SDL_FULLSCREEN;
}
}

/* Initialize the display */
switch (bpp) 
{
case 8:
rgb_size[0] = 2;
rgb_size[1] = 3;
rgb_size[2] = 3;
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, bpp);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
if (SDL_SetVideoMode(w, h, bpp, video_flags) == NULL) 
{
fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
SDL_Quit();
exit(1);
}

/* Set the window manager title bar */
SDL_WM_SetCaption("SDL GL test", "testgl");

glViewport(0, 0, w, h); CHECKERROR;
glMatrixMode(GL_PROJECTION); CHECKERROR;
glLoadIdentity(); CHECKERROR;
glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0); CHECKERROR;
glMatrixMode(GL_MODELVIEW); CHECKERROR;
glLoadIdentity(); CHECKERROR;
glEnable(GL_DEPTH_TEST); CHECKERROR;

/* glDepthFunc(GL_LESS); */

glShadeModel(GL_FLAT); CHECKERROR;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); CHECKERROR;
glGenTextures(1, &texName); CHECKERROR;
glBindTexture(GL_TEXTURE_2D, texName); CHECKERROR;

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
CHECKERROR;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
CHECKERROR;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
CHECKERROR;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
CHECKERROR;

if ((image = IMG_Load("/var/tmp/test.gif")) == NULL)
{
fprintf(stderr, "Could not open image /var/tmp/test.gif\n");
exit(1);
}

printf("image->w = %d\n", image->w);
printf("image->h = %d\n", image->h);
printf("image->pitch = %d\n", image->pitch);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
	 image->w, image->h, 0,
	 GL_RGB, GL_UNSIGNED_BYTE, image->pixels);
CHECKERROR;

/* Loop until done. */
start_time = SDL_GetTicks();
frames = 0;
while(! done) 
{
char* sdl_error;
SDL_Event event;

/* Do our drawing, too. */
glClearColor(0.0, 0.0, 0.0, 1.0); CHECKERROR;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); CHECKERROR;
glEnable(GL_TEXTURE_2D); CHECKERROR;
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); CHECKERROR;
glBindTexture(GL_TEXTURE_2D, texName); CHECKERROR;

glBegin(GL_QUADS);
{
    glTexCoord2f(0.0, 0.0); CHECKERROR;
    glVertex3fv(cube[0]); CHECKERROR;
    glTexCoord2f(0.0, 1.0); CHECKERROR;
    glVertex3fv(cube[1]); CHECKERROR;
    glTexCoord2f(1.0, 1.0); CHECKERROR;
    glVertex3fv(cube[2]); CHECKERROR;
    glTexCoord2f(1.0, 0.0); CHECKERROR;
    glVertex3fv(cube[3]); CHECKERROR;
    
    glTexCoord2f(0.0, 0.0); CHECKERROR;
    glVertex3fv(cube[3]); CHECKERROR;
    glTexCoord2f(0.0, 1.0); CHECKERROR;
    glVertex3fv(cube[4]); CHECKERROR;
    glTexCoord2f(1.0, 1.0); CHECKERROR;
    glVertex3fv(cube[7]); CHECKERROR;
    glTexCoord2f(1.0, 0.0); CHECKERROR;
    glVertex3fv(cube[2]); CHECKERROR;
    
    glTexCoord2f(0.0, 0.0); CHECKERROR;
    glVertex3fv(cube[0]); CHECKERROR;
    glTexCoord2f(0.0, 1.0); CHECKERROR;
    glVertex3fv(cube[5]); CHECKERROR;
    glTexCoord2f(1.0, 1.0); CHECKERROR;
    glVertex3fv(cube[6]); CHECKERROR;
    glTexCoord2f(1.0, 0.0); CHECKERROR;
    glVertex3fv(cube[1]); CHECKERROR;
    
    glTexCoord2f(0.0, 0.0); CHECKERROR;
    glVertex3fv(cube[5]); CHECKERROR;
    glTexCoord2f(0.0, 1.0); CHECKERROR;
    glVertex3fv(cube[4]); CHECKERROR;
    glTexCoord2f(1.0, 1.0); CHECKERROR;
    glVertex3fv(cube[7]); CHECKERROR;
    glTexCoord2f(1.0, 0.0); CHECKERROR;
    glVertex3fv(cube[6]); CHECKERROR;
    
    glTexCoord2f(0.0, 0.0); CHECKERROR;
    glVertex3fv(cube[5]); CHECKERROR;
    glTexCoord2f(0.0, 1.0); CHECKERROR;
    glVertex3fv(cube[0]); CHECKERROR;
    glTexCoord2f(1.0, 1.0); CHECKERROR;
    glVertex3fv(cube[3]); CHECKERROR;
    glTexCoord2f(1.0, 0.0); CHECKERROR;
    glVertex3fv(cube[4]); CHECKERROR;
    
    glTexCoord2f(0.0, 0.0); CHECKERROR;
    glVertex3fv(cube[6]); CHECKERROR;
    glTexCoord2f(0.0, 1.0); CHECKERROR;
    glVertex3fv(cube[1]); CHECKERROR;
    glTexCoord2f(1.0, 1.0); CHECKERROR;
    glVertex3fv(cube[2]); CHECKERROR;
    glTexCoord2f(1.0, 0.0); CHECKERROR;
    glVertex3fv(cube[7]); CHECKERROR;
}
glEnd(); CHECKERROR;

glMatrixMode(GL_MODELVIEW); CHECKERROR;
glRotatef(5.0, 1.0, 1.0, 1.0); CHECKERROR;

SDL_GL_SwapBuffers(); CHECKERROR;

sdl_error = SDL_GetError();
if(sdl_error[0] != '\0') 
{
    fprintf(stderr, "testgl: SDL error '%s'\n", sdl_error);
    SDL_ClearError();
}

/* Check if there's a pending event. */
while(SDL_PollEvent(&event)) 
{
    done = HandleEvent(&event);
}
++frames;
}

/* Print out the frames per second */
this_time = SDL_GetTicks();
if (this_time != start_time) 
{
printf("%2.2f FPS\n",
       ((float)frames/(this_time-start_time))*1000.0);
}

/* Destroy our GL context, etc. */
SDL_Quit();
return(0);

}

int main(int argc, char *argv[])
{
RunGLTest(argc, argv);
return 0;
}

-------------- next part --------------
A non-text attachment was scrubbed…
Name: test.gif
Type: image/gif
Size: 19382 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20001019/94034385/attachment.gif

Earlier I wrote:

I’ve modified the SDL demo program “testgl” to attempt to display an
image on each side of the rotating cube. When I run the program, I
get an error in glEnd():

    error 1282 (GL_INVALID_OPERATION)


#define CHECKERROR

GLenum gl_error;
gl_error = glGetError();


glBegin(GL_QUADS);
{
glTexCoord2f(0.0, 0.0); CHECKERROR;
glVertex3fv(cube[0]); CHECKERROR;
glTexCoord2f(0.0, 1.0); CHECKERROR;
glVertex3fv(cube[1]); CHECKERROR;
glTexCoord2f(1.0, 1.0); CHECKERROR;
glVertex3fv(cube[2]); CHECKERROR;
glTexCoord2f(1.0, 0.0); CHECKERROR;
glVertex3fv(cube[3]); CHECKERROR;

}
glEnd(); CHECKERROR;

Doh. You can’t call glGetError() during a glBegin/glEnd() sequence.
Sorry. This turned out to have nothing to do with SDL.

Derrell

If you use a DRI or MESA based GL driver you can export either
LIBGL_DEBUG=v or MESA_DEBUG=v to get more verbose output and information
where and why a GL error occured without calling glGetError. The NVIDIA
drivers don’t have such a functionality… yet.On Thu, Oct 19, 2000 at 02:56:27PM -0400, Derrell Lipman wrote:

Doh. You can’t call glGetError() during a glBegin/glEnd() sequence.
Sorry. This turned out to have nothing to do with SDL.


Daniel Vogel vogel at lokigames.com
Programmer 714-505-8915 x17
Loki Software www.lokigames.com