From 7294b417e3af9df28a08b06554140f3a91defba3 Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Wed, 14 Mar 2012 09:06:59 +0100 Subject: [PATCH] d3drm: Complete Load method by adding normals indices and terminating null DWORD to faces data + tests. --- dlls/d3drm/meshbuilder.c | 84 ++++++++++++++++++++++++++++++++----- dlls/d3drm/tests/d3drm.c | 91 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 164 insertions(+), 11 deletions(-) diff --git a/dlls/d3drm/meshbuilder.c b/dlls/d3drm/meshbuilder.c index 0cb3ea7597a..d8d9ff21490 100644 --- a/dlls/d3drm/meshbuilder.c +++ b/dlls/d3drm/meshbuilder.c @@ -1,7 +1,7 @@ /* * Implementation of IDirect3DRMMeshBuilder2 Interface * - * Copyright 2010 Christian Costa + * Copyright 2010, 2012 Christian Costa * Copyright 2011 André Hentschel * * This library is free software; you can redistribute it and/or @@ -734,7 +734,7 @@ static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_GetVertices(IDirect3DRMMeshBui if (face_data_size) *face_data_size = This->face_data_size; if (face_data && This->face_data_size) - memcpy(face_data, This->pFaceData, This->face_data_size); + memcpy(face_data, This->pFaceData, This->face_data_size * sizeof(DWORD)); return D3DRM_OK; } @@ -1039,8 +1039,16 @@ static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Load(IDirect3DRMMeshBuilder3* LPBYTE ptr; HRESULT hr; HRESULT ret = D3DRMERR_BADOBJECT; + DWORD* faces_vertex_idx_data = NULL; + DWORD* faces_vertex_idx_ptr; + DWORD faces_vertex_idx_size; + DWORD* faces_normal_idx_data = NULL; + DWORD* faces_normal_idx_ptr = NULL; + DWORD* faces_data_ptr; + DWORD faces_data_size = 0; + DWORD i; - FIXME("(%p)->(%p,%p,%x,%p,%p): partial stub\n", This, filename, name, loadflags, cb, arg); + TRACE("(%p)->(%p,%p,%x,%p,%p)\n", This, filename, name, loadflags, cb, arg); /* First free allocated buffers of previous mesh data */ HeapFree(GetProcessHeap(), 0, This->pVertices); @@ -1131,15 +1139,20 @@ static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Load(IDirect3DRMMeshBuilder3* This->nb_vertices = *(DWORD*)ptr; This->nb_faces = *(DWORD*)(ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR)); - This->face_data_size = size - sizeof(DWORD) - This->nb_vertices * sizeof(D3DVECTOR) - sizeof(DWORD); + faces_vertex_idx_size = size - sizeof(DWORD) - This->nb_vertices * sizeof(D3DVECTOR) - sizeof(DWORD); + faces_vertex_idx_ptr = (DWORD*)(ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR) + sizeof(DWORD)); - TRACE("Mesh: nb_vertices = %d, nb_faces = %d, face_data_size = %d\n", This->nb_vertices, This->nb_faces, This->face_data_size); + TRACE("Mesh: nb_vertices = %d, nb_faces = %d, faces_vertex_idx_size = %d\n", This->nb_vertices, This->nb_faces, faces_vertex_idx_size); This->pVertices = HeapAlloc(GetProcessHeap(), 0, This->nb_vertices * sizeof(D3DVECTOR)); memcpy(This->pVertices, ptr + sizeof(DWORD), This->nb_vertices * sizeof(D3DVECTOR)); - This->pFaceData = HeapAlloc(GetProcessHeap(), 0, This->face_data_size); - memcpy(This->pFaceData, ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR) + sizeof(DWORD), This->face_data_size); + faces_vertex_idx_ptr = faces_vertex_idx_data = HeapAlloc(GetProcessHeap(), 0, faces_vertex_idx_size); + memcpy(faces_vertex_idx_data, ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR) + sizeof(DWORD), faces_vertex_idx_size); + + /* Each vertex index will have its normal index counterpart so just allocate twice the size */ + This->pFaceData = HeapAlloc(GetProcessHeap(), 0, faces_vertex_idx_size*2); + faces_data_ptr = (DWORD*)This->pFaceData; while (1) { @@ -1165,19 +1178,26 @@ static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Load(IDirect3DRMMeshBuilder3* if (IsEqualGUID(pGuid, &TID_D3DRMMeshNormals)) { - DWORD tmp; + DWORD nb_faces_normals; + DWORD faces_normal_idx_size; hr = IDirectXFileData_GetData(pData2, NULL, &size, (void**)&ptr); if (hr != DXFILE_OK) goto end; This->nb_normals = *(DWORD*)ptr; - tmp = *(DWORD*)(ptr + sizeof(DWORD) + This->nb_normals * sizeof(D3DVECTOR)); + nb_faces_normals = *(DWORD*)(ptr + sizeof(DWORD) + This->nb_normals * sizeof(D3DVECTOR)); - TRACE("MeshNormals: nb_normals = %d, nb_faces_normals = %d\n", This->nb_normals, tmp); + TRACE("MeshNormals: nb_normals = %d, nb_faces_normals = %d\n", This->nb_normals, nb_faces_normals); + if (nb_faces_normals != This->nb_faces) + WARN("nb_face_normals (%d) != nb_faces (%d)\n", nb_faces_normals, This->nb_normals); This->pNormals = HeapAlloc(GetProcessHeap(), 0, This->nb_normals * sizeof(D3DVECTOR)); memcpy(This->pNormals, ptr + sizeof(DWORD), This->nb_normals * sizeof(D3DVECTOR)); + + faces_normal_idx_size = size - (2*sizeof(DWORD) + This->nb_normals * sizeof(D3DVECTOR)); + faces_normal_idx_ptr = faces_normal_idx_data = HeapAlloc(GetProcessHeap(), 0, faces_normal_idx_size); + memcpy(faces_normal_idx_data, ptr + sizeof(DWORD) + This->nb_normals * sizeof(D3DVECTOR) + sizeof(DWORD), faces_normal_idx_size); } else if (IsEqualGUID(pGuid, &TID_D3DRMMeshTextureCoords)) { @@ -1206,9 +1226,53 @@ static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Load(IDirect3DRMMeshBuilder3* pData2 = NULL; } + for (i = 0; i < This->nb_faces; i++) + { + DWORD j; + DWORD nb_face_indexes; + + if (faces_vertex_idx_size < sizeof(DWORD)) + WARN("Not enough data to read number of indices of face %d\n", i); + + nb_face_indexes = *(faces_data_ptr + faces_data_size++) = *(faces_vertex_idx_ptr++); + faces_vertex_idx_size--; + if (faces_normal_idx_data && (*(faces_normal_idx_ptr++) != nb_face_indexes)) + WARN("Faces indices number mismatch\n"); + + if (faces_vertex_idx_size < (nb_face_indexes * sizeof(DWORD))) + WARN("Not enough data to read all indices of face %d\n", i); + + for (j = 0; j < nb_face_indexes; j++) + { + /* Copy vertex index */ + *(faces_data_ptr + faces_data_size++) = *(faces_vertex_idx_ptr++); + /* Copy normal index */ + if (faces_normal_idx_data) + { + /* Read from x file */ + *(faces_data_ptr + faces_data_size++) = *(faces_normal_idx_ptr++); + } + else + { + FIXME("No normal available, generate a fake normal index\n"); + /* Must be generated, put 0 for now */ + *(faces_data_ptr + faces_data_size++) = 0; + } + } + faces_vertex_idx_size -= nb_face_indexes; + } + + /* Last DWORD must be 0 */ + *(faces_data_ptr + faces_data_size++) = 0; + + /* Set size (in number of DWORD) of all faces data */ + This->face_data_size = faces_data_size; + ret = D3DRM_OK; end: + HeapFree(GetProcessHeap(), 0, faces_normal_idx_data); + HeapFree(GetProcessHeap(), 0, faces_vertex_idx_data); if (pData2) IDirectXFileData_Release(pData2); if (pData) diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index e68d968fb75..1732db6af3f 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -96,6 +96,44 @@ static char data_ok[] = "3; 3, 1, 2;;\n" "}\n"; +static char data_full[] = +"xof 0302txt 0064\n" +"Header { 1; 0; 1; }\n" +"Mesh {\n" +" 3;\n" +" 0.1; 0.2; 0.3;,\n" +" 0.4; 0.5; 0.6;,\n" +" 0.7; 0.8; 0.9;;\n" +" 1;\n" +" 3; 0, 1, 2;;\n" +" MeshMaterialList {\n" +" 1; 1; 0;\n" +" Material {\n" +" 0.0; 1.0; 0.0; 1.0;;\n" +" 30.0;\n" +" 1.0; 0.0; 0.0;;\n" +" 0.5; 0.5; 0.5;;\n" +" TextureFileName {\n" +" \"Texture.bmp\";\n" +" }\n" +" }\n" +" }\n" +" MeshNormals {\n" +" 3;\n" +" 1.1; 1.2; 1.3;,\n" +" 1.4; 1.5; 1.6;,\n" +" 1.7; 1.8; 1.9;;\n" +" 1;" +" 3; 0, 1, 2;;\n" +" }\n" +" MeshTextureCoords {\n" +" 3;\n" +" 0.13; 0.17;,\n" +" 0.23; 0.27;,\n" +" 0.33; 0.37;;\n" +" }\n" +"}\n"; + static void test_MeshBuilder(void) { HRESULT hr; @@ -105,6 +143,9 @@ static void test_MeshBuilder(void) int val; DWORD val1, val2, val3; D3DVALUE valu, valv; + D3DVECTOR v[3]; + D3DVECTOR n[3]; + DWORD f[8]; hr = pDirect3DRMCreate(&pD3DRM); ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr); @@ -137,7 +178,7 @@ static void test_MeshBuilder(void) ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr); ok(val1 == 4, "Wrong number of vertices %d (must be 4)\n", val1); todo_wine ok(val2 == 4, "Wrong number of normals %d (must be 4)\n", val2); - todo_wine ok(val3 == 22, "Wrong number of face data bytes %d (must be 22)\n", val3); + ok(val3 == 22, "Wrong number of face data bytes %d (must be 22)\n", val3); valu = 1.23f; valv = 3.21f; @@ -160,6 +201,54 @@ static void test_MeshBuilder(void) IDirect3DRMMeshBuilder_Release(pMeshBuilder); + hr = IDirect3DRM_CreateMeshBuilder(pD3DRM, &pMeshBuilder); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface (hr = %x)\n", hr); + + info.lpMemory = data_full; + info.dSize = strlen(data_full); + hr = IDirect3DRMMeshBuilder_Load(pMeshBuilder, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL); + ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr); + + val = IDirect3DRMMeshBuilder_GetVertexCount(pMeshBuilder); + ok(val == 3, "Wrong number of vertices %d (must be 3)\n", val); + + val = IDirect3DRMMeshBuilder_GetFaceCount(pMeshBuilder); + ok(val == 1, "Wrong number of faces %d (must be 1)\n", val); + + hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f); + ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr); + ok(val1 == 3, "Wrong number of vertices %d (must be 3)\n", val1); + ok(val2 == 3, "Wrong number of normals %d (must be 3)\n", val2); + ok(val3 == 8, "Wrong number of face data bytes %d (must be 8)\n", val3); + ok(v[0].x == 0.1f, "Wrong component v[0].x = %f (expected 0.1)\n", v[0].x); + ok(v[0].y == 0.2f, "Wrong component v[0].y = %f (expected 0.2)\n", v[0].y); + ok(v[0].z == 0.3f, "Wrong component v[0].z = %f (expected 0.3)\n", v[0].z); + ok(v[1].x == 0.4f, "Wrong component v[1].x = %f (expected 0.4)\n", v[1].x); + ok(v[1].y == 0.5f, "Wrong component v[1].y = %f (expected 0.5)\n", v[1].y); + ok(v[1].z == 0.6f, "Wrong component v[1].z = %f (expected 0.6)\n", v[1].z); + ok(v[2].x == 0.7f, "Wrong component v[2].x = %f (expected 0.7)\n", v[2].x); + ok(v[2].y == 0.8f, "Wrong component v[2].y = %f (expected 0.8)\n", v[2].y); + ok(v[2].z == 0.9f, "Wrong component v[2].z = %f (expected 0.9)\n", v[2].z); + ok(n[0].x == 1.1f, "Wrong component n[0].x = %f (expected 1.1)\n", n[0].x); + ok(n[0].y == 1.2f, "Wrong component n[0].y = %f (expected 1.2)\n", n[0].y); + ok(n[0].z == 1.3f, "Wrong component n[0].z = %f (expected 1.3)\n", n[0].z); + ok(n[1].x == 1.4f, "Wrong component n[1].x = %f (expected 1.4)\n", n[1].x); + ok(n[1].y == 1.5f, "Wrong component n[1].y = %f (expected 1.5)\n", n[1].y); + ok(n[1].z == 1.6f, "Wrong component n[1].z = %f (expected 1.6)\n", n[1].z); + ok(n[2].x == 1.7f, "Wrong component n[2].x = %f (expected 1.7)\n", n[2].x); + ok(n[2].y == 1.8f, "Wrong component n[2].y = %f (expected 1.8)\n", n[2].y); + ok(n[2].z == 1.9f, "Wrong component n[2].z = %f (expected 1.9)\n", n[2].z); + ok(f[0] == 3 , "Wrong component f[0] = %d (expected 3)\n", f[0]); + ok(f[1] == 0 , "Wrong component f[1] = %d (expected 0)\n", f[1]); + ok(f[2] == 0 , "Wrong component f[2] = %d (expected 0)\n", f[2]); + ok(f[3] == 1 , "Wrong component f[3] = %d (expected 1)\n", f[3]); + ok(f[4] == 1 , "Wrong component f[4] = %d (expected 1)\n", f[4]); + ok(f[5] == 2 , "Wrong component f[5] = %d (expected 2)\n", f[5]); + ok(f[6] == 2 , "Wrong component f[6] = %d (expected 2)\n", f[6]); + ok(f[7] == 0 , "Wrong component f[7] = %d (expected 0)\n", f[7]); + + IDirect3DRMMeshBuilder_Release(pMeshBuilder); + IDirect3DRM_Release(pD3DRM); }