GLX, two windows

Hi,
my goal is simple: to have two windows drawn simultaniusly (well almost), as I am beginner coder it has made my life rather misrable the thing is that I started out with nebula device: the outcome was: the first window that was drawn was all messed up, second one worked OK,
So I tried GLUT, could not figure a way to draw to two different screens…
So the next step was offcource gl/glu/glx/X, evrything seems to be working but the same problem, first screen is messed up -> that in turn led me to think that maybe it is the problem of Nvidia drivers as I use Suse9 with FX5600 & GForce4 MX420 with Nvidia’s own drivers…

amyhow here is the code (it is likley that it is my own stupidity)

#include <X11/Xlib.h>
#include <unistd.h>

#include <iostream>
#include <stdlib.h>

#include <GL/glx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/keysym.h>

using namespace std;

static int wAttrSingle[]={GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None};
static int wAttrDouble[]={GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None};

class window {
public:
window();
~window();

	Display *getDisplay();
	
	void create(char *display, int screen, unsigned int height, unsigned int width, char *title);
	void kill();
	void draw();
	
	void resize(unsigned int width, unsigned int height);
private:
	void initGL();
	Display *wDisplay;
	XVisualInfo *wVisualInfo;
	Colormap wColormap;
	XSetWindowAttributes wWindowAttributes;
	Window wWindow;
	bool wDoubleBuffered;
	GLXContext wGLXContext;
	unsigned int wWidth, wHeight;

};

window::window() {}
window::~window() {}

Display *window::getDisplay() {
return wDisplay;
}

void window::create(char *display, int screen, unsigned int height, unsigned int width, char *title) {

wWidth=width;
wHeight=height;

if(display=="") wDisplay = XOpenDisplay(0);
else wDisplay = XOpenDisplay(0);

if(screen&lt;0) screen=DefaultScreen(wDisplay);

wVisualInfo = glXChooseVisual(wDisplay, screen, wAttrDouble);
if (wVisualInfo == NULL) {
	wDoubleBuffered=false;
	wVisualInfo = glXChooseVisual(wDisplay, screen, wAttrSingle);
}
wGLXContext = glXCreateContext(wDisplay, wVisualInfo, 0, GL_TRUE);
wColormap = XCreateColormap(wDisplay, RootWindow(wDisplay, wVisualInfo-&gt;screen), wVisualInfo-&gt;visual, AllocNone);
wWindowAttributes.colormap = wColormap;
wWindowAttributes.border_pixel = 0;
wWindowAttributes.event_mask = StructureNotifyMask;
wWindow  = XCreateWindow(	wDisplay,
														RootWindow(wDisplay, wVisualInfo-&gt;screen),
														0, 0, wWidth, wHeight, 0, 
														wVisualInfo-&gt;depth, InputOutput, 
														wVisualInfo-&gt;visual, 
														CWBorderPixel | CWColormap | CWEventMask, 
														&wWindowAttributes);
XSetStandardProperties(wDisplay, wWindow, title, title, None, NULL, 0, NULL);
XMapWindow(wDisplay, wWindow);
glXMakeCurrent(wDisplay, wWindow, wGLXContext);
initGL();

}

void window::initGL() {
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
resize(wWidth,wHeight);
glFlush();
}

void window::resize(unsigned int width, unsigned int height) {
if(height==0) height=1;
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
wWidth=width;
wHeight=height;
}

void window::draw() {
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -6.0f);
glBegin(GL_TRIANGLES);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
if(wDoubleBuffered) glXSwapBuffers(wDisplay,wWindow);
}

void window::kill() {
glXDestroyContext(wDisplay,wGLXContext);
XCloseDisplay(wDisplay);
}

int main() {
XEvent wEvent;
window aken1, aken2;
bool done=false;

aken1.create("",-1,100,100,"1 st");
aken2.create("",-1,100,100,"2 nd");

while(done==false) {
/* -&gt; Deal with events &lt;- */
	while(XPending(aken1.getDisplay())&gt;0) {
		XNextEvent(aken1.getDisplay(),&wEvent);
		switch(wEvent.type) {
			case Expose:
				if(wEvent.xexpose.count!=0) break;
				aken1.draw();
				aken2.draw();
				break;
			case ConfigureNotify:;
				break;
			case ButtonPress:
				done=true;
				break;
			case ClientMessage:
				if (*XGetAtomName(aken1.getDisplay(), wEvent.xclient.message_type)==*"WM_PROTOCOLS");
				done=true;
			default:
				break;
		}
	}
	aken1.draw();
	aken2.draw();
	sleep(0.1);
}

sleep(5);
aken1.kill();
aken2.kill();

}

I the problem is in my own stupidity but, I cant figure how to make two different rendering contect for a single screen?

when I make the second screen share the context the both windows display the same triangle, but I need it to be different (just syncronized animation) I am sure I am missing something quite fundamental in the spec

-Kaspar

You could use the same display (draw) function and use a different reshape (resize) function. That way you can draw the same things but use a different function to have 2 different cameras, to view your world from another point of view. Also remember that because you create a different rendering context I believe you have to reset things such as lighting, etc. This usually means running the initialization function another time for the second window.