| OLD | NEW |
| 1 // | 1 // |
| 2 // Book: OpenGL(R) ES 2.0 Programming Guide | 2 // Book: OpenGL(R) ES 2.0 Programming Guide |
| 3 // Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner | 3 // Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner |
| 4 // ISBN-10: 0321502795 | 4 // ISBN-10: 0321502795 |
| 5 // ISBN-13: 9780321502797 | 5 // ISBN-13: 9780321502797 |
| 6 // Publisher: Addison-Wesley Professional | 6 // Publisher: Addison-Wesley Professional |
| 7 // URLs: http://safari.informit.com/9780321563835 | 7 // URLs: http://safari.informit.com/9780321563835 |
| 8 // http://www.opengles-book.com | 8 // http://www.opengles-book.com |
| 9 // | 9 // |
| 10 | 10 |
| 11 // Stencil_Test.c | 11 // Stencil_Test.c |
| 12 // | 12 // |
| 13 // This example shows various stencil buffer | 13 // This example shows various stencil buffer |
| 14 // operations. | 14 // operations. |
| 15 // | 15 // |
| 16 #include <stdlib.h> | 16 #include <stdlib.h> |
| 17 #include "esUtil.h" | 17 #include "esUtil.h" |
| 18 | 18 |
| 19 typedef struct | 19 typedef struct |
| 20 { | 20 { |
| 21 // Handle to a program object | 21 // Handle to a program object |
| 22 GLuint programObject; | 22 GLuint programObject; |
| 23 | 23 |
| 24 // Attribute locations | 24 // Attribute locations |
| 25 GLint positionLoc; | 25 GLint positionLoc; |
| 26 | 26 |
| 27 // Uniform locations | 27 // Uniform locations |
| 28 GLint colorLoc; | 28 GLint colorLoc; |
| 29 | 29 |
| 30 // Vertex buffer object handles |
| 31 GLuint vboIds[2]; |
| 32 |
| 30 } UserData; | 33 } UserData; |
| 31 | 34 |
| 32 /// | 35 /// |
| 33 // Initialize the shader and program object | 36 // Initialize the shader and program object |
| 34 // | 37 // |
| 35 int Init ( ESContext *esContext ) | 38 int Init ( ESContext *esContext ) |
| 36 { | 39 { |
| 37 UserData *userData = esContext->userData; | 40 UserData *userData = esContext->userData; |
| 38 GLbyte vShaderStr[] = | 41 GLbyte vShaderStr[] = |
| 39 "attribute vec4 a_position; \n" | 42 "attribute vec4 a_position; \n" |
| 40 "void main() \n" | 43 "void main() \n" |
| 41 "{ \n" | 44 "{ \n" |
| 42 " gl_Position = a_position; \n" | 45 " gl_Position = a_position; \n" |
| 43 "} \n"; | 46 "} \n"; |
| 44 | 47 |
| 45 GLbyte fShaderStr[] = | 48 GLbyte fShaderStr[] = |
| 46 "precision mediump float; \n" | 49 "precision mediump float; \n" |
| 47 "uniform vec4 u_color; \n" | 50 "uniform vec4 u_color; \n" |
| 48 "void main() \n" | 51 "void main() \n" |
| 49 "{ \n" | 52 "{ \n" |
| 50 " gl_FragColor = u_color; \n" | 53 " gl_FragColor = u_color; \n" |
| 51 "} \n"; | 54 "} \n"; |
| 52 | 55 |
| 56 GLfloat vVertices[] = { |
| 57 -0.75f, 0.25f, 0.50f, // Quad #0 |
| 58 -0.25f, 0.25f, 0.50f, |
| 59 -0.25f, 0.75f, 0.50f, |
| 60 -0.75f, 0.75f, 0.50f, |
| 61 0.25f, 0.25f, 0.90f, // Quad #1 |
| 62 0.75f, 0.25f, 0.90f, |
| 63 0.75f, 0.75f, 0.90f, |
| 64 0.25f, 0.75f, 0.90f, |
| 65 -0.75f, -0.75f, 0.50f, // Quad #2 |
| 66 -0.25f, -0.75f, 0.50f, |
| 67 -0.25f, -0.25f, 0.50f, |
| 68 -0.75f, -0.25f, 0.50f, |
| 69 0.25f, -0.75f, 0.50f, // Quad #3 |
| 70 0.75f, -0.75f, 0.50f, |
| 71 0.75f, -0.25f, 0.50f, |
| 72 0.25f, -0.25f, 0.50f, |
| 73 -1.00f, -1.00f, 0.00f, // Big Quad |
| 74 1.00f, -1.00f, 0.00f, |
| 75 1.00f, 1.00f, 0.00f, |
| 76 -1.00f, 1.00f, 0.00f |
| 77 }; |
| 78 |
| 79 GLubyte indices[] = { |
| 80 0, 1, 2, 0, 2, 3, // Quad #0 |
| 81 4, 5, 6, 4, 6, 7, // Quad #1 |
| 82 8, 9, 10, 8, 10, 11, // Quad #2 |
| 83 12, 13, 14, 12, 14, 15, // Quad #3 |
| 84 16, 17, 18, 16, 18, 19 // Big Quad |
| 85 }; |
| 86 |
| 53 // Load the shaders and get a linked program object | 87 // Load the shaders and get a linked program object |
| 54 userData->programObject = esLoadProgram ( vShaderStr, fShaderStr ); | 88 userData->programObject = esLoadProgram ( vShaderStr, fShaderStr ); |
| 55 | 89 |
| 56 // Get the attribute locations | 90 // Get the attribute locations |
| 57 userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_pos
ition" ); | 91 userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_pos
ition" ); |
| 58 | 92 |
| 59 // Get the sampler location | 93 // Get the sampler location |
| 60 userData->colorLoc = glGetUniformLocation ( userData->programObject, "u_color
" ); | 94 userData->colorLoc = glGetUniformLocation ( userData->programObject, "u_color
" ); |
| 61 | 95 |
| 96 // Load vertex data |
| 97 glGenBuffers ( 2, userData->vboIds ); |
| 98 glBindBuffer ( GL_ARRAY_BUFFER, userData->vboIds[0] ); |
| 99 glBufferData ( GL_ARRAY_BUFFER, sizeof(vVertices), |
| 100 vVertices, GL_STATIC_DRAW ); |
| 101 glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, userData->vboIds[1] ); |
| 102 glBufferData ( GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), |
| 103 indices, GL_STATIC_DRAW ); |
| 104 |
| 62 // Set the clear color | 105 // Set the clear color |
| 63 glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f ); | 106 glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f ); |
| 64 | 107 |
| 65 // Set the stencil clear value | 108 // Set the stencil clear value |
| 66 glClearStencil ( 0x1 ); | 109 glClearStencil ( 0x1 ); |
| 67 | 110 |
| 68 // Set the depth clear value | 111 // Set the depth clear value |
| 69 glClearDepthf( 0.75f ); | 112 glClearDepthf( 0.75f ); |
| 70 | 113 |
| 71 // Enable the depth and stencil tests | 114 // Enable the depth and stencil tests |
| 72 glEnable( GL_DEPTH_TEST ); | 115 glEnable( GL_DEPTH_TEST ); |
| 73 glEnable( GL_STENCIL_TEST ); | 116 glEnable( GL_STENCIL_TEST ); |
| 74 | 117 |
| 75 return TRUE; | 118 return TRUE; |
| 76 } | 119 } |
| 77 | 120 |
| 78 /// | 121 /// |
| 79 // Initialize the stencil buffer values, and then use those | 122 // Initialize the stencil buffer values, and then use those |
| 80 // values to control rendering | 123 // values to control rendering |
| 81 // | 124 // |
| 82 void Draw ( ESContext *esContext ) | 125 void Draw ( ESContext *esContext ) |
| 83 { | 126 { |
| 84 int i; | 127 int i; |
| 128 GLubyte *offset = NULL; |
| 85 | 129 |
| 86 UserData *userData = esContext->userData; | 130 UserData *userData = esContext->userData; |
| 87 | 131 |
| 88 GLfloat vVertices[] = { | |
| 89 -0.75f, 0.25f, 0.50f, // Quad #0 | |
| 90 -0.25f, 0.25f, 0.50f, | |
| 91 -0.25f, 0.75f, 0.50f, | |
| 92 -0.75f, 0.75f, 0.50f, | |
| 93 0.25f, 0.25f, 0.90f, // Quad #1 | |
| 94 0.75f, 0.25f, 0.90f, | |
| 95 0.75f, 0.75f, 0.90f, | |
| 96 0.25f, 0.75f, 0.90f, | |
| 97 -0.75f, -0.75f, 0.50f, // Quad #2 | |
| 98 -0.25f, -0.75f, 0.50f, | |
| 99 -0.25f, -0.25f, 0.50f, | |
| 100 -0.75f, -0.25f, 0.50f, | |
| 101 0.25f, -0.75f, 0.50f, // Quad #3 | |
| 102 0.75f, -0.75f, 0.50f, | |
| 103 0.75f, -0.25f, 0.50f, | |
| 104 0.25f, -0.25f, 0.50f, | |
| 105 -1.00f, -1.00f, 0.00f, // Big Quad | |
| 106 1.00f, -1.00f, 0.00f, | |
| 107 1.00f, 1.00f, 0.00f, | |
| 108 -1.00f, 1.00f, 0.00f | |
| 109 }; | |
| 110 | |
| 111 GLubyte indices[][6] = { | |
| 112 { 0, 1, 2, 0, 2, 3 }, // Quad #0 | |
| 113 { 4, 5, 6, 4, 6, 7 }, // Quad #1 | |
| 114 { 8, 9, 10, 8, 10, 11 }, // Quad #2 | |
| 115 { 12, 13, 14, 12, 14, 15 }, // Quad #3 | |
| 116 { 16, 17, 18, 16, 18, 19 } // Big Quad | |
| 117 }; | |
| 118 | |
| 119 #define NumTests 4 | 132 #define NumTests 4 |
| 120 GLfloat colors[NumTests][4] = { | 133 GLfloat colors[NumTests][4] = { |
| 121 { 1.0f, 0.0f, 0.0f, 1.0f }, | 134 { 1.0f, 0.0f, 0.0f, 1.0f }, |
| 122 { 0.0f, 1.0f, 0.0f, 1.0f }, | 135 { 0.0f, 1.0f, 0.0f, 1.0f }, |
| 123 { 0.0f, 0.0f, 1.0f, 1.0f }, | 136 { 0.0f, 0.0f, 1.0f, 1.0f }, |
| 124 { 1.0f, 1.0f, 0.0f, 0.0f } | 137 { 1.0f, 1.0f, 0.0f, 0.0f } |
| 125 }; | 138 }; |
| 126 | 139 |
| 127 GLint numStencilBits; | 140 GLint numStencilBits; |
| 128 GLuint stencilValues[NumTests] = { | 141 GLuint stencilValues[NumTests] = { |
| 129 0x7, // Result of test 0 | 142 0x7, // Result of test 0 |
| 130 0x0, // Result of test 1 | 143 0x0, // Result of test 1 |
| 131 0x2, // Result of test 2 | 144 0x2, // Result of test 2 |
| 132 0xff // Result of test 3. We need to fill this | 145 0xff // Result of test 3. We need to fill this |
| 133 // value in a run-time | 146 // value in a run-time |
| 134 }; | 147 }; |
| 135 | 148 |
| 136 // Set the viewport | 149 // Set the viewport |
| 137 glViewport ( 0, 0, esContext->width, esContext->height ); | 150 glViewport ( 0, 0, esContext->width, esContext->height ); |
| 138 | 151 |
| 139 // Clear the color, depth, and stencil buffers. At this | 152 // Clear the color, depth, and stencil buffers. At this |
| 140 // point, the stencil buffer will be 0x1 for all pixels | 153 // point, the stencil buffer will be 0x1 for all pixels |
| 141 glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT )
; | 154 glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT )
; |
| 142 | 155 |
| 143 // Use the program object | 156 // Use the program object |
| 144 glUseProgram ( userData->programObject ); | 157 glUseProgram ( userData->programObject ); |
| 145 | 158 |
| 146 // Load the vertex position | 159 // Load the vertex position |
| 147 glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, | 160 glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, |
| 148 GL_FALSE, 0, vVertices ); | 161 GL_FALSE, 0, 0 ); |
| 149 | 162 |
| 150 glEnableVertexAttribArray ( userData->positionLoc ); | 163 glEnableVertexAttribArray ( userData->positionLoc ); |
| 151 | 164 |
| 152 // Test 0: | 165 // Test 0: |
| 153 // | 166 // |
| 154 // Initialize upper-left region. In this case, the | 167 // Initialize upper-left region. In this case, the |
| 155 // stencil-buffer values will be replaced because the | 168 // stencil-buffer values will be replaced because the |
| 156 // stencil test for the rendered pixels will fail the | 169 // stencil test for the rendered pixels will fail the |
| 157 // stencil test, which is | 170 // stencil test, which is |
| 158 // | 171 // |
| 159 // ref mask stencil mask | 172 // ref mask stencil mask |
| 160 // ( 0x7 & 0x3 ) < ( 0x1 & 0x7 ) | 173 // ( 0x7 & 0x3 ) < ( 0x1 & 0x7 ) |
| 161 // | 174 // |
| 162 // The value in the stencil buffer for these pixels will | 175 // The value in the stencil buffer for these pixels will |
| 163 // be 0x7. | 176 // be 0x7. |
| 164 // | 177 // |
| 165 glStencilFunc( GL_LESS, 0x7, 0x3 ); | 178 glStencilFunc( GL_LESS, 0x7, 0x3 ); |
| 166 glStencilOp( GL_REPLACE, GL_DECR, GL_DECR ); | 179 glStencilOp( GL_REPLACE, GL_DECR, GL_DECR ); |
| 167 glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[0] ); | 180 glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, offset ); |
| 168 | 181 |
| 169 // Test 1: | 182 // Test 1: |
| 170 // | 183 // |
| 171 // Initialize the upper-right region. Here, we'll decrement | 184 // Initialize the upper-right region. Here, we'll decrement |
| 172 // the stencil-buffer values where the stencil test passes | 185 // the stencil-buffer values where the stencil test passes |
| 173 // but the depth test fails. The stencil test is | 186 // but the depth test fails. The stencil test is |
| 174 // | 187 // |
| 175 // ref mask stencil mask | 188 // ref mask stencil mask |
| 176 // ( 0x3 & 0x3 ) > ( 0x1 & 0x3 ) | 189 // ( 0x3 & 0x3 ) > ( 0x1 & 0x3 ) |
| 177 // | 190 // |
| 178 // but where the geometry fails the depth test. The | 191 // but where the geometry fails the depth test. The |
| 179 // stencil values for these pixels will be 0x0. | 192 // stencil values for these pixels will be 0x0. |
| 180 // | 193 // |
| 181 glStencilFunc( GL_GREATER, 0x3, 0x3 ); | 194 glStencilFunc( GL_GREATER, 0x3, 0x3 ); |
| 182 glStencilOp( GL_KEEP, GL_DECR, GL_KEEP ); | 195 glStencilOp( GL_KEEP, GL_DECR, GL_KEEP ); |
| 183 glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[1] ); | 196 offset += 6; |
| 197 glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, offset ); |
| 184 | 198 |
| 185 // Test 2: | 199 // Test 2: |
| 186 // | 200 // |
| 187 // Initialize the lower-left region. Here we'll increment | 201 // Initialize the lower-left region. Here we'll increment |
| 188 // (with saturation) the stencil value where both the | 202 // (with saturation) the stencil value where both the |
| 189 // stencil and depth tests pass. The stencil test for | 203 // stencil and depth tests pass. The stencil test for |
| 190 // these pixels will be | 204 // these pixels will be |
| 191 // | 205 // |
| 192 // ref mask stencil mask | 206 // ref mask stencil mask |
| 193 // ( 0x1 & 0x3 ) == ( 0x1 & 0x3 ) | 207 // ( 0x1 & 0x3 ) == ( 0x1 & 0x3 ) |
| 194 // | 208 // |
| 195 // The stencil values for these pixels will be 0x2. | 209 // The stencil values for these pixels will be 0x2. |
| 196 // | 210 // |
| 197 glStencilFunc( GL_EQUAL, 0x1, 0x3 ); | 211 glStencilFunc( GL_EQUAL, 0x1, 0x3 ); |
| 198 glStencilOp( GL_KEEP, GL_INCR, GL_INCR ); | 212 glStencilOp( GL_KEEP, GL_INCR, GL_INCR ); |
| 199 glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[2] ); | 213 offset += 6; |
| 214 glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, offset ); |
| 200 | 215 |
| 201 // Test 3: | 216 // Test 3: |
| 202 // | 217 // |
| 203 // Finally, initialize the lower-right region. We'll invert | 218 // Finally, initialize the lower-right region. We'll invert |
| 204 // the stencil value where the stencil tests fails. The | 219 // the stencil value where the stencil tests fails. The |
| 205 // stencil test for these pixels will be | 220 // stencil test for these pixels will be |
| 206 // | 221 // |
| 207 // ref mask stencil mask | 222 // ref mask stencil mask |
| 208 // ( 0x2 & 0x1 ) == ( 0x1 & 0x1 ) | 223 // ( 0x2 & 0x1 ) == ( 0x1 & 0x1 ) |
| 209 // | 224 // |
| 210 // The stencil value here will be set to ~((2^s-1) & 0x1), | 225 // The stencil value here will be set to ~((2^s-1) & 0x1), |
| 211 // (with the 0x1 being from the stencil clear value), | 226 // (with the 0x1 being from the stencil clear value), |
| 212 // where 's' is the number of bits in the stencil buffer | 227 // where 's' is the number of bits in the stencil buffer |
| 213 // | 228 // |
| 214 glStencilFunc( GL_EQUAL, 0x2, 0x1 ); | 229 glStencilFunc( GL_EQUAL, 0x2, 0x1 ); |
| 215 glStencilOp( GL_INVERT, GL_KEEP, GL_KEEP ); | 230 glStencilOp( GL_INVERT, GL_KEEP, GL_KEEP ); |
| 216 glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[3] ); | 231 offset += 6; |
| 232 glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, offset ); |
| 217 | 233 |
| 218 // Since we don't know at compile time how many stecil bits are present, | 234 // Since we don't know at compile time how many stecil bits are present, |
| 219 // we'll query, and update the value correct value in the | 235 // we'll query, and update the value correct value in the |
| 220 // stencilValues arrays for the fourth tests. We'll use this value | 236 // stencilValues arrays for the fourth tests. We'll use this value |
| 221 // later in rendering. | 237 // later in rendering. |
| 222 glGetIntegerv( GL_STENCIL_BITS, &numStencilBits ); | 238 glGetIntegerv( GL_STENCIL_BITS, &numStencilBits ); |
| 223 | 239 |
| 224 stencilValues[3] = ~(((1 << numStencilBits) - 1) & 0x1) & 0xff; | 240 stencilValues[3] = ~(((1 << numStencilBits) - 1) & 0x1) & 0xff; |
| 225 | 241 |
| 226 // Use the stencil buffer for controlling where rendering will | 242 // Use the stencil buffer for controlling where rendering will |
| 227 // occur. We diable writing to the stencil buffer so we | 243 // occur. We diable writing to the stencil buffer so we |
| 228 // can test against them without modifying the values we | 244 // can test against them without modifying the values we |
| 229 // generated. | 245 // generated. |
| 230 glStencilMask( 0x0 ); | 246 glStencilMask( 0x0 ); |
| 231 | 247 offset += 6; |
| 232 for ( i = 0; i < NumTests; ++i ) | 248 for ( i = 0; i < NumTests; ++i ) |
| 233 { | 249 { |
| 234 glStencilFunc( GL_EQUAL, stencilValues[i], 0xff ); | 250 glStencilFunc( GL_EQUAL, stencilValues[i], 0xff ); |
| 235 glUniform4fv( userData->colorLoc, 1, colors[i] ); | 251 glUniform4fv( userData->colorLoc, 1, colors[i] ); |
| 236 glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[4] ); | 252 glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, offset ); |
| 237 } | 253 } |
| 238 | 254 |
| 239 eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface ); | 255 eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface ); |
| 240 } | 256 } |
| 241 | 257 |
| 242 /// | 258 /// |
| 243 // Cleanup | 259 // Cleanup |
| 244 // | 260 // |
| 245 void ShutDown ( ESContext *esContext ) | 261 void ShutDown ( ESContext *esContext ) |
| 246 { | 262 { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 264 | 280 |
| 265 if ( !Init ( &esContext ) ) | 281 if ( !Init ( &esContext ) ) |
| 266 return 0; | 282 return 0; |
| 267 | 283 |
| 268 esRegisterDrawFunc ( &esContext, Draw ); | 284 esRegisterDrawFunc ( &esContext, Draw ); |
| 269 | 285 |
| 270 esMainLoop ( &esContext ); | 286 esMainLoop ( &esContext ); |
| 271 | 287 |
| 272 ShutDown ( &esContext ); | 288 ShutDown ( &esContext ); |
| 273 } | 289 } |
| OLD | NEW |