Книга: DirectX 8 Programming Tutorial
How to make a sphere
How to make a sphere
Our sphere will be made up from a simple triangle list. We will need to specify the number of rings and segments for the sphere. The more rings and segments there are, the smoother and rounder the sphere will appear. The sphere will be made up using an index and vertex buffer. Fig 9.3 below shows a wireframe screenshot of a sphere. It shows how the sphere is constructed and divided into rings and segments.
Fig 9.3
To create the sphere we can use the following code snippet. The code below has been adapted from a sample by "Laurent" posted on the GameDev.net DirectX forum. To view the post in full go to http://www.gamedev.net/community/forums/topic.asp?topic_id=85779. I would like to thank Laurent for giving me permission to use the code in this tutorial.
bool CSphere::UpdateVertices() {
//Code adapted from a sample by "Laurent" posted on the GameDev.net DirectX forum
//http://www.gamedev.net/community/forums/topic.asp?topic_id=85779
WORD* pIndices;
SPHERE_CUSTOMVERTEX* pVertex;
WORD wVertexIndex = 0;
int nCurrentRing;
int nCurrentSegment;
D3DXVECTOR3 vNormal;
//Lock the vertex buffer
if (FAILED(m_pVertexBuffer->Lock(0, 0, (BYTE**)&pVertex, 0))) {
LogError("<li>CSphere: Unable to lock vertex buffer.");
return false;
}
//Lock the index buffer
if (FAILED(m_pIndexBuffer->Lock(0, m_dwNumOfIndices, (BYTE**)&pIndices, 0))) {
LogError("<li>CSphere: Unable to lock index buffer.");
return false;
}
//Establish constants used in sphere generation
FLOAT rDeltaRingAngle = (D3DX_PI / m_nRings);
FLOAT rDeltaSegAngle = (2.0f * D3DX_PI / m_nSegments);
//Generate the group of rings for the sphere
for (nCurrentRing = 0; nCurrentRing < m_nRings + 1; nCurrentRing++) {
FLOAT r0 = sinf(nCurrentRing * rDeltaRingAngle);
FLOAT y0 = cosf(nCurrentRing * rDeltaRingAngle);
//Generate the group of segments for the current ring
for (nCurrentSegment = 0; nCurrentSegment < m_nSegments + 1; nCurrentSegment++) {
FLOAT x0 = r0 * sinf(nCurrentSegment * rDeltaSegAngle);
FLOAT z0 = r0 * cosf(nCurrentSegment * rDeltaSegAngle);
vNormal.x = x0;
vNormal.y = y0;
vNormal.z = z0;
D3DXVec3Normalize(&vNormal, &vNormal);
//Add one vertex to the strip which makes up the sphere
pVertex->x = x0;
pVertex->y = y0;
pVertex->z = z0;
pVertex->nx = vNormal.x;
pVertex->ny = vNormal.y;
pVertex->nz = vNormal.z;
pVertex->tu = 1.0f – ((FLOAT)nCurrentSegment / (FLOAT)m_nSegments);
pVertex->tv = (FLOAT)nCurrentRing / (FLOAT)m_nRings;
pVertex++;
//Add two indices except for the last ring
if (nCurrentRing != m_nRings) {
*pIndices = wVertexIndex;
pIndices++;
*pIndices = wVertexIndex + (WORD)(m_nSegments + 1);
pIndices++;
wVertexIndex++;
}
}
}
if (FAILED(m_pIndexBuffer->Unlock())) {
LogError("<li>CSphere: Unable to unlock index buffer.");
return false;
}
if (FAILED(m_pVertexBuffer->Unlock())) {
LogError("<li>CSphere: Unable to unlock vertex buffer.");
return false;
}
return true;
}
So what is going on here? Once we have locked the index and vertex buffers we are ready to write to them. We use the same calculation as before to obtain the segment angle and a slight variation to obtain the ring angle. For the ring angle we only need to divide half a circle (PI radians) by the number of rings.
Once we have the ring and segment angles, we simply loop around once for each ring creating the vertices for each segment within that ring. We add an entry into the index buffer each time to create our triangle list. We set the normal values for each vertex to be the normalised position values. The radius of the sphere is always 1. You can use a scaling transformation matrix to increase or decrease the size of the sphere. Once complete, we unlock the vertex and index buffers ready for rendering.
The final scene when rendered will look something like the screenshot below:
- How to read
- Chapter 9. How a rule is built
- How it was written
- How to plan an IP filter
- chown
- How to place proxies
- How to use this License for your documents
- 2. How to Apply These Terms to Your New Programs
- 4.3.3. Makefile Targets
- Scaling makes your object darker?
- 1.3. Автоматизация процесса с помощью GNU-утилиты make
- Команды SHOW