Merge remote branch 'origin/master' into lp-binning
[mesa.git] / progs / tests / blitfb.c
1 /**
2 * Test glFramebufferBlit()
3 * Brian Paul
4 * 27 Oct 2009
5 */
6
7 #include <assert.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <math.h>
12 #include <GL/glew.h>
13 #include <GL/glut.h>
14
15
16 static int Win;
17 static int WinWidth = 1100, WinHeight = 600;
18
19 static int SrcWidth = 512, SrcHeight = 512;
20 static int DstWidth = 512, DstHeight = 512;
21
22 static GLuint SrcFB, DstFB;
23 static GLuint SrcTex, DstTex;
24
25 #if 0
26 static GLenum SrcTexTarget = GL_TEXTURE_2D, SrcTexFace = GL_TEXTURE_2D;
27 #else
28 static GLenum SrcTexTarget = GL_TEXTURE_CUBE_MAP, SrcTexFace = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
29 #endif
30
31 static GLenum DstTexTarget = GL_TEXTURE_2D, DstTexFace = GL_TEXTURE_2D;
32
33 static GLuint SrcTexLevel = 01, DstTexLevel = 0;
34
35
36 static void
37 Draw(void)
38 {
39 GLboolean rp = GL_FALSE;
40 GLubyte *buf;
41 GLint srcWidth = SrcWidth >> SrcTexLevel;
42 GLint srcHeight = SrcHeight >> SrcTexLevel;
43 GLint dstWidth = DstWidth >> DstTexLevel;
44 GLint dstHeight = DstHeight >> DstTexLevel;
45 GLenum status;
46
47 /* clear window */
48 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
49 glClearColor(0.5, 0.5, 0.5, 1.0);
50 glClear(GL_COLOR_BUFFER_BIT);
51
52
53 /* clear src buf */
54 glBindFramebufferEXT(GL_FRAMEBUFFER, SrcFB);
55 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
56 assert(status == GL_FRAMEBUFFER_COMPLETE_EXT);
57 glClearColor(0, 1, 0, 0);
58 glClear(GL_COLOR_BUFFER_BIT);
59
60 /* clear dst buf */
61 glBindFramebufferEXT(GL_FRAMEBUFFER, DstFB);
62 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
63 assert(status == GL_FRAMEBUFFER_COMPLETE_EXT);
64 glClearColor(1, 0, 0, 0);
65 glClear(GL_COLOR_BUFFER_BIT);
66
67 /* blit src -> dst */
68 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, SrcFB);
69 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, DstFB);
70 glBlitFramebufferEXT(0, 0, srcWidth, srcHeight,
71 0, 0, dstWidth, dstHeight,
72 GL_COLOR_BUFFER_BIT, GL_NEAREST);
73
74 #if 01
75 /* read src results */
76 buf = malloc(4 * srcWidth * srcHeight);
77 memset(buf, 0x88, 4 * srcWidth * srcHeight);
78 glBindFramebufferEXT(GL_FRAMEBUFFER, SrcFB);
79 if (rp)
80 glReadPixels(0, 0, srcWidth, srcHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
81 else {
82 glBindTexture(SrcTexTarget, SrcTex);
83 glGetTexImage(SrcTexFace, SrcTexLevel, GL_RGBA, GL_UNSIGNED_BYTE, buf);
84 }
85
86 /* draw dst in window */
87 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
88 glWindowPos2i(0, 0);
89 glDrawPixels(srcWidth, srcHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
90
91 printf("Src Pix[0] = %d %d %d %d\n", buf[0], buf[1], buf[2], buf[3]);
92 free(buf);
93 #endif
94
95 glFinish();
96
97 /* read dst results */
98 buf = malloc(4 * dstWidth * dstHeight);
99 memset(buf, 0x88, 4 * dstWidth * dstHeight);
100 glBindFramebufferEXT(GL_FRAMEBUFFER, DstFB);
101 if (rp)
102 glReadPixels(0, 0, dstWidth, dstHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
103 else {
104 glBindTexture(DstTexTarget, DstTex);
105 glGetTexImage(DstTexFace, DstTexLevel, GL_RGBA, GL_UNSIGNED_BYTE, buf);
106 }
107
108 /* draw dst in window */
109 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
110 glWindowPos2i(srcWidth + 2, 0);
111 glDrawPixels(dstWidth, dstHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
112
113 printf("Dst Pix[0] = %d %d %d %d\n", buf[0], buf[1], buf[2], buf[3]);
114 free(buf);
115
116 glFinish();
117
118 glutSwapBuffers();
119 }
120
121
122 static void
123 Reshape(int width, int height)
124 {
125 WinWidth = width;
126 WinHeight = height;
127 glViewport(0, 0, width, height);
128 glMatrixMode(GL_PROJECTION);
129 glLoadIdentity();
130 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
131 glMatrixMode(GL_MODELVIEW);
132 glLoadIdentity();
133 glTranslatef(0.0, 0.0, -15.0);
134 }
135
136
137 static void
138 Key(unsigned char key, int x, int y)
139 {
140 (void) x;
141 (void) y;
142 switch (key) {
143 case 27:
144 glutDestroyWindow(Win);
145 exit(0);
146 break;
147 }
148 glutPostRedisplay();
149 }
150
151
152 static void
153 SpecialKey(int key, int x, int y)
154 {
155 (void) x;
156 (void) y;
157 switch (key) {
158 }
159 glutPostRedisplay();
160 }
161
162
163 static void
164 InitFBOs(void)
165 {
166 GLuint w, h, lvl;
167
168 /* Src */
169 glGenTextures(1, &SrcTex);
170 glBindTexture(SrcTexTarget, SrcTex);
171 w = SrcWidth;
172 h = SrcHeight;
173 lvl = 0;
174 for (lvl = 0; ; lvl++) {
175 if (SrcTexTarget == GL_TEXTURE_CUBE_MAP) {
176 GLuint f;
177 for (f = 0; f < 6; f++) {
178 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, lvl, GL_RGBA8,
179 w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
180 }
181 }
182 else {
183 /* single face */
184 glTexImage2D(SrcTexFace, lvl, GL_RGBA8, w, h, 0,
185 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
186 }
187 if (w == 1 && h == 1)
188 break;
189 if (w > 1)
190 w /= 2;
191 if (h > 1)
192 h /= 2;
193 }
194
195 glGenFramebuffersEXT(1, &SrcFB);
196 glBindFramebufferEXT(GL_FRAMEBUFFER, SrcFB);
197 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
198 SrcTexFace, SrcTex, SrcTexLevel);
199
200 /* Dst */
201 glGenTextures(1, &DstTex);
202 glBindTexture(DstTexTarget, DstTex);
203 w = DstWidth;
204 h = DstHeight;
205 lvl = 0;
206 for (lvl = 0; ; lvl++) {
207 glTexImage2D(DstTexFace, lvl, GL_RGBA8, w, h, 0,
208 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
209 if (w == 1 && h == 1)
210 break;
211 if (w > 1)
212 w /= 2;
213 if (h > 1)
214 h /= 2;
215 }
216
217 glGenFramebuffersEXT(1, &DstFB);
218 glBindFramebufferEXT(GL_FRAMEBUFFER, DstFB);
219 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
220 DstTexFace, DstTex, DstTexLevel);
221 }
222
223
224 static void
225 Init(void)
226 {
227 if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
228 fprintf(stderr, "This test requires GL_EXT_framebuffer_object\n");
229 exit(1);
230 }
231
232 if (!glutExtensionSupported("GL_EXT_framebuffer_blit")) {
233 fprintf(stderr, "This test requires GL_EXT_framebuffer_blit,\n");
234 exit(1);
235 }
236
237 InitFBOs();
238
239 printf("Left rect = src FBO, Right rect = dst FBO.\n");
240 printf("Both should be green.\n");
241 }
242
243
244 int
245 main(int argc, char *argv[])
246 {
247 glutInit(&argc, argv);
248 glutInitWindowSize(WinWidth, WinHeight);
249 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
250 Win = glutCreateWindow(argv[0]);
251 glewInit();
252 glutReshapeFunc(Reshape);
253 glutKeyboardFunc(Key);
254 glutSpecialFunc(SpecialKey);
255 glutDisplayFunc(Draw);
256 Init();
257 glutMainLoop();
258 return 0;
259 }