int main(int argc, char **argv) { FILE *fp = fopen(argv[1], "r"); if (fp == NULL) return 0; dump_bmp(fp); fclose(fp); return 0; }
void test_stencil(void) { GLint numStencilBits; GLuint stencilValues[NumTests] = { 0x7, // Result of test 0 0x0, // Result of test 1 0x2, // Result of test 2 0xff // Result of test 3. We need to fill this value in a run-time }; int i; DEBUG_MSG("----------------------------------------------------------------"); RD_START("stencil", ""); ECHK(surface = eglCreatePbufferSurface(display, config, pbuffer_attribute_list)); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("PBuffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); GCHK(glFlush()); if (!program) { program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "aPosition")); link_program(program); /* now set up our uniform. */ GCHK(uniform_location = glGetUniformLocation(program, "uColor")); } GCHK(glClearColor(0.0, 0.0, 0.0, 0.0)); GCHK(glClearStencil(0x1)); GCHK(glClearDepthf(0.75)); GCHK(glEnable(GL_DEPTH_TEST)); GCHK(glEnable(GL_STENCIL_TEST)); // Set the viewport GCHK(glViewport(0, 0, width, height)); // Clear the color, depth, and stencil buffers. At this // point, the stencil buffer will be 0x1 for all pixels GCHK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); // Use the program object GCHK(glUseProgram(program)); // Load the vertex position GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices)); GCHK(glEnableVertexAttribArray(0)); // Test 0: // // Initialize upper-left region. In this case, the // stencil-buffer values will be replaced because the // stencil test for the rendered pixels will fail the // stencil test, which is // // ref mask stencil mask // ( 0x7 & 0x3 ) < ( 0x1 & 0x7 ) // // The value in the stencil buffer for these pixels will // be 0x7. // GCHK(glStencilFunc(GL_LESS, 0x7, 0x3)); GCHK(glStencilOp(GL_REPLACE, GL_DECR, GL_DECR)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[0])); // Test 1: // // Initialize the upper-right region. Here, we'll decrement // the stencil-buffer values where the stencil test passes // but the depth test fails. The stencil test is // // ref mask stencil mask // ( 0x3 & 0x3 ) > ( 0x1 & 0x3 ) // // but where the geometry fails the depth test. The // stencil values for these pixels will be 0x0. // GCHK(glStencilFunc(GL_GREATER, 0x3, 0x3)); GCHK(glStencilOp(GL_KEEP, GL_DECR, GL_KEEP)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[1])); // Test 2: // // Initialize the lower-left region. Here we'll increment // (with saturation) the stencil value where both the // stencil and depth tests pass. The stencil test for // these pixels will be // // ref mask stencil mask // ( 0x1 & 0x3 ) == ( 0x1 & 0x3 ) // // The stencil values for these pixels will be 0x2. // GCHK(glStencilFunc(GL_EQUAL, 0x1, 0x3)); GCHK(glStencilOp(GL_KEEP, GL_INCR, GL_INCR)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[2])); // Test 3: // // Finally, initialize the lower-right region. We'll invert // the stencil value where the stencil tests fails. The // stencil test for these pixels will be // // ref mask stencil mask // ( 0x2 & 0x1 ) == ( 0x1 & 0x1 ) // // The stencil value here will be set to ~((2^s-1) & 0x1), // (with the 0x1 being from the stencil clear value), // where 's' is the number of bits in the stencil buffer // GCHK(glStencilFunc(GL_EQUAL, 0x2, 0x1)); GCHK(glStencilOp(GL_INVERT, GL_KEEP, GL_KEEP)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[3])); // Since we don't know at compile time how many stencil bits are present, // we'll query, and update the value correct value in the // stencilValues arrays for the fourth tests. We'll use this value // later in rendering. GCHK(glGetIntegerv(GL_STENCIL_BITS, &numStencilBits)); stencilValues[3] = ~(((1 << numStencilBits) - 1) & 0x1) & 0xff; // Use the stencil buffer for controlling where rendering will // occur. We disable writing to the stencil buffer so we // can test against them without modifying the values we // generated. GCHK(glStencilMask(0x0)); for (i = 0; i < NumTests; i++) { GCHK(glStencilFunc(GL_EQUAL, stencilValues[i], 0xff)); GCHK(glUniform4fv(uniform_location, 1, colors[i])); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[4])); } ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); ECHK(eglDestroySurface(display, surface)); GCHK(glFlush()); usleep(1000000); dump_bmp(display, surface, "stencil.bmp"); RD_END(); }