aboutsummaryrefslogtreecommitdiff
path: root/samples
diff options
context:
space:
mode:
Diffstat (limited to 'samples')
-rw-r--r--samples/OpenGL/minimal_glsl/minimal_glsl.c69
-rw-r--r--samples/OpenGL/texture_distortion_glsl/Makefile3
-rw-r--r--samples/OpenGL/texture_distortion_glsl/texture_distortion_glsl.c291
-rw-r--r--samples/OpenGL/x11argb_opengl/x11argb_opengl.c87
-rw-r--r--samples/OpenGL/x11argb_opengl_glsl/Makefile3
-rw-r--r--samples/OpenGL/x11argb_opengl_glsl/README2
-rw-r--r--samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c529
7 files changed, 927 insertions, 57 deletions
diff --git a/samples/OpenGL/minimal_glsl/minimal_glsl.c b/samples/OpenGL/minimal_glsl/minimal_glsl.c
index e1db488..2d1b0fa 100644
--- a/samples/OpenGL/minimal_glsl/minimal_glsl.c
+++ b/samples/OpenGL/minimal_glsl/minimal_glsl.c
@@ -60,37 +60,46 @@ GLubyte textureDataRGB[TEX_RGB_WIDTH * TEX_RGB_HEIGHT][3] = {
};
GLuint texRGB = 0;
+/* 6----7
+ /| /|
+ 3----2 |
+ | 5--|-4
+ |/ |/
+ 0----1
+
+*/
+
GLfloat cube_vertices[][8] = {
- /* X Y Z Nx Ny Nz S T */
- {-1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 0
- { 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0}, // 1
- { 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0}, // 2
- {-1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0}, // 3
-
- { 1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0},
- {-1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0},
- {-1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0},
- { 1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0},
-
- {-1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0},
- {-1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0},
- {-1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 1.0},
- {-1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0},
-
- { 1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0},
- { 1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0},
- { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0},
- { 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0},
-
- { 1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0},
- {-1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0},
- {-1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 1.0, 1.0},
- { 1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0},
-
- {-1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0},
- { 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0},
- { 1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 1.0},
- {-1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0},
+ /* X Y Z Nx Ny Nz S T */
+ {-1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 0
+ { 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0}, // 1
+ { 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0}, // 2
+ {-1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0}, // 3
+
+ { 1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0}, // 4
+ {-1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0}, // 5
+ {-1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0}, // 6
+ { 1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0}, // 7
+
+ {-1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0}, // 5
+ {-1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0}, // 0
+ {-1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 1.0}, // 3
+ {-1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, // 6
+
+ { 1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 1
+ { 1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0}, // 4
+ { 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0}, // 7
+ { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, // 2
+
+ {-1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0}, // 5
+ { 1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0}, // 4
+ { 1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 1.0, 1.0}, // 1
+ {-1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0}, // 0
+
+ {-1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 3
+ { 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0}, // 2
+ { 1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 1.0}, // 7
+ {-1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0}, // 6
};
static void draw_cube(void)
diff --git a/samples/OpenGL/texture_distortion_glsl/Makefile b/samples/OpenGL/texture_distortion_glsl/Makefile
new file mode 100644
index 0000000..fbb01d0
--- /dev/null
+++ b/samples/OpenGL/texture_distortion_glsl/Makefile
@@ -0,0 +1,3 @@
+texture_distortion_glsl: texture_distortion_glsl.c
+ cc -o texture_distortion_glsl texture_distortion_glsl.c -lGL -lGLEW -lglfw
+
diff --git a/samples/OpenGL/texture_distortion_glsl/texture_distortion_glsl.c b/samples/OpenGL/texture_distortion_glsl/texture_distortion_glsl.c
new file mode 100644
index 0000000..7742746
--- /dev/null
+++ b/samples/OpenGL/texture_distortion_glsl/texture_distortion_glsl.c
@@ -0,0 +1,291 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <GL/glew.h>
+#include <GL/glfw.h>
+
+static void pushModelview()
+{
+ GLenum prev_matrix_mode;
+ glGetIntegerv(GL_MATRIX_MODE, &prev_matrix_mode);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glMatrixMode(prev_matrix_mode);
+}
+
+static void popModelview()
+{
+ GLenum prev_matrix_mode;
+ glGetIntegerv(GL_MATRIX_MODE, &prev_matrix_mode);
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ glMatrixMode(prev_matrix_mode);
+}
+
+static const GLchar *vertex_shader_source =
+"#version 120\n"
+"void main()"
+"{"
+" gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;"
+" gl_TexCoord[0] = gl_MultiTexCoord0;"
+" gl_FrontColor = gl_Color;"
+" gl_BackColor = gl_Color;"
+"}\0";
+GLuint shaderVertex = 0;
+
+static const GLchar *fragment_shader_source =
+"#version 120\n"
+"uniform sampler2D texCMYK;\n"
+"uniform sampler2D texRGB;\n"
+"uniform float T;\n"
+"const float pi = 3.14159265;\n"
+"void main()\n"
+"{\n"
+" float ts = gl_TexCoord[0].s;\n"
+" vec2 mod_texcoord = gl_TexCoord[0].st*vec2(1., 2.) + vec2(0, -0.5 + 0.5*sin(T + 1.5*ts*pi));\n"
+" if( mod_texcoord.t < 0. || mod_texcoord.t > 1. ) { discard; }\n"
+" gl_FragColor = -texture2D(texCMYK, mod_texcoord) + texture2D(texRGB, gl_TexCoord[0].st);\n"
+"}\n\0";
+GLuint shaderFragment = 0;
+
+GLuint shaderProgram = 0;
+
+#define TEX_CMYK_WIDTH 2
+#define TEX_CMYK_HEIGHT 2
+GLubyte textureDataCMYK[TEX_CMYK_WIDTH * TEX_CMYK_HEIGHT][3] = {
+ {0x00, 0xff, 0xff}, {0xff, 0x00, 0xff},
+ {0xff, 0xff, 0x00}, {0x00, 0x00, 0x00}
+};
+GLuint texCMYK = 0;
+
+#define TEX_RGB_WIDTH 2
+#define TEX_RGB_HEIGHT 2
+GLubyte textureDataRGB[TEX_RGB_WIDTH * TEX_RGB_HEIGHT][3] = {
+ {0x00, 0x00, 0xff}, {0xff, 0xff, 0xff},
+ {0xff, 0x00, 0x00}, {0x00, 0xff, 0x00}
+};
+GLuint texRGB = 0;
+
+/* 6----7
+ /| /|
+ 3----2 |
+ | 5--|-4
+ |/ |/
+ 0----1
+
+*/
+
+GLfloat cube_vertices[][8] = {
+ /* X Y Z Nx Ny Nz S T */
+ {-1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 0
+ { 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0}, // 1
+ { 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0}, // 2
+ {-1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0}, // 3
+
+ { 1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0}, // 4
+ {-1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0}, // 5
+ {-1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0}, // 6
+ { 1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0}, // 7
+
+ {-1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0}, // 5
+ {-1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0}, // 0
+ {-1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 1.0}, // 3
+ {-1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, // 6
+
+ { 1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 1
+ { 1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0}, // 4
+ { 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0}, // 7
+ { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, // 2
+
+ {-1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0}, // 5
+ { 1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0}, // 4
+ { 1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 1.0, 1.0}, // 1
+ {-1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0}, // 0
+
+ {-1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 3
+ { 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0}, // 2
+ { 1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 1.0}, // 7
+ {-1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0}, // 6
+};
+
+static void draw_cube(void)
+{
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][0]);
+ glNormalPointer(GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][3]);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][6]);
+
+ glDrawArrays(GL_QUADS, 0, 24);
+}
+
+static void bind_sampler_to_unit_with_texture(GLchar const * const sampler_name, GLuint texture_unit, GLuint texture)
+{
+ glActiveTexture(GL_TEXTURE0 + texture_unit);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ GLuint loc_sampler = glGetUniformLocation(shaderProgram, sampler_name);
+ glUniform1i(loc_sampler, texture_unit);
+}
+
+static void display(double T)
+{
+ int window_width, window_height;
+
+ glfwGetWindowSize(&window_width, &window_height);
+ if( !window_width || !window_height )
+ return;
+
+ const float window_aspect = (float)window_width / (float)window_height;
+
+ glDisable(GL_SCISSOR_TEST);
+
+ glClearColor(0.5, 0.5, 0.7, 1.0);
+ glClearDepth(1.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ glEnable(GL_DEPTH_TEST);
+ glViewport(0, 0, window_width, window_height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-window_aspect, window_aspect, -1, 1, 2.5, 10);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, -5);
+
+ pushModelview();
+ glRotatef(T * 0.1 * 180, 0., 1., 0.);
+ glRotatef(T * 0.1 * 60, 1., 0., 0.);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+ glUseProgram(shaderProgram);
+ glUniform1f(glGetUniformLocation(shaderProgram, "T"), T);
+ bind_sampler_to_unit_with_texture("texCMYK", 0, texCMYK);
+ bind_sampler_to_unit_with_texture("texRGB", 1, texRGB);
+
+ draw_cube();
+ popModelview();
+
+ glfwSwapBuffers();
+}
+
+static int open_window(void)
+{
+#if 0
+ glfwWindowHint(GLFW_OPENGL_VERSION_MAJOR, 2);
+ glfwWindowHint(GLFW_OPENGL_VERSION_MINOR, 0);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
+#endif
+
+ if( glfwOpenWindow(0, 0, /* default size */
+ 8, 8, 8, /* 8 bits per channel */
+ 8, 24, 8, /* 8 alpha, 24 depth, 8 stencil */
+ GLFW_WINDOW) != GL_TRUE ) {
+ fputs("Could not open window.\n", stderr);
+ return 0;
+ }
+
+ if( glewInit() != GLEW_OK ) {
+ fputs("Could not initialize extensions.\n", stderr);
+ return 0;
+ }
+ return 1;
+}
+
+static int check_extensions(void)
+{
+ if( !GLEW_ARB_vertex_shader ||
+ !GLEW_ARB_fragment_shader ) {
+ fputs("Required OpenGL functionality not supported by system.\n", stderr);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int check_shader_compilation(GLuint shader)
+{
+ GLint n;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &n);
+ if( n == GL_FALSE ) {
+ GLchar *info_log;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &n);
+ info_log = malloc(n);
+ glGetShaderInfoLog(shader, n, &n, info_log);
+ fprintf(stderr, "Shader compilation failed: %*s\n", n, info_log);
+ free(info_log);
+ return 0;
+ }
+ return 1;
+}
+
+static int init_resources(void)
+{
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+ glGenTextures(1, &texCMYK);
+ glBindTexture(GL_TEXTURE_2D, texCMYK);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, TEX_CMYK_WIDTH, TEX_CMYK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, textureDataCMYK);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glGenTextures(1, &texRGB);
+ glBindTexture(GL_TEXTURE_2D, texRGB);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, TEX_RGB_WIDTH, TEX_RGB_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, textureDataRGB);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ shaderVertex = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(shaderVertex, 1, (const GLchar**)&vertex_shader_source, NULL);
+ glCompileShader(shaderVertex);
+ if( !check_shader_compilation(shaderVertex) )
+ return 0;
+
+ shaderFragment = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(shaderFragment, 1, (const GLchar**)&fragment_shader_source, NULL);
+ glCompileShader(shaderFragment);
+ if( !check_shader_compilation(shaderFragment) )
+ return 0;
+
+ shaderProgram = glCreateProgram();
+ glAttachShader(shaderProgram, shaderVertex);
+ glAttachShader(shaderProgram, shaderFragment);
+ glLinkProgram(shaderProgram);
+
+ return 1;
+}
+
+static void main_loop(void)
+{
+ glfwSetTime(0);
+ while( glfwGetWindowParam(GLFW_OPENED) == GL_TRUE ) {
+ display(glfwGetTime());
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ if( glfwInit() != GL_TRUE ) {
+ fputs("Could not initialize framework.\n", stderr);
+ return -1;
+ }
+
+ if( !open_window() )
+ return -1;
+
+ if( !check_extensions() )
+ return -1;
+
+ if( !init_resources() )
+ return -1;
+
+ main_loop();
+
+ glfwTerminate();
+ return 0;
+}
diff --git a/samples/OpenGL/x11argb_opengl/x11argb_opengl.c b/samples/OpenGL/x11argb_opengl/x11argb_opengl.c
index fb8b814..f7f4c58 100644
--- a/samples/OpenGL/x11argb_opengl/x11argb_opengl.c
+++ b/samples/OpenGL/x11argb_opengl/x11argb_opengl.c
@@ -222,7 +222,7 @@ static void createTheRenderContext()
fatalError("OpenGL not supported by X server\n");
}
- render_context = glXCreateNewContext(Xdisplay, fbconfig, GLX_RGBA_TYPE, 0, False);
+ render_context = glXCreateNewContext(Xdisplay, fbconfig, GLX_RGBA_TYPE, 0, True);
if (!render_context) {
fatalError("Failed to create a GL context\n");
}
@@ -259,6 +259,15 @@ static int updateTheMessageQueue()
return 1;
}
+/* 6----7
+ /| /|
+ 3----2 |
+ | 5--|-4
+ |/ |/
+ 0----1
+
+*/
+
GLfloat cube_vertices[][8] = {
/* X Y Z Nx Ny Nz S T */
{-1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 0
@@ -266,30 +275,30 @@ GLfloat cube_vertices[][8] = {
{ 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0}, // 2
{-1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0}, // 3
- { 1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0},
- {-1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0},
- {-1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0},
- { 1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0},
+ { 1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0}, // 4
+ {-1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0}, // 5
+ {-1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0}, // 6
+ { 1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0}, // 7
- {-1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0},
- {-1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0},
- {-1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 1.0},
- {-1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0},
+ {-1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0}, // 5
+ {-1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0}, // 0
+ {-1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 1.0}, // 3
+ {-1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, // 6
- { 1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0},
- { 1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0},
- { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0},
- { 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0},
+ { 1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 1
+ { 1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0}, // 4
+ { 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0}, // 7
+ { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, // 2
- { 1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0},
- {-1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0},
- {-1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 1.0, 1.0},
- { 1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0},
-
- {-1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0},
- { 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0},
- { 1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 1.0},
- {-1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0},
+ {-1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0}, // 5
+ { 1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0}, // 4
+ { 1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 1.0, 1.0}, // 1
+ {-1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0}, // 0
+
+ {-1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 3
+ { 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0}, // 2
+ { 1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 1.0}, // 7
+ {-1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0}, // 6
};
static void draw_cube(void)
@@ -305,8 +314,14 @@ static void draw_cube(void)
glDrawArrays(GL_QUADS, 0, 24);
}
-float const light_dir[]={1,1,1,0};
-float const light_color[]={1,0.95,0.9,1};
+float const light0_dir[]={0,1,0,0};
+float const light0_color[]={78./255., 80./255., 184./255.,1};
+
+float const light1_dir[]={-1,1,1,0};
+float const light1_color[]={255./255., 220./255., 97./255.,1};
+
+float const light2_dir[]={0,-1,0,0};
+float const light2_color[]={31./255., 75./255., 16./255.,1};
static void redrawTheWindow()
{
@@ -332,10 +347,19 @@ static void redrawTheWindow()
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
+ glEnable(GL_CULL_FACE);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glLightfv(GL_LIGHT0, GL_POSITION, light_dir);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
+ glLightfv(GL_LIGHT0, GL_POSITION, light0_dir);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);
+
+ glLightfv(GL_LIGHT1, GL_POSITION, light1_dir);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_color);
+
+ glLightfv(GL_LIGHT2, GL_POSITION, light2_dir);
+ glLightfv(GL_LIGHT2, GL_DIFFUSE, light2_color);
glTranslatef(0., 0., -5.);
@@ -344,8 +368,17 @@ static void redrawTheWindow()
glRotatef(c, 0, 0, 1);
glEnable(GL_LIGHT0);
+ glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
+ glEnable(GL_COLOR_MATERIAL);
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+
+ glColor4f(1., 1., 1., 0.5);
+
+ glCullFace(GL_FRONT);
+ draw_cube();
+ glCullFace(GL_BACK);
draw_cube();
a = fmod(a+0.1, 360.);
diff --git a/samples/OpenGL/x11argb_opengl_glsl/Makefile b/samples/OpenGL/x11argb_opengl_glsl/Makefile
new file mode 100644
index 0000000..6c234cb
--- /dev/null
+++ b/samples/OpenGL/x11argb_opengl_glsl/Makefile
@@ -0,0 +1,3 @@
+x11argb_opengl_glsl: x11argb_opengl_glsl.c Makefile
+ $(CC) -std=c99 -g3 -o x11argb_opengl_glsl x11argb_opengl_glsl.c -lX11 -lXrender -lGLEW -lm
+
diff --git a/samples/OpenGL/x11argb_opengl_glsl/README b/samples/OpenGL/x11argb_opengl_glsl/README
new file mode 100644
index 0000000..391184e
--- /dev/null
+++ b/samples/OpenGL/x11argb_opengl_glsl/README
@@ -0,0 +1,2 @@
+The texture_distortion_glsl and x11argb_opengl codesamples combined
+
diff --git a/samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c b/samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c
new file mode 100644
index 0000000..f7fc68e
--- /dev/null
+++ b/samples/OpenGL/x11argb_opengl_glsl/x11argb_opengl_glsl.c
@@ -0,0 +1,529 @@
+/*------------------------------------------------------------------------
+ * A demonstration of OpenGL in a ARGB window
+ * => support for composited window transparency
+ *
+ * (c) 2011 by Wolfgang 'datenwolf' Draxinger
+ * See me at comp.graphics.api.opengl and StackOverflow.com
+
+ * License agreement: This source code is provided "as is". You
+ * can use this source code however you want for your own personal
+ * use. If you give this source code to anybody else then you must
+ * leave this message in it.
+ *
+ * This program is based on the simplest possible
+ * Linux OpenGL program by FTB (see info below)
+
+ The simplest possible Linux OpenGL program? Maybe...
+
+ (c) 2002 by FTB. See me in comp.graphics.api.opengl
+
+ --
+ <\___/>
+ / O O \
+ \_____/ FTB.
+
+------------------------------------------------------------------------*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/time.h>
+
+#include <GL/glew.h>
+#include <GL/glx.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/Xrender.h>
+#include <X11/Xutil.h>
+
+#define USE_CHOOSE_FBCONFIG
+#define USE_GLX_CREATE_WINDOW
+
+static const GLchar *vertex_shader_source =
+"#version 120\n"
+"void main()"
+"{"
+" gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;"
+" gl_TexCoord[0] = gl_MultiTexCoord0;"
+" gl_FrontColor = gl_Color;"
+" gl_BackColor = gl_Color;"
+"}\0";
+GLuint shaderVertex = 0;
+
+static const GLchar *fragment_shader_source =
+"#version 120\n"
+"uniform sampler2D texCMYK;\n"
+"uniform sampler2D texRGB;\n"
+"uniform float T;\n"
+"const float pi = 3.14159265;\n"
+"void main()\n"
+"{\n"
+" float ts = gl_TexCoord[0].s;\n"
+" vec2 mod_texcoord = gl_TexCoord[0].st*vec2(1., 2.) + vec2(0, -0.5 + 0.5*sin(T + 1.5*ts*pi));\n"
+" if( mod_texcoord.t < 0. || mod_texcoord.t > 1. ) { discard; }\n"
+" gl_FragColor = -texture2D(texCMYK, mod_texcoord) + texture2D(texRGB, gl_TexCoord[0].st);\n"
+" gl_FragColor.a = 1.0;\n"
+"}\n\0";
+GLuint shaderFragment = 0;
+
+GLuint shaderProgram = 0;
+
+#define TEX_CMYK_WIDTH 2
+#define TEX_CMYK_HEIGHT 2
+GLubyte textureDataCMYK[TEX_CMYK_WIDTH * TEX_CMYK_HEIGHT][3] = {
+ {0x00, 0xff, 0xff}, {0xff, 0x00, 0xff},
+ {0xff, 0xff, 0x00}, {0x00, 0x00, 0x00}
+};
+GLuint texCMYK = 0;
+
+#define TEX_RGB_WIDTH 2
+#define TEX_RGB_HEIGHT 2
+GLubyte textureDataRGB[TEX_RGB_WIDTH * TEX_RGB_HEIGHT][3] = {
+ {0x00, 0x00, 0xff}, {0xff, 0xff, 0xff},
+ {0xff, 0x00, 0x00}, {0x00, 0xff, 0x00}
+};
+GLuint texRGB = 0;
+
+/* 6----7
+ /| /|
+ 3----2 |
+ | 5--|-4
+ |/ |/
+ 0----1
+*/
+GLfloat cube_vertices[][8] = {
+ /* X Y Z Nx Ny Nz S T */
+ {-1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 0
+ { 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0}, // 1
+ { 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0}, // 2
+ {-1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0}, // 3
+
+ { 1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0}, // 4
+ {-1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0}, // 5
+ {-1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0}, // 6
+ { 1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0}, // 7
+
+ {-1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0}, // 5
+ {-1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0}, // 0
+ {-1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 1.0}, // 3
+ {-1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, // 6
+
+ { 1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 1
+ { 1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0}, // 4
+ { 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0}, // 7
+ { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, // 2
+
+ {-1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0}, // 5
+ { 1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0}, // 4
+ { 1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 1.0, 1.0}, // 1
+ {-1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0}, // 0
+
+ {-1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 3
+ { 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0}, // 2
+ { 1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 1.0}, // 7
+ {-1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0}, // 6
+};
+
+static void fatalError(const char *why)
+{
+ fprintf(stderr, "%s", why);
+ exit(0x666);
+}
+
+static int Xscreen;
+static Atom del_atom;
+static Colormap cmap;
+static Display *Xdisplay;
+static XVisualInfo *visual;
+static XRenderPictFormat *pict_format;
+static GLXFBConfig *fbconfigs, fbconfig;
+static int numfbconfigs;
+static GLXContext render_context;
+static Window Xroot, window_handle;
+static GLXWindow glX_window_handle;
+static int width, height;
+
+static int VisData[] = {
+GLX_RENDER_TYPE, GLX_RGBA_BIT,
+GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+GLX_DOUBLEBUFFER, True,
+GLX_RED_SIZE, 8,
+GLX_GREEN_SIZE, 8,
+GLX_BLUE_SIZE, 8,
+GLX_ALPHA_SIZE, 8,
+GLX_DEPTH_SIZE, 16,
+None
+};
+
+static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
+{
+ return d && e && arg && (e->type == MapNotify) && (e->xmap.window == *(Window*)arg);
+}
+
+static void describe_fbconfig(GLXFBConfig fbconfig)
+{
+ int doublebuffer;
+ int red_bits, green_bits, blue_bits, alpha_bits, depth_bits;
+
+ glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_DOUBLEBUFFER, &doublebuffer);
+ glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_RED_SIZE, &red_bits);
+ glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_GREEN_SIZE, &green_bits);
+ glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_BLUE_SIZE, &blue_bits);
+ glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_ALPHA_SIZE, &alpha_bits);
+ glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_DEPTH_SIZE, &depth_bits);
+
+ fprintf(stderr, "FBConfig selected:\n"
+ "Doublebuffer: %s\n"
+ "Red Bits: %d, Green Bits: %d, Blue Bits: %d, Alpha Bits: %d, Depth Bits: %d\n",
+ doublebuffer == True ? "Yes" : "No",
+ red_bits, green_bits, blue_bits, alpha_bits, depth_bits);
+}
+
+static void createTheWindow()
+{
+ XEvent event;
+ int x,y, attr_mask;
+ XSizeHints hints;
+ XWMHints *startup_state;
+ XTextProperty textprop;
+ XSetWindowAttributes attr = {0,};
+ static char *title = "FTB's little OpenGL example - ARGB extension by WXD";
+
+ Xdisplay = XOpenDisplay(NULL);
+ if (!Xdisplay) {
+ fatalError("Couldn't connect to X server\n");
+ }
+ Xscreen = DefaultScreen(Xdisplay);
+ Xroot = RootWindow(Xdisplay, Xscreen);
+
+ fbconfigs = glXChooseFBConfig(Xdisplay, Xscreen, VisData, &numfbconfigs);
+ fbconfig = 0;
+ for(int i = 0; i<numfbconfigs; i++) {
+ visual = (XVisualInfo*) glXGetVisualFromFBConfig(Xdisplay, fbconfigs[i]);
+ if(!visual)
+ continue;
+
+ pict_format = XRenderFindVisualFormat(Xdisplay, visual->visual);
+ if(!pict_format)
+ continue;
+
+ fbconfig = fbconfigs[i];
+ if(pict_format->direct.alphaMask > 0) {
+ break;
+ }
+ }
+
+ if(!fbconfig) {
+ fatalError("No matching FB config found");
+ }
+
+ describe_fbconfig(fbconfig);
+
+ /* Create a colormap - only needed on some X clients, eg. IRIX */
+ cmap = XCreateColormap(Xdisplay, Xroot, visual->visual, AllocNone);
+
+ attr.colormap = cmap;
+ attr.background_pixmap = None;
+ attr.border_pixmap = None;
+ attr.border_pixel = 0;
+ attr.event_mask =
+ StructureNotifyMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ ExposureMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ OwnerGrabButtonMask |
+ KeyPressMask |
+ KeyReleaseMask;
+
+ attr_mask =
+ CWBackPixmap|
+ CWColormap|
+ CWBorderPixel|
+ CWEventMask;
+
+ width = DisplayWidth(Xdisplay, DefaultScreen(Xdisplay))/2;
+ height = DisplayHeight(Xdisplay, DefaultScreen(Xdisplay))/2;
+ x=width/2, y=height/2;
+
+ window_handle = XCreateWindow( Xdisplay,
+ Xroot,
+ x, y, width, height,
+ 0,
+ visual->depth,
+ InputOutput,
+ visual->visual,
+ attr_mask, &attr);
+
+ if( !window_handle ) {
+ fatalError("Couldn't create the window\n");
+ }
+
+#ifdef USE_GLX_CREATE_WINDOW
+ int glXattr[] = { None };
+ glX_window_handle = glXCreateWindow(Xdisplay, fbconfig, window_handle, glXattr);
+ if( !glX_window_handle ) {
+ fatalError("Couldn't create the GLX window\n");
+ }
+#else
+ glX_window_handle = window_handle;
+#endif
+
+ textprop.value = (unsigned char*)title;
+ textprop.encoding = XA_STRING;
+ textprop.format = 8;
+ textprop.nitems = strlen(title);
+
+ hints.x = x;
+ hints.y = y;
+ hints.width = width;
+ hints.height = height;
+ hints.flags = USPosition|USSize;
+
+ startup_state = XAllocWMHints();
+ startup_state->initial_state = NormalState;
+ startup_state->flags = StateHint;
+
+ XSetWMProperties(Xdisplay, window_handle,&textprop, &textprop,
+ NULL, 0,
+ &hints,
+ startup_state,
+ NULL);
+
+ XFree(startup_state);
+
+ XMapWindow(Xdisplay, window_handle);
+ XIfEvent(Xdisplay, &event, WaitForMapNotify, (char*)&window_handle);
+
+ if ((del_atom = XInternAtom(Xdisplay, "WM_DELETE_WINDOW", 0)) != None) {
+ XSetWMProtocols(Xdisplay, window_handle, &del_atom, 1);
+ }
+}
+
+static void createTheRenderContext()
+{
+ int dummy;
+ if (!glXQueryExtension(Xdisplay, &dummy, &dummy)) {
+ fatalError("OpenGL not supported by X server\n");
+ }
+
+ render_context = glXCreateNewContext(Xdisplay, fbconfig, GLX_RGBA_TYPE, 0, True);
+ if (!render_context) {
+ fatalError("Failed to create a GL context\n");
+ }
+
+ if (!glXMakeContextCurrent(Xdisplay, glX_window_handle, glX_window_handle, render_context)) {
+ fatalError("glXMakeCurrent failed for window\n");
+ }
+
+ glewInit();
+}
+
+static int updateTheMessageQueue()
+{
+ XEvent event;
+ XConfigureEvent *xc;
+
+ while (XPending(Xdisplay))
+ {
+ XNextEvent(Xdisplay, &event);
+ switch (event.type)
+ {
+ case ClientMessage:
+ if (event.xclient.data.l[0] == del_atom)
+ {
+ return 0;
+ }
+ break;
+
+ case ConfigureNotify:
+ xc = &(event.xconfigure);
+ width = xc->width;
+ height = xc->height;
+ break;
+ }
+ }
+ return 1;
+}
+
+static int check_extensions(void)
+{
+ if( !GLEW_ARB_vertex_shader ||
+ !GLEW_ARB_fragment_shader ) {
+ fputs("Required OpenGL functionality not supported by system.\n", stderr);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int check_shader_compilation(GLuint shader)
+{
+ GLint n;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &n);
+ if( n == GL_FALSE ) {
+ GLchar *info_log;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &n);
+ info_log = malloc(n);
+ glGetShaderInfoLog(shader, n, &n, info_log);
+ fprintf(stderr, "Shader compilation failed: %*s\n", n, info_log);
+ free(info_log);
+ return 0;
+ }
+ return 1;
+}
+
+static int init_resources(void)
+{
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+ glGenTextures(1, &texCMYK);
+ glBindTexture(GL_TEXTURE_2D, texCMYK);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, TEX_CMYK_WIDTH, TEX_CMYK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, textureDataCMYK);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glGenTextures(1, &texRGB);
+ glBindTexture(GL_TEXTURE_2D, texRGB);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, TEX_RGB_WIDTH, TEX_RGB_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, textureDataRGB);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ shaderVertex = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(shaderVertex, 1, (const GLchar**)&vertex_shader_source, NULL);
+ glCompileShader(shaderVertex);
+ if( !check_shader_compilation(shaderVertex) )
+ return 0;
+
+ shaderFragment = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(shaderFragment, 1, (const GLchar**)&fragment_shader_source, NULL);
+ glCompileShader(shaderFragment);
+ if( !check_shader_compilation(shaderFragment) )
+ return 0;
+
+ shaderProgram = glCreateProgram();
+ glAttachShader(shaderProgram, shaderVertex);
+ glAttachShader(shaderProgram, shaderFragment);
+ glLinkProgram(shaderProgram);
+
+ return 1;
+}
+
+static void bind_sampler_to_unit_with_texture(GLchar const * const sampler_name, GLuint texture_unit, GLuint texture)
+{
+ glActiveTexture(GL_TEXTURE0 + texture_unit);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ GLuint loc_sampler = glGetUniformLocation(shaderProgram, sampler_name);
+ glUniform1i(loc_sampler, texture_unit);
+}
+
+static void pushModelview()
+{
+ GLenum prev_matrix_mode;
+ glGetIntegerv(GL_MATRIX_MODE, &prev_matrix_mode);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glMatrixMode(prev_matrix_mode);
+}
+
+static void popModelview()
+{
+ GLenum prev_matrix_mode;
+ glGetIntegerv(GL_MATRIX_MODE, &prev_matrix_mode);
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ glMatrixMode(prev_matrix_mode);
+}
+
+
+static void draw_cube(void)
+{
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][0]);
+ glNormalPointer(GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][3]);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][6]);
+
+ glDrawArrays(GL_QUADS, 0, 24);
+}
+
+static void redrawTheWindow(double T)
+{
+ int const window_width = width;
+ int const window_height = height;
+ const float window_aspect = (float)window_width / (float)window_height;
+
+ glDisable(GL_SCISSOR_TEST);
+
+ glClearColor(0., 0., 0., 0.0);
+ glClearDepth(1.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ glEnable(GL_DEPTH_TEST);
+ glViewport(0, 0, window_width, window_height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-window_aspect, window_aspect, -1, 1, 2.5, 10);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, -5);
+
+ glDisable(GL_BLEND);
+
+ pushModelview();
+ glRotatef(T * 0.1 * 180, 0., 1., 0.);
+ glRotatef(T * 0.1 * 60, 1., 0., 0.);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+ glUseProgram(shaderProgram);
+ glUniform1f(glGetUniformLocation(shaderProgram, "T"), T);
+ bind_sampler_to_unit_with_texture("texCMYK", 0, texCMYK);
+ bind_sampler_to_unit_with_texture("texRGB", 1, texRGB);
+
+ draw_cube();
+ popModelview();
+
+ glXSwapBuffers(Xdisplay, glX_window_handle);
+}
+
+static double getftime(void) {
+ static long long offset = 0;
+ long long t;
+ struct timeval timeofday;
+
+ gettimeofday(&timeofday, NULL);
+ t = (long long)timeofday.tv_sec * 1000000 + (long long)timeofday.tv_usec;
+
+ if(offset == 0)
+ offset = t;
+
+ return (double)(offset - t) * 1.e-6;
+}
+
+int main(int argc, char *argv[])
+{
+
+ createTheWindow();
+ createTheRenderContext();
+
+ if( !check_extensions() )
+ return -1;
+
+ if( !init_resources() )
+ return -1;
+
+ while (updateTheMessageQueue()) {
+ redrawTheWindow(getftime());
+ }
+
+ return 0;
+}
+