Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 7 of 7

Thread: directional works, positional only draws 1st time through

  1. #1
    Junior Member Regular Contributor
    Join Date
    Mar 2000
    Location
    east norwalk, ct, usa
    Posts
    184

    directional works, positional only draws 1st time through

    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?

    Code :
    // tiny_sdl_gl
    //
    // main.cpp
     
    #include <cstdlib>
    #include <iostream>
     
    #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( &amp;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:

    Code :
    # makefile for tiny_sdl_gl
    #
     
    APP_NAME = tiny_sdl_gl
     
    LDFLAGS = `sdl-config --libs` -L/usr/X11R6/lib -lGL -lGLU
     
    CFLAGS = -c `sdl-config --cflags` -I/usr/X11R6/include/GL
     
    #----------------------------------------------
    $(APP_NAME): main.o
            g++ -o $(APP_NAME) $(LDFLAGS) main.o
     
    main.o: main.cpp
            g++ $(CFLAGS) main.cpp
     
    clean:
            rm -f $(APP_NAME)
            rm -f *.o

    [This message has been edited by jmg (edited 11-30-2002).]

  2. #2
    Junior Member Regular Contributor
    Join Date
    Mar 2000
    Location
    east norwalk, ct, usa
    Posts
    184

    Re: directional works, positional only draws 1st time through

    If I add a call to glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE ) just before enabling the lighting, and leave the light set to positional, the GL_POINT doesn't show up at all...

    Can someone please confirm whether or not they get the same strange behaviour so I can tell if this is an implementation bug on my end?

  3. #3
    Senior Member OpenGL Guru knackered's Avatar
    Join Date
    Aug 2001
    Location
    UK
    Posts
    3,032

    Re: directional works, positional only draws 1st time through

    glVertex4fv( light_pos ); ?
    Try changing that to
    glVertex3fv( light_pos );

    dunno why you're using 4 component vertices..
    Knackered

  4. #4
    Junior Member Regular Contributor
    Join Date
    Nov 2002
    Location
    Los Angeles, CA
    Posts
    208

    Re: directional works, positional only draws 1st time through

    The fourth parameter to glVertex doesn't matter in this case. The default value for the fourth parameter is 1, which is the fourth value he's passing in with glVertex4fv.

  5. #5
    Junior Member Regular Contributor
    Join Date
    Mar 2000
    Location
    east norwalk, ct, usa
    Posts
    184

    Re: directional works, positional only draws 1st time through

    Whoa, knackered,.. it worked. Thanks.

    If anyone could offer an explanation, I'd love to hear it, because it makes no sense to me at all. I agreed with Coriolis that the default parameter is 1 anyway and it shouldn't matter.

    The only reason I'd written it that way was:
    A. I had light_pos hanging around looking to be reused, and
    B. I just assumed that since light_pos was a 4-element array, I should pass it to glVertex4fv(). It didn't even occur to me that using glVertex3fv() would compile just fine.

  6. #6
    Senior Member OpenGL Guru knackered's Avatar
    Join Date
    Aug 2001
    Location
    UK
    Posts
    3,032

    Re: directional works, positional only draws 1st time through

    Agreed, it should work because your w element is 1.0
    So, it must be a driver bug - what drivers are you using?
    Knackered

  7. #7
    Junior Member Regular Contributor
    Join Date
    Mar 2000
    Location
    east norwalk, ct, usa
    Posts
    184

    Re: directional works, positional only draws 1st time through

    > what drivers are you using?

    I don't think I know how to answer that. I'm running Mandrake Linux 8.2. I'm using DRI/Mesa with my Matrox G400 -- had to hand-edit XF86Config-4. I installed Mesa myself (./configure, make, make install); it's 4.0.4. Maybe this is useful:
    Code :
    [john@localhost src]$ lspci
    ---[snip]---
    01:00.0 VGA compatible controller: Matrox Graphics, Inc. MGA G400 AGP (rev 04)
     
    [john@localhost src]$ glxinfo
    name of display: :0.0
    display: :0  screen: 0
    direct rendering: Yes
    server glx vendor string: SGI
    server glx version string: 1.2
    server glx extensions:
        GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_EXT_import_context
    client glx vendor string: SGI
    client glx version string: 1.2
    client glx extensions:
        GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_EXT_import_context
    GLX extensions:
        GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_EXT_import_context
    OpenGL vendor string: VA Linux Systems Inc.
    OpenGL renderer string: Mesa DRI G400 20010622 AGP 1x x86/MMX/3DNow!
    OpenGL version string: 1.2 Mesa 3.4.2
    OpenGL extensions:
    ---[snip]---
    Hmm... dunno why it says Mesa 3.4.2 there... Uh oh. I think I recall reading somewhere that when you use DRI, you're supposed to use only the Mesa libs that come with the DRI release.

    I may have installed Mesa improperly. I need to study this some more.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •