Skip to content

Instantly share code, notes, and snippets.

@5HT
Created November 19, 2023 04:00
Show Gist options
  • Save 5HT/35480ce546e0781075ae5e5d274e5f8f to your computer and use it in GitHub Desktop.
Save 5HT/35480ce546e0781075ae5e5d274e5f8f to your computer and use it in GitHub Desktop.
Pure Windows X System, Xlib, GLX (Similar to Pure Win32 and Pure Cocoa/NeXT)
#include<stdio.h>
#include<stdlib.h>
#include<X11/X.h>
#include<X11/Xlib.h>
#include<GL/gl.h>
#include<GL/glx.h>
#include<GL/glu.h>
Display *dpy;
Window root;
GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
XVisualInfo *vi;
Colormap cmap;
XSetWindowAttributes swa;
Window win;
GLXContext glc;
XWindowAttributes gwa;
XEvent xev;
void DrawAQuad() {
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1., 1., -1., 1., 1., 20.);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0., 0., 10., 0., 0., 0., 0., 1., 0.);
glBegin(GL_QUADS);
glColor3f(1., 0., 0.); glVertex3f(-.75, -.75, 0.);
glColor3f(0., 1., 0.); glVertex3f( .75, -.75, 0.);
glColor3f(0., 0., 1.); glVertex3f( .75, .75, 0.);
glColor3f(1., 1., 0.); glVertex3f(-.75, .75, 0.);
glEnd();
}
int main(int argc, char *argv[]) {
dpy = XOpenDisplay(NULL);
if(dpy == NULL) {
printf("\n\tcannot connect to X server\n\n");
exit(0);
}
root = DefaultRootWindow(dpy);
vi = glXChooseVisual(dpy, 0, att);
if(vi == NULL) {
printf("\n\tno appropriate visual found\n\n");
exit(0);
}
else {
printf("\n\tvisual %p selected\n", (void *)vi->visualid); /* %p creates hexadecimal output like in glxinfo */
}
cmap = XCreateColormap(dpy, root, vi->visual, AllocNone);
swa.colormap = cmap;
swa.event_mask = ExposureMask | KeyPressMask;
win = XCreateWindow(dpy, root, 0, 0, 600, 600, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
XMapWindow(dpy, win);
XStoreName(dpy, win, "VERY SIMPLE APPLICATION");
glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
glXMakeCurrent(dpy, win, glc);
glEnable(GL_DEPTH_TEST);
while(1) {
XNextEvent(dpy, &xev);
if(xev.type == Expose) {
XGetWindowAttributes(dpy, win, &gwa);
glViewport(0, 0, gwa.width, gwa.height);
DrawAQuad();
glXSwapBuffers(dpy, win);
}
else if(xev.type == KeyPress) {
glXMakeCurrent(dpy, None, NULL);
glXDestroyContext(dpy, glc);
XDestroyWindow(dpy, win);
XCloseDisplay(dpy);
exit(0);
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
/*
If you get linking errors when using C++, you need
to add extern "C" here or in X11-xcb.h, unless
this bug is already fixed in your version:
http://bugs.freedesktop.org/show_bug.cgi?id=22252
*/
#include <X11/Xlib-xcb.h> /* for XGetXCBConnection, link with libX11-xcb */
#include <xcb/xcb.h>
#include <GL/glx.h>
#include <GL/gl.h>
/*
Attribs filter the list of FBConfigs returned by glXChooseFBConfig().
Visual attribs further described in glXGetFBConfigAttrib(3)
*/
static int visual_attribs[] =
{
GLX_X_RENDERABLE, True,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24,
GLX_STENCIL_SIZE, 8,
GLX_DOUBLEBUFFER, True,
//GLX_SAMPLE_BUFFERS , 1,
//GLX_SAMPLES , 4,
None
};
void draw()
{
glClearColor(0.2, 0.4, 0.9, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
}
int main_loop(Display *display, xcb_connection_t *connection, xcb_window_t window, GLXDrawable drawable)
{
int running = 1;
while(running)
{
/* Wait for event */
xcb_generic_event_t *event = xcb_wait_for_event(connection);
if(!event)
{
fprintf(stderr, "i/o error in xcb_wait_for_event");
return -1;
}
switch(event->response_type & ~0x80)
{
case XCB_KEY_PRESS:
/* Quit on key press */
running = 0;
break;
case XCB_EXPOSE:
/* Handle expose event, draw and swap buffers */
draw();
glXSwapBuffers(display, drawable);
break;
default:
break;
}
free(event);
}
return 0;
}
int setup_and_run(Display* display, xcb_connection_t *connection, int default_screen, xcb_screen_t *screen)
{
int visualID = 0;
/* Query framebuffer configurations that match visual_attribs */
GLXFBConfig *fb_configs = 0;
int num_fb_configs = 0;
fb_configs = glXChooseFBConfig(display, default_screen, visual_attribs, &num_fb_configs);
if(!fb_configs || num_fb_configs == 0)
{
fprintf(stderr, "glXGetFBConfigs failed\n");
return -1;
}
printf("Found %d matching FB configs", num_fb_configs);
/* Select first framebuffer config and query visualID */
GLXFBConfig fb_config = fb_configs[0];
glXGetFBConfigAttrib(display, fb_config, GLX_VISUAL_ID , &visualID);
GLXContext context;
/* Create OpenGL context */
context = glXCreateNewContext(display, fb_config, GLX_RGBA_TYPE, 0, True);
if(!context)
{
fprintf(stderr, "glXCreateNewContext failed\n");
return -1;
}
/* Create XID's for colormap and window */
xcb_colormap_t colormap = xcb_generate_id(connection);
xcb_window_t window = xcb_generate_id(connection);
/* Create colormap */
xcb_create_colormap(
connection,
XCB_COLORMAP_ALLOC_NONE,
colormap,
screen->root,
visualID
);
/* Create window */
uint32_t eventmask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
uint32_t valuelist[] = { eventmask, colormap, 0 };
uint32_t valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
xcb_create_window(
connection,
XCB_COPY_FROM_PARENT,
window,
screen->root,
0, 0,
150, 150,
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
visualID,
valuemask,
valuelist
);
// NOTE: window must be mapped before glXMakeContextCurrent
xcb_map_window(connection, window);
/* Create GLX Window */
GLXDrawable drawable = 0;
GLXWindow glxwindow =
glXCreateWindow(
display,
fb_config,
window,
0
);
if(!window)
{
xcb_destroy_window(connection, window);
glXDestroyContext(display, context);
fprintf(stderr, "glXDestroyContext failed\n");
return -1;
}
drawable = glxwindow;
/* make OpenGL context current */
if(!glXMakeContextCurrent(display, drawable, drawable, context))
{
xcb_destroy_window(connection, window);
glXDestroyContext(display, context);
fprintf(stderr, "glXMakeContextCurrent failed\n");
return -1;
}
/* run main loop */
int retval = main_loop(display, connection, window, drawable);
/* Cleanup */
glXDestroyWindow(display, glxwindow);
xcb_destroy_window(connection, window);
glXDestroyContext(display, context);
return retval;
}
int main(int argc, char* argv[])
{
Display *display;
int default_screen;
/* Open Xlib Display */
display = XOpenDisplay(0);
if(!display)
{
fprintf(stderr, "Can't open display\n");
return -1;
}
default_screen = DefaultScreen(display);
/* Get the XCB connection from the display */
xcb_connection_t *connection =
XGetXCBConnection(display);
if(!connection)
{
XCloseDisplay(display);
fprintf(stderr, "Can't get xcb connection from display\n");
return -1;
}
/* Acquire event queue ownership */
XSetEventQueueOwner(display, XCBOwnsEventQueue);
/* Find XCB screen */
xcb_screen_t *screen = 0;
xcb_screen_iterator_t screen_iter =
xcb_setup_roots_iterator(xcb_get_setup(connection));
for(int screen_num = default_screen;
screen_iter.rem && screen_num > 0;
--screen_num, xcb_screen_next(&screen_iter));
screen = screen_iter.data;
/* Initialize window and OpenGL context, run main loop and deinitialize */
int retval = setup_and_run(display, connection, default_screen, screen);
/* Cleanup */
XCloseDisplay(display);
return retval;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include "common/other.h"
#include "common/error.h"
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
typedef GLXContext (*glXCreateContextAttribsARBProc)
(Display*, GLXFBConfig, GLXContext, Bool, const int*);
const int visual_attribs[] = {
GLX_X_RENDERABLE , true,
GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
GLX_RENDER_TYPE , GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
GLX_RED_SIZE , 8,
GLX_GREEN_SIZE , 8,
GLX_BLUE_SIZE , 8,
GLX_ALPHA_SIZE , 8,
GLX_DEPTH_SIZE , 24,
GLX_STENCIL_SIZE , 8,
GLX_DOUBLEBUFFER , true,
//GLX_SAMPLE_BUFFERS , 1,
//GLX_SAMPLES , 4,
None
};
void checkGlxVersion(Display* display) {
int glx_major, glx_minor;
// FBConfigs were added in GLX version 1.3.
if (!glXQueryVersion(display, &glx_major, &glx_minor) ||
((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1))
fail("Invalid GLX version");
}
GLXFBConfig chooseFBConfig(Display* display) {
printf("Getting matching framebuffer configs\n");
int fbcount;
GLXFBConfig* fbc = glXChooseFBConfig(display, DefaultScreen(display),
visual_attribs, &fbcount);
if (!fbc)
fail("Failed to retrieve a framebuffer config\n");
printf("Found %d matching FB configs.\n", fbcount);
// Pick the FB config/visual with the most samples per pixel
printf("Getting XVisualInfos\n");
int best_fbc = -1, worst_fbc = -1, best_num_samp = -1,
worst_num_samp = 999;
for (int i = 0; i < fbcount; ++i) {
XVisualInfo *vi = glXGetVisualFromFBConfig(display, fbc[i]);
if (vi) {
int samp_buf, samples;
glXGetFBConfigAttrib(display, fbc[i], GLX_SAMPLE_BUFFERS,
&samp_buf);
glXGetFBConfigAttrib(display, fbc[i], GLX_SAMPLES, &samples);
printf("\tMatching fbconfig %d, visual ID 0x%2lx: "
"SAMPLE_BUFFERS = %d, SAMPLES = %d\n",
i, vi -> visualid, samp_buf, samples);
if (best_fbc < 0 || (samp_buf && samples) > best_num_samp)
best_fbc = i, best_num_samp = samples;
if (worst_fbc < 0 || !samp_buf || samples < worst_num_samp)
worst_fbc = i, worst_num_samp = samples;
}
XFree(vi);
}
GLXFBConfig best = fbc[best_fbc];
XFree(fbc);
return best;
}
GLXContext createContext(Display* display, GLXFBConfig bestFbc) {
// NOTE: It is not necessary to create or make current to a context before
// calling glXGetProcAddressARB
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB");
int context_attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
//GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
None
};
printf("Creating context\n");
GLXContext context = 0;
context = glXCreateContextAttribsARB(display, bestFbc, 0,
true, context_attribs);
// Sync to ensure any errors generated are processed.
XSync(display, false);
if (context) printf("Created GL 3.0 context\n");
else fail("Failed to create GL 3.0 context\n");
// Sync to ensure any errors generated are processed.
XSync(display, false);
if (! glXIsDirect(display, context))
printf("Indirect GLX rendering context obtained\n");
else
printf("Direct GLX rendering context obtained\n");
return context;
}
int main(int argc, char* argv[]) {
Display *display = XOpenDisplay(NULL);
if (!display)
fail("Failed to open X display\n");
checkGlxVersion(display);
auto bestFbc = chooseFBConfig(display);
// Get a visual
XVisualInfo *vi = glXGetVisualFromFBConfig(display, bestFbc);
printf("Chosen visual ID = 0x%lx\n", vi->visualid);
printf("Creating colormap\n");
XSetWindowAttributes swa;
Colormap cmap;
swa.colormap = cmap = XCreateColormap(display,
RootWindow(display, vi->screen),
vi->visual, AllocNone);
swa.background_pixmap = None ;
swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask;
printf("Creating window\n");
Window win = XCreateWindow(display, RootWindow(display, vi->screen),
0, 0, 100, 100, 0, vi->depth, InputOutput,
vi->visual,
CWBorderPixel|CWColormap|CWEventMask, &swa);
if (!win)
fail("Failed to create window.\n");
// Done with the visual info data
XFree(vi);
XStoreName(display, win, "GL 3.0 Window");
printf("Mapping window\n");
XMapWindow(display, win);
auto context = createContext(display, bestFbc);
printf("Making context current\n");
glXMakeCurrent(display, win, context);
initGlew();
glClearColor(0, 0.5, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
glXSwapBuffers(display, win);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
sleep(1);
glClearColor(1, 0.5, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glXSwapBuffers(display, win);
sleep(1);
glXMakeCurrent(display, 0, 0);
glXDestroyContext(display, context);
XDestroyWindow(display, win);
XFreeColormap(display, cmap);
XCloseDisplay(display);
return 0;
}
#include <stdio.h>
#include <X11/Xlib.h>
// This program draws a red line and some text in a chosen font.
Display *display;
Window window;
XSetWindowAttributes attributes;
XGCValues gr_values;
XFontStruct *fontinfo;
GC gr_context;
Visual *visual;
int depth;
int screen;
XEvent event;
XColor color, dummy;
int main() {
display = XOpenDisplay(NULL);
screen = DefaultScreen(display);
visual = DefaultVisual(display,screen);
depth = DefaultDepth(display,screen);
attributes.background_pixel = XWhitePixel(display,screen);
window = XCreateWindow( display,XRootWindow(display,screen),
200, 200, 350, 200, 5, depth, InputOutput,
visual ,CWBackPixel, &attributes);
XSelectInput(display,window,ExposureMask | KeyPressMask) ;
fontinfo = XLoadQueryFont(display,"8x14");
XAllocNamedColor(display, DefaultColormap(display, screen),"red",
&color,&dummy);
gr_values.font = fontinfo->fid;
gr_values.foreground = color.pixel;
gr_context=XCreateGC(display,window,GCFont+GCForeground, &gr_values);
XFlush(display);
XMapWindow(display,window);
XFlush(display);
while(1){
XNextEvent(display,&event);
switch(event.type){
case Expose:
XDrawLine(display,window,gr_context,0,0, 100, 100);
XDrawString(display,window,gr_context,100,100,"hello",5);
break;
case KeyPress:
XCloseDisplay(display);
return 1;
}
}
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<math.h>
#include<time.h>
#include<sys/time.h>
#include<X11/Xlib.h>
#include<X11/XKBlib.h>
#include<GL/glx.h>
#include<GL/glext.h>
#include<GL/glu.h>
//////////////////////////////////////////////////////////////////////////////////
// GLOBAL IDENTIFIERS //
//////////////////////////////////////////////////////////////////////////////////
Display *dpy;
Window root, win;
GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
XVisualInfo *vi;
GLXContext glc;
Colormap cmap;
XSetWindowAttributes swa;
XWindowAttributes wa;
XEvent xev;
float TimeCounter, LastFrameTimeCounter, DT, prevTime = 0.0, FPS;
struct timeval tv, tv0;
int Frame = 1, FramesPerFPS;
GLfloat rotation_matrix[16];
float rot_z_vel = 50.0, rot_y_vel = 30.0;
//////////////////////////////////////////////////////////////////////////////////
// DRAW A CUBE //
//////////////////////////////////////////////////////////////////////////////////
void DrawCube(float size) {
glBegin(GL_QUADS);
glColor3f(0.7, 0.0, 0.0);
glVertex3f(-size, -size, -size);
glVertex3f( size, -size, -size);
glVertex3f( size, size, -size);
glVertex3f(-size, size, -size);
glVertex3f(-size, -size, size);
glVertex3f( size, -size, size);
glVertex3f( size, size, size);
glVertex3f(-size, size, size);
glColor3f(0.0, 0.0, 0.7);
glVertex3f(-size, -size, -size);
glVertex3f(-size, -size, size);
glVertex3f(-size, size, size);
glVertex3f(-size, size, -size);
glVertex3f( size, -size, -size);
glVertex3f( size, -size, size);
glVertex3f( size, size, size);
glVertex3f( size, size, -size);
glColor3f(0.0, 0.7, 0.0);
glVertex3f(-size, -size, -size);
glVertex3f(-size, -size, size);
glVertex3f( size, -size, size);
glVertex3f( size, -size, -size);
glVertex3f(-size, size, -size);
glVertex3f(-size, size, size);
glVertex3f( size, size, size);
glVertex3f( size, size, -size);
glEnd();
}
//////////////////////////////////////////////////////////////////////////////////
// ROTATE THE CUBE //
//////////////////////////////////////////////////////////////////////////////////
void RotateCube() {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(rot_y_vel*DT, 0.0, 1.0, 0.0);
glRotatef(rot_z_vel*DT, 0.0, 0.0, 1.0);
glMultMatrixf(rotation_matrix);
glGetFloatv(GL_MODELVIEW_MATRIX, rotation_matrix);
}
//////////////////////////////////////////////////////////////////////////////////
// EXPOSURE FUNCTION //
//////////////////////////////////////////////////////////////////////////////////
void ExposeFunc() {
float aspect_ratio;
char info_string[256];
/////////////////////////////////
// RESIZE VIEWPORT //
/////////////////////////////////
XGetWindowAttributes(dpy, win, &wa);
glViewport(0, 0, wa.width, wa.height);
aspect_ratio = (float)(wa.width) / (float)(wa.height);
/////////////////////////////////////////
// SETUP PROJECTION & MODELVIEW //
/////////////////////////////////////////
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2.50*aspect_ratio, 2.50*aspect_ratio, -2.50, 2.50, 1., 100.);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(10., 0., 0., 0., 0., 0., 0., 0., 1.);
glMultMatrixf(rotation_matrix);
/////////////////////////////////
// DRAW CUBE //
/////////////////////////////////
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DrawCube(1.0);
/////////////////////////////////
// DISPLAY TIME, FPS etc. //
/////////////////////////////////
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, (float)wa.width, 0, (float)wa.height, -1., 1.);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(1.0, 1.0, 1.0);
sprintf(info_string, "%4.1f seconds * %4.1f fps at %i x %i", TimeCounter, FPS, wa.width, wa.height, rot_z_vel);
glRasterPos2i(10, 10);
glCallLists(strlen(info_string), GL_UNSIGNED_BYTE, info_string);
sprintf(info_string, "<up,down,left,right> rotate cube * <F1> stop rotation ");
glRasterPos2i(10, wa.height-32);
glCallLists(strlen(info_string), GL_UNSIGNED_BYTE, info_string);
/////////////////////////////////
// SWAP BUFFERS //
/////////////////////////////////
glXSwapBuffers(dpy, win);
}
//////////////////////////////////////////////////////////////////////////////////
// CREATE A GL CAPABLE WINDOW //
//////////////////////////////////////////////////////////////////////////////////
void CreateWindow() {
if((dpy = XOpenDisplay(NULL)) == NULL) {
printf("\n\tcannot connect to x server\n\n");
exit(0);
}
root = DefaultRootWindow(dpy);
if((vi = glXChooseVisual(dpy, 0, att)) == NULL) {
printf("\n\tno matching visual\n\n");
exit(0);
}
if((cmap = XCreateColormap(dpy, root, vi->visual, AllocNone)) == 0) {
printf("\n\tcannot create colormap\n\n");
exit(0);
}
swa.event_mask = KeyPressMask;
swa.colormap = cmap;
win = XCreateWindow(dpy, root, 0, 0, 700, 700, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
XStoreName(dpy, win, "OpenGL Animation");
XMapWindow(dpy, win);
}
//////////////////////////////////////////////////////////////////////////////////
// SETUP GL CONTEXT //
//////////////////////////////////////////////////////////////////////////////////
void SetupGL() {
char font_string[128];
XFontStruct *font_struct;
/////////////////////////////////////////////////
// CREATE GL CONTEXT AND MAKE IT CURRENT //
/////////////////////////////////////////////////
if((glc = glXCreateContext(dpy, vi, NULL, GL_TRUE)) == NULL) {
printf("\n\tcannot create gl context\n\n");
exit(0);
}
glXMakeCurrent(dpy, win, glc);
glEnable(GL_DEPTH_TEST);
glClearColor(0.00, 0.00, 0.40, 1.00);
/////////////////////////////////////////////////
// FIND A FONT //
/////////////////////////////////////////////////
for(int font_size = 14; font_size < 32; font_size += 2) {
sprintf(font_string, "Arial", font_size);
font_struct = XLoadQueryFont(dpy, font_string);
if(font_struct != NULL) {
glXUseXFont(font_struct->fid, 32, 192, 32);
break;
}
}
/////////////////////////////////////////////////
// INITIALIZE ROTATION MATRIX //
/////////////////////////////////////////////////
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, rotation_matrix);
}
//////////////////////////////////////////////////////////////////////////////////
// TIME COUNTER FUNCTIONS //
//////////////////////////////////////////////////////////////////////////////////
void InitTimeCounter() {
gettimeofday(&tv0, NULL);
FramesPerFPS = 30; }
void UpdateTimeCounter() {
LastFrameTimeCounter = TimeCounter;
gettimeofday(&tv, NULL);
TimeCounter = (float)(tv.tv_sec-tv0.tv_sec) + 0.000001*((float)(tv.tv_usec-tv0.tv_usec));
DT = TimeCounter - LastFrameTimeCounter;
}
void CalculateFPS() {
Frame ++;
if((Frame%FramesPerFPS) == 0) {
FPS = ((float)(FramesPerFPS)) / (TimeCounter-prevTime);
prevTime = TimeCounter;
}
}
//////////////////////////////////////////////////////////////////////////////////
// EXIT PROGRAM //
//////////////////////////////////////////////////////////////////////////////////
void ExitProgram() {
glXMakeCurrent(dpy, None, NULL);
glXDestroyContext(dpy, glc);
XDestroyWindow(dpy, win);
XCloseDisplay(dpy);
exit(0);
}
//////////////////////////////////////////////////////////////////////////////////
// CHECK EVENTS //
//////////////////////////////////////////////////////////////////////////////////
void CheckKeyboard() {
if(XCheckWindowEvent(dpy, win, KeyPressMask, &xev)) {
char *key_string = XKeysymToString(XkbKeycodeToKeysym(dpy, xev.xkey.keycode, 0, 0));
if(strncmp(key_string, "Left", 4) == 0) {
rot_z_vel -= 200.0*DT;
}
else if(strncmp(key_string, "Right", 5) == 0) {
rot_z_vel += 200.0*DT;
}
else if(strncmp(key_string, "Up", 2) == 0) {
rot_y_vel -= 200.0*DT;
}
else if(strncmp(key_string, "Down", 4) == 0) {
rot_y_vel += 200.0*DT;
}
else if(strncmp(key_string, "F1", 2) == 0) {
rot_y_vel = 0.0;
rot_z_vel = 0.0;
}
else if(strncmp(key_string, "Escape", 5) == 0) {
ExitProgram();
}
}
}
//////////////////////////////////////////////////////////////////////////////////
// MAIN PROGRAM //
//////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[]){
CreateWindow();
SetupGL();
InitTimeCounter();
while(1) {
UpdateTimeCounter();
CalculateFPS();
RotateCube();
ExposeFunc();
usleep(1000);
CheckKeyboard();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment