aboutsummaryrefslogtreecommitdiff
path: root/samples
diff options
context:
space:
mode:
Diffstat (limited to 'samples')
-rw-r--r--samples/OpenGL/compute_shader/.syntastic_c_config1
-rw-r--r--samples/OpenGL/compute_shader/Makefile19
-rw-r--r--samples/OpenGL/compute_shader/main.c289
-rw-r--r--samples/OpenGL/compute_shader/mvp.vs.glsl12
-rw-r--r--samples/OpenGL/compute_shader/phong.fs.glsl0
-rw-r--r--samples/OpenGL/compute_shader/phong.vs.glsl0
-rw-r--r--samples/OpenGL/compute_shader/positiongen.c51
-rw-r--r--samples/OpenGL/compute_shader/positiongen.glsl24
-rw-r--r--samples/OpenGL/compute_shader/positiongen.h15
-rw-r--r--samples/OpenGL/compute_shader/solid.c64
-rw-r--r--samples/OpenGL/compute_shader/solid.fs.glsl9
-rw-r--r--samples/OpenGL/compute_shader/solid.h17
-rw-r--r--samples/OpenGL/compute_shader/stats.c25
-rw-r--r--samples/OpenGL/compute_shader/stats.h35
-rw-r--r--samples/OpenGL/minimal_glsl/minimal_glsl.c2
-rw-r--r--samples/OpenGL/pocketwatch/pocketwatch.cpp4
-rw-r--r--samples/OpenGL/x11argb_opengl/x11argb_opengl.c16
-rw-r--r--samples/OpenGL/x11argb_opengl_glsl/Makefile4
-rw-r--r--samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c2
-rw-r--r--samples/X11/xcb_shm_image/Makefile9
-rw-r--r--samples/X11/xcb_shm_image/xcb_shm_image_example.c219
21 files changed, 804 insertions, 13 deletions
diff --git a/samples/OpenGL/compute_shader/.syntastic_c_config b/samples/OpenGL/compute_shader/.syntastic_c_config
new file mode 100644
index 0000000..8d5751c
--- /dev/null
+++ b/samples/OpenGL/compute_shader/.syntastic_c_config
@@ -0,0 +1 @@
+-I../../../extra
diff --git a/samples/OpenGL/compute_shader/Makefile b/samples/OpenGL/compute_shader/Makefile
new file mode 100644
index 0000000..f6191f1
--- /dev/null
+++ b/samples/OpenGL/compute_shader/Makefile
@@ -0,0 +1,19 @@
+OBJS = main.o positiongen.o solid.o stats.o shaderloader.o debuggl.o
+CFLAGS = -std=c99 -I../../../extra
+LDLIBS = -lGL -lGLEW -lglut -lm
+
+.PHONY: all clean
+
+all: computeshader
+
+clean:
+ -rm -f $(OBJS) computeshader
+
+computeshader: $(OBJS)
+ $(CC) $(LDFLAGS) -o computeshader $(OBJS) $(LOADLIBES) $(LDLIBS)
+
+shaderloader.o: ../../../extra/shaderloader/shaderloader.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
+
+debuggl.o: ../../../extra/debuggl/debuggl.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
diff --git a/samples/OpenGL/compute_shader/main.c b/samples/OpenGL/compute_shader/main.c
new file mode 100644
index 0000000..a519439
--- /dev/null
+++ b/samples/OpenGL/compute_shader/main.c
@@ -0,0 +1,289 @@
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "debuggl/debuggl.h"
+#include "linmath.h/linmath.h"
+
+#include "positiongen.h"
+#include "solid.h"
+#include "stats.h"
+
+#define HAS_ARCBALL 0
+
+static struct {
+ int width;
+ int height;
+ float aspect;
+} window;
+
+static struct {
+ GLuint vbo;
+ GLuint vao;
+ int grid[2];
+} vertexbuffer;
+
+static GLuint timerquery;
+
+#if HAS_ARCBALL
+#define MAT4X4_IDENTITY {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}}
+static struct dragging {
+ bool left;
+ vec2 v;
+} pointer_dragging;
+static mat4x4 view = MAT4X4_IDENTITY;
+static mat4x4 arcball = MAT4X4_IDENTITY;
+#endif
+
+static struct stats_running drawtime_stats = STATS_RUNNING_INIT;
+
+static
+int create_vertexbuffer(int rows, int cols)
+{
+ size_t const dim = 4;
+
+ debuggl_check( glGenVertexArrays(1, &vertexbuffer.vao) );
+ debuggl_check( glBindVertexArray(vertexbuffer.vao) );
+
+ debuggl_check( glGenBuffers(1, &vertexbuffer.vbo) );
+ debuggl_check( glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer.vbo) );
+
+ debuggl_check( glBufferStorage(GL_ARRAY_BUFFER,
+ sizeof(GLfloat)*dim * rows * cols,
+ NULL, 0 ) );
+
+ debuggl_check( glEnableVertexAttribArray(0) );
+ debuggl_check( glVertexAttribPointer(0, dim, GL_FLOAT, GL_FALSE, 0, 0) );
+
+ vertexbuffer.grid[0] = rows;
+ vertexbuffer.grid[1] = cols;
+
+ debuggl_check( glBindBuffer(GL_ARRAY_BUFFER, 0) );
+ debuggl_check( glBindVertexArray(0) );
+
+ return 0;
+}
+
+static
+int load_shaders(void)
+{
+ int rc;
+ (void)(0
+ || (rc= positiongen_load() )
+ || (rc= solid_load() )
+ );
+ return rc;
+}
+
+static
+int create_resources(void)
+{
+ int rc;
+ (void)(0
+ || (rc= create_vertexbuffer(1024, 1024) )
+ || (rc= load_shaders() )
+ );
+
+ if( !rc ) {
+ debuggl_check( glGenQueries(1, &timerquery) );
+ }
+
+ return rc;
+}
+
+static
+void keyboard(unsigned char key, int x, int y)
+{
+ switch(key) {
+ case 'r':
+ case 'R':
+ load_shaders();
+ glutPostRedisplay();
+ break;
+ }
+}
+
+#if HAS_ARCBALL
+static
+void pointer_button(int button, int state, int x, int y)
+{
+ if( GLUT_LEFT_BUTTON == button ) {
+ if( GLUT_UP == state ) {
+ pointer_dragging.left = false;
+
+ mat4x4_mul(view, arcball, view);
+ mat4x4_orthonormalize(view, view);
+ mat4x4_identity(arcball);
+ }
+ else {
+ pointer_dragging.left = true;
+
+ pointer_dragging.v[0] = 2.f * (float)x / window.width - 1.f;
+ pointer_dragging.v[1] = -2.f * (float)y / window.height + 1.f;
+ }
+ }
+}
+
+static
+void pointer_drag_motion(int x, int y)
+{
+ if( pointer_dragging.left ) {
+ vec2 motion_v = {
+ 2.f * (float)x / window.width - 1.f,
+ -2.f * (float)y / window.height + 1.f
+ };
+
+ mat4x4_identity(arcball);
+ mat4x4_arcball(arcball, arcball,
+ pointer_dragging.v,
+ motion_v,
+ 1 );
+ glutPostRedisplay();
+ }
+}
+#endif
+
+static
+void reshape(int w, int h)
+{
+ window.width = w;
+ window.height = h;
+ window.aspect = (float)w / (float)h;
+
+ stats_running_reset(&drawtime_stats);
+
+ glutPostRedisplay();
+}
+
+static
+void display(void)
+{
+ mat4x4 proj;
+ mat4x4_identity(proj);
+
+ float const fov = 0.5;
+ mat4x4_frustum(proj,
+ -window.aspect*fov,
+ window.aspect*fov,
+ -fov,
+ fov, 1, 5);
+
+ mat4x4 mv;
+ mat4x4_identity(mv);
+ mat4x4_translate(mv, 0, 0, -3);
+#if HAS_ARCBALL
+ mat4x4_mul(mv, mv, arcball);
+ mat4x4_mul(mv, mv, view);
+#endif
+
+ glViewport(0,0,window.width,window.height);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ positiongen_launch(
+ glutGet(GLUT_ELAPSED_TIME)*0.001,
+ vertexbuffer.vbo,
+ vertexbuffer.grid[0],
+ vertexbuffer.grid[1] );
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ float const white[4] = {1., 1., 1., 0.01};
+ glBeginQuery(GL_TIME_ELAPSED, timerquery);
+ solid_draw(
+ GL_POINTS,
+ vertexbuffer.vao,
+ vertexbuffer.grid[0] * vertexbuffer.grid[1],
+ white,
+ mv[0], proj[0]);
+ glEndQuery(GL_TIME_ELAPSED);
+
+ glutSwapBuffers();
+
+ GLuint timeresult;
+ glGetQueryObjectuiv(timerquery, GL_QUERY_RESULT, &timeresult);
+ stats_running_push(&drawtime_stats, timeresult*0.001);
+}
+
+enum {
+ win_width_inc = 64, win_height_inc = 64,
+ win_width_max = 1024, win_height_max = 1024
+};
+static int win_width = win_width_inc, win_height = win_height_inc;
+
+static
+void idle(void)
+{
+ if( 499 < stats_running_N(&drawtime_stats) ) {
+ printf("%4d x %4d: ( %7.1f +/- %7.1f )us\n",
+ win_width, win_height,
+ stats_running_mean(&drawtime_stats),
+ sqrt(stats_running_variance(&drawtime_stats)) );
+
+ win_width += win_width_inc;
+ if( win_width_max < win_width ) {
+ win_height += win_height_inc;
+ if( win_height_max < win_height ) {
+ exit(0);
+ }
+ win_width = win_width_inc;
+ }
+ glutReshapeWindow(win_width, win_height);
+ }
+ glutPostRedisplay();
+}
+
+static
+void gldebugcallback(
+ GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *message,
+ const void *userParam)
+{
+ fprintf(stderr, "(GL) %s\n", message);
+}
+
+static
+void glinfodump(void)
+{
+ printf(
+ "OpenGL vendor: %s\n"
+ "OpenGL renderer: %s\n"
+ "OpenGL version: %s\n",
+ " GLSL version: %s\n",
+ glGetString(GL_VENDOR),
+ glGetString(GL_RENDERER),
+ glGetString(GL_VERSION),
+ glGetString(GL_SHADING_LANGUAGE_VERSION) );
+}
+
+int main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+
+ glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
+ glutInitWindowPosition(0,0);
+ glutInitWindowSize(win_width, win_height);
+ glutCreateWindow("compute shader point overdraw benchmark");
+ if( GLEW_OK != glewInit() ) { return 1; }
+
+ glDebugMessageCallback((GLDEBUGPROC)gldebugcallback, NULL);
+ glEnable(GL_DEBUG_OUTPUT);
+
+ if( create_resources() ) { return 2; }
+
+ glutReshapeFunc(reshape);
+ glutKeyboardFunc(keyboard);
+#if HAS_ARCBALL
+ glutMouseFunc(pointer_button);
+ glutMotionFunc(pointer_drag_motion);
+#endif
+ glutDisplayFunc(display);
+ glutIdleFunc(idle);
+
+ glutMainLoop();
+ return 0;
+}
diff --git a/samples/OpenGL/compute_shader/mvp.vs.glsl b/samples/OpenGL/compute_shader/mvp.vs.glsl
new file mode 100644
index 0000000..4c4d062
--- /dev/null
+++ b/samples/OpenGL/compute_shader/mvp.vs.glsl
@@ -0,0 +1,12 @@
+#version 430
+
+layout(location = 0) in vec4 a_position;
+
+uniform mat4 u_modelview;
+uniform mat4 u_projection;
+
+void main()
+{
+ const mat4 mvp = u_projection * u_modelview;
+ gl_Position = mvp * a_position;
+}
diff --git a/samples/OpenGL/compute_shader/phong.fs.glsl b/samples/OpenGL/compute_shader/phong.fs.glsl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/samples/OpenGL/compute_shader/phong.fs.glsl
diff --git a/samples/OpenGL/compute_shader/phong.vs.glsl b/samples/OpenGL/compute_shader/phong.vs.glsl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/samples/OpenGL/compute_shader/phong.vs.glsl
diff --git a/samples/OpenGL/compute_shader/positiongen.c b/samples/OpenGL/compute_shader/positiongen.c
new file mode 100644
index 0000000..3349ff6
--- /dev/null
+++ b/samples/OpenGL/compute_shader/positiongen.c
@@ -0,0 +1,51 @@
+#include <GL/glew.h>
+#include "positiongen.h"
+
+#include "shaderloader/shaderloader.h"
+#include "debuggl/debuggl.h"
+
+#include <stdio.h>
+
+static struct {
+ GLuint program;
+ GLint w_output;
+ GLint u_time;
+} positiongen;
+
+int positiongen_load(void)
+{
+ debuggl_check( "pre positiongen_load check" );
+
+ char const * const paths[] = { "positiongen.glsl", 0 };
+ shader_program_sources const sources[] = { {GL_COMPUTE_SHADER, paths}, {0,0} };
+
+ if( positiongen.program ) {
+ debuggl_check( glDeleteProgram(positiongen.program) );
+ positiongen.program = 0;
+ }
+
+ positiongen.program = shader_program_load_from_files(sources);
+ if( !positiongen.program ) {
+ fprintf(stderr, "%s failed\n", __func__);
+ return -2;
+ }
+
+ debuggl_check( positiongen.w_output = glGetProgramResourceIndex(positiongen.program, GL_SHADER_STORAGE_BLOCK, "w_output") );
+ debuggl_check( positiongen.u_time = glGetProgramResourceLocation(positiongen.program, GL_UNIFORM, "u_time") );
+
+ return 0;
+}
+
+int positiongen_launch(
+ float t,
+ GLuint vbo,
+ int width,
+ int height )
+{
+ debuggl_check( glUseProgram(positiongen.program) );
+ debuggl_check( glUniform1f(positiongen.u_time, t) );
+ debuggl_check( glBindBufferBase(GL_SHADER_STORAGE_BUFFER, positiongen.w_output, vbo) );
+ debuggl_check( glDispatchCompute(width/16, height/16, 1) );
+ debuggl_check( glBindBufferBase(GL_SHADER_STORAGE_BUFFER, positiongen.w_output, 0) );
+ debuggl_check( glUseProgram(0) );
+}
diff --git a/samples/OpenGL/compute_shader/positiongen.glsl b/samples/OpenGL/compute_shader/positiongen.glsl
new file mode 100644
index 0000000..99018b6
--- /dev/null
+++ b/samples/OpenGL/compute_shader/positiongen.glsl
@@ -0,0 +1,24 @@
+#version 430
+
+layout( local_size_x = 16, local_size_y = 16 ) in;
+layout(std430) buffer;
+layout(binding = 0) buffer w_output {
+ vec4 data[];
+};
+
+uniform float u_time;
+
+void main()
+{
+ uvec3 GlobalSize = gl_WorkGroupSize * gl_NumWorkGroups;
+ uint GlobalInvocationIndex =
+ GlobalSize.x * GlobalSize.y * gl_GlobalInvocationID.z
+ + GlobalSize.x * gl_GlobalInvocationID.y
+ + gl_GlobalInvocationID.x;
+
+ vec2 p = 2*vec2(gl_GlobalInvocationID.xy)/GlobalSize.xy - 1;
+
+ float z = sin(10.*p.x + u_time) + sin(30.*p.y + 0.1*u_time);
+
+ data[GlobalInvocationIndex] = vec4(p, z*0.25, 1);
+}
diff --git a/samples/OpenGL/compute_shader/positiongen.h b/samples/OpenGL/compute_shader/positiongen.h
new file mode 100644
index 0000000..d1a30cd
--- /dev/null
+++ b/samples/OpenGL/compute_shader/positiongen.h
@@ -0,0 +1,15 @@
+#pragma once
+#ifndef POSITIONGEN_H
+#define POSITIONGEN_H
+
+#include <GL/gl.h>
+
+int positiongen_load(void);
+
+int positiongen_launch(
+ float t,
+ GLuint vbo,
+ int width,
+ int height );
+
+#endif/*POSITIONGEN_H*/
diff --git a/samples/OpenGL/compute_shader/solid.c b/samples/OpenGL/compute_shader/solid.c
new file mode 100644
index 0000000..982e24a
--- /dev/null
+++ b/samples/OpenGL/compute_shader/solid.c
@@ -0,0 +1,64 @@
+#include <GL/glew.h>
+#include "solid.h"
+
+#include "shaderloader/shaderloader.h"
+#include "debuggl/debuggl.h"
+
+#include <stdio.h>
+
+static struct {
+ GLint program;
+ GLint u_modelview;
+ GLint u_projection;
+ GLint u_color;
+} solid;
+
+int solid_load(void)
+{
+ debuggl_check( "pre solid_load check" );
+
+ char const * const paths_vs[] = { "mvp.vs.glsl", 0 };
+ char const * const paths_fs[] = { "solid.fs.glsl", 0 };
+ shader_program_sources const sources[] = {
+ {GL_VERTEX_SHADER, paths_vs},
+ {GL_FRAGMENT_SHADER, paths_fs},
+ {0,0}
+ };
+
+ if( solid.program ) {
+ debuggl_check( glDeleteProgram(solid.program) );
+ solid.program = 0;
+ }
+
+ solid.program = shader_program_load_from_files(sources);
+ if( !solid.program ) {
+ fprintf(stderr, "%s failed\n", __func__);
+ return -2;
+ }
+
+ debuggl_check( solid.u_modelview = glGetProgramResourceLocation(solid.program, GL_UNIFORM, "u_modelview") );
+ debuggl_check( solid.u_projection = glGetProgramResourceLocation(solid.program, GL_UNIFORM, "u_projection") );
+ debuggl_check( solid.u_color = glGetProgramResourceLocation(solid.program, GL_UNIFORM, "u_color") );
+
+ return 0;
+}
+
+int solid_draw(
+ GLenum primitive,
+ GLuint vao,
+ GLsizei count,
+ GLfloat const * const color,
+ GLfloat const * const modelview,
+ GLfloat const * const projection )
+{
+ debuggl_check( (void)"pre solid_draw check" );
+
+ debuggl_check( glBindVertexArray(vao) );
+ debuggl_check( glUseProgram(solid.program) );
+ debuggl_check( glUniform4fv(solid.u_color, 1, color) );
+ debuggl_check( glUniformMatrix4fv(solid.u_modelview, 1, GL_FALSE, modelview) );
+ debuggl_check( glUniformMatrix4fv(solid.u_projection, 1, GL_FALSE, projection) );
+ debuggl_check( glDrawArrays(primitive, 0, count) );
+ debuggl_check( glUseProgram(0) );
+ debuggl_check( glBindVertexArray(0) );
+}
diff --git a/samples/OpenGL/compute_shader/solid.fs.glsl b/samples/OpenGL/compute_shader/solid.fs.glsl
new file mode 100644
index 0000000..397cd33
--- /dev/null
+++ b/samples/OpenGL/compute_shader/solid.fs.glsl
@@ -0,0 +1,9 @@
+#version 430
+
+uniform vec4 u_color;
+out vec4 o_fragcolor;
+
+void main()
+{
+ o_fragcolor = u_color;
+}
diff --git a/samples/OpenGL/compute_shader/solid.h b/samples/OpenGL/compute_shader/solid.h
new file mode 100644
index 0000000..c89aeba
--- /dev/null
+++ b/samples/OpenGL/compute_shader/solid.h
@@ -0,0 +1,17 @@
+#pragma once
+#ifndef SOLID_H
+#define SOLID_H
+
+#include <GL/gl.h>
+
+int solid_load(void);
+
+int solid_draw(
+ GLenum primitive,
+ GLuint vao,
+ GLsizei count,
+ GLfloat const * const color,
+ GLfloat const * const modelview,
+ GLfloat const * const projection );
+
+#endif/*POSITIONGEN_H*/
diff --git a/samples/OpenGL/compute_shader/stats.c b/samples/OpenGL/compute_shader/stats.c
new file mode 100644
index 0000000..1cf7fcb
--- /dev/null
+++ b/samples/OpenGL/compute_shader/stats.c
@@ -0,0 +1,25 @@
+#include "stats.h"
+
+void stats_running_reset(struct stats_running *s)
+{
+ if( s ) {
+ s->n = 0;
+ s->S = NAN;
+ s->m = NAN;
+ }
+}
+
+void stats_running_push(struct stats_running *s, double value)
+{
+ if( s && isfinite(value) ) {
+ double const m_prev = 0 < s->n ? s->m : 0.;
+ double const S_prev = 1 < s->n ? s->S : 0.;
+ unsigned const n = (s->n += 1);
+
+ s->m = m_prev + (value - m_prev) / n;
+ if( 1 < n ) {
+ /* variance is defined only for n > 1 */
+ s->S = S_prev + (value - s->m) * (value - m_prev);
+ }
+ }
+}
diff --git a/samples/OpenGL/compute_shader/stats.h b/samples/OpenGL/compute_shader/stats.h
new file mode 100644
index 0000000..8796161
--- /dev/null
+++ b/samples/OpenGL/compute_shader/stats.h
@@ -0,0 +1,35 @@
+#pragma once
+#ifndef STATS_H
+#define STATS_H
+
+#include <math.h>
+
+struct stats_running {
+ unsigned n;
+ double S;
+ double m;
+};
+#define STATS_RUNNING_INIT {0, NAN, NAN}
+
+void stats_running_reset(struct stats_running *s);
+void stats_running_push(struct stats_running *s, double value);
+
+static inline
+unsigned stats_running_N(struct stats_running const *s)
+{
+ return s ? s->n : 0;
+}
+
+static inline
+double stats_running_mean(struct stats_running const *s)
+{
+ return s && (0 < s->n) ? s->m : NAN;
+}
+
+static inline
+double stats_running_variance(struct stats_running const *s)
+{
+ return s && (1 < s->n) ? s->S/s->n : NAN;
+}
+
+#endif/*STATS_H*/
diff --git a/samples/OpenGL/minimal_glsl/minimal_glsl.c b/samples/OpenGL/minimal_glsl/minimal_glsl.c
index 72ba3ff..f8599cb 100644
--- a/samples/OpenGL/minimal_glsl/minimal_glsl.c
+++ b/samples/OpenGL/minimal_glsl/minimal_glsl.c
@@ -1,7 +1,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <GL/glew.h>
-#include <GL/glfw.h>
+#include <GLFW/glfw3.h>
static void pushModelview()
{
diff --git a/samples/OpenGL/pocketwatch/pocketwatch.cpp b/samples/OpenGL/pocketwatch/pocketwatch.cpp
index e04ad0e..f6b49b0 100644
--- a/samples/OpenGL/pocketwatch/pocketwatch.cpp
+++ b/samples/OpenGL/pocketwatch/pocketwatch.cpp
@@ -14,7 +14,7 @@ void idle();
int main(int argc, char **argv)
{
glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
+ glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH|GLUT_MULTISAMPLE);
glutCreateWindow("PocketWatch");
glutDisplayFunc(display);
@@ -37,6 +37,8 @@ void init()
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
+
+ glEnable(GL_MULTISAMPLE);
}
float light_position[]={-0.5,0.5,1,0};
diff --git a/samples/OpenGL/x11argb_opengl/x11argb_opengl.c b/samples/OpenGL/x11argb_opengl/x11argb_opengl.c
index bf470b6..fb1b54c 100644
--- a/samples/OpenGL/x11argb_opengl/x11argb_opengl.c
+++ b/samples/OpenGL/x11argb_opengl/x11argb_opengl.c
@@ -160,6 +160,7 @@ static void createTheWindow()
if(pict_format->direct.alphaMask > 0) {
break;
}
+ XFree(visual);
}
if(!fbconfig) {
@@ -253,7 +254,7 @@ static void createTheWindow()
static int ctxErrorHandler( Display *dpy, XErrorEvent *ev )
{
- fputs("Error at context creation", stderr);
+ fputs("Error at context creation\n", stderr);
return 0;
}
@@ -270,12 +271,12 @@ static void createTheRenderContext()
render_context = NULL;
if( isExtensionSupported( glXQueryExtensionsString(Xdisplay, DefaultScreen(Xdisplay)), "GLX_ARB_create_context" ) ) {
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
- glXCreateContextAttribsARBProc glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
+ glXCreateContextAttribsARBProc glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB("glXCreateContextAttribsARB" );
if( glXCreateContextAttribsARB ) {
int context_attribs[] =
{
- GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
- GLX_CONTEXT_MINOR_VERSION_ARB, 0,
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 1,
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
None
};
@@ -286,17 +287,16 @@ static void createTheRenderContext()
XSync( Xdisplay, False );
XSetErrorHandler( oldHandler );
-
- fputs("glXCreateContextAttribsARB failed", stderr);
} else {
- fputs("glXCreateContextAttribsARB could not be retrieved", stderr);
+ fputs("glXCreateContextAttribsARB could not be retrieved\n", stderr);
}
} else {
- fputs("glXCreateContextAttribsARB not supported", stderr);
+ fputs("glXCreateContextAttribsARB not supported\n", stderr);
}
if(!render_context)
{
+ fputs("using fallback\n", stderr);
#else
{
#endif
diff --git a/samples/OpenGL/x11argb_opengl_glsl/Makefile b/samples/OpenGL/x11argb_opengl_glsl/Makefile
index 62e3496..b5e461a 100644
--- a/samples/OpenGL/x11argb_opengl_glsl/Makefile
+++ b/samples/OpenGL/x11argb_opengl_glsl/Makefile
@@ -3,8 +3,8 @@
all: x11argb_opengl_glsl x11argb_opengl_glsl3
x11argb_opengl_glsl: x11argb_opengl_glsl.c Makefile
- cc -std=c99 -g3 -o x11argb_opengl_glsl x11argb_opengl_glsl.c -lX11 -lXrender -lGLEW -lm
+ cc -std=c99 -g3 -o x11argb_opengl_glsl x11argb_opengl_glsl.c -lX11 -lXrender -lGL -lGLEW -lm
x11argb_opengl_glsl3: x11argb_opengl_glsl.c Makefile
- cc -std=c99 -g3 -o x11argb_opengl_glsl3 -D USE_GLX_CREATE_CONTEXT_ATTRIB x11argb_opengl_glsl.c -lX11 -lXrender -lGLEW -lm
+ cc -std=c99 -g3 -o x11argb_opengl_glsl3 -D USE_GLX_CREATE_CONTEXT_ATTRIB x11argb_opengl_glsl.c -lX11 -lXrender -lGL -lGLEW -lm
diff --git a/samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c b/samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c
index 2813e11..a5b6180 100644
--- a/samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c
+++ b/samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c
@@ -370,7 +370,7 @@ static void createTheRenderContext()
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
- //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+ GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
None
};
diff --git a/samples/X11/xcb_shm_image/Makefile b/samples/X11/xcb_shm_image/Makefile
new file mode 100644
index 0000000..963a04b
--- /dev/null
+++ b/samples/X11/xcb_shm_image/Makefile
@@ -0,0 +1,9 @@
+.PHONY: all clean
+
+all: xcb_shm_image_example
+
+clean:
+ - rm xcb_shm_image_example xcb_shm_image_example.o
+
+xcb_shm_image_example: LDFLAGS += -lxcb -lxcb-image -lxcb-shm
+xcb_shm_image_example: xcb_shm_image_example.o
diff --git a/samples/X11/xcb_shm_image/xcb_shm_image_example.c b/samples/X11/xcb_shm_image/xcb_shm_image_example.c
new file mode 100644
index 0000000..4f87e76
--- /dev/null
+++ b/samples/X11/xcb_shm_image/xcb_shm_image_example.c
@@ -0,0 +1,219 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include <xcb/xcb.h>
+#include <xcb/shm.h>
+#include <xcb/xcb_image.h>
+
+#if __ORDER_LITTLE_ENDIAN == __BYTE_ORDER__
+# define NATIVE_XCB_IMAGE_ORDER XCB_IMAGE_ORDER_LSB_FIRST
+#else
+# define NATIVE_XCB_IMAGE_ORDER XCB_IMAGE_ORDER_MSB_FIRST
+#endif
+
+enum {
+ IMAGE_WIDTH = 512,
+ IMAGE_HEIGHT = 512,
+ IMAGE_DEPTH = 24,
+};
+
+static xcb_format_t const *query_xcb_format_for_depth(
+ xcb_connection_t *const connection,
+ unsigned depth )
+{
+ xcb_setup_t const *const setup = xcb_get_setup(connection);
+ xcb_format_iterator_t it;
+ for( it = xcb_setup_pixmap_formats_iterator(setup)
+ ; it.rem
+ ; xcb_format_next(&it)
+ ){
+ xcb_format_t const *const format = it.data;
+ if( format->depth == depth ){
+ return format;
+ }
+ }
+ return NULL;
+}
+
+typedef struct shm_xcb_image_t {
+ xcb_connection_t *connection;
+ xcb_image_t *image;
+ xcb_shm_seg_t shm_seg;
+ int shm_id;
+} shm_xcb_image_t;
+
+static shm_xcb_image_t *shm_xcb_image_create(
+ xcb_connection_t *const connection,
+ unsigned const width,
+ unsigned const height,
+ unsigned const depth )
+{
+ xcb_generic_error_t *error = NULL;
+
+ shm_xcb_image_t *shmimg = calloc(1, sizeof(*shmimg));
+ if( !shmimg ){ goto fail; }
+ shmimg->connection = connection;
+
+ xcb_format_t const *const format = query_xcb_format_for_depth(connection, depth);
+ shmimg->image = xcb_image_create(
+ width, height,
+ XCB_IMAGE_FORMAT_Z_PIXMAP,
+ format->scanline_pad,
+ format->depth, format->bits_per_pixel, 0,
+ NATIVE_XCB_IMAGE_ORDER,
+ XCB_IMAGE_ORDER_MSB_FIRST,
+ NULL, ~0, 0);
+ if( !shmimg->image ){
+ fprintf(stderr, "could not create X11 image structure\n");
+ }
+ size_t const image_segment_size = shmimg->image->stride * shmimg->image->height;
+
+ shmimg->shm_id = shmget(IPC_PRIVATE, image_segment_size, IPC_CREAT | 0600);
+ if( 0 > shmimg->shm_id ){ goto fail; }
+
+ shmimg->image->data = shmat(shmimg->shm_id, 0, 0);
+ if( (void*)-1 == (void*)(shmimg->image->data) ){ goto fail; }
+
+ shmimg->shm_seg = xcb_generate_id(connection),
+ error = xcb_request_check(connection,
+ xcb_shm_attach_checked(
+ connection,
+ shmimg->shm_seg, shmimg->shm_id, 0) );
+fail:
+ if( shmimg ){
+ if( shmimg->image ){
+ if( shmimg->image->data && error ){
+ shmdt(shmimg->image->data);
+ shmimg->image->data = NULL;
+ }
+ if( !shmimg->image->data ){
+ shmctl(shmimg->shm_id, IPC_RMID, 0);
+ shmimg->shm_id = -1;
+ }
+ }
+ if( 0 > shmimg->shm_id ){
+ xcb_image_destroy(shmimg->image);
+ shmimg->image = NULL;
+ }
+ if( !shmimg->image ){
+ free(shmimg);
+ shmimg = NULL;
+ }
+ }
+ free(error);
+
+ return shmimg;
+}
+
+static void shm_xcb_image_destroy(shm_xcb_image_t *shmimg)
+{
+ xcb_shm_detach(shmimg->connection, shmimg->shm_seg);
+ shmdt(shmimg->image->data);
+ shmctl(shmimg->shm_id, IPC_RMID, 0);
+ xcb_image_destroy(shmimg->image);
+ free(shmimg);
+}
+
+static void generate_image(
+ shm_xcb_image_t *shmimg,
+ unsigned t )
+{
+ for( unsigned j = 0; j < shmimg->image->height; ++j ){
+ uint8_t *const line = shmimg->image->data + j * shmimg->image->stride;
+ for( unsigned i = 0; i < shmimg->image->width; ++i ){
+ unsigned const bytes_per_pixel = shmimg->image->bpp/8;
+ uint8_t *pixel = line + i * bytes_per_pixel;
+
+ unsigned const a = (i + t);
+ unsigned const b = (j + (i >> 8) & 0xFF);
+ unsigned const c = (j >> 8) & 0xFF;
+
+ switch( bytes_per_pixel ){
+ case 4: pixel[3] = 0xFF; /* fallthrough */
+ case 3: pixel[2] = a & 0xFF; /* fallthrough */
+ case 2: pixel[1] = b & 0xFF; /* fallthrough */
+ case 1: pixel[0] = c & 0xFF; /* fallthrough */
+ default: break;
+ }
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ /* Open the connection to the X server */
+ xcb_connection_t *connection = xcb_connect(NULL, NULL);
+
+ /* Check that X MIT-SHM is available (should be). */
+ const xcb_query_extension_reply_t *shm_extension = xcb_get_extension_data(connection, &xcb_shm_id);
+ if( !shm_extension || !shm_extension->present ){
+ fprintf(stderr, "Query for X MIT-SHM extension failed.\n");
+ return 1;
+ }
+
+ shm_xcb_image_t *shmimg = shm_xcb_image_create(connection, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DEPTH);
+ if( !shmimg ){
+ fprintf(stderr, "Creating shared memory image failed");
+ }
+
+ /* Get the first screen */
+ xcb_screen_t *const screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
+
+ /* Create a window */
+ uint32_t const window_mask = XCB_CW_EVENT_MASK;
+ uint32_t const window_values[] = { XCB_EVENT_MASK_EXPOSURE};
+ xcb_drawable_t const window = xcb_generate_id(connection);
+ xcb_create_window(connection,
+ XCB_COPY_FROM_PARENT, /* depth */
+ window, /* window Id */
+ screen->root, /* parent window */
+ 0, 0, /* x, y */
+ IMAGE_WIDTH, IMAGE_HEIGHT, /* width, height */
+ 0, /* border_width */
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
+ screen->root_visual, /* visual */
+ window_mask, window_values /* masks */
+ );
+
+ /* Create black (foreground) graphic context */
+ xcb_gcontext_t gc = xcb_generate_id( connection );
+ uint32_t const gc_mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
+ uint32_t const gc_values[] = {screen->black_pixel, 0};
+ xcb_create_gc(connection, gc, window, gc_mask, gc_values);
+
+ /* Map the window on the screen and flush*/
+ xcb_map_window(connection, window);
+ xcb_flush(connection);
+
+ /* Event loop */
+ unsigned counter = 0;
+ for( xcb_generic_event_t *event
+ ; (event = xcb_wait_for_event(connection))
+ ; free(event)
+ ){
+ switch( event->response_type & ~0x80 ){
+ case XCB_EXPOSE:
+ generate_image(shmimg, counter++);
+ xcb_shm_put_image(connection, window, gc,
+ shmimg->image->width, shmimg->image->height, 0, 0,
+ shmimg->image->width, shmimg->image->height, 0, 0,
+ shmimg->image->depth, shmimg->image->format, 0,
+ shmimg->shm_seg, 0);
+
+ /* flush the request */
+ xcb_flush(connection);
+ break;
+ default:
+ /* Unknown event type, ignore it */
+ break;
+ }
+
+ }
+
+ shm_xcb_image_destroy(shmimg);
+
+ return 0;
+}