|
|
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <float.h>
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
// #define PROFILE 1
#ifdef PROFILE
#include <icapexp.h>
#endif
typedef struct { float x, y, z; float nx, ny, nz; float tu, tv; DWORD color; } D3DVERTEX; typedef D3DVERTEX *LPD3DVERTEX;
typedef struct { int v1; int v2; int v3; } D3DTRIANGLE; typedef D3DTRIANGLE *LPD3DTRIANGLE;
#define D3DVAL(f) ((float)(f))
#define RGB_MAKE(r, g, b) \
(((DWORD)((r) & 0xff) << 0) | \ ((DWORD)((g) & 0xff) << 8) | \ ((DWORD)((b) & 0xff) << 16) | \ ((DWORD)(0xff) << 24))
typedef float __GLfloat;
typedef struct { __GLfloat matrix[4][4]; } __GLmatrix;
__GLmatrix identity = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f };
void __glMultMatrix(__GLmatrix *r, const __GLmatrix *a, const __GLmatrix *b) { __GLfloat b00, b01, b02, b03; __GLfloat b10, b11, b12, b13; __GLfloat b20, b21, b22, b23; __GLfloat b30, b31, b32, b33; GLint i;
b00 = b->matrix[0][0]; b01 = b->matrix[0][1]; b02 = b->matrix[0][2]; b03 = b->matrix[0][3]; b10 = b->matrix[1][0]; b11 = b->matrix[1][1]; b12 = b->matrix[1][2]; b13 = b->matrix[1][3]; b20 = b->matrix[2][0]; b21 = b->matrix[2][1]; b22 = b->matrix[2][2]; b23 = b->matrix[2][3]; b30 = b->matrix[3][0]; b31 = b->matrix[3][1]; b32 = b->matrix[3][2]; b33 = b->matrix[3][3];
for (i = 0; i < 4; i++) { r->matrix[i][0] = a->matrix[i][0]*b00 + a->matrix[i][1]*b10 + a->matrix[i][2]*b20 + a->matrix[i][3]*b30; r->matrix[i][1] = a->matrix[i][0]*b01 + a->matrix[i][1]*b11 + a->matrix[i][2]*b21 + a->matrix[i][3]*b31; r->matrix[i][2] = a->matrix[i][0]*b02 + a->matrix[i][1]*b12 + a->matrix[i][2]*b22 + a->matrix[i][3]*b32; r->matrix[i][3] = a->matrix[i][0]*b03 + a->matrix[i][1]*b13 + a->matrix[i][2]*b23 + a->matrix[i][3]*b33; } }
void MakePosMatrix(__GLmatrix *lpM, float x, float y, float z) { memcpy(lpM, &identity, sizeof(__GLmatrix)); lpM->matrix[3][0] = D3DVAL(x); lpM->matrix[3][1] = D3DVAL(y); lpM->matrix[3][2] = D3DVAL(z); }
void MakeRotMatrix(__GLmatrix *lpM, float rx, float ry, float rz) { float ct, st; __GLmatrix My, Mx, Mz, T; memcpy(&My, &identity, sizeof(__GLmatrix)); ct = D3DVAL(cos(ry)); st = D3DVAL(sin(ry)); My.matrix[0][0] = ct; My.matrix[0][2] = -st; My.matrix[2][0] = st; My.matrix[2][2] = ct; memcpy(&Mx, &identity, sizeof(__GLmatrix)); ct = D3DVAL(cos(rx)); st = D3DVAL(sin(rx)); Mx.matrix[1][1] = ct; Mx.matrix[1][2] = st; Mx.matrix[2][1] = -st; Mx.matrix[2][2] = ct; memcpy(&Mz, &identity, sizeof(__GLmatrix)); ct = D3DVAL(cos(rz)); st = D3DVAL(sin(rz)); Mz.matrix[0][0] = ct; Mz.matrix[0][1] = st; Mz.matrix[1][0] = -st; Mz.matrix[1][1] = ct; __glMultMatrix(&T, &My, &Mx); __glMultMatrix(lpM, &T, &Mz); }
void *Malloc(size_t bytes) { void *pv;
pv = malloc(bytes); if (pv == NULL) { printf("Unable to alloc %d bytes\n", bytes); exit(1); } return pv; }
#define PI ((float)3.14159265358979323846)
#define WIDTH 400
#define HEIGHT 400
#define SPWIDTH 140
#define SPHEIGHT 140
#define MAWIDTH 90
#define MAHEIGHT 75
#define LAWIDTH 230
#define LAHEIGHT 190
int iSwapWidth, iSwapHeight;
#define SRADIUS 0.4f
#define DMINUSR 0.6
#define DV 0.05
#define DR 0.3
#define DEPTH 0.6f
#define random(x) (((float)rand() / RAND_MAX) * (x))
#define FILL_TRIANGLES 50
#define MEDIUM_AREA 3000
#define LARGE_AREA 20000
#define FRONT_TO_BACK 0
#define BACK_TO_FRONT 1
#define ORDER_COUNT 2
int iOrder = FRONT_TO_BACK; char *pszOrders[] = { "front-to-back", "back-to-front" };
#define AREA_LARGE 0
#define AREA_MEDIUM 1
#define AREA_COUNT 2
int iFillSize = AREA_MEDIUM;
int iTriangleArea;
typedef struct _Sphere { GLfloat xrv, yrv, zrv; __GLmatrix pos, dpos; __GLmatrix rot, drot; } Sphere;
#define NSPHERES 8
Sphere spheres[NSPHERES];
BOOL fSingle = FALSE; BOOL fRotate = TRUE; BOOL fBounce = TRUE; BOOL fSwap = TRUE; BOOL fPaused = FALSE; BOOL fUseScissor = TRUE; BOOL fSpread = FALSE; BOOL fExit = FALSE; BOOL fSingleColor = TRUE; BOOL fVerbose = FALSE; BOOL fDisplayList = TRUE; int iMultiLoop = 1;
int nRings = 30; int nSections = 30;
GLint iDlist;
#define TEXOBJ
#ifdef TEXOBJ
GLuint uiTexObj; #endif
PFNGLADDSWAPHINTRECTWINPROC glAddSwapHintRectWIN;
#define TEST_FILL 0
#define TEST_POLYS 1
#define TEST_COUNT 2
int iTest = TEST_POLYS;
AUX_RGBImageRec *pTexture;
#define TEXMODE_REPLACE 0
#define TEXMODE_DECAL 1
#define TEXMODE_MODULATE 2
#define TEXMODE_COUNT 3
int iTexMode = TEXMODE_REPLACE; char *pszTexModes[] = { "replace", "decal", "modulate" }; GLenum eTexModes[] = { GL_REPLACE, GL_DECAL, GL_MODULATE };
BOOL fPerspective = TRUE;
//--------------------------------------------------------------------------;
//
// FunctionName: GenerateSphere()
//
// Purpose:
// Generate the geometry of a sphere.
//
// Returns BOOL
//
// History:
// 11/17/95 RichGr
//
//--------------------------------------------------------------------------;
/*
* Generates a sphere around the y-axis centered at the origin including * normals and texture coordinates. Returns TRUE on success and FALSE on * failure. * sphere_r Radius of the sphere. * num_rings Number of full rings not including the top and bottom * caps. * num_sections Number of sections each ring is divided into. Each * section contains two triangles on full rings and one * on top and bottom caps. * sx, sy, sz Scaling along each axis. Set each to 1.0 for a * perfect sphere. * plpv On exit points to the vertices of the sphere. The * function allocates this space. Not allocated if * function fails. * plptri On exit points to the triangles of the sphere which * reference vertices in the vertex list. The function * allocates this space. Not allocated if function fails. * pnum_v On exit contains the number of vertices. * pnum_tri On exit contains the number of triangles. */ BOOL GenerateSphere(float sphere_r, int num_rings, int num_sections, float sx, float sy, float sz, LPD3DVERTEX* plpv, LPD3DTRIANGLE* plptri, int* pnum_v, int* pnum_tri) { float theta, phi; /* Angles used to sweep around sphere */ float dtheta, dphi; /* Angle between each section and ring */ float x, y, z, v, rsintheta; /* Temporary variables */ int i, j, n, m; /* counters */ int num_v, num_tri; /* Internal vertex and triangle count */ LPD3DVERTEX lpv; /* Internal pointer for vertices */ LPD3DTRIANGLE lptri; /* Internal pointer for trianlges */
/*
* Check the parameters to make sure they are valid. */ if ((sphere_r <= 0) || (num_rings < 1) || (num_sections < 3) || (sx <= 0) || (sy <= 0) || (sz <= 0)) return FALSE; /*
* Generate space for the required triangles and vertices. */ num_tri = (num_rings + 1) * num_sections * 2; num_v = (num_rings + 1) * num_sections + 2; *plpv = (LPD3DVERTEX)Malloc(sizeof(D3DVERTEX) * num_v); *plptri = (LPD3DTRIANGLE)Malloc(sizeof(D3DTRIANGLE) * num_tri); lpv = *plpv; lptri = *plptri; *pnum_v = num_v; *pnum_tri = num_tri;
/*
* Generate vertices at the top and bottom points. */ lpv[0].x = D3DVAL(0.0f); lpv[0].y = D3DVAL(sy * sphere_r); lpv[0].z = D3DVAL(0.0f); lpv[0].nx = D3DVAL(0.0f); lpv[0].ny = D3DVAL(1.0f); lpv[0].nz = D3DVAL(0.0f); lpv[0].color = RGB_MAKE(0, 0, 255); lpv[0].tu = D3DVAL(0.0f); lpv[0].tv = D3DVAL(0.0f); lpv[num_v - 1].x = D3DVAL(0.0f); lpv[num_v - 1].y = D3DVAL(sy * -sphere_r); lpv[num_v - 1].z = D3DVAL(0.0f); lpv[num_v - 1].nx = D3DVAL(0.0f); lpv[num_v - 1].ny = D3DVAL(-1.0f); lpv[num_v - 1].nz = D3DVAL(0.0f); lpv[num_v - 1].tu = D3DVAL(0.0f); lpv[num_v - 1].tv = D3DVAL(1.0f); lpv[num_v - 1].color = RGB_MAKE(0, 255, 0);
/*
* Generate vertex points for rings */ dtheta = PI / (float) (num_rings + 2); dphi = 2.0f * PI / (float) num_sections; n = 1; /* vertex being generated, begins at 1 to skip top point */ theta = dtheta;
for (i = 0; i <= num_rings; i++) { y = (float)(sphere_r * cos(theta)); /* y is the same for each ring */ v = theta / PI; /* v is the same for each ring */ rsintheta = (float)(sphere_r * sin(theta)); phi = 0.0f; for (j = 0; j < num_sections; j++) { x = (float)(rsintheta * sin(phi)); z = (float)(rsintheta * cos(phi)); lpv[n].x = D3DVAL(sx * x); lpv[n].z = D3DVAL(sz * z); lpv[n].y = D3DVAL(sy * y); lpv[n].nx = D3DVAL(x / sphere_r); lpv[n].ny = D3DVAL(y / sphere_r); lpv[n].nz = D3DVAL(z / sphere_r); lpv[n].tv = D3DVAL(v); lpv[n].tu = D3DVAL(1.0f - phi / (2.0f * PI)); if (n & 1) { lpv[n].color = RGB_MAKE(0, 0, 255); } else { lpv[n].color = RGB_MAKE(0, 255, 0); } phi += dphi; ++n; } theta += dtheta; }
/*
* Generate triangles for top and bottom caps. */ for (i = 0; i < num_sections; i++) { lptri[i].v1 = 0; lptri[i].v2 = i + 1; lptri[i].v3 = 1 + ((i + 1) % num_sections); // lptri[i].flags = D3D_EDGE_ENABLE_TRIANGLE;
lptri[num_tri - num_sections + i].v1 = num_v - 1; lptri[num_tri - num_sections + i].v2 = num_v - 2 - i; lptri[num_tri - num_sections + i].v3 = num_v - 2 - ((1 + i) % num_sections); // lptri[num_tri - num_sections + i].flags= D3D_EDGE_ENABLE_TRIANGLE;
}
/*
* Generate triangles for the rings */ m = 1; /* first vertex in current ring,begins at 1 to skip top point*/ n = num_sections; /* triangle being generated, skip the top cap */ for (i = 0; i < num_rings; i++) { for (j = 0; j < num_sections; j++) { lptri[n].v1 = m + j; lptri[n].v2 = m + num_sections + j; lptri[n].v3 = m + num_sections + ((j + 1) % num_sections); // lptri[n].flags = D3D_EDGE_ENABLE_TRIANGLE;
lptri[n + 1].v1 = lptri[n].v1; lptri[n + 1].v2 = lptri[n].v3; lptri[n + 1].v3 = m + ((j + 1) % num_sections); // lptri[n + 1].flags = D3D_EDGE_ENABLE_TRIANGLE;
n += 2; } m += num_sections; } return TRUE; }
// Creates triangle and quad strip index sets for vertex data generated
// by GenerateSphere. The top and bottom triangle fans are omitted because
// they're degenerate cases for strips
int CreateStrip(int nSections, int **ppiStrip) { int nPts; int *piIdx, iIdxBase; int iRing, iSection;
// Stick to a single strip for now
nRings = 1; nPts = nRings*(nSections+1)*2;
*ppiStrip = (int *)Malloc(sizeof(int)*nPts);
piIdx = *ppiStrip; iIdxBase = 1; for (iRing = 0; iRing < nRings; iRing++) { for (iSection = 0; iSection <= nSections; iSection++) { *piIdx++ = iIdxBase+(iSection % nSections); *piIdx++ = iIdxBase+(iSection % nSections)+nSections; }
iIdxBase += nSections; }
return nPts; }
float fltCenter[NSPHERES][2] = { -SRADIUS, 0.0f, 0.0f, SRADIUS, SRADIUS, 0.0f, 0.0f, -SRADIUS };
void InitSpheres(void) { int i; Sphere *sp; float x, y, z;
#if 0
srand(time(NULL)); #else
srand( (unsigned)8269362521); #endif
for (i = 0; i < NSPHERES; i++) { sp = &spheres[i];
if (fBounce) { x = (float)DMINUSR - (float)random(2 * DMINUSR); y = (float)DMINUSR - (float)random(2 * DMINUSR); z = (float)-DEPTH + (float)random(2 * DEPTH); } else { x = fltCenter[i][0]; y = fltCenter[i][1]; z = 0.0f; } MakePosMatrix(&sp->pos, x, y, z); x = (float)DV - (float)random(2 * DV); y = (float)DV - (float)random(2 * DV); z = (float)DV - (float)random(2 * DV); MakePosMatrix(&sp->dpos, x, y, z);
MakeRotMatrix(&sp->rot, 0.0f, 0.0f, 0.0f); sp->xrv = (float)DR - (float)random(2 * DR); sp->yrv = (float)DR - (float)random(2 * DR); sp->zrv = (float)DR - (float)random(2 * DR); MakeRotMatrix(&sp->drot, sp->xrv, sp->yrv, sp->zrv); } }
void UpdateSphere(Sphere *sp) { GLboolean newRot; if (fBounce) { newRot = GL_FALSE; if (sp->pos.matrix[3][0] > DMINUSR || sp->pos.matrix[3][0] < -DMINUSR) { sp->dpos.matrix[3][0] = -sp->dpos.matrix[3][0]; sp->zrv = -sp->zrv; sp->yrv = -sp->yrv; newRot = GL_TRUE; } if (sp->pos.matrix[3][1] > DMINUSR || sp->pos.matrix[3][1] < -DMINUSR) { sp->dpos.matrix[3][1] = -sp->dpos.matrix[3][1]; sp->zrv = -sp->zrv; sp->xrv = -sp->xrv; newRot = GL_TRUE; } if (sp->pos.matrix[3][2] > DEPTH || sp->pos.matrix[3][2] < -DEPTH) { sp->dpos.matrix[3][2] = -sp->dpos.matrix[3][2]; sp->xrv = -sp->xrv; sp->yrv = -sp->yrv; newRot = GL_TRUE; }
if (newRot) { MakeRotMatrix(&sp->drot, sp->xrv, sp->yrv, sp->zrv); } __glMultMatrix(&sp->pos, &sp->dpos, &sp->pos); } if (fRotate) { __glMultMatrix(&sp->rot, &sp->drot, &sp->rot); } }
#define TAN_60 1.732
void SetTriangleVertices(LPD3DVERTEX v, float z, UINT ww, UINT wh, float a, int ox, int oy) { float dx, dy; float b = (float)sqrt((4 * a) / TAN_60); float h = (2 * a) / b; float x = (float)((b / 2) * (TAN_60 / 2)); float cx, cy; dx = (float)ww; dy = (float)wh; cx = dx / 2 + ox; cy = dy / 2 + oy; /* V 0 */ v[0].x = cx; v[0].y = cy + (h - x); v[0].z = z; v[0].color = RGB_MAKE(255, 0, 0); v[0].tu = D3DVAL(0.5); v[0].tv = D3DVAL(0.0); /* V 1 */ v[1].x = cx + (b / 2); v[1].y = cy - x; v[1].z = z; v[1].color = RGB_MAKE(255, 255, 255); v[1].tu = D3DVAL(1.0); v[1].tv = D3DVAL(1.0); /* V 2 */ v[2].x = cx - (b / 2); v[2].y = cy - x; v[2].z = z; v[2].color = RGB_MAKE(255, 255, 0); v[2].tu = D3DVAL(0.0); v[2].tv = D3DVAL(1.0); }
void InitFill(LPD3DVERTEX *ppVertices, LPD3DTRIANGLE *ppTriangles) { *ppVertices = (LPD3DVERTEX)Malloc(3 * FILL_TRIANGLES * sizeof(D3DVERTEX)); *ppTriangles = (LPD3DTRIANGLE)Malloc(FILL_TRIANGLES * sizeof(D3DTRIANGLE)); }
D3DVERTEX *pPolyVertices; D3DTRIANGLE *pPolyTriangles; int nNumVertices, nNumFaces; int *pPolyStrip; int nStripIndices;
D3DVERTEX *pFillVertices; D3DTRIANGLE *pFillTriangles;
int *pIndices; int nIndices; int nTriangles;
#define POLYMODE_POINT 0
#define POLYMODE_LINE 1
#define POLYMODE_FILL 2
#define POLYMODE_COUNT 3
GLenum ePolygonModes[] = { GL_POINT, GL_LINE, GL_FILL }; int iPolygonMode = POLYMODE_FILL;
#define SMODEL_SMOOTH 0
#define SMODEL_FLAT 1
#define SMODEL_COUNT 2
GLenum eShadeModels[] = { GL_SMOOTH, GL_FLAT }; char *pszShadeModels[] = { "smooth", "flat" }; int iShadeModel = SMODEL_SMOOTH;
#define PRIM_TRIANGLES 0
#define PRIM_TSTRIP 1
#define PRIM_QSTRIP 2
#define PRIM_COUNT 3
GLenum ePrimTypes[] = { GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_QUAD_STRIP }; char *pszPrimTypes[] = { "Tris", "TStrip", "QStrip" }; int iPrimType = PRIM_TRIANGLES;
int total_ms = 0; int total_tris = 0 ;
double peak_tri = 0, peak_fill = 0, avg_tri = 0, avg_fill = 0; int avg_cnt = 0;
void ModeChange(void) { total_ms = 0; total_tris = 0; avg_tri = 0; avg_fill = 0; avg_cnt = 0; }
void SetPrim(int iNew) { ModeChange(); iPrimType = iNew; switch(iTest) { case TEST_POLYS: switch(iPrimType) { case PRIM_TRIANGLES: pIndices = (int *)pPolyTriangles; nIndices = nNumFaces*3; nTriangles = nNumFaces; break; case PRIM_TSTRIP: case PRIM_QSTRIP: pIndices = pPolyStrip; nIndices = nStripIndices; nTriangles = nSections*2; break; } nTriangles *= NSPHERES; break;
case TEST_FILL: pIndices = (int *)pFillTriangles; nIndices = FILL_TRIANGLES*3; nTriangles = FILL_TRIANGLES; break; } }
void SetVertexArrayVertices(LPD3DVERTEX pVertices) { glVertexPointer(3, GL_FLOAT, sizeof(D3DVERTEX), &pVertices[0].x); glNormalPointer(GL_FLOAT, sizeof(D3DVERTEX), &pVertices[0].nx); glTexCoordPointer(2, GL_FLOAT, sizeof(D3DVERTEX), &pVertices[0].tu); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(D3DVERTEX), &pVertices[0].color); }
void SetFill(int iNewSize, int iNewOrder) { int i; float z; int NumTri; LPD3DVERTEX pVert; LPD3DTRIANGLE pTri; UINT w, h; float area; int ox, oy, dox, doy; RECT rct; ModeChange(); iFillSize = iNewSize; iOrder = iNewOrder; switch(iFillSize) { case AREA_LARGE: iTriangleArea = LARGE_AREA; iSwapWidth = LAWIDTH; iSwapHeight = LAHEIGHT; break; case AREA_MEDIUM: iTriangleArea = MEDIUM_AREA; iSwapWidth = MAWIDTH; iSwapHeight = MAHEIGHT; break; } glScissor((WIDTH-iSwapWidth)/2, (HEIGHT-iSwapHeight)/2, iSwapWidth, iSwapHeight); w = WIDTH; h = HEIGHT; NumTri = FILL_TRIANGLES;
pVert = pFillVertices; if (fSpread) { ox = -NumTri*2; oy = -NumTri*2; dox = 4; doy = 4; } else { ox = 0; oy = 0; dox = 0; doy = 0; } if (iOrder == FRONT_TO_BACK) { for (i = 0, z = (float)0.0; i < NumTri; i++, z -= (float)0.9 / NumTri) { SetTriangleVertices(pVert, z, w, h, (float)iTriangleArea, ox, oy); pVert += 3; ox += dox; oy += doy; } } else { for (i = 0, z = (float)-0.9; i < NumTri; i++, z += (float)0.9 / NumTri) { SetTriangleVertices(pVert, z, w, h, (float)iTriangleArea, ox, oy); pVert += 3; ox += dox; oy += doy; } }
pTri = pFillTriangles; for (i = 0; i < NumTri; i++) { pTri->v1 = i*3; pTri->v2 = i*3+1; pTri->v3 = i*3+2; pTri++; }
GetClientRect(auxGetHWND(), &rct); FillRect(auxGetHDC(), &rct, GetStockObject(BLACK_BRUSH)); }
static __GLmatrix proj = { D3DVAL(2.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(2.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(-1.0), D3DVAL(0.0) }; static __GLmatrix view = { D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(7.0), D3DVAL(1.0) };
void SetTest(int iNew) { RECT rct;
ModeChange(); iTest = iNew; switch(iTest) { case TEST_POLYS: glDisableClientState(GL_COLOR_ARRAY); glEnable(GL_LIGHTING); glEnable(GL_CULL_FACE); iTexMode = TEXMODE_REPLACE; glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, eTexModes[iTexMode]); glMatrixMode(GL_PROJECTION); glLoadIdentity(); #if 0
gluPerspective(45, 1, .01, 15); gluLookAt(0, 0, 8, 0, 0, 0, 0, 1, 0); #else
glLoadMatrixf((float *)&proj); glMultMatrixf((float *)&view); glDepthRange(1, 0); #endif
glMatrixMode(GL_MODELVIEW); SetVertexArrayVertices(pPolyVertices); iSwapWidth = SPWIDTH; iSwapHeight = SPHEIGHT; glScissor((WIDTH-iSwapWidth)/2, (HEIGHT-iSwapHeight)/2, iSwapWidth, iSwapHeight); break;
case TEST_FILL: glEnableClientState(GL_COLOR_ARRAY); glDisable(GL_LIGHTING); glDisable(GL_CULL_FACE); iTexMode = TEXMODE_MODULATE; glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, eTexModes[iTexMode]); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, WIDTH, 0, HEIGHT, 0.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); SetVertexArrayVertices(pFillVertices); SetFill(iFillSize, iOrder); break; }
SetPrim(iPrimType);
GetClientRect(auxGetHWND(), &rct); FillRect(auxGetHDC(), &rct, GetStockObject(BLACK_BRUSH)); }
void Init(void) { float fv4[4]; int iPrim, iOldPrim; if (!GenerateSphere(SRADIUS, nRings, nSections, 1.0f, 1.0f, 1.0f, &pPolyVertices, &pPolyTriangles, &nNumVertices, &nNumFaces)) { printf("Unable to generate sphere data\n"); exit(1); } nStripIndices = CreateStrip(nSections, &pPolyStrip);
InitSpheres();
InitFill(&pFillVertices, &pFillTriangles); fv4[0] = 0.05f; fv4[1] = 0.05f; fv4[2] = 0.05f; fv4[3] = 1.0f; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fv4); fv4[0] = 0.0f; fv4[1] = 1.0f; fv4[2] = 1.0f; fv4[3] = 0.0f; glLightfv(GL_LIGHT0, GL_POSITION, fv4); fv4[0] = 0.9f; fv4[1] = 0.9f; fv4[2] = 0.9f; fv4[3] = 1.0f; glLightfv(GL_LIGHT0, GL_DIFFUSE, fv4); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (!fSingleColor) { glEnableClientState(GL_COLOR_ARRAY); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); }
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
#ifdef TEXOBJ
glGenTextures(1, &uiTexObj); glBindTexture(GL_TEXTURE_2D, uiTexObj); #endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexImage2D(GL_TEXTURE_2D, 0, 3, pTexture->sizeX, pTexture->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, pTexture->data);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DITHER); #ifdef GL_EXT_clip_volume
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST); #endif
SetTest(iTest);
glClear(GL_COLOR_BUFFER_BIT);
if (fDisplayList) { iDlist = glGenLists(3); iOldPrim = iPrimType; for (iPrim = 0; iPrim < PRIM_COUNT; iPrim++) { SetPrim(iPrim); glNewList(iDlist+iPrim, GL_COMPILE); glDrawElements(ePrimTypes[iPrim], nIndices, GL_UNSIGNED_INT, pIndices); glEndList(); } SetPrim(iOldPrim); } }
void Redraw(void) { DWORD ms; int i; Sphere *sp; float fv4[4]; int iv1[1]; int loop; __GLmatrix xform;
ms = GetTickCount();
for (loop = 0; loop < iMultiLoop; loop++) { #if PROFILE
if (loop > 0) { StartCAP(); } #endif
if (fUseScissor) { glEnable(GL_SCISSOR_TEST); if (glAddSwapHintRectWIN != NULL) { glAddSwapHintRectWIN((WIDTH-iSwapWidth)/2, (HEIGHT-iSwapHeight)/2, iSwapWidth, iSwapHeight); } } if (glIsEnabled(GL_DEPTH_TEST)) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } else { glClear(GL_COLOR_BUFFER_BIT); }
if (fUseScissor) { glDisable(GL_SCISSOR_TEST); }
if (fSingleColor && iTest == TEST_POLYS) { fv4[0] = 1.0f; fv4[1] = 1.0f; fv4[2] = 1.0f; fv4[3] = 1.0f; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, fv4); }
fv4[0] = 0.6f; fv4[1] = 0.6f; fv4[2] = 0.6f; fv4[3] = 1.0f; glMaterialfv(GL_FRONT, GL_SPECULAR, fv4); iv1[0] = 40; glMaterialiv(GL_FRONT, GL_SHININESS, iv1); switch(iTest) { case TEST_POLYS: sp = &spheres[0]; for (i = 0; i < NSPHERES; i++) { UpdateSphere(sp); // Always done to even out timings
#if 1
__glMultMatrix(&xform, &sp->rot, &sp->pos); #else
__glMultMatrix(&xform, &sp->pos, &sp->rot); #endif
if (fBounce && fRotate) { glLoadMatrixf(&xform.matrix[0][0]); } else if (fRotate) { glLoadMatrixf(&sp->rot.matrix[0][0]); } else { glLoadMatrixf(&sp->pos.matrix[0][0]); }
#if 1
glVertexPointer(3, GL_FLOAT, sizeof(D3DVERTEX), &pPolyVertices[0].x); glNormalPointer(GL_FLOAT, sizeof(D3DVERTEX), &pPolyVertices[0].nx); glTexCoordPointer(2, GL_FLOAT, sizeof(D3DVERTEX), &pPolyVertices[0].tu); fv4[0] = 1.0f; fv4[1] = 1.0f; fv4[2] = 1.0f; fv4[3] = 1.0f; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, fv4); fv4[0] = 0.6f; fv4[1] = 0.6f; fv4[2] = 0.6f; fv4[3] = 1.0f; glMaterialfv(GL_FRONT, GL_SPECULAR, fv4); iv1[0] = 40; glMaterialiv(GL_FRONT, GL_SHININESS, iv1); glBindTexture(GL_TEXTURE_2D, uiTexObj); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); glDepthRange(1, 0); glEnableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glEnable(GL_LIGHTING); #endif
if (fDisplayList) { glCallList(iDlist+iPrimType); } else { glDrawElements(ePrimTypes[iPrimType], nIndices, GL_UNSIGNED_INT, pIndices); }
sp++; } break;
case TEST_FILL: glDrawElements(GL_TRIANGLES, nIndices, GL_UNSIGNED_INT, pIndices); break; } if (fSwap && !fSingle) { auxSwapBuffers(); } else { glFinish(); } }
#ifdef PROFILE
if (iMultiLoop > 1) { StopCAP(); } #endif
ms = GetTickCount()-ms;
total_ms += ms; total_tris += nTriangles*iMultiLoop; if (total_ms > 2000) { double val;
switch(iTest) { case TEST_POLYS: val = (double)total_tris*1000.0/total_ms; if (val > peak_tri) { peak_tri = val; } avg_tri += val; break; case TEST_FILL: val = (double)iTriangleArea*total_tris*1000.0/total_ms; if (val > peak_fill) { peak_fill = val; } avg_fill += val; break; } avg_cnt++;
if (fVerbose) { printf("%s, %s", pszPrimTypes[iPrimType], pszShadeModels[iShadeModel]); if (glIsEnabled(GL_CULL_FACE)) { printf(", cull"); } if (glIsEnabled(GL_LIGHTING)) { printf(", lit"); } if (glIsEnabled(GL_TEXTURE_2D)) { printf(", %s", pszTexModes[iTexMode]); } if (glIsEnabled(GL_DITHER)) { printf(", dither"); } if (glIsEnabled(GL_DEPTH_TEST)) { printf(", z"); } #ifdef GL_EXT_clip_volume
glGetIntegerv(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, &iv1[0]); if (iv1[0] != GL_FASTEST) #endif
{ printf(", clip"); } if (fSwap) { printf(", swap"); } if (fRotate) { printf(", rotate"); } if (fBounce) { printf(", bounce"); } if (fPerspective) { printf(", persp"); } printf(", %d tri/frame\n", nTriangles); switch(iTest) { case TEST_POLYS: printf("%d ms, %d tri, %.3lf tri/sec, %.3lf peak, %.3lf avg\n", total_ms, total_tris, val, peak_tri, avg_tri/avg_cnt); break; case TEST_FILL: printf("%d ms, %s, area %d, %.3lf pix/sec, " "%.3lf peak, %.3lf avg\n", total_ms, pszOrders[iOrder], iTriangleArea, val, peak_fill, avg_fill/avg_cnt); break; } } else { char msg[80]; switch(iTest) { case TEST_POLYS: sprintf(msg, "%.3lf tri/sec, %.3lf peak, %.3lf avg", val, peak_tri, avg_tri/avg_cnt); break; case TEST_FILL: sprintf(msg, "%.3lf pix/sec, %.3lf peak, %.3lf avg", val, peak_fill, avg_fill/avg_cnt); break; } SetWindowText(auxGetHWND(), msg); } total_ms = 0; total_tris = 0; } }
void Reshape(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); }
void Step(void) { Redraw(); }
void KeyB(void) { ModeChange(); fBounce = !fBounce; }
void Keyc(void) { ModeChange(); if (glIsEnabled(GL_CULL_FACE)) { glDisable(GL_CULL_FACE); } else { glEnable(GL_CULL_FACE); } }
void KeyC(void) { ModeChange(); fUseScissor = !fUseScissor; }
void Keyh(void) { ModeChange(); if (glIsEnabled(GL_DITHER)) { glDisable(GL_DITHER); } else { glEnable(GL_DITHER); } }
void Keyi(void) { iFillSize = (iFillSize+1) % AREA_COUNT; SetFill(iFillSize, iOrder); }
void Keyl(void) { ModeChange(); if (glIsEnabled(GL_LIGHTING)) { glDisable(GL_LIGHTING); } else { glEnable(GL_LIGHTING); } }
void Keym(void) { ModeChange(); iPolygonMode = (iPolygonMode+1) % POLYMODE_COUNT; glPolygonMode(GL_FRONT_AND_BACK, ePolygonModes[iPolygonMode]); }
void Keyo(void) { iOrder = (iOrder+1) % ORDER_COUNT; SetFill(iFillSize, iOrder); }
void Keyp(void) { ModeChange(); fPerspective = !fPerspective; glHint(GL_PERSPECTIVE_CORRECTION_HINT, fPerspective ? GL_NICEST : GL_FASTEST); }
void KeyP(void) { #ifdef GL_EXT_clip_volume
int iv1[1];
ModeChange(); glGetIntegerv(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, &iv1[0]); if (iv1[0] == GL_FASTEST) { glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_DONT_CARE); } else { glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST); } #endif
}
void KeyR(void) { ModeChange(); fRotate = !fRotate; }
void Keys(void) { ModeChange(); iShadeModel = (iShadeModel+1) % SMODEL_COUNT; glShadeModel(eShadeModels[iShadeModel]); }
void KeyS(void) { fSpread = !fSpread; SetFill(iFillSize, iOrder); }
void Keyt(void) { SetPrim((iPrimType+1) % PRIM_COUNT); }
void KeyT(void) { iTest = (iTest+1) % TEST_COUNT; SetTest(iTest); }
void Keyw(void) { ModeChange(); fSwap = !fSwap; }
void Keyx(void) { ModeChange(); if (glIsEnabled(GL_TEXTURE_2D)) { glDisable(GL_TEXTURE_2D); } else { glEnable(GL_TEXTURE_2D); } }
void KeyX(void) { ModeChange(); iTexMode = (iTexMode+1) % TEXMODE_COUNT; glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, eTexModes[iTexMode]); }
void Keyz(void) { ModeChange(); if (glIsEnabled(GL_DEPTH_TEST)) { glDisable(GL_DEPTH_TEST); } else { glEnable(GL_DEPTH_TEST); } }
void KeySPACE(void) { fPaused = !fPaused; if (fPaused) { auxIdleFunc(NULL); } else { auxIdleFunc(Step); } }
void __cdecl main(int argc, char **argv) { int mode; int wd, ht; char szWinDir[256]; int l;
wd = WIDTH; ht = HEIGHT; while (--argc > 0) { argv++;
if (!strcmp(*argv, "-sb")) { fSingle = TRUE; } else if (!strcmp(*argv, "-paused")) { fPaused = TRUE; } else if (!strcmp(*argv, "-exit")) { fExit = TRUE; } else if (!strcmp(*argv, "-cols")) { fSingleColor = FALSE; } else if (!strcmp(*argv, "-v")) { fVerbose = TRUE; } else if (!strcmp(*argv, "-nodlist")) { fDisplayList = FALSE; } else if (!strcmp(*argv, "-norotate")) { fRotate = FALSE; } else if (!strcmp(*argv, "-nobounce")) { fBounce = FALSE; } else if (!strcmp(*argv, "-noscissor")) { fUseScissor = FALSE; } else if (!strncmp(*argv, "-multi", 6)) { sscanf(*argv+6, "%d", &iMultiLoop); } else if (!strncmp(*argv, "-wd", 3)) { sscanf(*argv+3, "%d", &wd); } else if (!strncmp(*argv, "-ht", 3)) { sscanf(*argv+3, "%d", &ht); } else if (!strncmp(*argv, "-rings", 6)) { sscanf(*argv+6, "%d", &nRings); } else if (!strncmp(*argv, "-sections", 9)) { sscanf(*argv+9, "%d", &nSections); } else if (!strncmp(*argv, "-tst", 4)) { sscanf(*argv+4, "%d", &iTest); } else if (!strncmp(*argv, "-fsz", 4)) { sscanf(*argv+4, "%d", &iFillSize); } } auxInitPosition(10, 10, wd, ht); mode = AUX_RGB | AUX_DEPTH16; if (!fSingle) { mode |= AUX_DOUBLE; } auxInitDisplayMode(mode); auxInitWindow("DrawElements Performance Test");
auxReshapeFunc(Reshape); if (!fPaused) { auxIdleFunc(Step); }
l = GetWindowsDirectory(szWinDir, sizeof(szWinDir)); if (l == 0) { printf("Unable to get windows directory\n"); exit(1); } strcpy(szWinDir+l, "\\cover8.bmp"); pTexture = auxDIBImageLoad(szWinDir); if (pTexture == NULL) { printf("Unable to load texture\n"); exit(1); }
auxKeyFunc(AUX_B, KeyB); auxKeyFunc(AUX_c, Keyc); auxKeyFunc(AUX_C, KeyC); auxKeyFunc(AUX_h, Keyh); auxKeyFunc(AUX_i, Keyi); auxKeyFunc(AUX_l, Keyl); auxKeyFunc(AUX_m, Keym); auxKeyFunc(AUX_o, Keyo); auxKeyFunc(AUX_p, Keyp); auxKeyFunc(AUX_P, KeyP); auxKeyFunc(AUX_R, KeyR); auxKeyFunc(AUX_s, Keys); auxKeyFunc(AUX_S, KeyS); auxKeyFunc(AUX_t, Keyt); auxKeyFunc(AUX_T, KeyT); auxKeyFunc(AUX_w, Keyw); auxKeyFunc(AUX_x, Keyx); auxKeyFunc(AUX_X, KeyX); auxKeyFunc(AUX_z, Keyz); auxKeyFunc(AUX_SPACE, KeySPACE);
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
glAddSwapHintRectWIN = (PFNGLADDSWAPHINTRECTWINPROC) wglGetProcAddress("glAddSwapHintRectWIN");
#if 0
_controlfp((unsigned int) (~(_EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW)), _MCW_EM); #endif
Init();
if (fExit) { Redraw(); } else { auxMainLoop(Redraw); } }
|