Skip to content

Instantly share code, notes, and snippets.

@jlstrecker
Created January 7, 2016 18:13
Show Gist options
  • Save jlstrecker/9df10ef177c2a49bae3e to your computer and use it in GitHub Desktop.
Save jlstrecker/9df10ef177c2a49bae3e to your computer and use it in GitHub Desktop.
// clang++ -o test test.cc -Wno-deprecated-declarations -framework GLUT -framework OpenGL && ./test
#define SHARE_BUFFERS
#include <string.h>
#include <stdlib.h>
#include <GLUT/glut.h>
#include <dispatch/dispatch.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/CGLMacro.h>
#define glGenVertexArrays glGenVertexArraysAPPLE
#define glBindVertexArray glBindVertexArrayAPPLE
#define glDeleteVertexArrays glDeleteVertexArraysAPPLE
static GLuint compileShader(CGLContextObj cgl_ctx, GLenum type, const char *source)
{
GLint length = strlen(source);
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, (const GLchar**)&source, &length);
glCompileShader(shader);
return shader;
}
typedef struct
{
CGLContextObj localContext;
GLuint vertexShader;
GLuint fragmentShader;
GLuint program;
GLuint quadPositionBuffer;
GLuint quadElementBuffer;
} fboData;
void fbo(void *c)
{
fboData *d = (fboData *)c;
CGLContextObj cgl_ctx = d->localContext;
glViewport(0, 0, 640, 480);
while (true)
{
GLuint fbtex;
glGenTextures(1, &fbtex);
glBindTexture(GL_TEXTURE_2D, fbtex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 640, 480, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
GLuint fb;
glGenFramebuffers(1, &fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbtex, 0);
GLuint vertexArray;
glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);
glUseProgram(d->program);
glBindBuffer(GL_ARRAY_BUFFER, d->quadPositionBuffer);
GLint positionAttribute = glGetAttribLocation(d->program, "position");
glVertexAttribPointer(positionAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, (void*)0);
glEnableVertexAttribArray(positionAttribute);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, d->quadElementBuffer);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(positionAttribute);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
glBindVertexArray(0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteTextures(1, &fbtex);
glDeleteFramebuffers(1, &fb);
glDeleteVertexArrays(1, &vertexArray);
glFlushRenderAPPLE();
}
}
void display(void)
{
glutPostRedisplay();
}
const GLfloat quadPositions[] = {
-1, -1, 0, 1,
1, -1, 0, 1,
-1, 1, 0, 1,
1, 1, 0, 1
};
const GLushort quadElements[] = { 0, 1, 2, 3 };
#define GLSL_STRING(version,source) "#version " #version "\n" #source
const char *vertexShaderSource = GLSL_STRING(120,
attribute vec4 position;
void main()
{
gl_Position = position;
}
);
const char *fragmentShaderSource = GLSL_STRING(120,
void main()
{
gl_FragColor = vec4(gl_FragCoord.x/640, gl_FragCoord.y/480, 0, 1);
}
);
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(640, 480);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("OpenGL sharing test");
glutDisplayFunc(display);
CGLContextObj rootContext = CGLGetCurrentContext();
GLuint quadPositionBuffer = 0;
GLuint quadElementBuffer = 0;
for (int i = 0; i < 10; ++i)
{
fboData *d = (fboData *)malloc(sizeof(fboData));
CGLPixelFormatObj pf = CGLGetPixelFormat(rootContext);
CGLCreateContext(pf, rootContext, &d->localContext);
{
CGLContextObj cgl_ctx = d->localContext;
d->vertexShader = compileShader(d->localContext, GL_VERTEX_SHADER, vertexShaderSource);
d->fragmentShader = compileShader(d->localContext, GL_FRAGMENT_SHADER, fragmentShaderSource);
d->program = glCreateProgram();
glAttachShader(d->program, d->vertexShader);
glAttachShader(d->program, d->fragmentShader);
glLinkProgram(d->program);
#ifdef SHARE_BUFFERS
if (quadPositionBuffer == 0)
{
glGenBuffers(1, &quadPositionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, quadPositionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadPositions), quadPositions, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &quadElementBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadElementBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quadElements), quadElements, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
d->quadPositionBuffer = quadPositionBuffer;
d->quadElementBuffer = quadElementBuffer;
#else
glGenBuffers(1, &d->quadPositionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, d->quadPositionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadPositions), quadPositions, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &d->quadElementBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, d->quadElementBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quadElements), quadElements, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ fbo(d); });
}
glutMainLoop();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment