Example: Set up a GL context using GLFW and run a Vuo image filter.
#define GLFW_NO_GLU
#include <GL/glfw.h>
#include <OpenGL/glext.h>
#define glGenVertexArrays glGenVertexArraysAPPLE
#define glBindVertexArray glBindVertexArrayAPPLE
#define glDeleteVertexArrays glDeleteVertexArraysAPPLE
#include <OpenGL/CGLCurrent.h>
#include <Vuo/Vuo.h>
#define GLSL_STRING(version,source) "#version " #version "\n" #source
static const char * vertexShaderSource = GLSL_STRING(120,
attribute vec2 position;
varying vec2 texcoord;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
texcoord = position * vec2(0.5) + vec2(0.5);
}
);
static const char * fragmentShaderSource = GLSL_STRING(120,
uniform sampler2D texture;
varying vec2 texcoord;
void main()
{
gl_FragColor = texture2D(texture, texcoord);
}
);
static GLuint compileShader(GLenum type, const char * source)
{
GLint length = strlen(source);
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, (const GLchar**)&source, &length);
glCompileShader(shader);
return shader;
}
static const GLfloat quadPositions[] = { -1, -1, 1, -1, -1, 1, 1, 1 };
static const GLushort quadElements[] = { 0, 1, 2, 3 };
GLuint vertexArray;
GLuint quadPositionBuffer;
GLuint quadElementBuffer;
GLuint inputTexture;
GLuint vertexShader;
GLuint fragmentShader;
GLuint program;
int windowWillClose(void);
int main(void)
{
glfwInit();
glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, GL_TRUE);
glfwOpenWindow(640,480,8,8,8,8,8,0,GLFW_WINDOW);
glfwSetWindowCloseCallback(windowWillClose);
glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);
glGenBuffers(1, &quadPositionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, quadPositionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadPositions), quadPositions, GL_STATIC_DRAW);
glGenBuffers(1, &quadElementBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadElementBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quadElements), quadElements, GL_STATIC_DRAW);
glGenTextures(1,&inputTexture);
glBindTexture(GL_TEXTURE_2D, inputTexture);
GLFWimage glfwi;
glfwReadImage(EXAMPLE_PATH "/OttoOperatesTheRoller.tga",&glfwi,GLFW_NO_RESCALE_BIT);
glfwLoadTextureImage2D(&glfwi,0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);
fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
GLint positionAttribute = glGetAttribLocation(program, "position");
GLint textureUniform = glGetUniformLocation(program, "texture");
while(glfwGetWindowParam(GLFW_OPENED))
{
glUseProgram(program);
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, outputImage->glTextureName);
glUniform1i(textureUniform, 0);
glBindBuffer(GL_ARRAY_BUFFER, quadPositionBuffer);
glVertexAttribPointer(positionAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, (void*)0);
glEnableVertexAttribArray(positionAttribute);
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadElementBuffer);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0);
}
glDisableVertexAttribArray(positionAttribute);
}
glUseProgram(0);
glfwSwapBuffers();
vuoRelease(outputImage);
}
glfwTerminate();
return 0;
}
int windowWillClose(void)
{
delete runner;
glDetachShader(program, vertexShader);
glDetachShader(program, fragmentShader);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteProgram(program);
glDeleteTextures(1, &inputTexture);
glDeleteBuffers(1, &quadElementBuffer);
glDeleteBuffers(1, &quadPositionBuffer);
glDeleteVertexArrays(1, &vertexArray);
return true;
}