Recommended Posts

I posted a couple days ago about texture mapping a sphere with DX9 in C#, but I am unable to view past posts (the site just hangs) in this forum and it looks like something may gone wrong with it, since it doesn''t show up in the forum search.
Any way, I''m almost done my Perlin Noise demo - which creates some really neat effects - but I need to be able to take the texture and map it on to a sphere. The sooner I figure out how to do this, the sooner I can release something of value to the community (so maybe helping me figure out what I''m doing wrong will benefit other people too).
Onto the code...
The basic problem I''m having is that the sphere returned by the Mesh.Sphere function doesn''t seem to have texture coords. This is a known issue with the equivalent unmanaged C++ function (D3DX::CreateSphereMesh). I have found a workaround that works in C++ from elsewhere on this forum, but now I need to convert it into C#. Problem is, I''m having trouble mapping the unmanaged C++ DX functions to their C# counterparts - partly because the managed DX docs are so poor, partly because I''m a noob who has never used D3D before. Below is my attempt to create a function that returns a sphere mesh with texture coords. At the moment it doesn''t even compile. Below that is the C++ version of the function that I''m using as a template. It''s very frustrating because I know it''s just a one or two line fix. Please help!
private Mesh CreateMappedSphere(Device dev, float radius, int slices, int stacks)
{
Mesh sphere;
Mesh texSphere;
sphere = Mesh.Sphere(dev, radius, slices, stacks);
MeshFlags flags;
flags = sphere.Options.Use32Bit ? MeshFlags.Use32Bit : 0;
// if(sphere.VertexFormat & VertexFormats.Texture0 == 0)
// {
texSphere = sphere.Clone(flags | MeshFlags.Managed, sphere.VertexFormat | VertexFormats.Texture0, dev);
sphere.Dispose();
sphere = texSphere;
// } else {
// return sphere;}
CustomVertex.PositionNormalTextured[] verts =
(CustomVertex.PositionNormalTextured[])sphere.LockVertexBuffer(CustomVertex.PositionNormalTexture,LockFlags.None, 0);
int numVerts = sphere.NumberVertices;
for(int i = 0; i < numVerts; i++)
{
verts.Tu = Math.Asin(verts[i].Nx)/3.1415627 +0.5f;
verts[i].Tv = Math.Asin(verts[i].Ny)/3.1415626 +0.5f;
}
sphere.UnlockVertexBuffer();
return sphere;
}
That''s what my attempt looks like. It doesn''t work. Now here is code that does work. I think most of my problem centers around the functions involving the vertex buffer. Vertex buffers are new to me, since I never had to explicitely use them in OpenGL.
LPD3DXMESH CreateMappedSphere(LPDIRECT3DDEVICE8 pDev,float fRad,UINT slices,UINT stacks)
{
// create the sphere
LPD3DXMESH mesh;
if (FAILED(D3DXCreateSphere(pDev,fRad,slices,stacks,&mesh,NULL)))
return NULL;
// create a copy of the mesh with texture coordinates,
// since the D3DX function doesn''t include them
LPD3DXMESH texMesh;
if (FAILED(mesh->CloneMeshFVF(D3DXMESH_SYSTEMMEM,FVF_VERTEX,pDev,&texMesh)))
// failed, return un-textured mesh
return mesh;
// finished with the original mesh, release it
mesh->Release();
// lock the vertex buffer
LPVERTEX pVerts;
if (SUCCEEDED(texMesh->LockVertexBuffer(0,(BYTE **) &pVerts)))
{
// get vertex count
int numVerts=texMesh->GetNumVertices();
// loop through the vertices
for (int i=0;itu=asinf(pVerts->norm.x)/D3DX_PI+0.5f;
pVerts->tv=asinf(pVerts->norm.y)/D3DX_PI+0.5f;
// go to next vertex
pVerts++;
}
// unlock the vertex buffer
texMesh->UnlockVertexBuffer();
}
// return pointer to caller
return texMesh;
}
Thank you so much!
----------------------------------------
Let be be finale of seem, seems to me.
----------------------------------------
Coding:
http://www.stanford.edu/~jjshed/coding
Miscellany:
http://www.stanford.edu/~jjshed

Share this post

Link to post

Share on other sites

Hmmm... It does compile, but it crashed when I try to use it. I get "NullArguement Not Accepted" on the VertexBuffer locking step. I poked around with the debugger a little bit and it turns out that the BaseMesh.VertexBuffer.length field of the "sphere" variable at that point is equal to zero. It seems to me that if the sphere was cloned properly this would be a non-zero value. Is there something wrong with the way I''m cloning the sphere? I just gathered from the docs that that''s how you add more fields to the vertex information. I basically am looking for a C# substitute for the mesh->CloneMeshFVF function. Please help - I feel I''m very close, and having to deal with this low level stuff to just draw a simple sphere is very frustrating.