197 lines
5 KiB
C++
197 lines
5 KiB
C++
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <math.h>
|
||
|
#include <string.h>
|
||
|
#include <time.h>
|
||
|
#include <assert.h>
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <gl\gl.h>
|
||
|
#include <gl\glu.h>
|
||
|
#include <gl\glaux.h>
|
||
|
|
||
|
#include "mtk.hxx"
|
||
|
#include "objects.hxx"
|
||
|
|
||
|
#define RGB_COLOR(red, green, blue) \
|
||
|
(((DWORD)(BYTE)(red) << 0) | \
|
||
|
((DWORD)(BYTE)(green) << 8) | \
|
||
|
((DWORD)(BYTE)(blue) << 16))
|
||
|
|
||
|
#define RGBA_COLOR(red, green, blue, alpha) \
|
||
|
(((DWORD)(BYTE)(red) << 0) | \
|
||
|
((DWORD)(BYTE)(green) << 8) | \
|
||
|
((DWORD)(BYTE)(blue) << 16) | \
|
||
|
((DWORD)(BYTE)(alpha) << 24))
|
||
|
|
||
|
#define FRANDOM(x) (((float)rand() / RAND_MAX) * (x))
|
||
|
|
||
|
|
||
|
/****** OBJECT *******************************************************/
|
||
|
|
||
|
|
||
|
OBJECT::OBJECT( int rings, int sections )
|
||
|
: nRings( rings ), nSections( sections )
|
||
|
{
|
||
|
pTriData = NULL;
|
||
|
pVertData = NULL;
|
||
|
alphaVal = 255;
|
||
|
}
|
||
|
|
||
|
OBJECT::~OBJECT()
|
||
|
{
|
||
|
// These ptrs alloc'd in inheriting classes...
|
||
|
if( pVertData )
|
||
|
free( pVertData );
|
||
|
if( pTriData )
|
||
|
free( pTriData );
|
||
|
}
|
||
|
|
||
|
/****** SPHERE *******************************************************/
|
||
|
|
||
|
SPHERE::SPHERE(
|
||
|
int rings, int sections, float fOpacity )
|
||
|
: OBJECT( rings, sections )
|
||
|
{
|
||
|
iType = OBJECT_TYPE_SPHERE;
|
||
|
|
||
|
alphaVal = (int) (fOpacity * 255.0f);
|
||
|
SS_CLAMP_TO_RANGE2( alphaVal, 0, 255 );
|
||
|
|
||
|
nVerts = CalcNVertices();
|
||
|
nTris = CalcNTriangles();
|
||
|
|
||
|
// Allocate memory for the sphere data (freed by the base OBJECT class)
|
||
|
|
||
|
// Vertex data
|
||
|
pVertData = (VERTEX *) malloc( nVerts * sizeof(VERTEX) );
|
||
|
assert( pVertData != NULL );
|
||
|
|
||
|
// Triangle indices
|
||
|
pTriData = (TRIANGLE *) malloc( nTris * sizeof(TRIANGLE) );
|
||
|
assert( pTriData != NULL );
|
||
|
|
||
|
GenerateData(1.0f);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
SPHERE::CalcNVertices()
|
||
|
{
|
||
|
return (((nRings)+1)*(nSections)+2);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
SPHERE::CalcNTriangles()
|
||
|
{
|
||
|
return (((nRings)+1)*(nSections)*2);
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
SPHERE::GenerateData( float fRadius )
|
||
|
{
|
||
|
float fTheta, fPhi; /* Angles used to sweep around sphere */
|
||
|
float fDTheta, fDPhi; /* Angle between each section and ring */
|
||
|
float fX, fY, fZ, fV, fRSinTheta; /* Temporary variables */
|
||
|
int i, j, n, m; /* counters */
|
||
|
VERTEX *pvtx = pVertData;
|
||
|
TRIANGLE *ptri = pTriData;
|
||
|
//mf: ! give these different alpha values !
|
||
|
DWORD color0 = RGBA_COLOR( 255, 0, 0, alphaVal );
|
||
|
DWORD color1 = RGBA_COLOR( 255, 255, 0, alphaVal ); // yellow
|
||
|
|
||
|
/*
|
||
|
* Generate vertices at the top and bottom points.
|
||
|
*/
|
||
|
pvtx[0].fX = 0.0f;
|
||
|
pvtx[0].fY = fRadius;
|
||
|
pvtx[0].fZ = 0.0f;
|
||
|
pvtx[0].fNx = 0.0f;
|
||
|
pvtx[0].fNy = 1.0f;
|
||
|
pvtx[0].fNz = 0.0f;
|
||
|
pvtx[0].dwColor = color0;
|
||
|
pvtx[nVerts - 1].fX = 0.0f;
|
||
|
pvtx[nVerts - 1].fY = -fRadius;
|
||
|
pvtx[nVerts - 1].fZ = 0.0f;
|
||
|
pvtx[nVerts - 1].fNx = 0.0f;
|
||
|
pvtx[nVerts - 1].fNy = -1.0f;
|
||
|
pvtx[nVerts - 1].fNz = 0.0f;
|
||
|
pvtx[nVerts - 1].dwColor = color1;
|
||
|
|
||
|
/*
|
||
|
* Generate vertex points for rings
|
||
|
*/
|
||
|
fDTheta = PI / (float) (nRings + 2);
|
||
|
fDPhi = 2.0f * PI / (float) nSections;
|
||
|
n = 1; /* vertex being generated, begins at 1 to skip top point */
|
||
|
fTheta = fDTheta;
|
||
|
|
||
|
for (i = 0; i <= nRings; i++)
|
||
|
{
|
||
|
fY = (float)(fRadius * cos(fTheta)); /* y is the same for each ring */
|
||
|
fV = fTheta / PI; /* v is the same for each ring */
|
||
|
fRSinTheta = (float)(fRadius * sin(fTheta));
|
||
|
fPhi = 0.0f;
|
||
|
|
||
|
for (j = 0; j < nSections; j++)
|
||
|
{
|
||
|
fX = (float)(fRSinTheta * sin(fPhi));
|
||
|
fZ = (float)(fRSinTheta * cos(fPhi));
|
||
|
pvtx[n].fX = fX;
|
||
|
pvtx[n].fZ = fZ;
|
||
|
pvtx[n].fY = fY;
|
||
|
pvtx[n].fNx = fX / fRadius;
|
||
|
pvtx[n].fNy = fY / fRadius;
|
||
|
pvtx[n].fNz = fZ / fRadius;
|
||
|
if (n & 1)
|
||
|
{
|
||
|
pvtx[n].dwColor = color0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pvtx[n].dwColor = color1;
|
||
|
}
|
||
|
fPhi += fDPhi;
|
||
|
n++;
|
||
|
}
|
||
|
|
||
|
fTheta += fDTheta;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Generate triangles for top and bottom caps.
|
||
|
*/
|
||
|
for (i = 0; i < nSections; i++)
|
||
|
{
|
||
|
ptri[i].iV1 = 0;
|
||
|
ptri[i].iV2 = i + 1;
|
||
|
ptri[i].iV3 = 1 + ((i + 1) % nSections);
|
||
|
ptri[nTris - nSections + i].iV1 = nVerts - 1;
|
||
|
ptri[nTris - nSections + i].iV2 = nVerts - 2 - i;
|
||
|
ptri[nTris - nSections + i].iV3 = nVerts - 2 - ((1 + i) % nSections);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Generate triangles for the rings
|
||
|
*/
|
||
|
m = 1; /* first vertex in current ring, begins at 1 to skip top point*/
|
||
|
n = nSections; /* triangle being generated, skip the top cap */
|
||
|
|
||
|
for (i = 0; i < nRings; i++)
|
||
|
{
|
||
|
for (j = 0; j < nSections; j++)
|
||
|
{
|
||
|
ptri[n].iV1 = m + j;
|
||
|
ptri[n].iV2 = m + nSections + j;
|
||
|
ptri[n].iV3 = m + nSections + ((j + 1) % nSections);
|
||
|
ptri[n + 1].iV1 = ptri[n].iV1;
|
||
|
ptri[n + 1].iV2 = ptri[n].iV3;
|
||
|
ptri[n + 1].iV3 = m + ((j + 1) % nSections);
|
||
|
n += 2;
|
||
|
}
|
||
|
|
||
|
m += nSections;
|
||
|
}
|
||
|
}
|
||
|
|