Two-dimensional Array for sphere's vertices

Started by
2 comments, last by Gavin Williams 11 years, 4 months ago
Hi everyone smile.png ?

Im newer of D3D11, and Im doing some simple work for practice.

My 1st question is : I use following code to generate sphere's vertices' position data.

I use Two-dimensional Array to save vertices, but I don't know whether following code vertexData.pSysMem = vertices; correct ?
And will the data in vertex-buffer correct ?

My 2nd question is : I don't know how to compute index of each triangle ?

Following code shows my way to create sphere's vertices' data.

Variable 'stack' like weft, and slice like warp, by them I create sphere with 2 step, each step create half-sphere.

for(int iStack = 0; iStack < stack; iStack++)
{
if( iStack == (stack / 2) )
{
tmp_radius = 0;
height = 0;
}

if( iStack < ((stack - 1) / 2) )
{
double angle = 0.0f;
height = pos.y - radius + tmp_radius;
for(int iSlice = 0; iSlice < (slices * 2); iSlice++)
{
vertices[iStack][iSlice].position.x = pos.x + (float)(cos(angle) * tmp_radius);
vertices[iStack][iSlice].position.y = (float)height;
vertices[iStack][iSlice].position.z = pos.z + (float)(sin(angle) * tmp_radius);
angle += phi;
}
tmp_radius += delta_of_radius;
continue;
}

else
{
double angle = 0;
height = pos.y + radius - tmp_radius;
for(int iSlice = 0; iSlice < (slices * 2); iSlice++)
{
vertices[iStack][iSlice].position.x = pos.x + (float)(cos(angle) * tmp_radius);
vertices[iStack][iSlice].position.y = (float)height;
vertices[iStack][iSlice].position.z = pos.z + (float)(sin(angle) * tmp_radius);
angle += phi;
}
tmp_radius += delta_of_radius;
continue;
}
}
Advertisement
Why use a 2D array for your vertices ? I cannot think of a reason why I would ever need to do that !

Why use a 2D array for your vertices ? I cannot think of a reason why I would ever need to do that !


Ah.2D array I put vertices in, I think it may clearly show a sphere has how many stack, and how many slices ? Do you have some good idea for drawing sphere in D3D11 ? I try 'D3DXCreateSphere', but it needs D3D9 ! : (

I would appreciate.
You should record slices and stacks separately if you need that information. It doesn't need to be intrinsic to the vertex storage.

Here's some C# code for constructing a sphere ...


public Sphere(float radius, int lonSections, int latSections, Vector3 position, Device device11)
{
int primitiveCount = lonSections * (2 + 2 * (latSections - 2));
float deltaLon = (float)(2 * Math.PI / lonSections); // measured from (1,0,0) around the z-axis
float deltaLat = (float)(Math.PI / latSections); // measured from 0 north to 180 south
D3VertexPN_C8UNorm[] vertices = new D3VertexPN_C8UNorm[2 + lonSections * (latSections - 1)]; // sys copy of vertices
// Key verts, at 0 rads longitude
Vector3[] keyVerts = new Vector3[latSections + 1];
for (int ki = 0; ki < latSections + 1; ki++) // keyvert index
{
keyVerts[ki].X = (float)(radius * Math.Sin(deltaLat * ki));
keyVerts[ki].Y = 0;
keyVerts[ki].Z = (float)(radius * Math.Cos(deltaLat * ki));
}
// Rotate keyVerts around axis and apply to vertices[]
vertices[0].Position = keyVerts[0];
vertices[1].Position = keyVerts[keyVerts.Length - 1];
int ci = 2; // cumulative index
for (int loni = 0; loni < lonSections; loni++)
{
for (int lati = 1; lati < latSections; lati++) // dont apply the first and last keyVerts
{
Matrix rotM = Matrix.RotationZ(deltaLon * loni);
Vector3 v = keyVerts[lati];
//v = Vector3.Transform(v, rotM); xna code
Vector4 v4 = Vector3.Transform(v, rotM);
v.X = v4.X; v.Y = v4.Y; v.Z = v4.Z;
vertices[ci].Position = v;
ci++;
}
}
// Generate indices
short[] indices = new short[lonSections * (latSections * 6 - 6)]; // -6 because of the end triangles giving only 3 inds each
IndexCount = indices.Length;
int i = 0;
for (int loni = 0; loni < lonSections; loni++)
{
short lgA = (short)(2 + loni * (latSections - 1)); // longitute ref vert A (top)
short lgB = (short)(2 + loni * (latSections - 1) + latSections - 1); // longitude ref vert B (next along top)
if (loni == lonSections - 1) // join the last division with the first
lgB = 2;
// top triangle
indices[i++] = 0;
indices[i++] = lgA;
indices[i++] = lgB;
// For each quad
for (short mi = 0; mi < latSections - 2; mi++)
{
// upper tri
indices[i++] = (short)(lgA + mi);
indices[i++] = (short)(lgB + 1 + mi);
indices[i++] = (short)(lgB + mi);
// lower tri
indices[i++] = (short)(lgA + mi);
indices[i++] = (short)(lgA + 1 + mi);
indices[i++] = (short)(lgB + 1 + mi);
}
// bottom triangle
indices[i++] = (short)(lgA + latSections - 2);
indices[i++] = 1;
indices[i++] = (short)(lgB + latSections - 2);
}
// Calculate Normals
for (int ni = 0; ni < vertices.Length; ni++)
{
vertices[ni].Normal = vertices[ni].Position;
vertices[ni].Normal.Normalize();
}
// Normalize all normals (even if its done later, it costs nothing to do it now)
for (int vi = 0; vi < vertices.Length; vi++)
vertices[vi].Normal.Normalize();
// Calculate TextCoords - Projection Mapping
//for (int vi = 0; vi < vertices.Length; vi++)
//{
// vertices[vi].TextureCoordinate.X = (vertices[vi].Position.X) / (2f * radius);
// vertices[vi].TextureCoordinate.Y = (vertices[vi].Position.Z) / (2f * radius);
//}
// Assign Colors
for (int vi = 0; vi < vertices.Length; vi++)
vertices[vi].Color = new Byte4(255, 255, 255, 255);

//vb = new VertexBuffer(Game.graphics, typeof(VertexPositionNormalTexture), vertices.Length, BufferUsage.WriteOnly);
//vb.SetData(vertices);
DataStream stream = new DataStream(vertices, true, true);
VertexBuffer = new Buffer(device11, stream, vertices.Length * D3VertexPN_C8UNorm.SizeInBytes, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
stream.Dispose();
//ib = new IndexBuffer(Game.graphics, indices[0].GetType(), indices.Length, BufferUsage.WriteOnly);
//ib.SetData(indices);
stream = new DataStream(indices, true, true);
IndexBuffer = new Buffer(device11, stream, indices.Length * sizeof(ushort), ResourceUsage.Default, BindFlags.IndexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
stream.Dispose();
DataStream data = new DataStream(vertices, true, true);
DataBox dataBox = new DataBox(0, 0, data);
System.Diagnostics.Debug.WriteLine("Sphere.Sphere() ... UpdateSubresource");
device11.ImmediateContext.UpdateSubresource(dataBox, VertexBuffer, 0);
}


I think it's ok, in that I hope i haven't just left it sitting around in a broken state. But it will give you some ideas anyway.

This topic is closed to new replies.

Advertisement