Results 1 to 6 of 6

Thread: GLUT woes.

  1. #1

    Default GLUT woes.

    Hello,

    I'm a DirectX programmer but I'm trying to move away from Windows. So I've been learning GL/GLUT and it's been pretty simple so far. Right now I'm trying to get it to switch from windowed->fullscreen and vice versa via a menu( I'm not sure if one must maintain resources under OGL, like in DX, so for the moment I'm completely ignoring that train of thought ). However, when I click to make the switch everything goes ape. The resolution changes, but then the screen flickers wildly - sometimes going black for a few seconds and no input is recognised by the program anymore. I have to CTRL+Backspace out and run an init 3 followed by startx in order to get out of it. I'm sure I'm doing something newbish. Could someone please scan their eyes over this code and let me know if they can see anything stupid? - I've commented the bad lines. Thanks.

    Code:
    #include <GL/gl.h> 
    #include <GL/glut.h>
    #include <stdlib.h>
    
    int Handle;
    int Prim;
    GLfloat Rot;
    
    void Menu(int value)
    {
      if(value == 0)
      {
        glutDestroyWindow(Handle);
        exit(0);
      }
      else
      {
          Prim = value;
      }
      
      glutPostRedisplay();
    }
    
    void CreateMenu()
    {
      int submenuid = glutCreateMenu(Menu);
    
      glutAddMenuEntry("Teapot", 2);
      glutAddMenuEntry("Cube", 3);
      glutAddMenuEntry("Torus", 4);
      
      int submenuid0 = glutCreateMenu(Menu);
    
      glutAddMenuEntry("Teapot", 5);
      glutAddMenuEntry("Cube", 6);
      glutAddMenuEntry("Torus", 7);
      
      int submenuid1 = glutCreateMenu(Menu);
    
      glutAddMenuEntry("800x600x32", 9);
      glutAddMenuEntry("1024x768x32", 10);
      glutAddMenuEntry("1280x1024x32", 11);
    
      int menuid = glutCreateMenu(Menu);
    
      glutAddMenuEntry("Clear", 1);
      glutAddSubMenu("Draw As Wire", submenuid);
      glutAddSubMenu("Draw As Solid", submenuid0);
      glutAddSubMenu("Fullscreen", submenuid1);
      glutAddMenuEntry("Windowed", 8);
      glutAddMenuEntry("Quit", 0);
    
      glutAttachMenu(GLUT_RIGHT_BUTTON);
    }
    
    void EnableLight()
    {
        glClearDepth(1);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
    }
    
    //------------------------------------------------------------------------------
    
    void keyboard(unsigned char key, int x, int y) 
    {
        if(key == 'q')
        {
            glutDestroyWindow(Handle);
            exit(0); 
        }
    }
    
    void draw()
    {
        glTranslatef(0, 0, -1);
        //glRotatef(Rot, 0, 0, 1);
        glRotatef(Rot, 1, 0, 0);
        //glRotatef(Rot, 0, 1, 0);
        if(Prim == 1) glutPostRedisplay();
        if(Prim == 2) glutWireTeapot(0.5f);
        if(Prim == 3) glutWireCube(0.5f);
        if(Prim == 4) glutWireTorus(0.3f, 0.6f, 100, 100);
        if(Prim == 5) glutSolidTeapot(0.5f);
        if(Prim == 6) glutSolidCube(0.5f);
        if(Prim == 7) glutSolidTorus(0.3f, 0.6f, 100, 100);
        //if(Prim == 8) glutLeaveGameMode();
        
        if(Prim == 9)
        {
            //glutGameModeString("800x600:32@75");
            //glutEnterGameMode();
        }
        
        if(Prim == 10)
        {
            //glutGameModeString("1024x768:32@75");
            //glutEnterGameMode();
        }
        
        if(Prim == 11)
        {
            //glutGameModeString("1280x1024:32@75");
            //glutEnterGameMode();
        }
    }
    
    void display() 
    {
        glClearColor (0.0,0.0,0.0,1.0);
        glClearDepth(1);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
        glLoadIdentity(); 
        gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 
        draw();
        Rot++;
        glutSwapBuffers();
    }
    
    void reshape(int w, int h) 
    {
        glViewport(0, 0, (GLsizei)w, (GLsizei)h);
        glMatrixMode(GL_PROJECTION); 
        glLoadIdentity(); 
        gluPerspective(45, (GLfloat)w / (GLfloat)h, 1.0, 100.0); 
        glMatrixMode(GL_MODELVIEW); 
    }
    
    int main(int argc, char **argv)
    {
        Prim = 1;
        Rot  = 0.000000001;
        glutInit(&argc, argv);
        glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
        glutInitWindowSize(800, 600);
        glutInitWindowPosition(100, 100);
        Handle = glutCreateWindow("learn learn learn");
        glutDisplayFunc(display);
        glutIdleFunc(display);
        glutReshapeFunc(reshape);
        glutKeyboardFunc(keyboard);
        EnableLight();
        CreateMenu();
        glutMainLoop();
        return 0;
    }

  2. #2
    Join Date
    Jun 2008
    Location
    Oklahoma, US
    Posts
    822

    Default Re: GLUT woes.

    geoff001 wrote:

    >
    > Hello,
    >
    > I'm a DirectX programmer but I'm trying to move away from Windows. So
    > I've been learning GL/GLUT and it's been pretty simple so far. Right
    > now I'm trying to get it to switch from windowed->fullscreen and vice
    > versa via a menu( I'm not sure if one must maintain resources under
    > OGL, like in DX, so for the moment I'm completely ignoring that train
    > of thought ). However, when I click to make the switch everything goes
    > ape. The resolution changes, but then the screen flickers wildly -
    > sometimes going black for a few seconds and no input is recognised by
    > the program anymore. I have to CTRL+Backspace out and run an init 3
    > followed by startx in order to get out of it. I'm sure I'm doing
    > something newbish. Could someone please scan their eyes over this code
    > and let me know if they can see anything stupid? - I've commented the
    > bad lines. Thanks.
    >
    >
    > Code:
    > --------------------
    >
    > #include <GL/gl.h>
    > #include <GL/glut.h>
    > #include <stdlib.h>
    >
    > int Handle;
    > int Prim;
    > GLfloat Rot;
    >
    > void Menu(int value)
    > {
    > if(value == 0)
    > {
    > glutDestroyWindow(Handle);
    > exit(0);
    > }
    > else
    > {
    > Prim = value;
    > }
    >
    > glutPostRedisplay();
    > }
    >
    > void CreateMenu()
    > {
    > int submenuid = glutCreateMenu(Menu);
    >
    > glutAddMenuEntry("Teapot", 2);
    > glutAddMenuEntry("Cube", 3);
    > glutAddMenuEntry("Torus", 4);
    >
    > int submenuid0 = glutCreateMenu(Menu);
    >
    > glutAddMenuEntry("Teapot", 5);
    > glutAddMenuEntry("Cube", 6);
    > glutAddMenuEntry("Torus", 7);
    >
    > int submenuid1 = glutCreateMenu(Menu);
    >
    > glutAddMenuEntry("800x600x32", 9);
    > glutAddMenuEntry("1024x768x32", 10);
    > glutAddMenuEntry("1280x1024x32", 11);
    >
    > int menuid = glutCreateMenu(Menu);
    >
    > glutAddMenuEntry("Clear", 1);
    > glutAddSubMenu("Draw As Wire", submenuid);
    > glutAddSubMenu("Draw As Solid", submenuid0);
    > glutAddSubMenu("Fullscreen", submenuid1);
    > glutAddMenuEntry("Windowed", 8);
    > glutAddMenuEntry("Quit", 0);
    >
    > glutAttachMenu(GLUT_RIGHT_BUTTON);
    > }
    >
    > void EnableLight()
    > {
    > glClearDepth(1);
    > glEnable(GL_DEPTH_TEST);
    > glEnable(GL_LIGHTING);
    > glEnable(GL_LIGHT0);
    > }
    >
    > //------------------------------------------------------------------------------
    >
    > void keyboard(unsigned char key, int x, int y)
    > {
    > if(key == 'q')
    > {
    > glutDestroyWindow(Handle);
    > exit(0);
    > }
    > }
    >
    > void draw()
    > {
    > glTranslatef(0, 0, -1);
    > //glRotatef(Rot, 0, 0, 1);
    > glRotatef(Rot, 1, 0, 0);
    > //glRotatef(Rot, 0, 1, 0);
    > if(Prim == 1) glutPostRedisplay();
    > if(Prim == 2) glutWireTeapot(0.5f);
    > if(Prim == 3) glutWireCube(0.5f);
    > if(Prim == 4) glutWireTorus(0.3f, 0.6f, 100, 100);
    > if(Prim == 5) glutSolidTeapot(0.5f);
    > if(Prim == 6) glutSolidCube(0.5f);
    > if(Prim == 7) glutSolidTorus(0.3f, 0.6f, 100, 100);
    > //if(Prim == 8) glutLeaveGameMode();
    >
    > if(Prim == 9)
    > {
    > //glutGameModeString("800x600:32@75");
    > //glutEnterGameMode();
    > }
    >
    > if(Prim == 10)
    > {
    > //glutGameModeString("1024x768:32@75");
    > //glutEnterGameMode();
    > }
    >
    > if(Prim == 11)
    > {
    > //glutGameModeString("1280x1024:32@75");
    > //glutEnterGameMode();
    > }
    > }
    >
    > void display()
    > {
    > glClearColor (0.0,0.0,0.0,1.0);
    > glClearDepth(1);
    > glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    > glLoadIdentity();
    > gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    > draw();
    > Rot++;
    > glutSwapBuffers();
    > }
    >
    > void reshape(int w, int h)
    > {
    > glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    > glMatrixMode(GL_PROJECTION);
    > glLoadIdentity();
    > gluPerspective(45, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    > glMatrixMode(GL_MODELVIEW);
    > }
    >
    > int main(int argc, char **argv)
    > {
    > Prim = 1;
    > Rot = 0.000000001;
    > glutInit(&argc, argv);
    > glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    > glutInitWindowSize(800, 600);
    > glutInitWindowPosition(100, 100);
    > Handle = glutCreateWindow("learn learn learn");
    > glutDisplayFunc(display);
    > glutIdleFunc(display);
    > glutReshapeFunc(reshape);
    > glutKeyboardFunc(keyboard);
    > EnableLight();
    > CreateMenu();
    > glutMainLoop();
    > return 0;
    > }
    >
    > --------------------
    >
    >


    Testing with this (neat!!) gives the same issues you pointed out. it fails
    to respond once you flip to fullscreen mode.

    I did read that when you enter 'gamemode', you lose the ability to have
    popup menus... which prevents you from using your menu as written.

    http://www.lighthouse3d.com/opengl/g...x.php?gameglut

    a quote from that page:

    ====
    There is a detail which is very important in the function above, when we
    enter the game mode with glutEnterGameMode we must register the callbacks
    again, and redefine the OpenGL context. The game mode is just like a new
    window, with a different OpenGL and GLUT context. This implies that the
    callbacks for the window mode will have no effect in game mode. In order to
    use callback functions we must register them again. Furthermore, the OpenGL
    context needs to be defined again. For instance display lists created for
    the window mode need to be defined again when entering the game mode.
    ====

    The mouse fails to work too, which would be explained by the above quote.

    Implies that you'll need to reperform the initialization for the
    new 'fullscreen' window once you shift, and then again when you shift back.



    --
    L R Nix
    lornix@lornix.com

  3. #3

    Default Re: GLUT woes.

    Aha, sounds like the device does get reset under GL. Thank you lornix( and thanks for a new bookmarkable site on the subject ).

  4. #4

    Default Re: GLUT woes.

    This is probably more of a general C++ question that highlights my lack of knowledge. But I've put it in this thread so as not to litter the sub-forum.

    I've started classing up what I already know, so I have a basic template to continue learning off the back of. Anyway, on the first glut callback I get a build error. Here is the output:

    Running "/usr/bin/gmake -f Makefile CONF=Debug" in /home/geoff/Documents/projects/azl

    /usr/bin/gmake -f nbproject/Makefile-Debug.mk SUBPROJECTS= .build-conf
    gmake[1]: Entering directory `/home/geoff/Documents/projects/azl'
    mkdir -p build/Debug/GNU-Linux-x86
    g++ -lGL -lglut -c -g -o build/Debug/GNU-Linux-x86/pixieRenderer.o pixieRenderer.cpp
    pixieRenderer.cpp: In member function void pixieRenderer::Initialize(int, char**):
    pixieRenderer.cpp:43: error: argument of type void (pixieRenderer:() does not match void (*)()
    gmake[1]: *** [build/Debug/GNU-Linux-x86/pixieRenderer.o] Error 1
    gmake[1]: Leaving directory `/home/geoff/Documents/projects/azl'
    gmake: *** [.build-impl] Error 2

    Build failed. Exit value 2.
    If I write it all procedurally in one cpp file then simply pass the function to the callback it builds fine. Here is my code:

    Header:
    Code:
    /* 
     * File:   pixieRenderer.h
     * Author: geoff
     *
     * Created on August 10, 2008, 6:10 PM
     */
    
    #ifndef _PIXIERENDERER_H
    #define	_PIXIERENDERER_H
    
    #include "pixieMin.h"
    
    class pixieRenderer
    {
    private:
        int Handle;
        
        void Render();
    public:
        pixieRenderer(){}
        ~pixieRenderer(){}
        
        void Initialize(int argc, char **argv);
    };
    
    #endif	/* _PIXIERENDERER_H */
    CPP:
    Code:
    /* 
     * File:   pixieRenderer.cpp
     * Author: geoff
     *
     * Created on August 10, 2008, 6:16 PM
     */
    
    #include "pixieRenderer.h"
    
    //-----------------------------------------------------------------------------------------
    //## PRIVATE
    //-----------------------------------------------------------------------------------------
    
    ///<summary>
    //  Rendering function, used as glut callback.
    //</summary>
    void pixieRenderer::Render()
    {
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClearDepth(1);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
        glLoadIdentity(); 
        
        //Do drawing here, maybe some kind of meshlists once you have a loader on the go.
        
        glutSwapBuffers();
    }
    
    //-----------------------------------------------------------------------------------------
    //## PUBLIC
    //-----------------------------------------------------------------------------------------
    
    ///<summary>
    //  Setup GL(ut).
    ///</summary>
    void pixieRenderer::Initialize(int argc, char **argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
        glutInitWindowSize(1024, 768);
        glutInitWindowPosition(100, 100);
        pixieRenderer::Handle = glutCreateWindow("Pixie, Aug 2008"); 
        glutDisplayFunc(Render);
    }
    The "glutDisplayFunc()" is the problem line. I've also tried pixieRenderer::Render.

  5. #5
    Join Date
    Jun 2008
    Location
    Oklahoma, US
    Posts
    822

    Default Re: GLUT woes.

    geoff001 wrote:

    > header file:
    > void Render();
    >
    > cpp file:
    > glutDisplayFunc(Render);


    Hi geoff,

    Based on what I found, glut is a 'c' based system, and does not take kindly
    (nor really understand) c++ calling mechanisms. There *is* a c++ based
    glut, called 'glui', but I am not sure it's the right solution. (why add
    another layer of complexity?)

    I was able to reproduce your error here from your posted code and header,
    and with two changes, was able to compile it. (well, it complained about
    no 'main' function, but it DID compile and link!)

    In your pixieRenderer.h header file:

    make the 'void Render();' definition static.

    static void Render();

    In your pixieRenderer.cpp file:

    provide the address of the fully qualified method name:

    glutDisplayFunc(&pixieRenderer::Render);

    Some goodness found here, essentially saying the same:
    http://www.codeguru.com/forum/showthread.php?t=312700

    It's either that, or provide a non-c++ method as a wrapper function. Not
    the best solution there I think. The static method and &... pointer seems
    to work well.

    Hope this helps

    Loni


    --
    L R Nix
    lornix@lornix.com

  6. #6

    Default Re: GLUT woes.

    Thanks Lornix, I'm still learning C++ as you can probably tell( I'm a Delphi programmer at heart ) so the idea that it might be C and therefore not play well in terms of OOP never crossed my mind. Thanks again, the static solution seems the simplest.

Posting Permissions

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