aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Draxinger <Wolfgang.Draxinger@draxit.de>2016-08-02 16:39:18 +0200
committerWolfgang Draxinger <Wolfgang.Draxinger@draxit.de>2016-08-02 16:39:18 +0200
commit5f280e26b131fd5f2b569ce0ff48a2b9cfa9b128 (patch)
tree4fe74ee7bd34eb21f40ef803310cbe08470a85d3
parentff5c0c58953aa679b2b794906428f8a7cd2b2696 (diff)
downloadcodesamples-5f280e26b131fd5f2b569ce0ff48a2b9cfa9b128.tar.gz
codesamples-5f280e26b131fd5f2b569ce0ff48a2b9cfa9b128.tar.bz2
-rw-r--r--samples/OpenGL/x11argb_opengl/Makefile2
-rw-r--r--samples/OpenGL/x11argb_opengl/x11argb_opengl.c3
-rw-r--r--samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c36
-rw-r--r--samples/OpenGL/x11xcb_opengl/x11xcb_opengl.c238
4 files changed, 271 insertions, 8 deletions
diff --git a/samples/OpenGL/x11argb_opengl/Makefile b/samples/OpenGL/x11argb_opengl/Makefile
index abafd5c..5b35c1b 100644
--- a/samples/OpenGL/x11argb_opengl/Makefile
+++ b/samples/OpenGL/x11argb_opengl/Makefile
@@ -1,3 +1,3 @@
x11argb_opengl: x11argb_opengl.c Makefile
- $(CC) -std=c99 -g3 -o x11argb_opengl -DUSE_GLX_CREATE_CONTEXT_ATTRIB=1 x11argb_opengl.c -lX11 -lXrender -lGL -lm
+ $(CC) -std=c99 -g3 -o x11argb_opengl -DUSE_GLX_CREATE_CONTEXT_ATTRIB=1 -DUSE_GLX_CREATE_WINDOW=1 x11argb_opengl.c -lX11 -lXrender -lGL -lm
diff --git a/samples/OpenGL/x11argb_opengl/x11argb_opengl.c b/samples/OpenGL/x11argb_opengl/x11argb_opengl.c
index 092c202..bf470b6 100644
--- a/samples/OpenGL/x11argb_opengl/x11argb_opengl.c
+++ b/samples/OpenGL/x11argb_opengl/x11argb_opengl.c
@@ -210,6 +210,7 @@ static void createTheWindow()
}
#if USE_GLX_CREATE_WINDOW
+ fputs("glXCreateWindow ", stderr);
int glXattr[] = { None };
glX_window_handle = glXCreateWindow(Xdisplay, fbconfig, window_handle, glXattr);
if( !glX_window_handle ) {
@@ -471,7 +472,7 @@ static void redrawTheWindow()
glXSwapBuffers(Xdisplay, glX_window_handle);
clock_gettime(CLOCK_MONOTONIC_RAW, &Tb);
- fprintf(stderr, "glXSwapBuffers returned after %f ms\n", 1e3*((double)Tb.tv_sec + 1e-6*(double)Tb.tv_nsec) - 1e3*((double)Ta.tv_sec + 1e-6*(double)Ta.tv_nsec));
+ // fprintf(stderr, "glXSwapBuffers returned after %f ms\n", 1e3*((double)Tb.tv_sec + 1e-6*(double)Tb.tv_nsec) - 1e3*((double)Ta.tv_sec + 1e-6*(double)Ta.tv_nsec));
}
int main(int argc, char *argv[])
diff --git a/samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c b/samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c
index 7aae5a8..2813e11 100644
--- a/samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c
+++ b/samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c
@@ -26,6 +26,7 @@
#define _GNU_SOURCE
+#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -41,8 +42,8 @@
#include <X11/extensions/Xrender.h>
#include <X11/Xutil.h>
-#define USE_CHOOSE_FBCONFIG
-#define USE_GLX_CREATE_WINDOW
+#define USE_GLX_CREATE_WINDOW 1
+#define USE_DOUBLEBUFFER 1
static const GLchar *vertex_shader_source =
"#version 120\n"
@@ -182,7 +183,11 @@ static int width, height;
static int VisData[] = {
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+#if USE_DOUBLEBUFFER
GLX_DOUBLEBUFFER, True,
+#else
+GLX_DOUBLEBUFFER, False,
+#endif
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
@@ -296,7 +301,7 @@ static void createTheWindow()
fatalError("Couldn't create the window\n");
}
-#ifdef USE_GLX_CREATE_WINDOW
+#if USE_GLX_CREATE_WINDOW
int glXattr[] = { None };
glX_window_handle = glXCreateWindow(Xdisplay, fbconfig, window_handle, glXattr);
if( !glX_window_handle ) {
@@ -578,8 +583,12 @@ static void redrawTheWindow(double T)
struct timespec Ta, Tb;
+#if USE_DOUBLEBUFFER
glXSwapBuffers(Xdisplay, glX_window_handle);
- glXWaitGL();
+#else
+ glFlush();
+ usleep(10000);
+#endif
}
static double getftime(void) {
@@ -608,8 +617,23 @@ int main(int argc, char *argv[])
if( !init_resources() )
return -1;
- while (updateTheMessageQueue()) {
- redrawTheWindow(getftime());
+ int n_dT_accum = 0;
+ float dT_accum = 0;
+ while( updateTheMessageQueue() ) {
+ float const dT = getftime();
+ redrawTheWindow(dT);
+
+ dT_accum += dT;
+ ++n_dT_accum;
+
+ if( 100 < n_dT_accum ) {
+ fprintf(stderr, "%d frames in %fs (~%fFPS)\n",
+ n_dT_accum,
+ dT_accum,
+ (float)n_dT_accum / dT_accum);
+ dT_accum = 0.f;
+ n_dT_accum = 0;
+ }
}
return 0;
diff --git a/samples/OpenGL/x11xcb_opengl/x11xcb_opengl.c b/samples/OpenGL/x11xcb_opengl/x11xcb_opengl.c
new file mode 100644
index 0000000..e1fc3c3
--- /dev/null
+++ b/samples/OpenGL/x11xcb_opengl/x11xcb_opengl.c
@@ -0,0 +1,238 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.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>
+
+static
+void draw()
+{
+ glClearColor(0.2, 0.4, 0.9, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+static
+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;
+}
+
+static
+int setup_and_run(
+ Display* display,
+ xcb_connection_t *connection,
+ int default_screen,
+ xcb_screen_t *screen )
+{
+ xcb_generic_error_t *error;
+
+ /* Query framebuffer configurations */
+ int num_fb_configs = 0;
+ GLXFBConfig * const fb_configs = glXGetFBConfigs(display, default_screen, &num_fb_configs);
+ if( !fb_configs || !num_fb_configs ){
+ fprintf(stderr, "glXGetFBConfigs failed\n");
+ return -1;
+ }
+
+ GLXFBConfig fb_config;
+ int visualID = 0;
+ for(int i = 0; !visualID && i < num_fb_configs; ++i) {
+ /* Select first framebuffer config with a valid visual and query visualID */
+ fb_config = fb_configs[i];
+ XVisualInfo * const visual = glXGetVisualFromFBConfig(display, fb_config);
+ if( !visual ) { continue; }
+ visualID = visual->visualid;
+ }
+ if( !visualID ) {
+ return -1;
+ }
+
+ /* Create OpenGL context */
+ GLXContext const 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 */
+ if((error = xcb_request_check(connection, xcb_create_colormap_checked(
+ connection,
+ XCB_COLORMAP_ALLOC_NONE,
+ colormap,
+ screen->root,
+ visualID)
+ )
+ )){
+ fprintf(stderr, "error creating colormap: %d\n", error->error_code);
+ free(error);
+ return -1;
+ }
+
+ /* Create window */
+ uint32_t const eventmask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
+ uint32_t const valuelist[] = { eventmask, colormap };
+ uint32_t const valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
+
+ if((error= xcb_request_check(connection, xcb_create_window_checked(
+ connection,
+ XCB_COPY_FROM_PARENT,
+ window,
+ screen->root,
+ 0, 0,
+ 150, 150,
+ 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ visualID,
+ valuemask,
+ valuelist)
+ )
+ )){
+ fprintf(stderr, "error creating window: %d\n", error->error_code);
+ return -1;
+ }
+
+ // NOTE: window must be mapped before glXMakeContextCurrent
+ if((error= xcb_request_check(connection, xcb_map_window(connection, window)) )) {
+ fprintf(stderr, "error mapping window");
+ return -1;
+ }
+
+ /* 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;
+}
+
+static
+void screen_from_Xlib_Display(
+ Display * const display,
+ xcb_connection_t *connection,
+ int * const out_screen_num,
+ xcb_screen_t ** const out_screen)
+{
+ xcb_screen_iterator_t screen_iter = xcb_setup_roots_iterator(xcb_get_setup(connection));
+ int screen_num = DefaultScreen(display);
+ while( screen_iter.rem && screen_num > 0 ) {
+ xcb_screen_next(&screen_iter);
+ --screen_num;
+ }
+ *out_screen_num = screen_num;
+ *out_screen = screen_iter.data;
+}
+
+int main(int argc, char* argv[])
+{
+ Display *display;
+
+ /* Open Xlib Display */
+ display = XOpenDisplay(0);
+ if( !display ) {
+ fprintf(stderr, "Can't open display\n");
+ return -1;
+ }
+
+
+ /* 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 */
+ int screen_num;
+ xcb_screen_t *screen = 0;
+ screen_from_Xlib_Display(display, connection, &screen_num, &screen);
+ if( !screen ) {
+ return -1;
+ }
+
+ /* Initialize window and OpenGL context, run main loop and deinitialize */
+ int retval = setup_and_run(display, connection, screen_num, screen);
+
+ /* Cleanup */
+ XCloseDisplay(display);
+
+ return retval;
+}