int width = 64;
int height = 64;
+static void
+set_2d_projection (void)
+{
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho (0, width, height, 0, 0, 1);
+ glMatrixMode (GL_MODELVIEW);
+}
+
+static void
+draw_fullscreen_quad (void)
+{
+ glBegin (GL_QUADS);
+ glVertex2f (0, 0);
+ glVertex2f (width, 0);
+ glVertex2f (width, height);
+ glVertex2f (0, height);
+ glEnd ();
+}
+
+static void
+draw_fullscreen_textured_quad (void)
+{
+ glBegin (GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f (0, 0);
+ glTexCoord2f(1, 0); glVertex2f (width, 0);
+ glTexCoord2f(1, 1); glVertex2f (width, height);
+ glTexCoord2f(0, 1); glVertex2f (0, height);
+ glEnd ();
+}
+
+static void
+paint_rgb_using_clear (double r, double g, double b)
+{
+ glClearColor(r, g, b, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+static void
+paint_rgb_using_glsl (double r, double g, double b)
+{
+ const char * vs_source =
+ "void main()\n"
+ "{\n"
+ " gl_Position = ftransform();\n"
+ "}\n";
+ const char * fs_source =
+ "#version 120\n"
+ "uniform vec4 color;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = color;\n"
+ "}\n";
+
+ GLuint vs, fs, program;
+ GLint color;
+
+ vs = glCreateShader (GL_VERTEX_SHADER);
+ glShaderSource (vs, 1, &vs_source, NULL);
+ glCompileShader (vs);
+
+ fs = glCreateShader (GL_FRAGMENT_SHADER);
+ glShaderSource (fs, 1, &fs_source, NULL);
+ glCompileShader (fs);
+
+ program = glCreateProgram ();
+ glAttachShader (program, vs);
+ glAttachShader (program, fs);
+
+ glLinkProgram (program);
+ glUseProgram (program);
+
+ color = glGetUniformLocation (program, "color");
+
+ glUniform4f (color, r, g, b, 1.0);
+
+ draw_fullscreen_quad ();
+
+ glUseProgram (0);
+}
+
+static GLuint
+create_rgb_texture (double r, double g, double b)
+{
+ uint8_t data[3];
+ GLuint texture = 0;
+
+ data[0] = (uint8_t) (255.0 * r);
+ data[1] = (uint8_t) (255.0 * g);
+ data[2] = (uint8_t) (255.0 * b);
+
+ glGenTextures (1, &texture);
+
+ glBindTexture (GL_TEXTURE_2D, texture);
+
+ glTexImage2D (GL_TEXTURE_2D,
+ 0, GL_COMPRESSED_RGBA,
+ 1, 1, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, data);
+
+ return texture;
+}
+
+static void
+paint_using_texture (GLuint texture)
+{
+ glBindTexture (GL_TEXTURE_2D, texture);
+
+ glEnable (GL_TEXTURE_2D);
+
+ draw_fullscreen_textured_quad ();
+
+ glDisable (GL_TEXTURE_2D);
+}
+
static void
draw (Display *dpy, Window window, int width, int height)
{
+#define PASSES 2
+ int i;
GLenum glew_err;
+ GLuint texture[PASSES];
int visual_attr[] = {
GLX_RGBA,
GLX_X_VISUAL_TYPE, GLX_DIRECT_COLOR,
None
};
+
+ /* Window and context setup. */
XVisualInfo *visual_info = glXChooseVisual(dpy, 0, visual_attr);
GLXContext ctx = glXCreateContext(dpy, visual_info, NULL, True);
glXMakeCurrent(dpy, window, ctx);
}
glViewport(0, 0, width, height);
- glClearColor(1, 0, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT);
- glXSwapBuffers (dpy, window);
+ set_2d_projection ();
+
+/* Simply count through some colors, frame by frame. */
+#define RGB(frame) (((frame+1)/4) % 2), (((frame+1)/2) % 2), ((frame+1) % 2)
+
+ int frame = 0;
+ for (i = 0; i < PASSES; i++) {
+
+ /* Frame: Draw a solid frame using glClear. */
+ paint_rgb_using_clear (RGB(frame));
+ glXSwapBuffers (dpy, window);
+ frame++;
+
+ /* Frame: Draw a solid frame using GLSL. */
+ paint_rgb_using_glsl (RGB(frame));
+ glXSwapBuffers (dpy, window);
+ frame++;
+
+ /* Frame: Draw a solid frame using a texture. */
+ texture[i] = create_rgb_texture (RGB(frame));
+ paint_using_texture (texture[i]);
+ glXSwapBuffers (dpy, window);
+ frame++;
+ }
+
+ /* Draw another frame with a re-used texture. */
+ paint_using_texture (texture[0]);
+ glXSwapBuffers (dpy, window);
+ frame++;
+ /* Cleanup */
glXDestroyContext (dpy, ctx);
}