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.


#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;
}

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/glut/index.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

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

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. :slight_smile:

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:


/* 
 * 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:


/* 
 * 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.

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

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. :slight_smile:

I was registered at your forum. I have printed the test message. Do not delete, please.

taux demande pret personnel en ligne credit simulation](http://pretpersonnelenligne.org) Faire un pret immobilier en ligne avec un bon credittaux demande pret personnel en ligne credit simulation](http://pretpersonnelenligne.org)