# Algorithmically generating a sphere in DX9

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

## 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 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 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 on other sites
If you just want to get a sphere you can use the D3DXCreateSphere function.

1. 1
Rutin
38
2. 2
3. 3
4. 4
5. 5

• 12
• 10
• 13
• 104
• 11
• ### Forum Statistics

• Total Topics
632983
• Total Posts
3009698
• ### Who's Online (See full list)

There are no registered users currently online

×