From 2d904495003f65a9fefb96eacf828617f3bb9c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com> Date: Wed, 19 Dec 2007 17:10:02 +0100 Subject: [PATCH] wined3d: Fixed function vertex attribute types are flexible. --- dlls/d3d9/tests/visual.c | 241 +++++++++++++++++++++++++++++++++ dlls/wined3d/directx.c | 140 ++++++++++++++++++- dlls/wined3d/drawprim.c | 85 +++++------- dlls/wined3d/state.c | 7 +- dlls/wined3d/wined3d_private.h | 7 + 5 files changed, 425 insertions(+), 55 deletions(-) diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 764b5faf030..dd38d553b36 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -5437,6 +5437,246 @@ static void alpha_test(IDirect3DDevice9 *device) } } +struct vertex_shortcolor { + float x, y, z; + unsigned short r, g, b, a; +}; +struct vertex_floatcolor { + float x, y, z; + float r, g, b, a; +}; + +static void fixed_function_decl_test(IDirect3DDevice9 *device) +{ + HRESULT hr; + DWORD color; + void *data; + static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = { + {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, + {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, + D3DDECL_END() + }; + static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = { + {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, + {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, + D3DDECL_END() + }; + static const D3DVERTEXELEMENT9 decl_elements_short4[] = { + {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, + {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, + D3DDECL_END() + }; + static const D3DVERTEXELEMENT9 decl_elements_float[] = { + {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, + {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, + D3DDECL_END() + }; + IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL; + IDirect3DVertexBuffer9 *vb; + struct vertex quad1[] = /* D3DCOLOR */ + { + {-1.0f, -1.0f, 0.1f, 0x00ffff00}, + {-1.0f, 0.0f, 0.1f, 0x00ffff00}, + { 0.0f, -1.0f, 0.1f, 0x00ffff00}, + { 0.0f, 0.0f, 0.1f, 0x00ffff00}, + }; + struct vertex quad2[] = /* UBYTE4N */ + { + {-1.0f, 0.0f, 0.1f, 0x00ffff00}, + {-1.0f, 1.0f, 0.1f, 0x00ffff00}, + { 0.0f, 0.0f, 0.1f, 0x00ffff00}, + { 0.0f, 1.0f, 0.1f, 0x00ffff00}, + }; + struct vertex_shortcolor quad3[] = /* short */ + { + { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff}, + { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff}, + { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff}, + { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff}, + }; + struct vertex_floatcolor quad4[] = + { + { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0}, + { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0}, + { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0}, + { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0}, + }; + + hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0); + ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr); + + hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color); + ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr); + hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte); + ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr); + hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short); + ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr); + hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float); + ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr); + + hr = IDirect3DDevice9_CreateVertexBuffer(device, max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), sizeof(quad4)))), + 0, 0, D3DPOOL_MANAGED, &vb, NULL); + ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr)); + + hr = IDirect3DDevice9_BeginScene(device); + ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr); + if(SUCCEEDED(hr)) { + if(dcl_color) { + hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color); + ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0])); + ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr); + } + + if(dcl_ubyte) { + hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte); + ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0])); + ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr); + } + + if(dcl_short) { + hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short); + ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0])); + ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr); + } + + if(dcl_float) { + hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float); + ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0])); + ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr); + } + + hr = IDirect3DDevice9_EndScene(device); + ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr); + } + + IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + if(dcl_short) { + color = getPixelColor(device, 480, 360); + ok(color == 0x000000ff, + "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color); + } + if(dcl_ubyte) { + color = getPixelColor(device, 160, 120); + ok(color == 0x0000ffff, + "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color); + } + if(dcl_color) { + color = getPixelColor(device, 160, 360); + ok(color == 0x00ffff00, + "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color); + } + if(dcl_float) { + color = getPixelColor(device, 480, 120); + ok(color == 0x00ff0000, + "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color); + } + + /* The following test with vertex buffers doesn't serve to find out new information from windows. + * It is a plain regression test because wined3d uses different codepaths for attribute conversion + * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests + * wether the immediate mode code works + */ + hr = IDirect3DDevice9_BeginScene(device); + ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr); + if(SUCCEEDED(hr)) { + if(dcl_color) { + hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0); + ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr)); + memcpy(data, quad1, sizeof(quad1)); + hr = IDirect3DVertexBuffer9_Unlock(vb); + ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr); + hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color); + ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr); + hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0])); + ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr)); + hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2); + ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr); + } + + if(dcl_ubyte) { + hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0); + ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr)); + memcpy(data, quad2, sizeof(quad2)); + hr = IDirect3DVertexBuffer9_Unlock(vb); + ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr); + hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte); + ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr); + hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0])); + ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr)); + hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2); + ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr); + } + + if(dcl_short) { + hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0); + ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr)); + memcpy(data, quad3, sizeof(quad3)); + hr = IDirect3DVertexBuffer9_Unlock(vb); + ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr); + hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short); + ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr); + hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0])); + ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr)); + hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2); + ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr); + } + + if(dcl_float) { + hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0); + ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr)); + memcpy(data, quad4, sizeof(quad4)); + hr = IDirect3DVertexBuffer9_Unlock(vb); + ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr); + hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float); + ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr); + hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0])); + ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr)); + hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2); + ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr); + } + + hr = IDirect3DDevice9_EndScene(device); + ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr); + } + + hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0); + ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr)); + hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr); + + IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + if(dcl_short) { + color = getPixelColor(device, 480, 360); + ok(color == 0x000000ff, + "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color); + } + if(dcl_ubyte) { + color = getPixelColor(device, 160, 120); + ok(color == 0x0000ffff, + "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color); + } + if(dcl_color) { + color = getPixelColor(device, 160, 360); + ok(color == 0x00ffff00, + "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color); + } + if(dcl_float) { + color = getPixelColor(device, 480, 120); + ok(color == 0x00ff0000, + "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color); + } + + IDirect3DVertexBuffer9_Release(vb); + if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float); + if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short); + if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte); + if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color); +} + START_TEST(visual) { IDirect3DDevice9 *device_ptr; @@ -5517,6 +5757,7 @@ START_TEST(visual) g16r16_texture_test(device_ptr); texture_transform_flags_test(device_ptr); autogen_mipmap_test(device_ptr); + fixed_function_decl_test(device_ptr); if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1)) { diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 7badb4c4ad3..70a21a08949 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -143,6 +143,12 @@ DWORD *stateLookup[MAX_LOOKUPS]; DWORD minMipLookup[WINED3DTEXF_ANISOTROPIC + 1][WINED3DTEXF_LINEAR + 1]; +/* drawStridedSlow attributes */ +glAttribFunc position_funcs[WINED3DDECLTYPE_UNUSED]; +glAttribFunc diffuse_funcs[WINED3DDECLTYPE_UNUSED]; +glAttribFunc specular_funcs[WINED3DDECLTYPE_UNUSED]; +glAttribFunc normal_funcs[WINED3DDECLTYPE_UNUSED]; +glTexAttribFunc texcoord_funcs[WINED3DDECLTYPE_UNUSED]; /** * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created @@ -2879,8 +2885,139 @@ static void fixup_extensions(WineD3D_GL_Info *gl_info) { } } -#define PUSH1(att) attribs[nAttribs++] = (att); +void invalid_func(void *data) { + ERR("Invalid vertex attribute function called\n"); + DebugBreak(); +} + #define GLINFO_LOCATION (Adapters[0].gl_info) + +/* Helper functions for providing vertex data to opengl. The arrays are initialized based on + * the extension detection and are used in drawStridedSlow + */ +static void position_d3dcolor(void *data) { + DWORD pos = *((DWORD *) data); + + FIXME("Add a test for fixed function position from d3dcolor type\n"); + glVertex4s(D3DCOLOR_B_R(pos), + D3DCOLOR_B_G(pos), + D3DCOLOR_B_B(pos), + D3DCOLOR_B_A(pos)); +} +static void position_float4(void *data) { + GLfloat *pos = (float *) data; + float w = 1.0 / pos[3]; + + glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w); +} + +static void diffuse_d3dcolor(void *data) { + DWORD diffuseColor = *((DWORD *) data); + + glColor4ub(D3DCOLOR_B_R(diffuseColor), + D3DCOLOR_B_G(diffuseColor), + D3DCOLOR_B_B(diffuseColor), + D3DCOLOR_B_A(diffuseColor)); +} + +static void specular_d3dcolor(void *data) { + DWORD specularColor = *((DWORD *) data); + + GL_EXTCALL(glSecondaryColor3ubEXT)(D3DCOLOR_B_R(specularColor), + D3DCOLOR_B_G(specularColor), + D3DCOLOR_B_B(specularColor)); +} +static void warn_no_specular_func(void *data) { + WARN("GL_EXT_secondary_color not supported\n"); +} + +void fillGLAttribFuncs(WineD3D_GL_Info *gl_info) { + position_funcs[WINED3DDECLTYPE_FLOAT1] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_FLOAT2] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) glVertex3fv; + position_funcs[WINED3DDECLTYPE_FLOAT4] = (void *) position_float4; + position_funcs[WINED3DDECLTYPE_D3DCOLOR] = (void *) position_d3dcolor; + position_funcs[WINED3DDECLTYPE_UBYTE4] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_SHORT2] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_SHORT4] = (void *) glVertex2sv; + position_funcs[WINED3DDECLTYPE_UBYTE4N] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_SHORT2N] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_SHORT4N] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_USHORT2N] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_USHORT4N] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_UDEC3] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_DEC3N] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) invalid_func; + position_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) invalid_func; + + diffuse_funcs[WINED3DDECLTYPE_FLOAT1] = (void *) invalid_func; + diffuse_funcs[WINED3DDECLTYPE_FLOAT2] = (void *) invalid_func; + diffuse_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) glColor3fv; + diffuse_funcs[WINED3DDECLTYPE_FLOAT4] = (void *) glColor4fv; + diffuse_funcs[WINED3DDECLTYPE_D3DCOLOR] = (void *) diffuse_d3dcolor; + diffuse_funcs[WINED3DDECLTYPE_UBYTE4] = (void *) invalid_func; + diffuse_funcs[WINED3DDECLTYPE_SHORT2] = (void *) invalid_func; + diffuse_funcs[WINED3DDECLTYPE_SHORT4] = (void *) invalid_func; + diffuse_funcs[WINED3DDECLTYPE_UBYTE4N] = (void *) glColor4ubv; + diffuse_funcs[WINED3DDECLTYPE_SHORT2N] = (void *) invalid_func; + diffuse_funcs[WINED3DDECLTYPE_SHORT4N] = (void *) glColor4sv; + diffuse_funcs[WINED3DDECLTYPE_USHORT2N] = (void *) invalid_func; + diffuse_funcs[WINED3DDECLTYPE_USHORT4N] = (void *) glColor4usv; + diffuse_funcs[WINED3DDECLTYPE_UDEC3] = (void *) invalid_func; + diffuse_funcs[WINED3DDECLTYPE_DEC3N] = (void *) invalid_func; + diffuse_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) invalid_func; + diffuse_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) invalid_func; + + /* No 4 component entry points here */ + specular_funcs[WINED3DDECLTYPE_FLOAT1] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_FLOAT2] = (void *) invalid_func; + if(GL_SUPPORT(EXT_SECONDARY_COLOR)) { + specular_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) GL_EXTCALL(glSecondaryColor3fvEXT); + } else { + specular_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) warn_no_specular_func; + } + specular_funcs[WINED3DDECLTYPE_FLOAT4] = (void *) invalid_func; + if(GL_SUPPORT(EXT_SECONDARY_COLOR)) { + specular_funcs[WINED3DDECLTYPE_D3DCOLOR] = (void *) specular_d3dcolor; + } else { + specular_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) warn_no_specular_func; + } + specular_funcs[WINED3DDECLTYPE_UBYTE4] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_SHORT2] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_SHORT4] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_UBYTE4N] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_SHORT2N] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_SHORT4N] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_USHORT2N] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_USHORT4N] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_UDEC3] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_DEC3N] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) invalid_func; + specular_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) invalid_func; + + /* Only 3 component entry points here. Test how others behave. Float4 normals are used + * by one of our tests, trying to pass it to the pixel shader, which fails on Windows. + */ + normal_funcs[WINED3DDECLTYPE_FLOAT1] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_FLOAT2] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) glNormal3fv; + normal_funcs[WINED3DDECLTYPE_FLOAT4] = (void *) glNormal3fv; /* Just ignore the 4th value */ + normal_funcs[WINED3DDECLTYPE_D3DCOLOR] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_UBYTE4] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_SHORT2] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_SHORT4] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_UBYTE4N] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_SHORT2N] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_SHORT4N] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_USHORT2N] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_USHORT4N] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_UDEC3] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_DEC3N] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) invalid_func; + normal_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) invalid_func; +} + +#define PUSH1(att) attribs[nAttribs++] = (att); BOOL InitAdapters(void) { static HMODULE mod_gl; BOOL ret; @@ -3022,6 +3159,7 @@ BOOL InitAdapters(void) { select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode); select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info); + fillGLAttribFuncs(&Adapters[0].gl_info); } numAdapters = 1; diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 59a952f4fca..aa7dd6250f3 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -302,8 +302,6 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData const WORD *pIdxBufS = NULL; const DWORD *pIdxBufL = NULL; LONG vx_index; - float x = 0.0f, y = 0.0f, z = 0.0f; /* x,y,z coordinates */ - float rhw = 0.0f; /* rhw */ DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */ DWORD specularColor = 0; /* Specular Color */ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; @@ -353,6 +351,32 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData position = sd->u.s.position.lpData + streamOffset[sd->u.s.position.streamNo]; } + /* The texture coordinate types are not so easy to map into a common function signature - we're + * not using the vector functions here + */ + if(FIXME_ON(d3d_draw)) { + for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) { + DWORD type = sd->u.s.texCoords[textureNo].dwType; + if (sd->u.s.texCoords[textureNo].lpData && + type != WINED3DDECLTYPE_FLOAT1 && + type != WINED3DDECLTYPE_FLOAT2 && + type != WINED3DDECLTYPE_FLOAT3 && + type != WINED3DDECLTYPE_FLOAT4) { + FIXME("Implement fixed function texture coordinates from %s\n", debug_d3ddecltype(type)); + } + } + if(specular && This->stateBlock->renderState[WINED3DRS_FOGENABLE] && + (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || sd->u.s.position_transformed )&& + This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) { + if(GL_SUPPORT(EXT_FOG_COORD) && sd->u.s.specular.dwType != WINED3DDECLTYPE_D3DCOLOR) { + FIXME("Implement fog coordinates from %s\n", debug_d3ddecltype(sd->u.s.specular.dwType)); + } + } + if(This->activeContext->num_untracked_materials && sd->u.s.diffuse.dwType != WINED3DDECLTYPE_D3DCOLOR) { + FIXME("Implement diffuse color tracking from %s\n", debug_d3ddecltype(sd->u.s.diffuse.dwType)); + } + } + /* Start drawing in GL */ VTRACE(("glBegin(%x)\n", glPrimType)); glBegin(glPrimType); @@ -486,22 +510,13 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData /* Diffuse -------------------------------- */ if (diffuse) { DWORD *ptrToCoords = (DWORD *)(diffuse + (SkipnStrides * sd->u.s.diffuse.dwStride)); - diffuseColor = ptrToCoords[0]; - VTRACE(("diffuseColor=%lx\n", diffuseColor)); - - glColor4ub(D3DCOLOR_B_R(diffuseColor), - D3DCOLOR_B_G(diffuseColor), - D3DCOLOR_B_B(diffuseColor), - D3DCOLOR_B_A(diffuseColor)); - VTRACE(("glColor4ub: r,g,b,a=%lu,%lu,%lu,%lu\n", - D3DCOLOR_B_R(diffuseColor), - D3DCOLOR_B_G(diffuseColor), - D3DCOLOR_B_B(diffuseColor), - D3DCOLOR_B_A(diffuseColor))); + diffuse_funcs[sd->u.s.diffuse.dwType]((void *) ptrToCoords); if(This->activeContext->num_untracked_materials) { unsigned char i; float color[4]; + + diffuseColor = ptrToCoords[0]; color[0] = D3DCOLOR_B_R(diffuseColor) / 255.0; color[1] = D3DCOLOR_B_G(diffuseColor) / 255.0; color[2] = D3DCOLOR_B_B(diffuseColor) / 255.0; @@ -516,14 +531,13 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData /* Specular ------------------------------- */ if (specular) { DWORD *ptrToCoords = (DWORD *)(specular + (SkipnStrides * sd->u.s.specular.dwStride)); - specularColor = ptrToCoords[0]; - VTRACE(("specularColor=%lx\n", specularColor)); /* special case where the fog density is stored in the specular alpha channel */ if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] && (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || sd->u.s.position.dwType == WINED3DDECLTYPE_FLOAT4 )&& This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) { if(GL_SUPPORT(EXT_FOG_COORD)) { + specularColor = ptrToCoords[0]; GL_EXTCALL(glFogCoordfEXT(specularColor >> 24)); } else { static BOOL warned = FALSE; @@ -535,52 +549,19 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData } } - VTRACE(("glSecondaryColor4ub: r,g,b=%lu,%lu,%lu\n", - D3DCOLOR_B_R(specularColor), - D3DCOLOR_B_G(specularColor), - D3DCOLOR_B_B(specularColor))); - if (GL_SUPPORT(EXT_SECONDARY_COLOR)) { - GL_EXTCALL(glSecondaryColor3ubEXT)( - D3DCOLOR_B_R(specularColor), - D3DCOLOR_B_G(specularColor), - D3DCOLOR_B_B(specularColor)); - } else { - /* Do not worry if specular colour missing and disable request */ - VTRACE(("Specular color extensions not supplied\n")); - } + specular_funcs[sd->u.s.specular.dwType]((void *) ptrToCoords); } /* Normal -------------------------------- */ if (normal != NULL) { float *ptrToCoords = (float *)(normal + (SkipnStrides * sd->u.s.normal.dwStride)); - - VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", ptrToCoords[0], ptrToCoords[1], ptrToCoords[2])); - glNormal3f(ptrToCoords[0], ptrToCoords[1], ptrToCoords[2]); + normal_funcs[sd->u.s.normal.dwType](ptrToCoords); } /* Position -------------------------------- */ if (position) { float *ptrToCoords = (float *)(position + (SkipnStrides * sd->u.s.position.dwStride)); - x = ptrToCoords[0]; - y = ptrToCoords[1]; - z = ptrToCoords[2]; - rhw = 1.0; - VTRACE(("x,y,z=%f,%f,%f\n", x,y,z)); - - /* RHW follows, only if transformed, ie 4 floats were provided */ - if (sd->u.s.position_transformed) { - rhw = ptrToCoords[3]; - VTRACE(("rhw=%f\n", rhw)); - } - - if (1.0f == rhw || ((rhw < eps) && (rhw > -eps))) { - VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z)); - glVertex3f(x, y, z); - } else { - GLfloat w = 1.0 / rhw; - VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw)); - glVertex4f(x*w, y*w, z*w, w); - } + position_funcs[sd->u.s.position.dwType](ptrToCoords); } /* For non indexed mode, step onto next parts */ diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index d26b91dbebb..39868cfdac2 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3232,7 +3232,9 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte checkGLcall("glBindBufferARB"); curVBO = sd->u.s.diffuse.VBO; } - glColorPointer(4, GL_UNSIGNED_BYTE, + + glColorPointer(WINED3D_ATR_SIZE(sd->u.s.diffuse.dwType), + WINED3D_ATR_GLTYPE(sd->u.s.diffuse.dwType), sd->u.s.diffuse.dwStride, sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]); checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); @@ -3257,7 +3259,8 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte checkGLcall("glBindBufferARB"); curVBO = sd->u.s.specular.VBO; } - GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, + GL_EXTCALL(glSecondaryColorPointerEXT)(WINED3D_ATR_SIZE(sd->u.s.specular.dwType), + WINED3D_ATR_GLTYPE(sd->u.s.specular.dwType), sd->u.s.specular.dwStride, sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]); vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)"); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ad8047c7d62..0934080123f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -410,6 +410,13 @@ void primitiveDeclarationConvertToStridedData( DWORD get_flexible_vertex_size(DWORD d3dvtVertexType); +typedef void (*glAttribFunc)(void *data); +typedef void (*glTexAttribFunc)(GLuint unit, void *data); +extern glAttribFunc position_funcs[WINED3DDECLTYPE_UNUSED]; +extern glAttribFunc diffuse_funcs[WINED3DDECLTYPE_UNUSED]; +extern glAttribFunc specular_funcs[WINED3DDECLTYPE_UNUSED]; +extern glAttribFunc normal_funcs[WINED3DDECLTYPE_UNUSED]; + #define eps 1e-8 #define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \