Sign in to follow this  

Algorithmically generating a sphere in DX9

This topic is 4866 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I posted my code in the beginner forum and I was wondering if anybody here would also be of assistance. I have been going through the tutorials that came with the SDK and I've been trying to approximate a sphere based on the cylinder algorithm given in the lighting tutorial. However, all I get is a shape that resembles a Hershey's kiss. If anyone has a better method or any suggestions based on my code:
FLOAT Y = 1.0f;
	FLOAT Y2 = 0.0f;
	Y2 = (FLOAT)(Y - 0.04);
	DWORD n = 0;
    for( DWORD i=1; i<26; i++ )
    {
		if( i>=13 )
		{ 
			cylinderSize = i - n;
			n = n + 2;
		}
		else 
		{
			
			cylinderSize = i;
			
		}

		if(i>=2)
		{
			Y = Y2;
			Y2 = (FLOAT)(Y - 0.04);
		}

		for( DWORD  j=0; j<50; j++)
		{
			FLOAT theta = (2*D3DX_PI*j)/(50-1);
			
				pVertices[2*j+((i-1)*48)].position = D3DXVECTOR3( cylinderSize*(sinf(theta)/13), Y, cylinderSize*(cosf(theta)/13) );
				
				pVertices[2*j+((i-1)*49)].position = D3DXVECTOR3( cylinderSize*(sinf(theta)/13), Y2, cylinderSize*(cosf(theta)/13) );
				
			
		}
		
		
	}
I would greatly appreciated it. Someone has already suggested that my problem is that I'm linearly increasing and decreasing the radius of each cylinder and he/she suggested that I take the square root of the normalized cylinder radius. Is this the best way and what does normalized mean exactly? Thanx!

Share this post


Link to post
Share on other sites
Something like


