Merge branch '7.8'
[mesa.git] / progs / tests / fbotest3.c
1 /*
2 * Test GL_EXT_framebuffer_object
3 * Like fbotest2.c but use a texture for the Z buffer / renderbuffer.
4 * Note: the Z texture is never resized so that limits what can be
5 * rendered if the window is resized.
6 *
7 * This tests a bug reported by Christoph Bumiller on 1 Feb 2010
8 * on mesa3d-dev.
9 *
10 * XXX this should be made into a piglit test.
11 *
12 * Brian Paul
13 * 1 Feb 2010
14 */
15
16
17 #include <assert.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <math.h>
21 #include <GL/glew.h>
22 #include <GL/glut.h>
23
24
25 static int Win = 0;
26 static int Width = 400, Height = 400;
27 static GLuint Tex = 0;
28 static GLuint MyFB, ColorRb, DepthRb;
29 static GLboolean Animate = GL_FALSE;
30 static GLfloat Rotation = 0.0;
31
32
33 static void
34 CheckError(int line)
35 {
36 GLenum err = glGetError();
37 if (err) {
38 printf("fbotest3: GL Error 0x%x at line %d\n", (int) err, line);
39 }
40 }
41
42
43 static void
44 Display( void )
45 {
46 GLubyte *buffer = malloc(Width * Height * 4);
47 GLenum status;
48
49 CheckError(__LINE__);
50
51 /* draw to user framebuffer */
52 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
53 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
54 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
55
56 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
57 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
58 printf("fbotest3: Error: Framebuffer is incomplete!!!\n");
59 }
60
61 CheckError(__LINE__);
62
63 glClearColor(0.5, 0.5, 1.0, 0.0);
64 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
65
66 glEnable(GL_DEPTH_TEST);
67 glEnable(GL_LIGHTING);
68 glEnable(GL_LIGHT0);
69
70 glPushMatrix();
71 glRotatef(30.0, 1, 0, 0);
72 glRotatef(Rotation, 0, 1, 0);
73 glutSolidTeapot(2.0);
74 glPopMatrix();
75
76 /* read from user framebuffer */
77 glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
78
79 /* draw to window */
80 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
81 glDisable(GL_DEPTH_TEST); /* in case window has depth buffer */
82 glWindowPos2iARB(0, 0);
83 glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
84
85 free(buffer);
86 glutSwapBuffers();
87 CheckError(__LINE__);
88 }
89
90
91 static void
92 Reshape( int width, int height )
93 {
94 float ar = (float) width / (float) height;
95
96 glViewport( 0, 0, width, height );
97 glMatrixMode( GL_PROJECTION );
98 glLoadIdentity();
99 glFrustum( -ar, ar, -1.0, 1.0, 5.0, 25.0 );
100
101 glMatrixMode( GL_MODELVIEW );
102 glLoadIdentity();
103 glTranslatef( 0.0, 0.0, -15.0 );
104
105 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb);
106 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, width, height);
107
108 Width = width;
109 Height = height;
110 }
111
112
113 static void
114 CleanUp(void)
115 {
116 glDeleteFramebuffersEXT(1, &MyFB);
117 glDeleteRenderbuffersEXT(1, &ColorRb);
118 glDeleteRenderbuffersEXT(1, &DepthRb);
119 glDeleteTextures(1, &Tex);
120 assert(!glIsFramebufferEXT(MyFB));
121 assert(!glIsRenderbufferEXT(ColorRb));
122 assert(!glIsRenderbufferEXT(DepthRb));
123 glutDestroyWindow(Win);
124 exit(0);
125 }
126
127
128 static void
129 Idle(void)
130 {
131 Rotation = glutGet(GLUT_ELAPSED_TIME) * 0.1;
132 glutPostRedisplay();
133 }
134
135
136 static void
137 Key( unsigned char key, int x, int y )
138 {
139 (void) x;
140 (void) y;
141 switch (key) {
142 case 'a':
143 Animate = !Animate;
144 if (Animate)
145 glutIdleFunc(Idle);
146 else
147 glutIdleFunc(NULL);
148 break;
149 case 27:
150 CleanUp();
151 break;
152 }
153 glutPostRedisplay();
154 }
155
156
157 static void
158 Init( void )
159 {
160 if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
161 printf("fbotest3: GL_EXT_framebuffer_object not found!\n");
162 exit(0);
163 }
164 printf("fbotest3: GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
165
166 /* create initial tex obj as an RGBA texture */
167 glGenTextures(1, &Tex);
168 glBindTexture(GL_TEXTURE_2D, Tex);
169 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0,
170 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
171 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
172 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
173 glEnable(GL_TEXTURE_2D);
174
175 /* draw something to make sure the texture is used */
176 glBegin(GL_POINTS);
177 glVertex2f(0, 0);
178 glEnd();
179
180 /* done w/ texturing */
181 glDisable(GL_TEXTURE_2D);
182
183 /* Create my Framebuffer Object */
184 glGenFramebuffersEXT(1, &MyFB);
185 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
186 assert(glIsFramebufferEXT(MyFB));
187
188 /* Setup color renderbuffer */
189 glGenRenderbuffersEXT(1, &ColorRb);
190 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb);
191 assert(glIsRenderbufferEXT(ColorRb));
192 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
193 GL_RENDERBUFFER_EXT, ColorRb);
194 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
195
196 /* Setup depth renderbuffer (a texture) */
197 glGenRenderbuffersEXT(1, &DepthRb);
198 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRb);
199 assert(glIsRenderbufferEXT(DepthRb));
200 /* replace RGBA texture with Z texture */
201 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, Width, Height, 0,
202 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
203 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
204 GL_TEXTURE_2D, Tex, 0);
205
206 CheckError(__LINE__);
207
208 /* restore to default */
209 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
210 CheckError(__LINE__);
211 }
212
213
214 int
215 main( int argc, char *argv[] )
216 {
217 glutInit( &argc, argv );
218 glutInitWindowPosition( 0, 0 );
219 glutInitWindowSize(Width, Height);
220 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
221 Win = glutCreateWindow(argv[0]);
222 glewInit();
223 glutReshapeFunc( Reshape );
224 glutKeyboardFunc( Key );
225 glutDisplayFunc( Display );
226 if (Animate)
227 glutIdleFunc(Idle);
228 Init();
229 glutMainLoop();
230 return 0;
231 }