~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/glbook/Chapter_11/Stencil_Test/Stencil_Test.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
// Stencil_Test.c
 
12
//
 
13
//    This example shows various stencil buffer
 
14
//    operations.
 
15
//
 
16
#include <stdlib.h>
 
17
#include "esUtil.h"
 
18
 
 
19
typedef struct
 
20
{
 
21
   // Handle to a program object
 
22
   GLuint programObject;
 
23
 
 
24
   // Attribute locations
 
25
   GLint  positionLoc;
 
26
 
 
27
   // Uniform locations
 
28
   GLint  colorLoc;
 
29
 
 
30
} UserData;
 
31
 
 
32
///
 
33
// Initialize the shader and program object
 
34
//
 
35
int Init ( ESContext *esContext )
 
36
{
 
37
   UserData *userData = esContext->userData;
 
38
   GLbyte vShaderStr[] =  
 
39
      "attribute vec4 a_position;   \n"
 
40
      "void main()                  \n"
 
41
      "{                            \n"
 
42
      "   gl_Position = a_position; \n"
 
43
      "}                            \n";
 
44
   
 
45
   GLbyte fShaderStr[] =  
 
46
      "precision mediump float;  \n"
 
47
      "uniform vec4  u_color;    \n"
 
48
      "void main()               \n"
 
49
      "{                         \n"
 
50
      "  gl_FragColor = u_color; \n"
 
51
      "}                         \n";
 
52
 
 
53
   // Load the shaders and get a linked program object
 
54
   userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
 
55
 
 
56
   // Get the attribute locations
 
57
   userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
 
58
   
 
59
   // Get the sampler location
 
60
   userData->colorLoc = glGetUniformLocation ( userData->programObject, "u_color" );
 
61
 
 
62
   // Set the clear color
 
63
   glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
 
64
   
 
65
   // Set the stencil clear value
 
66
   glClearStencil ( 0x1 );
 
67
 
 
68
   // Set the depth clear value
 
69
   glClearDepthf( 0.75f );
 
70
 
 
71
   // Enable the depth and stencil tests
 
72
   glEnable( GL_DEPTH_TEST );
 
73
   glEnable( GL_STENCIL_TEST );
 
74
 
 
75
   return TRUE;
 
76
}
 
77
 
 
78
///
 
79
// Initialize the stencil buffer values, and then use those
 
80
//   values to control rendering
 
81
//
 
82
void Draw ( ESContext *esContext )
 
83
{
 
84
   int  i;
 
85
 
 
86
   UserData *userData = esContext->userData;
 
87
 
 
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
 
120
   GLfloat  colors[NumTests][4] = { 
 
121
       { 1.0f, 0.0f, 0.0f, 1.0f },
 
122
       { 0.0f, 1.0f, 0.0f, 1.0f },
 
123
       { 0.0f, 0.0f, 1.0f, 1.0f },
 
124
       { 1.0f, 1.0f, 0.0f, 0.0f }
 
125
   };
 
126
 
 
127
   GLint   numStencilBits;
 
128
   GLuint  stencilValues[NumTests] = { 
 
129
      0x7, // Result of test 0
 
130
      0x0, // Result of test 1
 
131
      0x2, // Result of test 2
 
132
      0xff // Result of test 3.  We need to fill this
 
133
           //  value in a run-time
 
134
   };
 
135
 
 
136
   // Set the viewport
 
137
   glViewport ( 0, 0, esContext->width, esContext->height );
 
138
   
 
139
   // Clear the color, depth, and stencil buffers.  At this
 
140
   //   point, the stencil buffer will be 0x1 for all pixels
 
141
   glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
 
142
 
 
143
   // Use the program object
 
144
   glUseProgram ( userData->programObject );
 
145
 
 
146
   // Load the vertex position
 
147
   glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, 
 
148
                           GL_FALSE, 0, vVertices );
 
149
  
 
150
   glEnableVertexAttribArray ( userData->positionLoc );
 
151
 
 
152
   // Test 0:
 
153
   //
 
154
   // Initialize upper-left region.  In this case, the
 
155
   //   stencil-buffer values will be replaced because the
 
156
   //   stencil test for the rendered pixels will fail the
 
157
   //   stencil test, which is
 
158
   //
 
159
   //        ref   mask   stencil  mask
 
160
   //      ( 0x7 & 0x3 ) < ( 0x1 & 0x7 )
 
161
   //
 
162
   //   The value in the stencil buffer for these pixels will
 
163
   //   be 0x7.
 
164
   //
 
165
   glStencilFunc( GL_LESS, 0x7, 0x3 );
 
