diff options
| -rw-r--r-- | progs/tests/drawbuffers.c | 298 | 
1 files changed, 298 insertions, 0 deletions
| diff --git a/progs/tests/drawbuffers.c b/progs/tests/drawbuffers.c new file mode 100644 index 0000000000..8583bac0dd --- /dev/null +++ b/progs/tests/drawbuffers.c @@ -0,0 +1,298 @@ +/* + * Test GL_ARB_draw_buffers, GL_EXT_framebuffer_object + * and GLSL's gl_FragData[]. + * + * Brian Paul + * 11 March 2007 + */ + + +#define GL_GLEXT_PROTOTYPES +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> +#include "extfuncs.h" + +static int Win; +static int Width = 400, Height = 400; +static GLuint FBobject, RBobjects[3]; +static GLfloat Xrot = 0.0, Yrot = 0.0; + + +static void +CheckError(int line) +{ +   GLenum err = glGetError(); +   if (err) { +      printf("GL Error 0x%x at line %d\n", (int) err, line); +   } +} + + +static void +Display(void) +{ +   GLubyte *buffer = malloc(Width * Height * 4); +   static const GLenum buffers[2] = { +      GL_COLOR_ATTACHMENT0_EXT, +      GL_COLOR_ATTACHMENT1_EXT +   }; + +   /* draw to user framebuffer */ +   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject); + +   /* Clear color buffer 0 (blue) */ +   glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); +   glClearColor(0.5, 0.5, 1.0, 0.0); +   glClear(GL_COLOR_BUFFER_BIT); + +   /* Clear color buffer 1 (1 - blue) */ +   glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); +   glClearColor(0.5, 0.5, 0.0, 0.0); +   glClear(GL_COLOR_BUFFER_BIT); + +   glClear(GL_DEPTH_BUFFER_BIT); + +   /* draw to two buffers w/ fragment shader */ +   glDrawBuffersARB(2, buffers); + +   glPushMatrix(); +   glRotatef(Xrot, 1, 0, 0); +   glRotatef(Yrot, 0, 1, 0); +   glutSolidTorus(0.75, 2.0, 10, 20); +   glPopMatrix(); + +   /* read from user framebuffer */ +   /* bottom half = colorbuffer 0 */ +   glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); +   glReadPixels(0, 0, Width, Height / 2, GL_RGBA, GL_UNSIGNED_BYTE, +                buffer); +   /* top half = colorbuffer 1 */ +   glReadBuffer(GL_COLOR_ATTACHMENT1_EXT); +   glReadPixels(0, Height/2, Width, Height / 2, GL_RGBA, GL_UNSIGNED_BYTE, +                buffer + Width * Height / 2 * 4); + +   /* draw to window */ +   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +   glWindowPos2iARB(0, 0); +   glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + +   free(buffer); +   glutSwapBuffers(); +   CheckError(__LINE__); +} + + +static void +Reshape(int width, int height) +{ +   float ar = (float) width / (float) height; + +   glViewport(0, 0, width, height); +   glMatrixMode(GL_PROJECTION); +   glLoadIdentity(); +   glFrustum(-ar, ar, -1.0, 1.0, 5.0, 35.0); +   glMatrixMode(GL_MODELVIEW); +   glLoadIdentity(); +   glTranslatef(0.0, 0.0, -20.0); + +   Width = width; +   Height = height; + +   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]); +   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); +   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]); +   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); +   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]); +   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, +                            Width, Height); +} + + +static void +CleanUp(void) +{ +   glDeleteFramebuffersEXT(1, &FBobject); +   glDeleteRenderbuffersEXT(3, RBobjects); +   glutDestroyWindow(Win); +   exit(0); +} + + +static void +Key(unsigned char key, int x, int y) +{ +   (void) x; +   (void) y; +   switch (key) { +      case 'x': +         Xrot += 5.0; +         break; +      case 'y': +         Yrot += 5.0; +         break; +      case 27: +         CleanUp(); +         break; +   } +   glutPostRedisplay(); +} + + +static void +CheckExtensions(void) +{ +   const char *version = (const char *) glGetString(GL_VERSION); +   GLint numBuf; + +   if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { +      printf("Sorry, GL_EXT_framebuffer_object is required!\n"); +      exit(1); +   } +   if (!glutExtensionSupported("GL_ARB_draw_buffers")) { +      printf("Sorry, GL_ARB_draw_buffers is required!\n"); +      exit(1); +   } +   if (version[0] != '2') { +      printf("Sorry, OpenGL 2.0 is required!\n"); +      exit(1); +   } + +   glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &numBuf); +   printf("GL_MAX_DRAW_BUFFERS_ARB = %d\n", numBuf); +   if (numBuf < 2) { +      printf("Sorry, GL_MAX_DRAW_BUFFERS_ARB needs to be >= 2\n"); +      exit(1); +   } + +   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); +} + + +static void +SetupRenderbuffers(void) +{ +   glGenFramebuffersEXT(1, &FBobject); +   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject); + +   glGenRenderbuffersEXT(3, RBobjects); + +   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]); +   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + +   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]); +   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + +   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]); +   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, +                            Width, Height); + +   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, +                                GL_RENDERBUFFER_EXT, RBobjects[0]); +   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, +                                GL_RENDERBUFFER_EXT, RBobjects[1]); +   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, +                                GL_RENDERBUFFER_EXT, RBobjects[2]); + +   CheckError(__LINE__); +} + + +static GLuint +LoadAndCompileShader(GLenum target, const char *text) +{ +   GLint stat; +   GLuint shader = glCreateShader_func(target); +   glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); +   glCompileShader_func(shader); +   glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetShaderInfoLog_func(shader, 1000, &len, log); +      fprintf(stderr, "drawbuffers: problem compiling shader:\n%s\n", log); +      exit(1); +   } +   return shader; +} + + +static void +CheckLink(GLuint prog) +{ +   GLint stat; +   glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      glGetProgramInfoLog_func(prog, 1000, &len, log); +      fprintf(stderr, "drawbuffers: shader link error:\n%s\n", log); +   } +} + + +static void +SetupShaders(void) +{ +   /* second color output = 1 - first color */ +   static const char *fragShaderText = +      "void main() {\n" +      "   gl_FragData[0] = gl_Color; \n" +      "   gl_FragData[1] = vec4(1.0) - gl_Color; \n" +      "}\n"; + +   GLuint fragShader, program; + +   fragShader = LoadAndCompileShader(GL_FRAGMENT_SHADER, fragShaderText); +   program = glCreateProgram_func(); + +   glAttachShader_func(program, fragShader); +   glLinkProgram_func(program); +   CheckLink(program); +   glUseProgram_func(program); +} + + +static void +SetupLighting(void) +{ +   static const GLfloat frontMat[4] = { 1.0, 0.5, 0.5, 1.0 }; +   static const GLfloat backMat[4] = { 1.0, 0.5, 0.5, 1.0 }; + +   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, frontMat); +   glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, backMat); +   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); +   glEnable(GL_LIGHT0); +   glEnable(GL_LIGHTING); +} + + +static void +Init(void) +{ +   CheckExtensions(); +   GetExtensionFuncs(); +   SetupRenderbuffers(); +   SetupShaders(); +   SetupLighting(); +   glEnable(GL_DEPTH_TEST); +} + + +int +main(int argc, char *argv[]) +{ +   glutInit(&argc, argv); +   glutInitWindowPosition(0, 0); +   glutInitWindowSize(Width, Height); +   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); +   Win = glutCreateWindow(argv[0]); +   glutReshapeFunc(Reshape); +   glutKeyboardFunc(Key); +   glutDisplayFunc(Display); +   Init(); +   glutMainLoop(); +   return 0; +} | 
