I posted this in the beginner area but no luck.
Below is the complete program so you can have something to copy/paste/compile/run if you’d like to try it yourself and see if you can help.
The program draws glColor3d()'d coordinate axes, a single lit shaded triangle in the x-z plane (y is up), with a light circling around the triangle, about the (+) z axis, in the x-y plane. I draw a little glColor3d()'d GL_POINT where the light is.
The problem is, the little dot is only drawn in the first frame. After that it’s not drawn, but everything else works fine. I put in an SDL_Delay( 500 ) to make this effect more obvious.
If I change the last arg in the glLightfv() call (in draw(), where the // XXX is) from light_pos to light_dir, the problem goes away. Am I using glLightfv() incorrectly?
// 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(int width, int height)
{
if ( SDL_Init( SDL_INIT_VIDEO ) != 0 )
{
cout << "couldn’t initialize SDL: " << SDL_GetError() << endl;
SDL_Quit();
exit(1);
}const SDL_VideoInfo * vid_info = SDL_GetVideoInfo(); int bpp = vid_info->vfmt->BitsPerPixel; cout << "Found bpp = " << bpp << endl; unsigned int vid_flags = SDL_DOUBLEBUF | SDL_OPENGL | SDL_HWPALETTE | SDL_HWACCEL; if ( vid_info->hw_available ) { cout << "Found hw_available. Setting vid_flags |= SDL_HWSURFACE." << endl; vid_flags |= SDL_HWSURFACE; } else { cout << "Didn't find hw_available. Setting vid_flags |= SDL_SWSURFACE." << endl; vid_flags |= SDL_SWSURFACE; } if ( vid_info->blit_hw ) { cout << "Found blit_hw. Setting vid_flags |= SDL_HWACCEL." << endl; vid_flags |= SDL_HWACCEL; }
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( width, height, bpp, vid_flags ); 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(int width, int height)
{
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, width, height ); 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 // 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 )
{
int width = 400;
int height = 400;
initSDL( width, height );
initGL( width, height );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;
}
//------------------------------------------------
And here’s the makefile:
makefile for tiny_sdl_gl
APP_NAME = tiny_sdl_gl
LDFLAGS =
sdl-config --libs
-L/usr/X11R6/lib -lGL -lGLUCFLAGS = -c
sdl-config --cflags
-I/usr/X11R6/include/GL#----------------------------------------------
(APP_NAME): main.o g++ -o (APP_NAME) $(LDFLAGS) main.omain.o: main.cpp
g++ $(CFLAGS) main.cppclean:
rm -f $(APP_NAME)
rm -f *.o
[This message has been edited by jmg (edited 11-30-2002).]