166
   glStencilOp( GL_REPLACE, GL_DECR, GL_DECR );
 
167
   glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[0] );
 
168
 
 
169
   // Test 1:
 
170
   //
 
171
   // Initialize the upper-right region.  Here, we'll decrement
 
172
   //   the stencil-buffer values where the stencil test passes
 
173
   //   but the depth test fails.  The stencil test is
 
174
   //
 
175
   //        ref  mask    stencil  mask
 
176
   //      ( 0x3 & 0x3 ) > ( 0x1 & 0x3 )
 
177
   //
 
178
   //    but where the geometry fails the depth test.  The
 
179
   //    stencil values for these pixels will be 0x0.
 
180
   //
 
181
   glStencilFunc( GL_GREATER, 0x3, 0x3 );
 
182
   glStencilOp( GL_KEEP, GL_DECR, GL_KEEP );
 
183
   glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[1] );
 
184
 
 
185
   // Test 2:
 
186
   //
 
187
   // Initialize the lower-left region.  Here we'll increment 
 
188
   //   (with saturation) the stencil value where both the
 
189
   //   stencil and depth tests pass.  The stencil test for
 
190
   //   these pixels will be
 
191
   //
 
192
   //        ref  mask     stencil  mask
 
193
   //      ( 0x1 & 0x3 ) == ( 0x1 & 0x3 )
 
194
   //
 
195
   //   The stencil values for these pixels will be 0x2.
 
196
   //
 
197
   glStencilFunc( GL_EQUAL, 0x1, 0x3 );
 
198
   glStencilOp( GL_KEEP, GL_INCR, GL_INCR );
 
199
   glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[2] );
 
200
 
 
201
   // Test 3:
 
202
   //
 
203
   // Finally, initialize the lower-right region.  We'll invert
 
204
   //   the stencil value where the stencil tests fails.  The
 
205
   //   stencil test for these pixels will be
 
206
   //
 
207
   //        ref   mask    stencil  mask
 
208
   //      ( 0x2 & 0x1 ) == ( 0x1 & 0x1 )
 
209
   //
 
210
   //   The stencil value here will be set to ~((2^s-1) & 0x1),
 
211
   //   (with the 0x1 being from the stencil clear value),
 
212
   //   where 's' is the number of bits in the stencil buffer
 
213
   //
 
214
   glStencilFunc( GL_EQUAL, 0x2, 0x1 );
 
215
   glStencilOp( GL_INVERT, GL_KEEP, GL_KEEP );
 
216
   glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[3] );
 
217
   
 
218
   // 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
 
220
   //   stencilValues arrays for the fourth tests.  We'll use this value
 
221
   //   later in rendering.
 
222
   glGetIntegerv( GL_STENCIL_BITS, &numStencilBits );
 
223
   
 
224
   stencilValues[3] = ~(((1 << numStencilBits) - 1) & 0x1) & 0xff;
 
225
 
 
226
   // Use the stencil buffer for controlling where rendering will
 
227
   //   occur.  We diable writing to the stencil buffer so we
 
228
   //   can test against them without modifying the values we
 
229
   //   generated.
 
230
   glStencilMask( 0x0 );
 
231
   
 
232
   for ( i = 0; i < NumTests; ++i )
 
233
   {
 
234
      glStencilFunc( GL_EQUAL, stencilValues[i], 0xff );
 
235
      glUniform4fv( userData->colorLoc, 1, colors[i] );
 
236
      glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[4] );
 
237
   }
 
238
 
 
239
   eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
 
240
}
 
241
 
 
242
///
 
243
// Cleanup
 
244
//
 
245
void ShutDown ( ESContext *esContext )
 
246
{
 
247
   UserData *userData = esContext->userData;
 
248
 
 
249
   // Delete program object
 
250
   glDeleteProgram ( userData->programObject );
 
251
}
 
252
 
 
253
 
 
254
int main ( int argc, char *argv[] )
 
255
{
 
256
   ESContext esContext;
 
257
   UserData  userData;
 
258
 
 
259
   esInitContext ( &esContext );
 
260
   esContext.userData = &userData;
 
261
 
 
262
   esCreateWindow ( &esContext, "Stencil Test", 320, 240,
 
263
                    ES_WINDOW_RGB | ES_WINDOW_DEPTH | ES_WINDOW_STENCIL );
 
264
   
 
265
   if ( !Init ( &esContext ) )
 
266
      return 0;
 
267
 
 
268
   esRegisterDrawFunc ( &esContext, Draw );
 
269
   
 
270
   esMainLoop ( &esContext );
 
271
 
 
272
   ShutDown ( &esContext );
 
273
}