mesa: fix all(bvec2) function typo, add missing bvec2/3/4() constuctors
[mesa.git] / progs / tests / fbotexture.c
index e1f10c94185ce307401717653cb2370915355525..aa9f6171221ce5950b7d60e22dc38166f06a9d0d 100644 (file)
 
 
 #define GL_GLEXT_PROTOTYPES
+#include <GL/glut.h>
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <math.h>
-#include <GL/glut.h>
 
+/* For debug */
+#define DEPTH 1
+#define STENCIL 1
+#define DRAW 1
+
+
+static int Win = 0;
 static int Width = 400, Height = 400;
+
+static GLenum TexTarget = GL_TEXTURE_2D; /*GL_TEXTURE_RECTANGLE_ARB;*/
 static int TexWidth = 512, TexHeight = 512;
+/*static int TexWidth = 600, TexHeight = 600;*/
+
 static GLuint MyFB;
 static GLuint TexObj;
 static GLuint DepthRB, StencilRB;
 static GLboolean Anim = GL_FALSE;
 static GLfloat Rot = 0.0;
+static GLboolean UsePackedDepthStencil = GL_FALSE;
+static GLuint TextureLevel = 1;  /* which texture level to render to */
+static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */
 
 
 static void
@@ -38,7 +53,7 @@ CheckError(int line)
 static void
 Idle(void)
 {
-   Rot = glutGet(GLUT_ELAPSED_TIME) * 0.05;
+   Rot = glutGet(GLUT_ELAPSED_TIME) * 0.1;
    glutPostRedisplay();
 }
 
@@ -46,7 +61,6 @@ Idle(void)
 static void
 RenderTexture(void)
 {
-   GLint level = 0;
    GLenum status;
 
    glMatrixMode(GL_PROJECTION);
@@ -56,10 +70,8 @@ RenderTexture(void)
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -15.0);
 
-   /* draw to texture */
+   /* draw to texture image */
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
-   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
-                             GL_TEXTURE_2D, TexObj, level);
 
    status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
@@ -70,12 +82,21 @@ RenderTexture(void)
 
    glClearColor(0.5, 0.5, 1.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+   CheckError(__LINE__);
 
+#if DEPTH
    glEnable(GL_DEPTH_TEST);
+#endif
+
+#if STENCIL
    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_NEVER, 1, ~0);
    glStencilOp(GL_REPLACE, GL_KEEP, GL_REPLACE);
+#endif
+
+   CheckError(__LINE__);
 
+#if DEPTH || STENCIL
    /* draw diamond-shaped stencil pattern */
    glColor3f(0, 1, 0);
    glBegin(GL_POLYGON);
@@ -84,10 +105,15 @@ RenderTexture(void)
    glVertex2f( 0.2,  0.0);
    glVertex2f( 0.0,  0.2);
    glEnd();
+#endif
 
    /* draw teapot where stencil != 1 */
+#if STENCIL
    glStencilFunc(GL_NOTEQUAL, 1, ~0);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+#endif
+
+   CheckError(__LINE__);
 
 #if 0
    glBegin(GL_POLYGON);
@@ -106,12 +132,18 @@ RenderTexture(void)
    glutSolidTeapot(0.5);
    glPopMatrix();
    glDisable(GL_LIGHTING);
+   /*
+   PrintStencilHistogram(TexWidth, TexHeight);
+   */
 #endif
+
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);
 
+#if DRAW
    /* Bind normal framebuffer */
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+#endif
 
    CheckError(__LINE__);
 }
@@ -126,7 +158,7 @@ Display(void)
    RenderTexture();
 
    /* draw textured quad in the window */
-
+#if DRAW
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
@@ -141,22 +173,38 @@ Display(void)
 
    glPushMatrix();
    glRotatef(Rot, 0, 1, 0);
-   glEnable(GL_TEXTURE_2D);
+   glEnable(TexTarget);
+   glBindTexture(TexTarget, TexObj);
    glBegin(GL_POLYGON);
    glColor3f(0.25, 0.25, 0.25);
-   glTexCoord2f(0, 0);
-   glVertex2f(-1, -1);
-   glTexCoord2f(1, 0);
-   glVertex2f(1, -1);
-   glColor3f(1.0, 1.0, 1.0);
-   glTexCoord2f(1, 1);
-   glVertex2f(1, 1);
-   glTexCoord2f(0, 1);
-   glVertex2f(-1, 1);
+   if (TexTarget == GL_TEXTURE_2D) {
+      glTexCoord2f(0, 0);
+      glVertex2f(-1, -1);
+      glTexCoord2f(1, 0);
+      glVertex2f(1, -1);
+      glColor3f(1.0, 1.0, 1.0);
+      glTexCoord2f(1, 1);
+      glVertex2f(1, 1);
+      glTexCoord2f(0, 1);
+      glVertex2f(-1, 1);
+   }
+   else {
+      assert(TexTarget == GL_TEXTURE_RECTANGLE_ARB);
+      glTexCoord2f(0, 0);
+      glVertex2f(-1, -1);
+      glTexCoord2f(TexWidth, 0);
+      glVertex2f(1, -1);
+      glColor3f(1.0, 1.0, 1.0);
+      glTexCoord2f(TexWidth, TexHeight);
+      glVertex2f(1, 1);
+      glTexCoord2f(0, TexHeight);
+      glVertex2f(-1, 1);
+   }
    glEnd();
    glPopMatrix();
-   glDisable(GL_TEXTURE_2D);
-   
+   glDisable(TexTarget);
+#endif
+
    glutSwapBuffers();
    CheckError(__LINE__);
 }
@@ -171,6 +219,26 @@ Reshape(int width, int height)
 }
 
 