for (real a = 0; a < x width; a += x step)
for (real b = 0; b < y width; b += y step)
point(a, b, sqrt(abs(r^2 - x^2 - y^2)), point(a, b, -sqrt(abs(r^2 - x^2 - y^2)))

should work, since x^2 + y^2 + z^2 = r^2.

Share this post


Link to post
Share on other sites
Slightly modified version of how I do it in my engine. Some of the functions should be (hopefully) self explanatory, but feel free to ask if you're not sure what anything does:


void BuildSphere(float Radius,UINT TesselationLevel)
{
if(Radius <= 0.0f || TesselationLevel > 8)
return;

Vec Corners[6];
Corners[0] = Vec(0.0f,0.0f,0.0f); // Top
Corners[0].y += Radius; // Top
Corners[1] = Vec(0.0f,0.0f,0.0f); // Bottom
Corners[1].y -= Radius; // Bottom

Matrix TempMat;

// Corners
for(UINT ui = 2; ui < 6; ui++)
{
Corners[ui].y = Corners[ui].z = 0.0f;
Corners[ui].x = Radius;
if(ui-1 < 4)
{
MatRotateY(TempMat,PI_OVER_2 * (ui-1));
TransformVec(Corners[ui],Corners[ui],TempMat);
}
}

// Form triangles.
Poly Faces[10000];
UINT NumFaces = 8;
const float TexScale = 0.125f;
const float RadTex = TexScale * Radius;
// Top 4 triangles.
for(UINT ui = 0; ui < 4; ui++)
{
Faces[ui].Verts[0].Pos = Corners[0];
Faces[ui].Verts[0].TexU = RadTex * 0.5f;
Faces[ui].Verts[0].TexV = 0.0f;
Faces[ui].Verts[1].Pos = Corners[ui+2];
Faces[ui].Verts[1].TexU = RadTex;
Faces[ui].Verts[1].TexV = RadTex;
Faces[ui].Verts[2].Pos = ui == 3 ? Corners[2] : Corners[ui+3];
Faces[ui].Verts[2].TexU = 0.0f;
Faces[ui].Verts[2].TexV = RadTex; }

// Bottom 4 triangles.
for(UINT ui = 0; ui < 4; ui++)
{
Faces[ui].Verts[0].Pos = Corners[1];
Faces[ui].Verts[0].TexU = RadTex * 0.5f;
Faces[ui].Verts[0].TexV = 0.0f;
Faces[ui].Verts[1].Pos = ui == 3 ? Corners[2] : Corners[ui+3];
Faces[ui].Verts[1].TexU = RadTex;
Faces[ui].Verts[1].TexV = RadTex;
Faces[ui].Verts[2].Pos = Corners[ui+2];
Faces[ui].Verts[2].TexU = 0.0f;
Faces[ui].Verts[2].TexV = RadTex;
}

Vert Center;
Vert NewTriVerts[3];
Vert NewVerts[6];
Vert* FaceVerts;
// Tesselate the sphere.
for(UINT ui = 0; ui < TesselationLevel; ui++)
{
UINT LastFaceCount = NumFaces;
for(UINT face = 0; face < LastFaceCount; face++)
{
FaceVerts = Faces[face].Verts;

NewVerts[0] = FaceVerts[0];
NewVerts[2] = FaceVerts[1];
NewVerts[4] = FaceVerts[2];

NewVerts[1].Pos = (FaceVerts[0].Pos + FaceVerts[1].Pos) * 0.5f;
NewVerts[1].TexU = (FaceVerts[0].TexU + FaceVerts[1].TexU) * 0.5f;
NewVerts[1].TexV = (FaceVerts[0].TexV + FaceVerts[1].TexV) * 0.5f;

NewVerts[3].Pos = (FaceVerts[1].Pos + FaceVerts[2].Pos) * 0.5f;
NewVerts[3].TexU = (FaceVerts[1].TexU + FaceVerts[2].TexU) * 0.5f;
NewVerts[3].TexV = (FaceVerts[1].TexV + FaceVerts[2].TexV) * 0.5f;

NewVerts[5].Pos = (FaceVerts[2].Pos + FaceVerts[0].Pos) * 0.5f;
NewVerts[5].TexU = (FaceVerts[2].TexU + FaceVerts[0].TexU) * 0.5f;
NewVerts[5].TexV = (FaceVerts[2].TexV + FaceVerts[0].TexV) * 0.5f;

// Top Triangle
NewTriVerts[0] = NewVerts[0];
NewTriVerts[1] = NewVerts[1];
NewTriVerts[2] = NewVerts[5];
Faces[NumFaces++].Rebuild(NewTriVerts,3);
// left Triangle.
NewTriVerts[0] = NewVerts[5];
NewTriVerts[1] = NewVerts[3];
NewTriVerts[2] = NewVerts[4];
Faces[NumFaces++].Rebuild(NewTriVerts,3);
// Right triangle
NewTriVerts[0] = NewVerts[1];
NewTriVerts[1] = NewVerts[2];
NewTriVerts[2] = NewVerts[3];
Faces[NumFaces++].Rebuild(NewTriVerts,3);

// center Triangle (replaces current)
NewTriVerts[0] = NewVerts[5];
NewTriVerts[1] = NewVerts[1];
NewTriVerts[2] = NewVerts[3];
Faces[face].Rebuild(NewTriVerts,3);
}
}
// Extend the sphere out to the proper radius and move to the proper origin.
for(UINT ui = 0; ui < NumFaces; ui++)
{
Vert* FaceVerts = Faces[ui].Verts;
for(UINT v = 0; v < Faces[ui].NumVerts; v++)
{
NormalizeVec(FaceVerts[v].Pos);
FaceVerts[v].Pos *= Radius;
FaceVerts[v].Pos += DrawingBrush.Origin;
}
Faces[ui].Recalculate();
}
DrawingBrush.Rebuild(Faces,NumFaces);
}

Share this post


Link to post
Share on other sites

This topic is 4866 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this