#define GL_GLEXT_PROTOTYPES #include #include #include #include #include #include #define TEX_W 256 #define TEX_H 256 #define CHECK_GLERROR() \ { \ GLenum err = glGetError(); \ while (err != GL_NO_ERROR) \ { \ fprintf(stderr, "GL Error %#x, %s, line %d\n", \ err, __FILE__, __LINE__); \ err = glGetError(); \ } \ } void init(void) { GLuint tex, fbo_dst, rb, fbo_src; GLenum status; unsigned int mem[TEX_W][TEX_H]; /* Generate a destination texture */ glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, TEX_W, TEX_H, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, mem); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); glBindTexture(GL_TEXTURE_2D, 0); CHECK_GLERROR(); /* Source renderbuffer */ glGenRenderbuffers(1, &rb); glBindRenderbuffer(GL_RENDERBUFFER, rb); glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, TEX_W, TEX_H); CHECK_GLERROR(); glGenFramebuffers(1, &fbo_src); glBindFramebuffer(GL_FRAMEBUFFER, fbo_src); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) fprintf(stderr, "FBO status %#x\n", status); CHECK_GLERROR(); glDrawBuffer(GL_COLOR_ATTACHMENT0); glViewport(0, 0, TEX_W, TEX_H); glClearColor(0.0, 1.0, 0.5, 0); glClear(GL_COLOR_BUFFER_BIT); CHECK_GLERROR(); /* Prepare a fbo with the texture as color attachment */ glGenFramebuffers(1, &fbo_dst); glBindFramebuffer(GL_FRAMEBUFFER, fbo_dst); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) fprintf(stderr, "FBO status %#x\n", status); CHECK_GLERROR(); glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_src); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_dst); printf("Going to blit\n"); glBlitFramebuffer(0, 0, TEX_W, TEX_H, 0, 0, TEX_W, TEX_H, GL_COLOR_BUFFER_BIT, GL_NEAREST); printf("Blit done\n"); CHECK_GLERROR(); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); CHECK_GLERROR(); glBindTexture(GL_TEXTURE_2D, tex); glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, mem); printf("read result: %08x\n", mem[16][16]); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_ACCUM); glutInitWindowSize(200, 200); glutCreateWindow(argv[0]); init(); return 0; }