/* A simple program to show how to set up an X window for OpenGL rendering.
* X86 compilation: gcc -o -L/usr/X11/lib main main.c -lGL -lX11
* X64 compilation: gcc -o -L/usr/X11/lib64 main main.c -lGL -lX11
*/
#include <iostream>
#include <string>
#include <stdlib.h>
#include <GL/glx.h> /* this includes the necessary X headers */
#include <GL/gl.h>
#include <X11/X.h> /* X11 constant (e.g. TrueColor) */
#include <X11/keysym.h>
#include "double_cube.h"
#define DEBUG true
int main(int argc, char ** argv)
{
static int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
Display * dpy;
Window win;
float first;
GLfloat start, xAngle = 42.0, yAngle = 82.0, zAngle = 112.0;;
GLboolean doubleBuffer = GL_TRUE;
XVisualInfo * vi;
Colormap cmap;
XSetWindowAttributes swa;
GLXContext cx;
XEvent * event;
GLboolean needRedraw = GL_FALSE, recalcModelView = GL_TRUE;
event = new XEvent;
int dummy;
dpy = XOpenDisplay(NULL);
if (dpy == NULL)
{
fatalError("could not open display");
}
/*** (2) make sure OpenGL's GLX extension supported ***/
if(!glXQueryExtension(dpy, &dummy, &dummy))
{
fatalError("X server has no OpenGL GLX extension");
}
/*** (3) find an appropriate visual ***/
/* find an OpenGL-capable RGB visual with depth buffer */
vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
if (vi == NULL)
{
vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
if (vi == NULL) fatalError("no RGB visual with depth buffer");
doubleBuffer = GL_FALSE;
}
/*** (4) create an OpenGL rendering context ***/
/* create an OpenGL rendering context */
cx = glXCreateContext(dpy, vi, /* no shared dlists */ None, /* direct rendering if possible */ GL_TRUE);
if (cx == NULL)
{
fatalError("could not create rendering context");
}
/*** (5) create an X window with the selected visual ***/
/* create an X colormap since probably not using default visual */
cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
swa.colormap = cmap;
swa.border_pixel = 0;
swa.event_mask = KeyPressMask | ExposureMask | ButtonPressMask | StructureNotifyMask;
win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 1000, 1500, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa);
XSetStandardProperties(dpy, win, "main", "main", None, argv, argc, NULL);
/*** (6) bind the rendering context to the window ***/
glXMakeCurrent(dpy, win, cx);
/*** (7) request the X window to be displayed on the screen ***/
XMapWindow(dpy, win);
/*** (8) configure the OpenGL context for rendering ***/
glEnable(GL_DEPTH_TEST); /* enable depth buffering */
glDepthFunc(GL_LESS); /* pedantic, GL_LESS is the default */
glClearDepth(1.0); /* pedantic, 1.0 is the default */
/* frame buffer clears should be to black */
glClearColor(0.0, 0.0, 0.0, 0.0);
/* set up projection transform */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10.0);
/* establish initial viewport */
/* pedantic, full window size is default viewport */
glViewport(0, 0, 1000, 1500);
glMatrixMode(GL_MODELVIEW);
std::cout<<"Press left mouse button to rotate around X axis.\n";
std::cout<<"Press middle mouse button to rotate around Y axis.\n";
std::cout<<"Press right mouse button to rotate around Z axis.\n";
std::cout<<"Press ESC to quit the application\n";
std::cout<<"Press the any other key to advance to the next stage.\n";
std::cout<<"Please note: due to the limited capacity of OpenGL to display curved lines, a small amount of imprecision may occur in results.\n";
/*** (9) dispatch X events ***/
while (1)
{
if (recalcModelView)
{
glMatrixMode(GL_MODELVIEW);
/* reset modelview matrix to the identity matrix */
glLoadIdentity();
/* move the camera back three units */
glTranslatef(0.0, 0.0, -3.0);
/* rotate by X, Y, and Z angles */
glRotatef(xAngle, 0.1, 0.0, 0.0);
glRotatef(yAngle, 0.0, 0.1, 0.0);
glRotatef(zAngle, 0.0, 0.0, 1.0);
recalcModelView = GL_FALSE;
needRedraw = GL_TRUE;
}
if (needRedraw)
{
glMatrixMode(GL_MODELVIEW);
glMatrixMode(GL_PROJECTION);
glXSwapBuffers(dpy, win);
#if DEBUG
std::cout<<"starting\n";
#endif
double_cube(start, doubleBuffer, dpy, win, event);
needRedraw = GL_FALSE;
}
}
return 0;
}