#include #include #include #include static const char *vertex_shader_text = "#version 120\n" "#extension GL_ARB_texture_rectangle : require\n" "uniform ivec2 tex_offset[8];\n" "uniform sampler2DRect input_texture[8];\n" "uniform int input_count;\n" "uniform ivec2 frame_size;\n" "uniform ivec2 frame_offset;\n" "attribute vec2 position;\n" "varying vec2 tex_coord[8];\n" "varying vec2 frame_coord;\n" "\n" "void main() {\n" " gl_Position = vec4(position * vec2(2.0, 2.0) + vec2(-1.0, -1.0), 0.0, 1.0);\n" " frame_coord = position * vec2(frame_size) + frame_offset;\n" "\n" " for( int i = 0; i < input_count; i++ ) {\n" " tex_coord[i] = position * vec2(frame_size) + frame_offset + tex_offset[i];\n" " }\n" "}\n"; static const char *gain_offset_shader_text = "#version 120\n" "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect input_texture[8];\n" "varying vec2 tex_coord[8];\n" "uniform float gain, offset;" "" "void main() {" " vec4 color = texture2DRect( input_texture[0], tex_coord[0] );" "" " gl_FragColor = color * vec4(gain, gain, gain, 1.0)" " + vec4(offset, offset, offset, 0.0);" "}"; int main( int argc, char *argv[]) { Display *display; int fb_attrs[] = { GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, None }; int pbuf_attrs[] = { GLX_PBUFFER_WIDTH, 8, GLX_PBUFFER_HEIGHT, 8, GLX_PRESERVED_CONTENTS, False, None }; int config_count = 0; GLXFBConfig *configs; GLXContext new_context; GLXPbuffer pbuf; printf( "Opening X display...\n" ); display = XOpenDisplay( NULL ); if( !display ) { printf( "Could not open X display.\n" ); return -1; } printf( "Choosing framebuffer config\n" ); configs = glXChooseFBConfig( display, DefaultScreen( display ), fb_attrs, &config_count ); if( !config_count ) { printf( "No frame buffer configurations available. Which is weird.\n" ); return -1; } new_context = glXCreateNewContext( display, configs[0], GLX_RGBA_TYPE, NULL, True ); if( !new_context ) { printf( "Failed to create context.\n" ); return -1; } pbuf = glXCreatePbuffer( display, configs[0], pbuf_attrs ); if( pbuf == None ) { printf( "Failed to create XGL pixel buffer.\n" ); return -1; } if( !glXMakeContextCurrent( display, pbuf, pbuf, new_context ) ) { printf( "Failed to set context current.\n" ); return -1; } glewInit(); GLuint vbuf; glGenBuffers( 1, &vbuf ); float positions[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; glBindBuffer( GL_ARRAY_BUFFER, vbuf ); glBufferData( GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW ); GLuint vshader = glCreateShader( GL_VERTEX_SHADER ); glShaderSource( vshader, 1, &vertex_shader_text, NULL ); glCompileShader( vshader ); GLuint fshader = glCreateShader( GL_FRAGMENT_SHADER ); glShaderSource( fshader, 1, &gain_offset_shader_text, NULL ); glCompileShader( fshader ); GLuint program = glCreateProgram(); glAttachShader( program, vshader ); glAttachShader( program, fshader ); glLinkProgram( program ); glUseProgram( program ); GLuint position_attribute = glGetAttribLocation( program, "position" ); glEnableVertexAttribArray( position_attribute ); glVertexAttribPointer( position_attribute, 2, GL_FLOAT, GL_FALSE, 0, 0 ); glDrawArrays( GL_TRIANGLE_FAN, 0, 4 ); glXDestroyPbuffer( display, pbuf ); glXDestroyContext( display, new_context ); printf( "Success\n" ); return 0; }