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
19 static int Width
= 400, Height
= 400;
20 static int TexWidth
= 512, TexHeight
= 512;
23 static GLuint DepthRB
, StencilRB
;
24 static GLboolean Anim
= GL_FALSE
;
25 static GLfloat Rot
= 0.0;
31 GLenum err
= glGetError();
33 printf("GL Error 0x%x at line %d\n", (int) err
, line
);
41 Rot
= glutGet(GLUT_ELAPSED_TIME
) * 0.05;
52 glMatrixMode(GL_PROJECTION
);
54 glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
55 glMatrixMode(GL_MODELVIEW
);
57 glTranslatef(0.0, 0.0, -15.0);
60 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, MyFB
);
61 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT
, GL_COLOR_ATTACHMENT0_EXT
,
62 GL_TEXTURE_2D
, TexObj
, level
);
64 status
= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT
);
65 if (status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
66 printf("Framebuffer incomplete!!!\n");
69 glViewport(0, 0, TexWidth
, TexHeight
);
71 glClearColor(0.5, 0.5, 1.0, 0.0);
72 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
);
74 glEnable(GL_DEPTH_TEST
);
75 glEnable(GL_STENCIL_TEST
);
76 glStencilFunc(GL_NEVER
, 1, ~0);
77 glStencilOp(GL_REPLACE
, GL_KEEP
, GL_REPLACE
);
79 /* draw diamond-shaped stencil pattern */
82 glVertex2f(-0.2, 0.0);
83 glVertex2f( 0.0, -0.2);
84 glVertex2f( 0.2, 0.0);
85 glVertex2f( 0.0, 0.2);
88 /* draw teapot where stencil != 1 */
89 glStencilFunc(GL_NOTEQUAL
, 1, ~0);
90 glStencilOp(GL_KEEP
, GL_KEEP
, GL_KEEP
);
102 glEnable(GL_LIGHTING
);
105 glRotatef(0.5 * Rot
, 1.0, 0.0, 0.0);
106 glutSolidTeapot(0.5);
108 glDisable(GL_LIGHTING
);
110 glDisable(GL_DEPTH_TEST
);
111 glDisable(GL_STENCIL_TEST
);
113 /* Bind normal framebuffer */
114 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, 0);
116 CheckError(__LINE__
);
124 float ar
= (float) Width
/ (float) Height
;
128 /* draw textured quad in the window */
130 glMatrixMode(GL_PROJECTION
);
132 glFrustum(-ar
, ar
, -1.0, 1.0, 5.0, 25.0);
133 glMatrixMode(GL_MODELVIEW
);
135 glTranslatef(0.0, 0.0, -7.0);
137 glViewport(0, 0, Width
, Height
);
139 glClearColor(0.25, 0.25, 0.25, 0);
140 glClear(GL_COLOR_BUFFER_BIT
);
143 glRotatef(Rot
, 0, 1, 0);
144 glEnable(GL_TEXTURE_2D
);
146 glColor3f(0.25, 0.25, 0.25);
151 glColor3f(1.0, 1.0, 1.0);
158 glDisable(GL_TEXTURE_2D
);
161 CheckError(__LINE__
);
166 Reshape(int width
, int height
)
168 glViewport(0, 0, width
, height
);
175 Key(unsigned char key
, int x
, int y
)
200 if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
201 printf("GL_EXT_framebuffer_object not found!\n");
204 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
206 /* make framebuffer */
207 glGenFramebuffersEXT(1, &MyFB
);
209 assert(!glIsFramebufferEXT(MyFB
));
210 glDeleteFramebuffersEXT(1, &MyFB
);
211 assert(!glIsFramebufferEXT(MyFB
));
212 /* Note, continue to use MyFB below */
214 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, MyFB
);
215 assert(glIsFramebufferEXT(MyFB
));
216 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT
, &i
);
219 /* make depth renderbuffer */
220 glGenRenderbuffersEXT(1, &DepthRB
);
222 assert(!glIsRenderbufferEXT(DepthRB
));
223 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT
, DepthRB
);
224 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT
, GL_DEPTH_COMPONENT
,
225 TexWidth
, TexHeight
);
226 glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT
,
227 GL_RENDERBUFFER_DEPTH_SIZE_EXT
, &i
);
228 printf("Depth renderbuffer size = %d bits\n", i
);
231 /* make stencil renderbuffer */
232 glGenRenderbuffersEXT(1, &StencilRB
);
234 assert(!glIsRenderbufferEXT(StencilRB
));
235 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT
, StencilRB
);
236 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT
, GL_STENCIL_INDEX
,
237 TexWidth
, TexHeight
);
238 glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT
,
239 GL_RENDERBUFFER_STENCIL_SIZE_EXT
, &i
);
240 printf("Stencil renderbuffer size = %d bits\n", i
);
243 /* attach DepthRB to MyFB */
244 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
, GL_DEPTH_ATTACHMENT_EXT
,
245 GL_RENDERBUFFER_EXT
, DepthRB
);
247 /* attach StencilRB to MyFB */
248 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
, GL_STENCIL_ATTACHMENT_EXT
,
249 GL_RENDERBUFFER_EXT
, StencilRB
);
252 /* bind regular framebuffer */
253 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, 0);
255 /* Make texture object/image */
256 glGenTextures(1, &TexObj
);
257 glBindTexture(GL_TEXTURE_2D
, TexObj
);
258 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, TexWidth
, TexHeight
, 0,
259 GL_RGBA
, GL_UNSIGNED_BYTE
, NULL
);
260 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
261 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
262 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
264 CheckError(__LINE__
);
269 main(int argc
, char *argv
[])
271 glutInit(&argc
, argv
);
272 glutInitWindowPosition(0, 0);
273 glutInitWindowSize(Width
, Height
);
274 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
);
275 glutCreateWindow(argv
[0]);
276 glutReshapeFunc(Reshape
);
277 glutKeyboardFunc(Key
);
278 glutDisplayFunc(Display
);