PDA

View Full Version : GLX, two windows



12-01-2003, 06:04 AM
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<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->screen), wVisualInfo->visual, AllocNone);
wWindowAttributes.colormap = wColormap;
wWindowAttributes.border_pixel = 0;
wWindowAttributes.event_mask = StructureNotifyMask;
wWindow = XCreateWindow( wDisplay,
RootWindow(wDisplay, wVisualInfo->screen),
0, 0, wWidth, wHeight, 0,
wVisualInfo->depth, InputOutput,
wVisualInfo->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) {
/* -> Deal with events <- */
while(XPending(aken1.getDisplay())>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();

}

12-01-2003, 08:35 AM
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

dvm
12-01-2003, 10:47 AM
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.