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();
}