This post may be a bit longish, but it’s that way so you can have a complete program to copy/paste if you’d like to try it yourself and see if you can help.
Using SDL under linux. The following program draws coordinate axes, a single triangle in the x-z plane (y is up), with a light circling around the triangle in the x-y plane. I draw a little GL_POINT where the light is.
The problem is, as the program stands below, the little dot is only drawn the first frame. After that it’s not drawn, but everything else works fine.
If I change the last arg in the glLightfv() call (see where the // XXX is) from light_pos to light_dir, the problem goes away. (!?)
I’m using DRI/mesa, and I believe hardware acceleration is working (although, I’m not sure, and that is another post altogether).
// tiny_sdl_gl
//
// main.cpp#include
#include#include <gl.h>
#include <glu.h>#include <SDL.h>
#include <SDL_video.h>using std::exit;
using std::cout;
using std::endl;//------------------------------
GLfloat radius = 2.5;
GLfloat light_pos[] = { 0.0, radius, 0.0, 1.0 }; // positional
GLfloat light_dir[] = { 0.0, radius, 0.0, 0.0 }; // directional
GLfloat theta = 0; // rotation of light about the z-axis.//---------------------------------------------------------------------
void processEvents()
{
SDL_Event event;while( SDL_PollEvent( &event ) ) { if ( event.type == SDL_QUIT ) { cout << "quit has been requested via ctrl-c or close window" << endl; SDL_Quit(); exit( 0 ); break; } }
}
//---------------------------------------------------------
void initSDL()
{
if ( SDL_Init( SDL_INIT_VIDEO ) != 0 )
{
cout << "couldn’t initialize SDL: " << SDL_GetError() << endl;
SDL_Quit();
exit(1);
}SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); 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, 24 ); // default anyway. SDL_Surface * surf = SDL_SetVideoMode( 400, 400, 32, SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_OPENGL ); if ( surf == NULL ) { cout << "unable to set video mode: " << SDL_GetError() << endl; SDL_Quit(); exit(1); } SDL_WM_SetCaption( "sdl_ast", "sdl_ast" );
}
//---------------------------------------------------------
void initGL()
{
glPolygonMode( GL_FRONT, GL_FILL );glShadeModel( GL_SMOOTH ); glCullFace( GL_BACK ); glEnable( GL_CULL_FACE ); glClearColor( 0.0, 0.0, 0.0, 0.0 ); glPointSize( 4.0 ); glLineWidth( 2.0 ); glEnable( GL_DEPTH_TEST ); GLfloat mat_spec[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shin = 50.0; GLfloat mat_emerald[] = { 0.0, 0.8, 0.1, 1.0 }; GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat amb_light[] = { 0.2, 0.2, 0.2, 1.0 }; glMaterialfv( GL_FRONT, GL_SPECULAR, mat_spec ); glMaterialf( GL_FRONT, GL_SHININESS, mat_shin ); glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_emerald ); glLightfv( GL_LIGHT0, GL_AMBIENT, amb_light ); glLightfv( GL_LIGHT0, GL_DIFFUSE, white_light ); glLightfv( GL_LIGHT0, GL_SPECULAR, white_light ); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); glViewport( 0, 0, 400, 400 ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 40.0, 1.0, 4.0, 16.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity();
}
//------------------------------------------------
void draw()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );glPushMatrix(); gluLookAt( 2.0, 4.0, 7.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ); glPushMatrix(); glRotated( theta, 0.0, 0.0, 1.0 ); glLightfv( GL_LIGHT0, GL_POSITION, light_pos ); // XXX // And then draw the dot representing the light. glDisable( GL_LIGHTING ); glBegin( GL_POINTS ); glColor3d( 1.0, 1.0, 1.0 ); glVertex4fv( light_pos ); glEnd(); glEnable( GL_LIGHTING ); glPopMatrix(); // Draw the x y z coordinate axes. glDisable( GL_LIGHTING ); glBegin( GL_LINES ); glColor3d( 1.0, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, 0.0 ); glVertex3d( 2.0, 0.0, 0.0 ); glColor3d( 0.0, 1.0, 0.0 ); glVertex3d( 0.0, 0.0, 0.0 ); glVertex3d( 0.0, 2.0, 0.0 ); glColor3d( 0.0, 0.0, 1.0 ); glVertex3d( 0.0, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, 2.0 ); glEnd(); glEnable( GL_LIGHTING ); // Draw a simple triangle facing up near the origin. glBegin( GL_TRIANGLES ); glNormal3d( 0.0, 1.0, 0.0 ); // Normal facing up. // The winding is correct so the "front" is facing up, // in the same direction as the normal. glVertex3d( 0.0, 0.0, 0.0 ); glVertex3d( 0.5, 0.0, 1.0 ); glVertex3d( 1.0, 0.0, 0.2 ); glEnd(); glPopMatrix(); glFinish();
}
//------------------------------------------------
int main( int argc, char * argv[] )
{
initSDL();
initGL();while ( true ) { SDL_Delay( 500 ); // This is just here to slow things down // enough to see the effect I'm asking about. processEvents(); theta += 5.0; if ( theta > 360.0 ) { theta -= 360.0; } draw(); SDL_GL_SwapBuffers(); } SDL_Quit(); return 0;
}
//------------------------------------------------