#include <cstdlib>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/glx.h>
// #include <GL/gl.h>
#include <GL/glu.h>
#include <cassert>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <algorithm>
#include <memory.h>
#include <iostream>
Display *display;
int defaultScreen;
GLXFBConfig *fbConfig;
XVisualInfo *visual;
Window root;
Colormap colorMap;
Window createWindow() {
XSetWindowAttributes swa;
swa.colormap = colorMap;
swa.event_mask = ExposureMask | KeyPressMask;
unsigned long valueMask = CWColormap | CWEventMask;
auto window = XCreateWindow(display, root, 100, 100, 320, 240, 0, visual->depth, InputOutput, visual->visual,
valueMask, &swa);
XMapWindow(display, window);
XStoreName(display, window, "show me");
XFlush(display);
// XSync(display, 0);
return window;
}
void render() {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
int main() {
// connect to X Server
auto displayName = getenv("DISPLAY");
display = XOpenDisplay(displayName);
assert(display);
// get default screen
defaultScreen = DefaultScreen(display);
// get frame buffer configurations
int att[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DOUBLEBUFFER, True, GLX_DEPTH_SIZE, 16, None};
int nelements;
fbConfig = glXChooseFBConfig(display, defaultScreen, att, &nelements);
assert(fbConfig);
// get visual
visual = glXGetVisualFromFBConfig(display, *fbConfig);
assert(visual);
// get root window
root = RootWindow(display, defaultScreen);
colorMap = XCreateColormap(display, root, visual->visual, AllocNone);
// create gl context
auto glContext = glXCreateNewContext(display, *fbConfig, GLX_RGBA_TYPE, 0, GL_TRUE);
// =================================================================
// create window
auto window1 = createWindow();
glXMakeCurrent(display, window1, glContext);
GLenum err = glewInit();
assert(GLEW_OK == err);
glXMakeCurrent(display, None, 0);
XDestroyWindow(display, window1);
auto window = createWindow();
// init opengl status, or create resources
// message loop
for (;;) {
XEvent event;
// XNextEvent(app.display, &event);
if (XCheckMaskEvent(display, ExposureMask | KeyPressMask, &event)) {
switch (event.type) {
case Expose:
break;
case KeyPress:
auto keySys = XkbKeycodeToKeysym(display, event.xkey.keycode, 0,
event.xkey.state & ShiftMask ? 1 : 0);
if (keySys == XK_Escape) { goto L_EXIT; }
// Root::GetInstance()->SetInvalidate();
break;
}
} else {
if (event.xexpose.window == window) {
glXMakeCurrent(display, event.xexpose.window, glContext);
// render
render();
// swap buffer
glXSwapBuffers(display, event.xexpose.window);
}
pthread_yield();
}
}
L_EXIT:
// clear
XFreeColormap(display, colorMap);
if (glXGetCurrentDrawable() == window) {
glXMakeCurrent(display, None, 0);
}
XDestroyWindow(display, window);
XFree(visual);
XFree(fbConfig);
if (glXGetCurrentContext() == glContext) {
glXMakeCurrent(display, None, 0);
}
glXDestroyContext(display, glContext);
// disconnect to X Server
XCloseDisplay(display);
return 0;
}