aboutsummaryrefslogtreecommitdiff
path: root/samples/OpenGL
diff options
context:
space:
mode:
Diffstat (limited to 'samples/OpenGL')
-rw-r--r--samples/OpenGL/minimal_glsl/Makefile3
-rw-r--r--samples/OpenGL/minimal_glsl/README3
-rw-r--r--samples/OpenGL/minimal_glsl/minimal_glsl.c277
3 files changed, 283 insertions, 0 deletions
diff --git a/samples/OpenGL/minimal_glsl/Makefile b/samples/OpenGL/minimal_glsl/Makefile
new file mode 100644
index 0000000..0a4fdae
--- /dev/null
+++ b/samples/OpenGL/minimal_glsl/Makefile
@@ -0,0 +1,3 @@
+minimal_glsl: minimal_glsl.c
+ cc -o minimal_glsl minimal_glsl.c -lGL -lGLEW -lglfw
+
diff --git a/samples/OpenGL/minimal_glsl/README b/samples/OpenGL/minimal_glsl/README
new file mode 100644
index 0000000..84185e4
--- /dev/null
+++ b/samples/OpenGL/minimal_glsl/README
@@ -0,0 +1,3 @@
+Minimal example for GLSL usage.
+
+Creates a OpenGL window and context using GLFW. Extensions provided by GLEW.
diff --git a/samples/OpenGL/minimal_glsl/minimal_glsl.c b/samples/OpenGL/minimal_glsl/minimal_glsl.c
new file mode 100644
index 0000000..e1db488
--- /dev/null
+++ b/samples/OpenGL/minimal_glsl/minimal_glsl.c
@@ -0,0 +1,277 @@
+#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;"
+"uniform sampler2D texRGB;"
+"void main()"
+"{"
+" gl_FragColor = -texture2D(texCMYK, gl_TexCoord[0].st) + texture2D(texRGB, gl_TexCoord[0].st);"
+"}\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;
+
+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},
+};
+
+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, 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);
+ 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;
+}
+