Jump to content
  • Advertisement
Sign in to follow this  
byrdJR

Algorithmically generating a sphere in DX9

This topic is 5085 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
Advertisement
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!