2
* Test GL_EXT_framebuffer_object render-to-texture
4
* Draw a teapot into a texture image with stenciling.
5
* Then draw a textured quad using that texture.
12
#define GL_GLEXT_PROTOTYPES
26
static int Width = 400, Height = 400;
28
static GLenum TexTarget = GL_TEXTURE_2D; /*GL_TEXTURE_RECTANGLE_ARB;*/
29
static int TexWidth = 512, TexHeight = 512;
30
/*static int TexWidth = 600, TexHeight = 600;*/
34
static GLuint DepthRB, StencilRB;
35
static GLboolean Anim = GL_FALSE;
36
static GLfloat Rot = 0.0;
37
static GLboolean UsePackedDepthStencil = GL_FALSE;
38
static GLuint TextureLevel = 1; /* which texture level to render to */
39
static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */
45
GLenum err = glGetError();
47
printf("GL Error 0x%x at line %d\n", (int) err, line);
55
Rot = glutGet(GLUT_ELAPSED_TIME) * 0.1;
65
glMatrixMode(GL_PROJECTION);
67
glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
68
glMatrixMode(GL_MODELVIEW);
70
glTranslatef(0.0, 0.0, -15.0);
72
/* draw to texture image */
73
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
75
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
76
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
77
printf("Framebuffer incomplete!!!\n");
80
glViewport(0, 0, TexWidth, TexHeight);
82
glClearColor(0.5, 0.5, 1.0, 0.0);
83
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
87
glEnable(GL_DEPTH_TEST);
91
glEnable(GL_STENCIL_TEST);
92
glStencilFunc(GL_NEVER, 1, ~0);
93
glStencilOp(GL_REPLACE, GL_KEEP, GL_REPLACE);
99
/* draw diamond-shaped stencil pattern */
102
glVertex2f(-0.2, 0.0);
103
glVertex2f( 0.0, -0.2);
104
glVertex2f( 0.2, 0.0);
105
glVertex2f( 0.0, 0.2);
109
/* draw teapot where stencil != 1 */
111
glStencilFunc(GL_NOTEQUAL, 1, ~0);
112
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
115
CheckError(__LINE__);
127
glEnable(GL_LIGHTING);
130
glRotatef(0.5 * Rot, 1.0, 0.0, 0.0);
131
glutSolidTeapot(0.5);
133
glDisable(GL_LIGHTING);
135
PrintStencilHistogram(TexWidth, TexHeight);
139
glDisable(GL_DEPTH_TEST);
140
glDisable(GL_STENCIL_TEST);
143
/* Bind normal framebuffer */
144
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
147
CheckError(__LINE__);
155
float ar = (float) Width / (float) Height;
159
/* draw textured quad in the window */
161
glMatrixMode(GL_PROJECTION);
163
glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
164
glMatrixMode(GL_MODELVIEW);
166
glTranslatef(0.0, 0.0, -7.0);
168
glViewport(0, 0, Width, Height);
170
glClearColor(0.25, 0.25, 0.25, 0);
171
glClear(GL_COLOR_BUFFER_BIT);
174
glRotatef(Rot, 0, 1, 0);
176
glBindTexture(TexTarget, TexObj);
178
glColor3f(0.25, 0.25, 0.25);
179
if (TexTarget == GL_TEXTURE_2D) {
184
glColor3f(1.0, 1.0, 1.0);
191
assert(TexTarget == GL_TEXTURE_RECTANGLE_ARB);
194
glTexCoord2f(TexWidth, 0);
196
glColor3f(1.0, 1.0, 1.0);
197
glTexCoord2f(TexWidth, TexHeight);
199
glTexCoord2f(0, TexHeight);
204
glDisable(TexTarget);
208
CheckError(__LINE__);
213
Reshape(int width, int height)
215
glViewport(0, 0, width, height);
225
glDeleteRenderbuffersEXT(1, &DepthRB);
228
if (!UsePackedDepthStencil)
229
glDeleteRenderbuffersEXT(1, &StencilRB);
231
glDeleteFramebuffersEXT(1, &MyFB);
233
glDeleteTextures(1, &TexObj);
240
Key(unsigned char key, int x, int y)
264
Init(int argc, char *argv[])
266
static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 };
269
if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
270
printf("GL_EXT_framebuffer_object not found!\n");
274
if (argc > 1 && strcmp(argv[1], "-ds") == 0) {
275
if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) {
276
printf("GL_EXT_packed_depth_stencil not found!\n");
279
UsePackedDepthStencil = GL_TRUE;
280
printf("Using GL_EXT_packed_depth_stencil\n");
283
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
285
/* gen framebuffer id, delete it, do some assertions, just for testing */
286
glGenFramebuffersEXT(1, &MyFB);
288
assert(!glIsFramebufferEXT(MyFB));
289
glDeleteFramebuffersEXT(1, &MyFB);
290
assert(!glIsFramebufferEXT(MyFB));
291
/* Note, continue to use MyFB below */
293
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
294
assert(glIsFramebufferEXT(MyFB));
295
glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &i);
298
/* Make texture object/image */
299
glGenTextures(1, &TexObj);
300
glBindTexture(TexTarget, TexObj);
301
/* make two image levels */
302
glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0,
303
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
304
glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0,
305
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
306
TexWidth = TexWidth >> TextureLevel;
307
TexHeight = TexHeight >> TextureLevel;
309
glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
310
glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
311
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
312
glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel);
313
glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel);
315
CheckError(__LINE__);
317
/* Render color to texture */
318
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
319
TexTarget, TexObj, TextureLevel);
323
/* make depth renderbuffer */
324
glGenRenderbuffersEXT(1, &DepthRB);
326
assert(!glIsRenderbufferEXT(DepthRB));
327
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB);
328
assert(glIsRenderbufferEXT(DepthRB));
329
if (UsePackedDepthStencil)
330
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT,
331
TexWidth, TexHeight);
333
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
334
TexWidth, TexHeight);
335
CheckError(__LINE__);
336
glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT,
337
GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
338
CheckError(__LINE__);
339
printf("Depth renderbuffer size = %d bits\n", i);
342
/* attach DepthRB to MyFB */
343
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
344
GL_RENDERBUFFER_EXT, DepthRB);
347
CheckError(__LINE__);
350
if (UsePackedDepthStencil) {
351
/* DepthRb is a combined depth/stencil renderbuffer */
352
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
353
GL_STENCIL_ATTACHMENT_EXT,
354
GL_RENDERBUFFER_EXT, DepthRB);
357
/* make stencil renderbuffer */
358
glGenRenderbuffersEXT(1, &StencilRB);
360
assert(!glIsRenderbufferEXT(StencilRB));
361
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilRB);
362
assert(glIsRenderbufferEXT(StencilRB));
363
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX,
364
TexWidth, TexHeight);
365
/* attach StencilRB to MyFB */
366
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
367
GL_STENCIL_ATTACHMENT_EXT,
368
GL_RENDERBUFFER_EXT, StencilRB);
370
glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT,
371
GL_RENDERBUFFER_STENCIL_SIZE_EXT, &i);
372
CheckError(__LINE__);
373
printf("Stencil renderbuffer size = %d bits\n", i);
377
CheckError(__LINE__);
379
/* bind regular framebuffer */
380
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
384
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat);
389
main(int argc, char *argv[])
391
glutInit(&argc, argv);
392
glutInitWindowPosition(0, 0);
393
glutInitWindowSize(Width, Height);
394
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
395
glutCreateWindow(argv[0]);
396
glutReshapeFunc(Reshape);
397
glutKeyboardFunc(Key);
398
glutDisplayFunc(Display);