PDA

View Full Version : Implement Game of Life with OpenGL buffers



xorserq
07-27-2014, 08:48 AM
Hello,

I'm trying to implement Game of Life as specified in the red book:


One way to create this game using OpenGL is to use a multipass algorithm. Keep the data in the color buffer, one pixel for each grid point. Assume that black (all zeros) is the background color, and the color of a live pixel is nonzero. Initialize by clearing the depth and stencil buffers to zero, set the depth-buffer writemask to zero, and set the depth comparison function so that it passes on not-equal. To iterate, read the image off the screen, enable drawing into the depth buffer, and set the stencil function so that it increments whenever a depth comparison succeeds but leaves the stencil buffer unchanged otherwise. Disable drawing into the color buffer.

Next, draw the image eight times, offset one pixel in each vertical, horizontal, and diagonal direction. When you're done, the stencil buffer contains a count of the number of live neighbors for each pixel. Enable drawing to the color buffer, set the color to the color for live cells, and set the stencil function to draw only if the value in the stencil buffer is 3 (three live neighbors). In addition, if this drawing occurs, decrement the value in the stencil buffer. Then draw a rectangle covering the image; this paints each cell that has exactly three live neighbors with the "alive" color.

At this point, the stencil buffers contain 0, 1, 2, 4, 5, 6, 7, 8, and the values under the 2's are correct. The values under 0, 1, 4, 5, 6, 7, and 8 must be cleared to the "dead" color. Set the stencil function to draw whenever the value is not 2, and to zero the stencil values in all cases. Then draw a large polygon of the "dead" color across the entire image. You're done.

I want to know if I'm doing things correctly. This is my display function:

void display(void)
{
glReadPixels(0, 0, win_x, win_y, GL_RGB, GL_UNSIGNED_BYTE, image); //Reading framebuffer content
glDepthMask(GL_TRUE);
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

//drawing the image 8 times
glPushMatrix();
glTranslatef(1, 0, 0);
glDrawPixels(win_x, win_y, GL_RGB, GL_UNSIGNED_BYTE, image);
glPopMatrix();

glPushMatrix();
glTranslatef(0, 1, 0);
glDrawPixels(win_x, win_y, GL_RGB, GL_UNSIGNED_BYTE, image);
glPopMatrix();

glPushMatrix();
glTranslatef(1, 1, 0);
glDrawPixels(win_x, win_y, GL_RGB, GL_UNSIGNED_BYTE, image);
glPopMatrix();

glPushMatrix();
glTranslatef(-1, 0, 0);
glDrawPixels(win_x, win_y, GL_RGB, GL_UNSIGNED_BYTE, image);
glPopMatrix();

glPushMatrix();
glTranslatef(0, -1, 0);
glDrawPixels(win_x, win_y, GL_RGB, GL_UNSIGNED_BYTE, image);
glPopMatrix();

glPushMatrix();
glTranslatef(-1, -1, 0);
glDrawPixels(win_x, win_y, GL_RGB, GL_UNSIGNED_BYTE, image);
glPopMatrix();

glPushMatrix();
glTranslatef(1, -1, 0);
glDrawPixels(win_x, win_y, GL_RGB, GL_UNSIGNED_BYTE, image);
glPopMatrix();

glPushMatrix();
glTranslatef(-1, 1, 0);
glDrawPixels(win_x, win_y, GL_RGB, GL_UNSIGNED_BYTE, image);
glPopMatrix();

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

//drawing life cells
glStencilFunc(GL_EQUAL, 3, 0xffffffff);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
glColor3f(1, 0, 0);
glRectf(-1, -1, 1, 1);
glFlush();

//drawing dead cells
glStencilFunc(GL_NOTEQUAL, 2, 0xffffffff);
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
glColor3f(0, 0, 1);
glRectf(-1, -1, 1, 1);
glFlush();
}


Note: I defined the prespective as:
glOrtho(-1,1,-1,1,-1,1);
So the rectangle defined by
glRectf(-1, -1, 1, 1); fits the screen
Am I drawing the image correctly in each vertical? Is using glTrasnlatef does what they wanted?

Any help would be appreciated.