VVGL::GLScene is a frontend for a performing custom render commands in an OpenGL context. It's a relatively simple class- it lets you provide a block that executes drawing commands and performs a series of rendering steps that can be customized, with built-in support for orthogonal rendering, rendering to textures/GLBufferRef, and support for a variety of different versions of OpenGL.
Following are some examples that demonstrate creating and configuring a GLScene, and then rendering it into a texture.
Creating and GLScene and rendering it to a texture for older versions of GL:
glScene->setRenderCallback([](const GLScene & inScene) {
Quad<VertXYZRGBA> texQuad;
texQuad.populateGeo(
VVGL::Rect(0,0,sceneSize.width,sceneSize.height));
texQuad.bl.color = GLColor(1., 1., 1., 1.);
texQuad.tl.color = GLColor(1., 0., 0., 1.);
texQuad.tr.color = GLColor(0., 1., 0., 1.);
texQuad.br.color = GLColor(0., 0., 1., 1.);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(texQuad.bl.geo.numComponents(), GL_FLOAT, texQuad.stride(), &texQuad.bl.geo[0]);
glColorPointer(texQuad.bl.color.numComponents(), GL_FLOAT, texQuad.stride(), &texQuad.bl.color[0]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
});
glScene->renderToBuffer(renderedTexture);
Creating a GLScene and rendering it to a texture for desktop GL 3+:
string vsString("\r\
#version 330 core\r\
in vec3 inXYZ;\r\
in vec4 inRGBA;\r\
uniform mat4 vvglOrthoProj;\r\
out vec4 programRGBA;\r\
void main() {\r\
gl_Position = vec4(inXYZ.x, inXYZ.y, inXYZ.z, 1.0) * vvglOrthoProj;\r\
programRGBA = inRGBA;\r\
}\r\
");
string fsString("\r\
#version 330 core\r\
in vec4 programRGBA;\r\
out vec4 FragColor;\r\
void main() {\r\
FragColor = programRGBA;\r\
}\r\
");
glScene->setVertexShaderString(vsString);
glScene->setFragmentShaderString(fsString);
static Quad<VertXYZRGBA> vboData = Quad<VertXYZRGBA>();
glScene->setRenderPrepCallback([](const GLScene & inScene, const bool & inReshaped, const bool & inPgmChanged) {
if (inPgmChanged) {
GLint myProgram = inScene.program();
xyzAttr->cacheTheLoc(myProgram);
rgbaAttr->cacheTheLoc(myProgram);
}
});
glScene->setRenderCallback([](const GLScene & inScene) {
VVGL::Rect boundsRect(0, 0, orthoSize.width, orthoSize.height);
Quad<VertXYZRGBA> targetQuad;
targetQuad.populateGeo(boundsRect);
targetQuad.bl.color = GLColor(1., 1., 1., 1.);
targetQuad.tl.color = GLColor(1., 0., 0., 1.);
targetQuad.tr.color = GLColor(0., 1., 0., 1.);
targetQuad.br.color = GLColor(0., 0., 1., 1.);
glBindVertexArray(vao->name);
uint32_t vbo = 0;
if (vboData != targetQuad) {
vboData = targetQuad;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(targetQuad), (void*)(&targetQuad), GL_STATIC_DRAW);
if (xyzAttr->loc >= 0) {
glVertexAttribPointer(xyzAttr->loc, targetQuad.bl.geo.numComponents(), GL_FLOAT, GL_FALSE, targetQuad.stride(), BUFFER_OFFSET(targetQuad.geoOffset()));
xyzAttr->enable();
}
if (rgbaAttr->loc >= 0) {
glVertexAttribPointer(rgbaAttr->loc, targetQuad.bl.color.numComponents(), GL_FLOAT, GL_FALSE, targetQuad.stride(), BUFFER_OFFSET(targetQuad.colorOffset()));
rgbaAttr->enable();
}
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
if (vbo != 0) {
glDeleteBuffers(1, &vbo);
}
});
glScene->renderToBuffer(renderedTexture);