d3dx9_36: Implement D3DXCreateCylinder.
This commit is contained in:
parent
a7ded9a67d
commit
09af2a2bf9
|
@ -1112,7 +1112,7 @@ static BOOL compute_sincos_table(struct sincos_table *sincos_table, float angle_
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static WORD sphere_vertex(UINT slices, int slice, int stack)
|
||||
static WORD vertex_index(UINT slices, int slice, int stack)
|
||||
{
|
||||
return stack*slices+slice+1;
|
||||
}
|
||||
|
@ -1225,14 +1225,14 @@ HRESULT WINAPI D3DXCreateSphere(LPDIRECT3DDEVICE9 device, FLOAT radius, UINT sli
|
|||
else
|
||||
{
|
||||
/* stacks in between top and bottom are quad strips */
|
||||
faces[face][0] = sphere_vertex(slices, slice-1, stack-1);
|
||||
faces[face][1] = sphere_vertex(slices, slice, stack-1);
|
||||
faces[face][2] = sphere_vertex(slices, slice-1, stack);
|
||||
faces[face][0] = vertex_index(slices, slice-1, stack-1);
|
||||
faces[face][1] = vertex_index(slices, slice, stack-1);
|
||||
faces[face][2] = vertex_index(slices, slice-1, stack);
|
||||
face++;
|
||||
|
||||
faces[face][0] = sphere_vertex(slices, slice, stack-1);
|
||||
faces[face][1] = sphere_vertex(slices, slice, stack);
|
||||
faces[face][2] = sphere_vertex(slices, slice-1, stack);
|
||||
faces[face][0] = vertex_index(slices, slice, stack-1);
|
||||
faces[face][1] = vertex_index(slices, slice, stack);
|
||||
faces[face][2] = vertex_index(slices, slice-1, stack);
|
||||
face++;
|
||||
}
|
||||
}
|
||||
|
@ -1249,14 +1249,14 @@ HRESULT WINAPI D3DXCreateSphere(LPDIRECT3DDEVICE9 device, FLOAT radius, UINT sli
|
|||
}
|
||||
else
|
||||
{
|
||||
faces[face][0] = sphere_vertex(slices, slice-1, stack-1);
|
||||
faces[face][1] = sphere_vertex(slices, 0, stack-1);
|
||||
faces[face][2] = sphere_vertex(slices, slice-1, stack);
|
||||
faces[face][0] = vertex_index(slices, slice-1, stack-1);
|
||||
faces[face][1] = vertex_index(slices, 0, stack-1);
|
||||
faces[face][2] = vertex_index(slices, slice-1, stack);
|
||||
face++;
|
||||
|
||||
faces[face][0] = sphere_vertex(slices, 0, stack-1);
|
||||
faces[face][1] = sphere_vertex(slices, 0, stack);
|
||||
faces[face][2] = sphere_vertex(slices, slice-1, stack);
|
||||
faces[face][0] = vertex_index(slices, 0, stack-1);
|
||||
faces[face][1] = vertex_index(slices, 0, stack);
|
||||
faces[face][2] = vertex_index(slices, slice-1, stack);
|
||||
face++;
|
||||
}
|
||||
}
|
||||
|
@ -1271,14 +1271,14 @@ HRESULT WINAPI D3DXCreateSphere(LPDIRECT3DDEVICE9 device, FLOAT radius, UINT sli
|
|||
/* bottom stack is triangle fan */
|
||||
for (slice = 1; slice < slices; slice++)
|
||||
{
|
||||
faces[face][0] = sphere_vertex(slices, slice-1, stack-1);
|
||||
faces[face][1] = sphere_vertex(slices, slice, stack-1);
|
||||
faces[face][0] = vertex_index(slices, slice-1, stack-1);
|
||||
faces[face][1] = vertex_index(slices, slice, stack-1);
|
||||
faces[face][2] = vertex;
|
||||
face++;
|
||||
}
|
||||
|
||||
faces[face][0] = sphere_vertex(slices, slice-1, stack-1);
|
||||
faces[face][1] = sphere_vertex(slices, 0, stack-1);
|
||||
faces[face][0] = vertex_index(slices, slice-1, stack-1);
|
||||
faces[face][1] = vertex_index(slices, 0, stack-1);
|
||||
faces[face][2] = vertex;
|
||||
|
||||
free_sincos_table(&phi);
|
||||
|
@ -1292,9 +1292,188 @@ HRESULT WINAPI D3DXCreateSphere(LPDIRECT3DDEVICE9 device, FLOAT radius, UINT sli
|
|||
HRESULT WINAPI D3DXCreateCylinder(LPDIRECT3DDEVICE9 device, FLOAT radius1, FLOAT radius2, FLOAT length, UINT slices,
|
||||
UINT stacks, LPD3DXMESH* mesh, LPD3DXBUFFER* adjacency)
|
||||
{
|
||||
FIXME("(%p, %f, %f, %f, %u, %u, %p, %p): stub\n", device, radius1, radius2, length, slices, stacks, mesh, adjacency);
|
||||
DWORD number_of_vertices, number_of_faces;
|
||||
HRESULT hr;
|
||||
ID3DXMesh *cylinder;
|
||||
struct vertex *vertices;
|
||||
face *faces;
|
||||
float theta_step, theta_start;
|
||||
struct sincos_table theta;
|
||||
float delta_radius, radius, radius_step;
|
||||
float z, z_step, z_normal;
|
||||
DWORD vertex, face;
|
||||
int slice, stack;
|
||||
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p, %f, %f, %f, %u, %u, %p, %p)\n", device, radius1, radius2, length, slices, stacks, mesh, adjacency);
|
||||
|
||||
if (device == NULL || radius1 < 0.0f || radius2 < 0.0f || length < 0.0f || slices < 2 || stacks < 1 || mesh == NULL)
|
||||
{
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
if (adjacency)
|
||||
{
|
||||
FIXME("Case of adjacency != NULL not implemented.\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
number_of_vertices = 2 + (slices * (3 + stacks));
|
||||
number_of_faces = 2 * slices + stacks * (2 * slices);
|
||||
|
||||
hr = D3DXCreateMeshFVF(number_of_faces, number_of_vertices, D3DXMESH_MANAGED,
|
||||
D3DFVF_XYZ | D3DFVF_NORMAL, device, &cylinder);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = cylinder->lpVtbl->LockVertexBuffer(cylinder, D3DLOCK_DISCARD, (LPVOID *)&vertices);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
cylinder->lpVtbl->Release(cylinder);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = cylinder->lpVtbl->LockIndexBuffer(cylinder, D3DLOCK_DISCARD, (LPVOID *)&faces);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
cylinder->lpVtbl->UnlockVertexBuffer(cylinder);
|
||||
cylinder->lpVtbl->Release(cylinder);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* theta = angle on xy plane wrt x axis */
|
||||
theta_step = -2 * M_PI / slices;
|
||||
theta_start = M_PI / 2;
|
||||
|
||||
if (!compute_sincos_table(&theta, theta_start, theta_step, slices))
|
||||
{
|
||||
cylinder->lpVtbl->UnlockIndexBuffer(cylinder);
|
||||
cylinder->lpVtbl->UnlockVertexBuffer(cylinder);
|
||||
cylinder->lpVtbl->Release(cylinder);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
vertex = 0;
|
||||
face = 0;
|
||||
stack = 0;
|
||||
|
||||
delta_radius = radius1 - radius2;
|
||||
radius = radius1;
|
||||
radius_step = delta_radius / stacks;
|
||||
|
||||
z = -length / 2;
|
||||
z_step = length / stacks;
|
||||
z_normal = delta_radius / length;
|
||||
if (isnan(z_normal))
|
||||
{
|
||||
z_normal = 0.0f;
|
||||
}
|
||||
|
||||
vertices[vertex].normal.x = 0.0f;
|
||||
vertices[vertex].normal.y = 0.0f;
|
||||
vertices[vertex].normal.z = -1.0f;
|
||||
vertices[vertex].position.x = 0.0f;
|
||||
vertices[vertex].position.y = 0.0f;
|
||||
vertices[vertex++].position.z = z;
|
||||
|
||||
for (slice = 0; slice < slices; slice++, vertex++)
|
||||
{
|
||||
vertices[vertex].normal.x = 0.0f;
|
||||
vertices[vertex].normal.y = 0.0f;
|
||||
vertices[vertex].normal.z = -1.0f;
|
||||
vertices[vertex].position.x = radius * theta.cos[slice];
|
||||
vertices[vertex].position.y = radius * theta.sin[slice];
|
||||
vertices[vertex].position.z = z;
|
||||
|
||||
if (slice > 0)
|
||||
{
|
||||
faces[face][0] = 0;
|
||||
faces[face][1] = slice;
|
||||
faces[face++][2] = slice + 1;
|
||||
}
|
||||
}
|
||||
|
||||
faces[face][0] = 0;
|
||||
faces[face][1] = slice;
|
||||
faces[face++][2] = 1;
|
||||
|
||||
for (stack = 1; stack <= stacks+1; stack++)
|
||||
{
|
||||
for (slice = 0; slice < slices; slice++, vertex++)
|
||||
{
|
||||
vertices[vertex].normal.x = theta.cos[slice];
|
||||
vertices[vertex].normal.y = theta.sin[slice];
|
||||
vertices[vertex].normal.z = z_normal;
|
||||
D3DXVec3Normalize(&vertices[vertex].normal, &vertices[vertex].normal);
|
||||
vertices[vertex].position.x = radius * theta.cos[slice];
|
||||
vertices[vertex].position.y = radius * theta.sin[slice];
|
||||
vertices[vertex].position.z = z;
|
||||
|
||||
if (stack > 1 && slice > 0)
|
||||
{
|
||||
faces[face][0] = vertex_index(slices, slice-1, stack-1);
|
||||
faces[face][1] = vertex_index(slices, slice-1, stack);
|
||||
faces[face++][2] = vertex_index(slices, slice, stack-1);
|
||||
|
||||
faces[face][0] = vertex_index(slices, slice, stack-1);
|
||||
faces[face][1] = vertex_index(slices, slice-1, stack);
|
||||
faces[face++][2] = vertex_index(slices, slice, stack);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack > 1)
|
||||
{
|
||||
faces[face][0] = vertex_index(slices, slice-1, stack-1);
|
||||
faces[face][1] = vertex_index(slices, slice-1, stack);
|
||||
faces[face++][2] = vertex_index(slices, 0, stack-1);
|
||||
|
||||
faces[face][0] = vertex_index(slices, 0, stack-1);
|
||||
faces[face][1] = vertex_index(slices, slice-1, stack);
|
||||
faces[face++][2] = vertex_index(slices, 0, stack);
|
||||
}
|
||||
|
||||
if (stack < stacks + 1)
|
||||
{
|
||||
z += z_step;
|
||||
radius -= radius_step;
|
||||
}
|
||||
}
|
||||
|
||||
for (slice = 0; slice < slices; slice++, vertex++)
|
||||
{
|
||||
vertices[vertex].normal.x = 0.0f;
|
||||
vertices[vertex].normal.y = 0.0f;
|
||||
vertices[vertex].normal.z = 1.0f;
|
||||
vertices[vertex].position.x = radius * theta.cos[slice];
|
||||
vertices[vertex].position.y = radius * theta.sin[slice];
|
||||
vertices[vertex].position.z = z;
|
||||
|
||||
if (slice > 0)
|
||||
{
|
||||
faces[face][0] = vertex_index(slices, slice-1, stack);
|
||||
faces[face][1] = number_of_vertices - 1;
|
||||
faces[face++][2] = vertex_index(slices, slice, stack);
|
||||
}
|
||||
}
|
||||
|
||||
vertices[vertex].position.x = 0.0f;
|
||||
vertices[vertex].position.y = 0.0f;
|
||||
vertices[vertex].position.z = z;
|
||||
vertices[vertex].normal.x = 0.0f;
|
||||
vertices[vertex].normal.y = 0.0f;
|
||||
vertices[vertex].normal.z = 1.0f;
|
||||
|
||||
faces[face][0] = vertex_index(slices, slice-1, stack);
|
||||
faces[face][1] = number_of_vertices - 1;
|
||||
faces[face][2] = vertex_index(slices, 0, stack);
|
||||
|
||||
free_sincos_table(&theta);
|
||||
cylinder->lpVtbl->UnlockIndexBuffer(cylinder);
|
||||
cylinder->lpVtbl->UnlockVertexBuffer(cylinder);
|
||||
*mesh = cylinder;
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI D3DXCreateTeapot(LPDIRECT3DDEVICE9 device, LPD3DXMESH *mesh, LPD3DXBUFFER* adjacency)
|
||||
|
|
|
@ -1788,7 +1788,7 @@ static void test_cylinder(IDirect3DDevice9 *device, FLOAT radius1, FLOAT radius2
|
|||
char name[256];
|
||||
|
||||
hr = D3DXCreateCylinder(device, radius1, radius2, length, slices, stacks, &cylinder, NULL);
|
||||
todo_wine ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
|
||||
ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
|
||||
if (hr != D3D_OK)
|
||||
{
|
||||
skip("Couldn't create cylinder\n");
|
||||
|
@ -1822,10 +1822,10 @@ static void D3DXCreateCylinderTest(void)
|
|||
ID3DXMesh* cylinder = NULL;
|
||||
|
||||
hr = D3DXCreateCylinder(NULL, 0.0f, 0.0f, 0.0f, 0, 0, NULL, NULL);
|
||||
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
|
||||
hr = D3DXCreateCylinder(NULL, 1.0f, 1.0f, 1.0f, 2, 1, &cylinder, NULL);
|
||||
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
|
||||
wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
|
||||
d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
|
@ -1854,10 +1854,10 @@ static void D3DXCreateCylinderTest(void)
|
|||
}
|
||||
|
||||
hr = D3DXCreateCylinder(device, -0.1f, 1.0f, 1.0f, 2, 1, &cylinder, NULL);
|
||||
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
|
||||
hr = D3DXCreateCylinder(device, 0.0f, 1.0f, 1.0f, 2, 1, &cylinder, NULL);
|
||||
todo_wine ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n",hr);
|
||||
ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n",hr);
|
||||
|
||||
if (SUCCEEDED(hr) && cylinder)
|
||||
{
|
||||
|
@ -1865,10 +1865,10 @@ static void D3DXCreateCylinderTest(void)
|
|||
}
|
||||
|
||||
hr = D3DXCreateCylinder(device, 1.0f, -0.1f, 1.0f, 2, 1, &cylinder, NULL);
|
||||
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
|
||||
hr = D3DXCreateCylinder(device, 1.0f, 0.0f, 1.0f, 2, 1, &cylinder, NULL);
|
||||
todo_wine ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n",hr);
|
||||
ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n",hr);
|
||||
|
||||
if (SUCCEEDED(hr) && cylinder)
|
||||
{
|
||||
|
@ -1876,11 +1876,11 @@ static void D3DXCreateCylinderTest(void)
|
|||
}
|
||||
|
||||
hr = D3DXCreateCylinder(device, 1.0f, 1.0f, -0.1f, 2, 1, &cylinder, NULL);
|
||||
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
|
||||
/* Test with length == 0.0f succeeds */
|
||||
hr = D3DXCreateCylinder(device, 1.0f, 1.0f, 0.0f, 2, 1, &cylinder, NULL);
|
||||
todo_wine ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n",hr);
|
||||
ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n",hr);
|
||||
|
||||
if (SUCCEEDED(hr) && cylinder)
|
||||
{
|
||||
|
@ -1888,13 +1888,13 @@ static void D3DXCreateCylinderTest(void)
|
|||
}
|
||||
|
||||
hr = D3DXCreateCylinder(device, 1.0f, 1.0f, 1.0f, 1, 1, &cylinder, NULL);
|
||||
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
|
||||
hr = D3DXCreateCylinder(device, 1.0f, 1.0f, 1.0f, 2, 0, &cylinder, NULL);
|
||||
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
|
||||
hr = D3DXCreateCylinder(device, 1.0f, 1.0f, 1.0f, 2, 1, NULL, NULL);
|
||||
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
|
||||
|
||||
test_cylinder(device, 0.0f, 0.0f, 0.0f, 2, 1);
|
||||
test_cylinder(device, 1.0f, 1.0f, 1.0f, 2, 1);
|
||||
|
|
Loading…
Reference in New Issue