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