wined3d: Fixed function vertex attribute types are flexible.
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 764b5fa..dd38d55 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -5437,6 +5437,246 @@
}
}
+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 @@
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 7badb4c..70a21a0 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -143,6 +143,12 @@
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 @@
}
}
-#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 @@
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 59a952f..aa7dd62 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -302,8 +302,6 @@
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 @@
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 @@
/* 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 @@
/* 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 @@
}
}
- 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 d26b91d..39868cf 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -3232,7 +3232,9 @@
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 @@
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 ad8047c..0934080 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -410,6 +410,13 @@
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) \