From 9a7ba79b2bb60d83fc3bc04280e64cc564cb8760 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 10 Mar 2010 11:51:44 -0700 Subject: progs/trivial: added clear-fbo-scissor.c to test scissored clear of FBO --- progs/trivial/clear-fbo-scissor.c | 186 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 progs/trivial/clear-fbo-scissor.c (limited to 'progs/trivial/clear-fbo-scissor.c') diff --git a/progs/trivial/clear-fbo-scissor.c b/progs/trivial/clear-fbo-scissor.c new file mode 100644 index 00000000000..b0d9651772e --- /dev/null +++ b/progs/trivial/clear-fbo-scissor.c @@ -0,0 +1,186 @@ +/* + * Use scissor to clear the four quadrants of the FBO to different + * colors. Then draw a grey triangle in the middle. + */ + + +#include +#include +#include +#include +#include +#include +#include + + +static int Width = 512, Height = 512; +static GLuint MyFB, MyRB; + + +#define CheckError() assert(glGetError() == 0) + + +static void +Init(void) +{ + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + fflush(stderr); + + if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { + printf("GL_EXT_framebuffer_object not found!\n"); + exit(0); + } + + glGenFramebuffersEXT(1, &MyFB); + glGenRenderbuffersEXT(1, &MyRB); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, MyRB); + + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, MyRB); + + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + + Width = width; + Height = height; + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); +} + + +static void +Key(unsigned char key, int x, int y) +{ + if (key == 27) { + exit(0); + } + glutPostRedisplay(); +} + + +static void +Draw(void) +{ + GLboolean scissor = GL_TRUE; + GLboolean copyPix = GL_FALSE; + + /* draw to user framebuffer */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); + + glViewport(0, 0, Width, Height); + CheckError(); + + if (scissor) { + glEnable(GL_SCISSOR_TEST); + + /* lower-left = red */ + glClearColor(1, 0, 0, 0); + glScissor(0, 0, Width / 2, Height / 2); + glClear(GL_COLOR_BUFFER_BIT); + + /* lower-right = green */ + glClearColor(0, 1, 0, 0); + glScissor(Width / 2, 0, Width - Width / 2, Height / 2); + glClear(GL_COLOR_BUFFER_BIT); + + /* upper-left = blue */ + glClearColor(0, 0, 1, 0); + glScissor(0, Height / 2, Width / 2, Height - Height / 2); + glClear(GL_COLOR_BUFFER_BIT); + + /* upper-right = white */ + glClearColor(1, 1, 1, 0); + glScissor(Width / 2, Height / 2, Width - Width / 2, Height - Height / 2); + glClear(GL_COLOR_BUFFER_BIT); + + glDisable(GL_SCISSOR_TEST); + } + else { + glClearColor(0, 1, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + } + + /* gray triangle in middle, pointing up */ + glColor3f(0.5, 0.5, 0.5); + glBegin(GL_TRIANGLES); + glVertex2f(Width/4, Height/4); + glVertex2f(Width*3/4, Height/4); + glVertex2f(Width/2, Height*3/4); + glVertex2f(-0.5, -0.5); + glVertex2f(+0.5, -0.5); + glVertex2f( 0.0, 0.7); + glEnd(); + + CheckError(); + + /* copy fbo to window */ + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, MyFB); + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); + glDrawBuffer(GL_BACK); + + if (copyPix) { + glWindowPos2i(0, 0); + glCopyPixels(0, 0, Width, Height, GL_COLOR); + } + else { + GLubyte *buffer = malloc(Width * Height * 4); + + /* read from user framebuffer */ + glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + /* draw to window */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glWindowPos2iARB(0, 0); + glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + free(buffer); + } + + /* Bind normal framebuffer */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + + glutSwapBuffers(); + + CheckError(); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition(100, 0); + glutInitWindowSize(Width, Height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + + if (!glutCreateWindow(argv[0])) { + exit(1); + } + + glewInit(); + Init(); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; +} -- cgit v1.2.3 From 3c48f40f61d8122009175273b3c15e108927b146 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 10 Mar 2010 12:19:26 -0700 Subject: progs/trivial: add -t (RTT) option for clear-fbo-scissor.c --- progs/trivial/clear-fbo-scissor.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'progs/trivial/clear-fbo-scissor.c') diff --git a/progs/trivial/clear-fbo-scissor.c b/progs/trivial/clear-fbo-scissor.c index b0d9651772e..5ec0b57328b 100644 --- a/progs/trivial/clear-fbo-scissor.c +++ b/progs/trivial/clear-fbo-scissor.c @@ -15,6 +15,7 @@ static int Width = 512, Height = 512; static GLuint MyFB, MyRB; +static GLboolean UseTex = GL_FALSE; #define CheckError() assert(glGetError() == 0) @@ -38,12 +39,25 @@ Init(void) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, MyRB); + if (UseTex) { + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, tex, 0); + } + else { + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, MyRB); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_RENDERBUFFER_EXT, MyRB); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, MyRB); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } @@ -60,7 +74,9 @@ Reshape(int width, int height) Width = width; Height = height; - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + if (!UseTex) { + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + } } @@ -167,11 +183,23 @@ Draw(void) int main(int argc, char *argv[]) { + int i; + glutInit(&argc, argv); glutInitWindowPosition(100, 0); glutInitWindowSize(Width, Height); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-t") == 0) + UseTex = GL_TRUE; + } + + if (UseTex) + printf("Using render to texture\n"); + else + printf("Using user-created render buffer\n"); + if (!glutCreateWindow(argv[0])) { exit(1); } -- cgit v1.2.3 From d5ccbea63cb9ba96cd4c0e2f40824ec1939c806c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 10 Mar 2010 14:32:56 -0700 Subject: progs/trivial: make clear-fbo-scissor.c work with other GL drivers NVIDIA's driver requires that the texture that we're going to render into be complete. Need to set min/mag filters to non-mipmap modes. Plus added other error/debug checks. --- progs/trivial/clear-fbo-scissor.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'progs/trivial/clear-fbo-scissor.c') diff --git a/progs/trivial/clear-fbo-scissor.c b/progs/trivial/clear-fbo-scissor.c index 5ec0b57328b..28c613ccfba 100644 --- a/progs/trivial/clear-fbo-scissor.c +++ b/progs/trivial/clear-fbo-scissor.c @@ -11,6 +11,7 @@ #include #include #include +#include static int Width = 512, Height = 512; @@ -18,12 +19,20 @@ static GLuint MyFB, MyRB; static GLboolean UseTex = GL_FALSE; -#define CheckError() assert(glGetError() == 0) +#define CheckError() \ + do { \ + GLenum err = glGetError(); \ + if (err != GL_NO_ERROR) \ + printf("Error: %s\n", gluErrorString(err)); \ + assert(err == GL_NO_ERROR); \ + } while (0) static void Init(void) { + GLenum status; + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); @@ -45,6 +54,8 @@ Init(void) glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0); @@ -59,6 +70,11 @@ Init(void) glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); } + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { + fprintf(stderr, "Framebuffer object is incomplete (0x%x)!\n", status); + } + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } @@ -134,6 +150,8 @@ Draw(void) glClear(GL_COLOR_BUFFER_BIT); } + CheckError(); + /* gray triangle in middle, pointing up */ glColor3f(0.5, 0.5, 0.5); glBegin(GL_TRIANGLES); -- cgit v1.2.3 From c7be039fad6d93911d1142fc5dea18d0c2684143 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 10 Mar 2010 14:35:57 -0700 Subject: progs/trivial: use -c option to use glCopyPixels() Otherwise we use glRead/DrawPixels to copy the off-screen FBO image into the window. Looks like NVIDIA's broken when using -c (the image is upside down), but OK with -c -t. --- progs/trivial/clear-fbo-scissor.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'progs/trivial/clear-fbo-scissor.c') diff --git a/progs/trivial/clear-fbo-scissor.c b/progs/trivial/clear-fbo-scissor.c index 28c613ccfba..6a605e16a8b 100644 --- a/progs/trivial/clear-fbo-scissor.c +++ b/progs/trivial/clear-fbo-scissor.c @@ -17,6 +17,7 @@ static int Width = 512, Height = 512; static GLuint MyFB, MyRB; static GLboolean UseTex = GL_FALSE; +static GLboolean UseCopyPix = GL_FALSE; #define CheckError() \ @@ -110,7 +111,6 @@ static void Draw(void) { GLboolean scissor = GL_TRUE; - GLboolean copyPix = GL_FALSE; /* draw to user framebuffer */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); @@ -171,7 +171,7 @@ Draw(void) glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); glDrawBuffer(GL_BACK); - if (copyPix) { + if (UseCopyPix) { glWindowPos2i(0, 0); glCopyPixels(0, 0, Width, Height, GL_COLOR); } @@ -211,6 +211,8 @@ main(int argc, char *argv[]) for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-t") == 0) UseTex = GL_TRUE; + else if (strcmp(argv[i], "-c") == 0) + UseCopyPix = GL_TRUE; } if (UseTex) -- cgit v1.2.3