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 "glut_wrap.h" 14 15 16static int Win; 17static int WinWidth = 1100, WinHeight = 600; 18 19static int SrcWidth = 512, SrcHeight = 512; 20static int DstWidth = 512, DstHeight = 512; 21 22static GLuint SrcFB, DstFB; 23static GLuint SrcTex, DstTex; 24 25#if 0 26static GLenum SrcTexTarget = GL_TEXTURE_2D, SrcTexFace = GL_TEXTURE_2D; 27#else 28static GLenum SrcTexTarget = GL_TEXTURE_CUBE_MAP, SrcTexFace = GL_TEXTURE_CUBE_MAP_POSITIVE_X; 29#endif 30 31static GLenum DstTexTarget = GL_TEXTURE_2D, DstTexFace = GL_TEXTURE_2D; 32 33static GLuint SrcTexLevel = 01, DstTexLevel = 0; 34 35 36static void 37Draw(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 122static void 123Reshape(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 137static void 138Key(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 152static void 153SpecialKey(int key, int x, int y) 154{ 155 (void) x; 156 (void) y; 157 switch (key) { 158 } 159 glutPostRedisplay(); 160} 161 162 163static void 164InitFBOs(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 224static void 225Init(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 244int 245main(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} 260