windows-nt/Source/XPSP1/NT/multimedia/opengl/test/misc/membrane/objects.cxx
2020-09-26 16:20:57 +08:00

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;
}
}