Subwindows not working?

This is a self contained example except for zpr. I simply would like to have 2 sub windows, one 2d and one 3d. The problem is, they dont update! and sometimes they dont get drawn at all!

Surely I am just doing something slightly wrong…

Is it ok to PostRedisplay() to a window from within a different display() function?

Do you have to glutSetWindow(SubID) at the beginning of the subwindow display functions?

Do you have to glutSetWindow(MainID) at the end of the subwindow display functions?

Can someone please glance at this and see if I am doing anything wrong?

Thanks!

Dave


#include <iostream>

#include "zpr.h"
#include <glut.h>
#include <glu.h>
#include <gl.h>

// g++ Test.cpp zpr.c -o Test -lglut -lGLU -lGL -lXmu -lX11 -I/usr/include/GL/ -I./ -L/usr/local/lib
using namespace std;

int MainID, Sub2dID, Sub3dID;

void OpenGLinit(int argc, char *argv[]);
int Create2dSubWindow(int MainID, const double x, const double y, const double w, const double h);
int Create3dSubWindow(int MainID, const double x, const double y, const double w, const double h);
void Display(void);
void DisplaySub3d(void);
void DisplaySub2d(void);
void DrawCube();

int main(int argc, char *argv[])
{
	
	OpenGLinit(argc, argv);
	MainID = glutCreateWindow("LidarSimulation");
	zprInit();
	
	glutDisplayFunc(Display);
	//glutKeyboardFunc(ProcessKeyboard);
	//glutSpecialFunc(ProcessSpecialKeys);
	zprSelectionFunc(Display); // Selection mode draw function
	//zprPickFunc(pick);
	
	//setup 2d subwindow
	Sub2dID = Create2dSubWindow(MainID, 0, 0, 300, 200);
	glutDisplayFunc(DisplaySub2d);
	
	glutSetWindow(MainID);
	
	//setup 3d subwindow
	Sub3dID = Create3dSubWindow(MainID, 0, 500, 300, 200);
	glutDisplayFunc(DisplaySub3d);
		
	glutSetWindow(MainID);//return focus to main window
	
	glutMainLoop();

	return 0;
}

void Display(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	DrawCube();
	
	glutSwapBuffers();
	
	//update the 2d subwindow
	glutPostWindowRedisplay(Sub2dID);
	//DisplaySub2d();

	//update the 3d subwindow
	glutPostWindowRedisplay(Sub3dID);
	//DisplaySub3d();
	
	glutSetWindow(MainID);
}

void DisplaySub2d(void)
{
	//glutSetWindow(Sub2dID);

	//glLoadIdentity();

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	DrawCube();
	
	glutSwapBuffers();
	
	//glutSetWindow(MainID);
}

void DisplaySub3d(void)
{
	//glutSetWindow(Sub3dID);
	
	//glLoadIdentity();

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	DrawCube();
		
	glutSwapBuffers();
	
	//glutSetWindow(MainID);
}

void OpenGLinit(int argc, char *argv[])
{
	int WindowHeight = 1000;
	int WindowWidth = 1000;

	//Initialise GLUT and create a window
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(WindowWidth,WindowHeight);
	glutInitWindowPosition(0,0);
	
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	
	//back face culling
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);
	
	//z clipping
	double near = 1, far = 1000;
	glDepthRange(near, far);
	
}

int Create2dSubWindow(int MainID, const double x, const double y, const double w, const double h)
{
	int SubWindowID = glutCreateSubWindow(MainID, x, y, w, h);
                                           
	gluOrtho2D(0, w, 0, h);

	// invert the y axis, down is positive                                  
	glScalef(1, -1, 1);
	//glScalef(1, -1);  

	// move the origin from the bottom left corner to the upper left corner
	glTranslatef(0, -h, 0);                                             

	//glMatrixMode(GL_MODELVIEW);                                           
	
	return SubWindowID;
}



int Create3dSubWindow(int MainID, const double x, const double y, const double w, const double h)
{
	int SubWindowID = glutCreateSubWindow(MainID, x, y, w, h);
                                           
	//glOrtho(-100, 100, -100, 100, 0, 1000);//(left, right, bottom, top, near, far)
	
	//glEnable(GL_LIGHTING);
	//glEnable(GL_LIGHT0);
	
	/*
	glMatrixMode(GL_PROJECTION);    
	
	
	gluLookAt(0, 10, 0,
		  0, 0, 0,
    		  0, 0, 1);

	glMatrixMode(GL_MODELVIEW);                                           
	*/
	
	return SubWindowID;
}



void DrawCube()
{
	glBegin(GL_QUADS);
		glColor3f(1.0f,0.0f,0.0f); // Red
		glVertex3f(-1.0f, 1.0f, 1.0f);
		glVertex3f( 1.0f, 1.0f, 1.0f);
		glVertex3f( 1.0f, 1.0f,-1.0f);
		glVertex3f(-1.0f, 1.0f,-1.0f);
	
		glColor3f(0.0f,0.0f,1.0f); // Blue
		glVertex3f(-1.0f,-1.0f, 1.0f);
		glVertex3f(-1.0f,-1.0f,-1.0f);
		glVertex3f( 1.0f,-1.0f,-1.0f);
		glVertex3f( 1.0f,-1.0f, 1.0f);
	glEnd();
     glBegin(GL_TRIANGLE_STRIP);
	glColor3f(1.0f,1.0f,1.0f); // White
	glVertex3f(-1.0f, 1.0f, 1.0f);
	glVertex3f(-1.0f,-1.0f, 1.0f);
	glVertex3f( 1.0f, 1.0f, 1.0f);
	glColor3f(0.0f,1.0f,0.0f); // Green
	glVertex3f( 1.0f,-1.0f, 1.0f);
	glColor3f(1.0f,1.0f,0.0f); // Yellow
	glVertex3f( 1.0f, 1.0f,-1.0f);
	glColor3f(0.0f,1.0f,1.0f); // Aqua?
	glVertex3f( 1.0f,-1.0f,-1.0f);
	glColor3f(0.6f,0.6f,0.6f); // Gray
	glVertex3f(-1.0f, 1.0f,-1.0f);
	glColor3f(0.1f,0.1f,0.1f); // Dark Gray
	glVertex3f(-1.0f,-1.0f,-1.0f);
	glColor3f(0.0f,0.0f,1.0f); // Blue
	glVertex3f(-1.0f, 1.0f, 1.0f);
	glColor3f(1.0f,0.0f,1.0f); // Red
	glVertex3f(-1.0f,-1.0f, 1.0f);
     glEnd();
}


Here are my findings:

Is it ok to PostRedisplay() to a window from within a different display() function?
seems like its working, but it may be better to refresh all windows on an event (keypress, etc).

Do you have to glutSetWindow(SubID) at the beginning of the subwindow display functions?
no, it seems to do this automatically

Do you have to glutSetWindow(MainID) at the end of the subwindow display functions?
nope, especially if you call glutSetWindow(ID) at the beginning of every display (even though I just said I don’t think that is necessary!)

NOTE WELL: subwindows have their own “context” so display lists are not shared between the main window and the subwindow. Ie. if you create display list “1” in the main window context and then call glCallList(1) in the subwindow, nothing will happen because list “1” is not defined for the subwindow!