diff options
-rw-r--r-- | src/mesa/drivers/common/driverfuncs.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/common/meta.c | 137 | ||||
-rw-r--r-- | src/mesa/drivers/common/meta.h | 3 |
3 files changed, 141 insertions, 0 deletions
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 263d4025ff3..80db4bde8d3 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -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; diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index c7bb9338029..3e553341d18 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -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 */ +} diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h index e0435a822f5..71981398492 100644 --- a/src/mesa/drivers/common/meta.h +++ b/src/mesa/drivers/common/meta.h @@ -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 */ |