From 78e95198cb6c8919bdc981504a5a2cee4bb34f25 Mon Sep 17 00:00:00 2001 From: Lionel Ulmer Date: Sun, 12 Jun 2005 10:43:11 +0000 Subject: [PATCH] Support all possible texture coordinates sizes. --- dlls/ddraw/d3d_private.h | 6 +++++ dlls/ddraw/d3d_utils.c | 16 ++++++----- dlls/ddraw/device_opengl.c | 66 ++++++++++++++++++++++++++++++--------------- dlls/ddraw/gl_api.h | 3 +++ dlls/ddraw/gl_private.h | 3 +++ dlls/ddraw/opengl_private.h | 2 +- dlls/ddraw/vertexbuffer.c | 14 +++++++--- 7 files changed, 76 insertions(+), 34 deletions(-) diff --git a/dlls/ddraw/d3d_private.h b/dlls/ddraw/d3d_private.h index 2dbee3275c9..ddcffa4d054 100644 --- a/dlls/ddraw/d3d_private.h +++ b/dlls/ddraw/d3d_private.h @@ -270,6 +270,12 @@ struct IDirect3DVertexBufferImpl }; /* Various dump and helper functions */ +#define GET_TEXCOUNT_FROM_FVF(d3dvtVertexType) \ + (((d3dvtVertexType) & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) + +#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \ + (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1) + extern const char *_get_renderstate(D3DRENDERSTATETYPE type); extern void dump_D3DMATERIAL7(LPD3DMATERIAL7 lpMat); extern void dump_D3DCOLORVALUE(D3DCOLORVALUE *lpCol); diff --git a/dlls/ddraw/d3d_utils.c b/dlls/ddraw/d3d_utils.c index 0ba65c737f7..bbe0ec0a2e6 100644 --- a/dlls/ddraw/d3d_utils.c +++ b/dlls/ddraw/d3d_utils.c @@ -235,10 +235,10 @@ dump_D3DMATRIX(D3DMATRIX *mat) DPRINTF(" %f %f %f %f\n", mat->_41, mat->_42, mat->_43, mat->_44); } - DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) { DWORD size = 0; + int i; if (d3dvtVertexType & D3DFVF_NORMAL) size += 3 * sizeof(D3DVALUE); if (d3dvtVertexType & D3DFVF_DIFFUSE) size += sizeof(DWORD); @@ -249,8 +249,10 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break; default: TRACE(" matrix weighting not handled yet...\n"); } - size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); - + for (i = 0; i < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); i++) { + size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(D3DVALUE); + } + return size; } @@ -288,8 +290,8 @@ void dump_flexible_vertex(DWORD d3dvtVertexType) GEN_CASE(D3DFVF_TEX8); } #undef GEN_CASE - for (i = 0; i < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); i++) { - DPRINTF(" T%d-s%ld", i + 1, (((d3dvtVertexType >> (16 + (2 * i))) + 1) & 0x03) + 1); + for (i = 0; i < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); i++) { + DPRINTF(" T%d-s%ld", i + 1, GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i)); } DPRINTF("\n"); } @@ -325,9 +327,9 @@ convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPR strided->specular.lpvData = ((char *) lpvVertices) + current_offset; current_offset += sizeof(DWORD); } - for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { + for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); tex_index++) { strided->textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset; - current_offset += 2 * sizeof(D3DVALUE); + current_offset += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index) * sizeof(D3DVALUE); } strided->position.dwStride = current_offset; strided->normal.dwStride = current_offset; diff --git a/dlls/ddraw/device_opengl.c b/dlls/ddraw/device_opengl.c index ca88442ba09..43e1a6d9a77 100644 --- a/dlls/ddraw/device_opengl.c +++ b/dlls/ddraw/device_opengl.c @@ -1296,14 +1296,20 @@ inline static void handle_diffuse_and_specular(STATEBLOCK *sb, BYTE *fog_table, } } -inline static void handle_texture(D3DVALUE *coords) { - glTexCoord2fv(coords); +static void handle_texture(DWORD size, const D3DVALUE *coords) { + switch (size) { + case 1: glTexCoord1fv(coords); break; + case 2: glTexCoord2fv(coords); break; + case 3: glTexCoord3fv(coords); break; + case 4: glTexCoord4fv(coords); break; + } } -inline static void handle_textures(const D3DVALUE *coords, int tex_stage) { - if (GL_extensions.glMultiTexCoord2fv) { - GL_extensions.glMultiTexCoord2fv(GL_TEXTURE0_WINE + tex_stage, coords); + +inline static void handle_textures(DWORD size, const D3DVALUE *coords, int tex_stage) { + if (GL_extensions.max_texture_units > 0) { + GL_extensions.glMultiTexCoord[size - 1](GL_TEXTURE0_WINE + tex_stage, coords); } else { - if (tex_stage == 0) glTexCoord2fv(coords); + if (tex_stage == 0) handle_texture(size, coords); } } @@ -1319,7 +1325,7 @@ static void draw_primitive_strided(IDirect3DDeviceImpl *This, BOOLEAN vertex_lighted = FALSE; IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This; int num_active_stages = 0; - int num_tex_index = ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); + int num_tex_index = GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); /* I put the trace before the various locks... So as to better understand where locks occur :-) */ if (TRACE_ON(ddraw)) { @@ -1412,7 +1418,7 @@ static void draw_primitive_strided(IDirect3DDeviceImpl *This, GL_extensions.glClientActiveTexture(GL_TEXTURE0_WINE + tex_stage); } glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride, + glTexCoordPointer(GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index), GL_FLOAT, lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride, lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData); } if (dwIndices != NULL) { @@ -1450,7 +1456,7 @@ static void draw_primitive_strided(IDirect3DDeviceImpl *This, (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); handle_normal(normal); - handle_texture(tex_coord); + handle_texture(2, tex_coord); handle_xyz(position); TRACE_(ddraw_geom)(" %f %f %f / %f %f %f (%f %f)\n", @@ -1473,7 +1479,7 @@ static void draw_primitive_strided(IDirect3DDeviceImpl *This, (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); handle_diffuse_and_specular(&(This->state_block), glThis->fog_table, color_d, color_s, TRUE); - handle_texture(tex_coord); + handle_texture(2, tex_coord); handle_xyzrhw(position); TRACE_(ddraw_geom)(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n", @@ -1494,7 +1500,7 @@ static void draw_primitive_strided(IDirect3DDeviceImpl *This, Note that people should write a fast path for all vertex formats out there... */ unsigned int index; - static const D3DVALUE no_index[] = { 0.0, 0.0, 0.0, 0.0 }; + /* static const D3DVALUE no_index[] = { 0.0, 0.0, 0.0, 0.0 }; */ for (index = 0; index < dwIndexCount; index++) { int i = (dwIndices == NULL) ? index : dwIndices[index]; @@ -1525,14 +1531,19 @@ static void draw_primitive_strided(IDirect3DDeviceImpl *This, for (tex_stage = 0; tex_stage < num_active_stages; tex_stage++) { int tex_index = This->state_block.texture_stage_state[tex_stage][D3DTSS_TEXCOORDINDEX - 1] & 0x0000FFFF; + D3DVALUE *tex_coord; + if (tex_index >= num_tex_index) { - handle_textures((const D3DVALUE *) no_index, tex_stage); - } else { - D3DVALUE *tex_coord = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) + - i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride); - handle_textures(tex_coord, tex_stage); + /* This will have to be checked on Windows. RealMYST uses this feature and I would find it more + * logical to re-use the index of the previous stage than a default index of '0'. + */ + + /* handle_textures((const D3DVALUE *) no_index, tex_stage); */ + tex_index = num_tex_index - 1; } + tex_coord = (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) + + i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride); + handle_textures(GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index), tex_coord, tex_stage); } if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { @@ -1580,11 +1591,17 @@ static void draw_primitive_strided(IDirect3DDeviceImpl *This, (*color_s >> 0) & 0xFF, (*color_s >> 24) & 0xFF); } - for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { + for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); tex_index++) { D3DVALUE *tex_coord = (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride); - TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); + switch (GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index)) { + case 1: TRACE_(ddraw_geom)(" / %f", tex_coord[0]); break; + case 2: TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); break; + case 3: TRACE_(ddraw_geom)(" / %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2]); break; + case 4: TRACE_(ddraw_geom)(" / %f %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2], tex_coord[3]); break; + default: TRACE_(ddraw_geom)("Invalid texture size (%ld) !!!", GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index)); break; + } } TRACE_(ddraw_geom)("\n"); } @@ -4397,15 +4414,20 @@ d3ddevice_init_at_startup(void *gl_handle) TRACE(" - multi-texturing (%d stages)\n", GL_extensions.max_texture_units); /* We query the ARB version to be the most portable we can... */ GL_extensions.glActiveTexture = pglXGetProcAddressARB("glActiveTextureARB"); - GL_extensions.glMultiTexCoord2fv = pglXGetProcAddressARB("glMultiTexCoord2fv"); + GL_extensions.glMultiTexCoord[0] = pglXGetProcAddressARB("glMultiTexCoord1fvARB"); + GL_extensions.glMultiTexCoord[1] = pglXGetProcAddressARB("glMultiTexCoord2fvARB"); + GL_extensions.glMultiTexCoord[2] = pglXGetProcAddressARB("glMultiTexCoord3fvARB"); + GL_extensions.glMultiTexCoord[3] = pglXGetProcAddressARB("glMultiTexCoord4fvARB"); GL_extensions.glClientActiveTexture = pglXGetProcAddressARB("glClientActiveTextureARB"); + } else { + GL_extensions.max_texture_units = 0; } if (strstr(glExtensions, "GL_EXT_texture_compression_s3tc")) { TRACE(" - S3TC compression supported\n"); GL_extensions.s3tc_compressed_texture = TRUE; - GL_extensions.glCompressedTexImage2D = pglXGetProcAddressARB("glCompressedTexImage2D"); - GL_extensions.glCompressedTexSubImage2D = pglXGetProcAddressARB("glCompressedTexSubImage2D"); + GL_extensions.glCompressedTexImage2D = pglXGetProcAddressARB("glCompressedTexImage2DARB"); + GL_extensions.glCompressedTexSubImage2D = pglXGetProcAddressARB("glCompressedTexSubImage2DARB"); } } diff --git a/dlls/ddraw/gl_api.h b/dlls/ddraw/gl_api.h index 04fe09d259d..9e48099b27d 100644 --- a/dlls/ddraw/gl_api.h +++ b/dlls/ddraw/gl_api.h @@ -98,8 +98,11 @@ GL_API_FUNCTION(glShadeModel) GL_API_FUNCTION(glStencilFunc) GL_API_FUNCTION(glStencilMask) GL_API_FUNCTION(glStencilOp) +GL_API_FUNCTION(glTexCoord1fv) GL_API_FUNCTION(glTexCoord2f) GL_API_FUNCTION(glTexCoord2fv) +GL_API_FUNCTION(glTexCoord3fv) +GL_API_FUNCTION(glTexCoord4fv) GL_API_FUNCTION(glTexCoordPointer) GL_API_FUNCTION(glTexEnvf) GL_API_FUNCTION(glTexEnvfv) diff --git a/dlls/ddraw/gl_private.h b/dlls/ddraw/gl_private.h index 7eb1a4c9cdf..52027c489ac 100644 --- a/dlls/ddraw/gl_private.h +++ b/dlls/ddraw/gl_private.h @@ -141,8 +141,11 @@ #define glStencilFunc pglStencilFunc #define glStencilMask pglStencilMask #define glStencilOp pglStencilOp +#define glTexCoord1fv pglTexCoord1fv #define glTexCoord2f pglTexCoord2f #define glTexCoord2fv pglTexCoord2fv +#define glTexCoord3fv pglTexCoord3fv +#define glTexCoord4fv pglTexCoord4fv #define glTexCoordPointer pglTexCoordPointer #define glTexEnvf pglTexEnvf #define glTexEnvfv pglTexEnvfv diff --git a/dlls/ddraw/opengl_private.h b/dlls/ddraw/opengl_private.h index dff01b70577..ced765e61e1 100644 --- a/dlls/ddraw/opengl_private.h +++ b/dlls/ddraw/opengl_private.h @@ -171,7 +171,7 @@ typedef struct { /* Multi-texturing */ GLint max_texture_units; void (*glActiveTexture)(GLenum texture); - void (*glMultiTexCoord2fv)(GLenum target, const GLfloat *v); + void (*glMultiTexCoord[4])(GLenum target, const GLfloat *v); void (*glClientActiveTexture)(GLenum texture); /* S3TC/DXTN compressed texture */ BOOLEAN s3tc_compressed_texture; diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c index deb970a5a11..1081815033f 100644 --- a/dlls/ddraw/vertexbuffer.c +++ b/dlls/ddraw/vertexbuffer.c @@ -358,11 +358,11 @@ process_vertices_strided(IDirect3DVertexBufferImpl *This, (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride); copy_and_next(dest_ptr, color_s, sizeof(DWORD)); } - for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { + for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); tex_index++) { D3DVALUE *tex_coord = (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + i * lpStrideData->textureCoords[tex_index].dwStride); - copy_and_next(dest_ptr, tex_coord, 2 * sizeof(D3DVALUE)); + copy_and_next(dest_ptr, tex_coord, GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, i) * sizeof(D3DVALUE)); } if (TRACE_ON(ddraw_geom)) { @@ -398,11 +398,17 @@ process_vertices_strided(IDirect3DVertexBufferImpl *This, (*color_s >> 0) & 0xFF, (*color_s >> 24) & 0xFF); } - for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { + for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); tex_index++) { D3DVALUE *tex_coord = (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + i * lpStrideData->textureCoords[tex_index].dwStride); - TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); + switch (GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)) { + case 1: TRACE_(ddraw_geom)(" / %f", tex_coord[0]); break; + case 2: TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); break; + case 3: TRACE_(ddraw_geom)(" / %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2]); break; + case 4: TRACE_(ddraw_geom)(" / %f %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2], tex_coord[3]); break; + default: TRACE_(ddraw_geom)("Invalid texture size (%ld) !!!", GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)); break; + } } TRACE_(ddraw_geom)("\n"); } -- 2.11.4.GIT