void GraphicsSystem::Initialize()
{
//create frame buffer
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
//create texture for frame buffer
glGenTextures(1, &sourceTexture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sourceTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, 0); //note GL_RED internal format, to save memory.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //GL_REPEAT specified so that CGOL is simulated on a torus.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, sourceTexture, 0);
glBindTexture(GL_TEXTURE_2D, 0);
GL_ERROR(); //asserts of glGetError returns an error code.
//create texture for frame buffer
glGenTextures(1, &destinationTexture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, destinationTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, 0); //note GL_RED internal format, to save memory.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //GL_REPEAT specified so that CGOL is simulated on a torus.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, destinationTexture, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
GL_ERROR(); //asserts of glGetError returns an error code.
colorAttachment = GL_COLOR_ATTACHMENT1;
}
void GraphicsSystem::Draw()
{
const vec3 verts[4] = { vec3(0 , 0 , 0),
vec3(width, 0 , 0),
vec3(width, height, 0),
vec3(0 , height, 0) };
const vec2 uv[4] = { vec2(0 , 0 ),
vec2(1.0f, 0 ),
vec2(1.0f, 1.0f),
vec2(0 , 1.0f) };
//==========================//
//CGOL SIMULATION
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glDrawBuffer(colorAttachment);
cgolShader.Execute();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sourceTexture);
cgolShader.UniformMat4("u_transformation", &projection.Top()[0][0]);
cgolShader.UniformInt("u_source_texture", 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, verts);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, uv);
glDrawArrays(GL_QUADS, 0, 4);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
cgolShader.Terminate();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
GL_ERROR(); //asserts of glGetError returns an error code.
//==========================//
//==========================//
//DRAW SOME GEOMETRY
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glDrawBuffer(colorAttachment);
//draw some simple geometry however you wish here.
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GL_ERROR(); //asserts of glGetError returns an error code.
//==========================//
//==========================//
//FINAL PASS
//render destinationTexture to screen however you wish here
//==========================//
//==========================//
//SWAP TEXTURES
GLint temp = outputFrameTexture;
outputFrameTexture = nextGenerationTexture;
nextGenerationTexture = temp;
//switch color attachments since we swapped the textures.
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
if(colorAttachment == GL_COLOR_ATTACHMENT1)
{
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClear(GL_COLOR_BUFFER_BIT);
colorAttachment = GL_COLOR_ATTACHMENT0;
}
else
{
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glClear(GL_COLOR_BUFFER_BIT);
colorAttachment = GL_COLOR_ATTACHMENT1;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GL_ERROR(); //asserts of glGetError returns an error code.
//==========================//
}