Merge remote branch 'origin/7.8'
[mesa.git] / progs / tests / fbotest2.c
1 /*
2 * Test GL_EXT_framebuffer_object
3 *
4 * Brian Paul
5 * 19 Mar 2006
6 */
7
8
9 #include <assert.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <math.h>
13 #include <GL/glew.h>
14 #include <GL/glut.h>
15
16 static int Win = 0;
17 static int Width = 400, Height = 400;
18 static GLuint MyFB, ColorRb, DepthRb;
19 static GLboolean Animate = GL_TRUE;
20 static GLfloat Rotation = 0.0;
21
22
23 static void
24 CheckError(int line)
25 {
26 GLenum err = glGetError();
27 if (err) {
28 printf("fbotest2: GL Error 0x%x at line %d\n", (int) err, line);
29 }
30 }
31
32
33 static void
34 Display( void )
35 {
36 GLboolean copyPix = GL_FALSE;
37 GLboolean blitPix = GL_FALSE;
38 GLenum status;
39
40 CheckError(__LINE__);
41
42 /* draw to user framebuffer */
43 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
44 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
45 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
46
47 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
48 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
49 printf("fbotest2: Error: Framebuffer is incomplete!!!\n");
50 }
51
52 CheckError(__LINE__);
53
54 glClearColor(0.5, 0.5, 1.0, 0.0);
55 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
56
57 glEnable(GL_DEPTH_TEST);
58 glEnable(GL_LIGHTING);
59 glEnable(GL_LIGHT0);
60
61 glPushMatrix();
62 glRotatef(30.0, 1, 0, 0);
63 glRotatef(Rotation, 0, 1, 0);
64 glutSolidTeapot(2.0);
65 glPopMatrix();
66
67 if (copyPix) {
68 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, MyFB);
69 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
70 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
71 glDrawBuffer(GL_BACK);
72
73 glDisable(GL_DEPTH_TEST); /* in case window has depth buffer */
74
75 glWindowPos2iARB(0, 0);
76 glCopyPixels(0, 0, Width, Height, GL_COLOR);
77 }
78 else if (blitPix) {
79 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, MyFB);
80 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
81 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
82 glDrawBuffer(GL_BACK);
83
84 glDisable(GL_DEPTH_TEST); /* in case window has depth buffer */
85
86 glBlitFramebufferEXT(0, 0, Width, Height,
87 0, 0, Width, Height,
88 GL_COLOR_BUFFER_BIT, GL_NEAREST);
89 }
90 else {
91 GLubyte *buffer = malloc(Width * Height * 4);
92 /* read from user framebuffer */
93 glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
94
95 /* draw to window */
96 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
97 glDisable(GL_DEPTH_TEST); /* in case window has depth buffer */
98 glWindowPos2iARB(0, 0);
99 glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
100
101 free(buffer);
102 }
103
104 glutSwapBuffers();
105 CheckError(__LINE__);
106 }
107
108
109 static void
110 Reshape( int width, int height )
111 {
112 float ar = (float) width / (float) height;
113
114 glViewport( 0, 0, width, height );
115 glMatrixMode( GL_PROJECTION );
116 glLoadIdentity();
117 glFrustum( -ar, ar, -1.0, 1.0, 5.0, 25.0 );
118
119 glMatrixMode( GL_MODELVIEW );
120 glLoadIdentity();
121 glTranslatef( 0.0, 0.0, -15.0 );
122
123 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb);
124 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, width, height);
125 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRb);
126 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
127 width, height);
128
129 Width = width;
130 Height = height;
131 }
132
133
134 static void
135 CleanUp(void)
136 {
137 glDeleteFramebuffersEXT(1, &MyFB);
138 glDeleteRenderbuffersEXT(1, &ColorRb);
139 glDeleteRenderbuffersEXT(1, &DepthRb);
140 assert(!glIsFramebufferEXT(MyFB));
141 assert(!glIsRenderbufferEXT(ColorRb));
142 assert(!glIsRenderbufferEXT(DepthRb));
143 glutDestroyWindow(Win);
144 exit(0);
145 }
146
147
148 static void
149 Idle(void)
150 {
151 Rotation = glutGet(GLUT_ELAPSED_TIME) * 0.1;
152 glutPostRedisplay();
153 }
154
155
156 static void
157 Key( unsigned char key, int x, int y )
158 {
159 (void) x;
160 (void) y;
161 switch (key) {
162 case 'a':
163 Animate = !Animate;
164 if (Animate)
165 glutIdleFunc(Idle);
166 else
167 glutIdleFunc(NULL);
168 break;
169 case 27:
170 CleanUp();
171 break;
172 }
173 glutPostRedisplay();
174 }
175
176
177 static void
178 Init( void )
179 {
180 if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
181 printf("fbotest2: GL_EXT_framebuffer_object not found!\n");
182 exit(0);
183 }
184 printf("fbotest2: GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
185
186 glGenFramebuffersEXT(1, &MyFB);
187 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
188 assert(glIsFramebufferEXT(MyFB));
189
190 /* set color buffer */
191 glGenRenderbuffersEXT(1, &ColorRb);
192 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb);
193 assert(glIsRenderbufferEXT(ColorRb));
194 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
195 GL_RENDERBUFFER_EXT, ColorRb);
196 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
197
198 /* setup depth buffer */
199 glGenRenderbuffersEXT(1, &DepthRb);
200 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRb);
201 assert(glIsRenderbufferEXT(DepthRb));
202 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
203 GL_RENDERBUFFER_EXT, DepthRb);
204 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, Width, Height);
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 }