progs/tests: added new blitfb.c test
Tests glBlitFramebuffer() between two texture/renderbuffer surfaces. In particular, blit from level[1] of a cube map face to a 2D texture. Used to find/fix bug in intel do_copy_texsubimage(). See commit aef1ab1073f3e30d699b99dae17518ed48b57c72
This commit is contained in:
parent
3e45788d5d
commit
3bee7610be
|
@ -29,6 +29,7 @@ SOURCES = \
|
|||
blendminmax.c \
|
||||
blendsquare.c \
|
||||
blendxor.c \
|
||||
blitfb.c \
|
||||
bufferobj.c \
|
||||
bumpmap.c \
|
||||
bug_3050.c \
|
||||
|
|
|
@ -52,6 +52,7 @@ progs = [
|
|||
'blendminmax',
|
||||
'blendsquare',
|
||||
'blendxor',
|
||||
'blitfb',
|
||||
'bufferobj',
|
||||
'bug_3050',
|
||||
'bug_3101',
|
||||
|
|
|
@ -0,0 +1,259 @@
|
|||
/**
|
||||
* 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;
|
||||
}
|
Loading…
Reference in New Issue