blob: 18c8380a5e269cdaa086ac2f36856aa458011e23 [file] [log] [blame]
/**
* Test glFramebufferBlit()
* Brian Paul
* 27 Oct 2009
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/glut.h>
static int Win;
static int WinWidth = 1100, WinHeight = 600;
static int SrcWidth = 512, SrcHeight = 512;
static int DstWidth = 512, DstHeight = 512;
static GLuint SrcFB, DstFB;
static GLuint SrcTex, DstTex;
#if 0
static GLenum SrcTexTarget = GL_TEXTURE_2D, SrcTexFace = GL_TEXTURE_2D;
#else
static GLenum SrcTexTarget = GL_TEXTURE_CUBE_MAP, SrcTexFace = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
#endif
static GLenum DstTexTarget = GL_TEXTURE_2D, DstTexFace = GL_TEXTURE_2D;
static GLuint SrcTexLevel = 01, DstTexLevel = 0;
static void
Draw(void)
{
GLboolean rp = GL_FALSE;
GLubyte *buf;
GLint srcWidth = SrcWidth >> SrcTexLevel;
GLint srcHeight = SrcHeight >> SrcTexLevel;
GLint dstWidth = DstWidth >> DstTexLevel;
GLint dstHeight = DstHeight >> DstTexLevel;
GLenum status;
/* clear window */
glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
/* clear src buf */
glBindFramebufferEXT(GL_FRAMEBUFFER, SrcFB);
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
assert(status == GL_FRAMEBUFFER_COMPLETE_EXT);
glClearColor(0, 1, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
/* clear dst buf */
glBindFramebufferEXT(GL_FRAMEBUFFER, DstFB);
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
assert(status == GL_FRAMEBUFFER_COMPLETE_EXT);
glClearColor(1, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
/* blit src -> dst */
glBindFramebufferEXT(GL_READ_FRAMEBUFFER, SrcFB);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, DstFB);
glBlitFramebufferEXT(0, 0, srcWidth, srcHeight,
0, 0, dstWidth, dstHeight,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
#if 01
/* read src results */
buf = malloc(4 * srcWidth * srcHeight);
memset(buf, 0x88, 4 * srcWidth * srcHeight);
glBindFramebufferEXT(GL_FRAMEBUFFER, SrcFB);
if (rp)
glReadPixels(0, 0, srcWidth, srcHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
else {
glBindTexture(SrcTexTarget, SrcTex);
glGetTexImage(SrcTexFace, SrcTexLevel, GL_RGBA, GL_UNSIGNED_BYTE, buf);
}
/* draw dst in window */
glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
glWindowPos2i(0, 0);
glDrawPixels(srcWidth, srcHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
printf("Src Pix[0] = %d %d %d %d\n", buf[0], buf[1], buf[2], buf[3]);
free(buf);
#endif
glFinish();
/* read dst results */
buf = malloc(4 * dstWidth * dstHeight);
memset(buf, 0x88, 4 * dstWidth * dstHeight);
glBindFramebufferEXT(GL_FRAMEBUFFER, DstFB);
if (rp)
glReadPixels(0, 0, dstWidth, dstHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
else {
glBindTexture(DstTexTarget, DstTex);
glGetTexImage(DstTexFace, DstTexLevel, GL_RGBA, GL_UNSIGNED_BYTE, buf);
}
/* draw dst in window */
glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
glWindowPos2i(srcWidth + 2, 0);
glDrawPixels(dstWidth, dstHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
printf("Dst Pix[0] = %d %d %d %d\n", buf[0], buf[1], buf[2], buf[3]);
free(buf);
glFinish();
glutSwapBuffers();
}
static void
Reshape(int width, int height)
{
WinWidth = width;
WinHeight = height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -15.0);
}
static void
Key(unsigned char key, int x, int y)
{
(void) x;
(void) y;
switch (key) {
case 27:
glutDestroyWindow(Win);
exit(0);
break;
}
glutPostRedisplay();
}
static void
SpecialKey(int key, int x, int y)
{
(void) x;
(void) y;
switch (key) {
}
glutPostRedisplay();
}
static void
InitFBOs(void)
{
GLuint w, h, lvl;
/* Src */
glGenTextures(1, &SrcTex);
glBindTexture(SrcTexTarget, SrcTex);
w = SrcWidth;
h = SrcHeight;
lvl = 0;
for (lvl = 0; ; lvl++) {
if (SrcTexTarget == GL_TEXTURE_CUBE_MAP) {
GLuint f;
for (f = 0; f < 6; f++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, lvl, GL_RGBA8,
w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
}
else {
/* single face */
glTexImage2D(SrcTexFace, lvl, GL_RGBA8, w, h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
if (w == 1 && h == 1)
break;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
glGenFramebuffersEXT(1, &SrcFB);
glBindFramebufferEXT(GL_FRAMEBUFFER, SrcFB);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
SrcTexFace, SrcTex, SrcTexLevel);
/* Dst */
glGenTextures(1, &DstTex);
glBindTexture(DstTexTarget, DstTex);
w = DstWidth;
h = DstHeight;
lvl = 0;
for (lvl = 0; ; lvl++) {
glTexImage2D(DstTexFace, lvl, GL_RGBA8, w, h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
if (w == 1 && h == 1)
break;
if (w > 1)
w /= 2;
if (h > 1)
h /= 2;
}
glGenFramebuffersEXT(1, &DstFB);
glBindFramebufferEXT(GL_FRAMEBUFFER, DstFB);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
DstTexFace, DstTex, DstTexLevel);
}
static void
Init(void)
{
if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
fprintf(stderr, "This test requires GL_EXT_framebuffer_object\n");
exit(1);
}
if (!glutExtensionSupported("GL_EXT_framebuffer_blit")) {
fprintf(stderr, "This test requires GL_EXT_framebuffer_blit,\n");
exit(1);
}
InitFBOs();
printf("Left rect = src FBO, Right rect = dst FBO.\n");
printf("Both should be green.\n");
}
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(WinWidth, WinHeight);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
Win = glutCreateWindow(argv[0]);
glewInit();
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutSpecialFunc(SpecialKey);
glutDisplayFunc(Draw);
Init();
glutMainLoop();
return 0;
}