meta: add _mesa_meta_DrawTex()
authorChia-I Wu <olv@lunarg.com>
Sun, 21 Aug 2011 13:08:25 +0000 (21:08 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Sun, 30 Oct 2011 12:00:03 +0000 (20:00 +0800)
It is set to dd->DrawTex.

Reviewed-by: Brian Paul <brianp@vmware.com>
[olv: set dd->DrawTex in _mesa_init_driver_functions]

src/mesa/drivers/common/driverfuncs.c
src/mesa/drivers/common/meta.c
src/mesa/drivers/common/meta.h

index 263d4025ff3ad5bb0a17512323d0fa3f412839df..80db4bde8d34292c80959c94dfb28fde3fb5f9c1 100644 (file)
@@ -120,6 +120,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
    driver->UnmapTexture = NULL;
    driver->TextureMemCpy = memcpy;
    driver->IsTextureResident = NULL;
+   driver->DrawTex = _mesa_meta_DrawTex;
 
    /* Vertex/fragment programs */
    driver->BindProgram = NULL;
index c7bb93380291b9f37e881348f41f701868655030..3e553341d18997a6fda80c0a37374c899a880beb 100644 (file)
@@ -278,6 +278,14 @@ struct decompress_state
    GLint Width, Height;
 };
 
+/**
+ * State for glDrawTex()
+ */
+struct drawtex_state
+{
+   GLuint ArrayObj;
+   GLuint VBO;
+};
 
 #define MAX_META_OPS_DEPTH      8
 /**
@@ -299,6 +307,7 @@ struct gl_meta_state
    struct bitmap_state Bitmap;    /**< For _mesa_meta_Bitmap() */
    struct gen_mipmap_state Mipmap;    /**< For _mesa_meta_GenerateMipmap() */
    struct decompress_state Decompress;  /**< For texture decompression */
+   struct drawtex_state DrawTex;  /**< For _mesa_meta_DrawTex() */
 };
 
 
@@ -3332,3 +3341,131 @@ _mesa_meta_GetTexImage(struct gl_context *ctx,
       _mesa_get_teximage(ctx, format, type, pixels, texImage);
    }
 }
+
+
+/**
+ * Meta implementation of ctx->Driver.DrawTex() in terms
+ * of polygon rendering.
+ */
+void
+_mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
+                   GLfloat width, GLfloat height)
+{
+#if FEATURE_OES_draw_texture
+   struct drawtex_state *drawtex = &ctx->Meta->DrawTex;
+   struct vertex {
+      GLfloat x, y, z, st[MAX_TEXTURE_UNITS][2];
+   };
+   struct vertex verts[4];
+   GLuint i;
+
+   _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION |
+                          MESA_META_SHADER |
+                          MESA_META_TRANSFORM |
+                          MESA_META_VERTEX |
+                          MESA_META_VIEWPORT));
+
+   if (drawtex->ArrayObj == 0) {
+      /* one-time setup */
+      GLint active_texture;
+
+      /* create vertex array object */
+      _mesa_GenVertexArrays(1, &drawtex->ArrayObj);
+      _mesa_BindVertexArray(drawtex->ArrayObj);
+
+      /* create vertex array buffer */
+      _mesa_GenBuffersARB(1, &drawtex->VBO);
+      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
+      _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
+                          NULL, GL_DYNAMIC_DRAW_ARB);
+
+      /* client active texture is not part of the array object */
+      active_texture = ctx->Array.ActiveTexture;
+
+      /* setup vertex arrays */
+      _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
+      _mesa_EnableClientState(GL_VERTEX_ARRAY);
+      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+         _mesa_ClientActiveTextureARB(GL_TEXTURE0 + i);
+         _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(st[i]));
+         _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
+      }
+
+      /* restore client active texture */
+      _mesa_ClientActiveTextureARB(GL_TEXTURE0 + active_texture);
+   }
+   else {
+      _mesa_BindVertexArray(drawtex->ArrayObj);
+      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
+   }
+
+   /* vertex positions, texcoords */
+   {
+      const GLfloat x1 = x + width;
+      const GLfloat y1 = y + height;
+
+      z = CLAMP(z, 0.0, 1.0);
+      z = invert_z(z);
+
+      verts[0].x = x;
+      verts[0].y = y;
+      verts[0].z = z;
+
+      verts[1].x = x1;
+      verts[1].y = y;
+      verts[1].z = z;
+
+      verts[2].x = x1;
+      verts[2].y = y1;
+      verts[2].z = z;
+
+      verts[3].x = x;
+      verts[3].y = y1;
+      verts[3].z = z;
+
+      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+         const struct gl_texture_object *texObj;
+         const struct gl_texture_image *texImage;
+         GLfloat s, t, s1, t1;
+         GLuint tw, th;
+
+         if (!ctx->Texture.Unit[i]._ReallyEnabled) {
+            GLuint j;
+            for (j = 0; j < 4; j++) {
+               verts[j].st[i][0] = 0.0f;
+               verts[j].st[i][1] = 0.0f;
+            }
+            continue;
+         }
+
+         texObj = ctx->Texture.Unit[i]._Current;
+         texImage = texObj->Image[0][texObj->BaseLevel];
+         tw = texImage->Width2;
+         th = texImage->Height2;
+
+         s = (GLfloat) texObj->CropRect[0] / tw;
+         t = (GLfloat) texObj->CropRect[1] / th;
+         s1 = (GLfloat) (texObj->CropRect[0] + texObj->CropRect[2]) / tw;
+         t1 = (GLfloat) (texObj->CropRect[1] + texObj->CropRect[3]) / th;
+
+         verts[0].st[i][0] = s;
+         verts[0].st[i][1] = t;
+
+         verts[1].st[i][0] = s1;
+         verts[1].st[i][1] = t;
+
+         verts[2].st[i][0] = s1;
+         verts[2].st[i][1] = t1;
+
+         verts[3].st[i][0] = s;
+         verts[3].st[i][1] = t1;
+      }
+
+      _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+   }
+
+   _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+   _mesa_meta_end(ctx);
+#endif /* FEATURE_OES_draw_texture */
+}
index e0435a822f51d1c34cd1159c5311d02ebefe274e..71981398492d383aed35ca194426ac5495fa6a9a 100644 (file)
@@ -129,5 +129,8 @@ _mesa_meta_GetTexImage(struct gl_context *ctx,
                        GLenum format, GLenum type, GLvoid *pixels,
                        struct gl_texture_image *texImage);
 
+extern void
+_mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
+                   GLfloat width, GLfloat height);
 
 #endif /* META_H */