+static void
+CleanUp(void)
+{
+#if DEPTH
+   glDeleteRenderbuffersEXT(1, &DepthRB);
+#endif
+#if STENCIL
+   if (!UsePackedDepthStencil)
+      glDeleteRenderbuffersEXT(1, &StencilRB);
+#endif
+   glDeleteFramebuffersEXT(1, &MyFB);
+
+   glDeleteTextures(1, &TexObj);
+
+   glutDestroyWindow(Win);
+
+   exit(0);
+}
+
+
 static void
 Key(unsigned char key, int x, int y)
 {
@@ -184,8 +252,11 @@ Key(unsigned char key, int x, int y)
          else
             glutIdleFunc(NULL);
          break;
+      case 's':
+         Rot += 2.0;
+         break;
       case 27:
-         exit(0);
+         CleanUp();
          break;
    }
    glutPostRedisplay();
@@ -193,17 +264,28 @@ Key(unsigned char key, int x, int y)
 
 
 static void
-Init(void)
+Init(int argc, char *argv[])
 {
+   static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 };
    GLint i;
 
    if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
       printf("GL_EXT_framebuffer_object not found!\n");
       exit(0);
    }
+
+   if (argc > 1 && strcmp(argv[1], "-ds") == 0) {
+      if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) {
+         printf("GL_EXT_packed_depth_stencil not found!\n");
+         exit(0);
+      }
+      UsePackedDepthStencil = GL_TRUE;
+      printf("Using GL_EXT_packed_depth_stencil\n");
+   }
+
    printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
 
-   /* make framebuffer */
+   /* gen framebuffer id, delete it, do some assertions, just for testing */
    glGenFramebuffersEXT(1, &MyFB);
    assert(MyFB);
    assert(!glIsFramebufferEXT(MyFB));
@@ -216,52 +298,93 @@ Init(void)
    glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &i);
    assert(i == MyFB);
 
+   /* Make texture object/image */
+   glGenTextures(1, &TexObj);
+   glBindTexture(TexTarget, TexObj);
+   /* make two image levels */
+   glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0,
+                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+   glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0,
+                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+   TexWidth = TexWidth >> TextureLevel;
+   TexHeight = TexHeight >> TextureLevel;
+
+   glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+   glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel);
+   glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel);
+
+   CheckError(__LINE__);
+
+   /* Render color to texture */
+   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+                             TexTarget, TexObj, TextureLevel);
+
+
+#if DEPTH
    /* make depth renderbuffer */
    glGenRenderbuffersEXT(1, &DepthRB);
    assert(DepthRB);
    assert(!glIsRenderbufferEXT(DepthRB));
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB);
-   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
-                            TexWidth, TexHeight);
+   assert(glIsRenderbufferEXT(DepthRB));
+   if (UsePackedDepthStencil)
+      glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT,
+                               TexWidth, TexHeight);
+   else
+      glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
+                               TexWidth, TexHeight);
+   CheckError(__LINE__);
    glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT,
                                    GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
+   CheckError(__LINE__);
    printf("Depth renderbuffer size = %d bits\n", i);
    assert(i > 0);
 
-   /* make stencil renderbuffer */
-   glGenRenderbuffersEXT(1, &StencilRB);
-   assert(StencilRB);
-   assert(!glIsRenderbufferEXT(StencilRB));
-   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilRB);
-   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX,
-                            TexWidth, TexHeight);
-   glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT,
-                                   GL_RENDERBUFFER_STENCIL_SIZE_EXT, &i);
-   printf("Stencil renderbuffer size = %d bits\n", i);
-   assert(i > 0);
-
    /* attach DepthRB to MyFB */
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                 GL_RENDERBUFFER_EXT, DepthRB);
+#endif
 
-   /* attach StencilRB to MyFB */
-   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
-                                GL_RENDERBUFFER_EXT, StencilRB);
+   CheckError(__LINE__);
 
+#if STENCIL
+   if (UsePackedDepthStencil) {
+      /* DepthRb is a combined depth/stencil renderbuffer */
+      glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+                                   GL_STENCIL_ATTACHMENT_EXT,
+                                   GL_RENDERBUFFER_EXT, DepthRB);
+   }
+   else {
+      /* make stencil renderbuffer */
+      glGenRenderbuffersEXT(1, &StencilRB);
+      assert(StencilRB);
+      assert(!glIsRenderbufferEXT(StencilRB));
+      glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilRB);
+      assert(glIsRenderbufferEXT(StencilRB));
+      glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX,
+                               TexWidth, TexHeight);
+      /* attach StencilRB to MyFB */
+      glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+                                   GL_STENCIL_ATTACHMENT_EXT,
+                                   GL_RENDERBUFFER_EXT, StencilRB);
+   }
+   glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT,
+                                   GL_RENDERBUFFER_STENCIL_SIZE_EXT, &i);
+   CheckError(__LINE__);
+   printf("Stencil renderbuffer size = %d bits\n", i);
+   assert(i > 0);
+#endif
+
+   CheckError(__LINE__);
 
    /* bind regular framebuffer */
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
 
-   /* Make texture object/image */
-   glGenTextures(1, &TexObj);
-   glBindTexture(GL_TEXTURE_2D, TexObj);
-   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 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);
-   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
-   CheckError(__LINE__);
+   /* lighting */
+   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat);
 }
 
 
@@ -272,13 +395,13 @@ main(int argc, char *argv[])
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(Width, Height);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
-   glutCreateWindow(argv[0]);
+   Win = glutCreateWindow(argv[0]);
    glutReshapeFunc(Reshape);
    glutKeyboardFunc(Key);
    glutDisplayFunc(Display);
    if (Anim)
       glutIdleFunc(Idle);
-   Init();
+   Init(argc, argv);
    glutMainLoop();
    return 0;
 }