home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * isfast - routines for subjectively assessing performance of selected
- * OpenGL drawing operations
- *
- * History:
- *
- * 1.0 9/93 akin Written. See accompanying README for
- * rationale and examples.
- *****************************************************************************/
-
-
-
- #include "tk.h"
- #include "pdb.h"
- #include "isfast.h"
-
- #define WINDOW_X 50
- #define WINDOW_Y 50
- #define WINDOW_W 400
- #define WINDOW_H 400
-
-
-
- static double BaseTriangleRate = 0.0;
- static double DisplayListRate = 0.0;
- static double NoDepthBufferRate = 0.0;
- static double StencillingRate = 0.0;
- static double TextureMappingRate = 0.0;
-
- static const char* cIsFast = "IsFast";
- static const char* cBaseTriangle = "BaseTriangle";
-
-
-
- static void BaseTriangleTest (int width,
- int height);
- static void DisplayListTest (int width,
- int height);
- static void DrawBaseTriangles (void);
- static void DrawDisplayList (void);
- static void NoDepthBufferTest (int width,
- int height);
- static int RunTest (void (*testFunction)(int, int),
- const char* testName,
- double* rate,
- GLenum windowType);
- static int Setup (GLenum windowType,
- const char* windowTitle,
- void (*testFunc)(int, int));
- static void StencillingTest (int width,
- int height);
- static void TextureMappingTest (int width,
- int height);
- static void Viewport (int width,
- int height);
-
-
-
- /*****************************************************************************
- * BaseTriangleTest - measure drawing rate for baseline triangles
- *****************************************************************************/
-
- static void
- BaseTriangleTest(int width, int height)
- {
- Viewport(width, height);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glPushAttrib(GL_DEPTH_BUFFER_BIT);
- glDepthFunc(GL_LEQUAL); /* force some drawing to occur */
-
- pdbMeasureRate(glFinish, DrawBaseTriangles, glFinish,
- &BaseTriangleRate);
-
- glPopAttrib();
-
- tkExit();
- }
-
-
-
- /*****************************************************************************
- * DepthBufferingIsFast - see if depth-buffered triangles are at least half as
- * fast as triangles without depth-buffering
- *****************************************************************************/
-
- int
- DepthBufferingIsFast(void)
- {
- if (!RunTest(BaseTriangleTest, cBaseTriangle, &BaseTriangleRate,
- TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
- return 0;
-
- if (!RunTest(NoDepthBufferTest, "NoDepthBuffer", &NoDepthBufferRate,
- TK_RGB | TK_SINGLE | TK_DIRECT))
- return 0;
-
- return BaseTriangleRate > 0.5 * NoDepthBufferRate;
- }
-
-
-
- /*****************************************************************************
- * DisplayListTest - measure drawing rate for display-listed triangle strip
- *****************************************************************************/
-
- static void
- DisplayListTest(int width, int height)
- {
- Viewport(width, height);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glPushAttrib(GL_DEPTH_BUFFER_BIT);
- glDepthFunc(GL_LEQUAL); /* force some drawing to occur */
-
- glNewList(1, GL_COMPILE);
- DrawBaseTriangles();
- glEndList();
-
- pdbMeasureRate(glFinish, DrawDisplayList, glFinish, &DisplayListRate);
-
- glDeleteLists(1, 1);
- glPopAttrib();
-
- tkExit();
- }
-
-
-
- /*****************************************************************************
- * DrawBaseTriangles - draw a simple triangle strip
- *
- * The caller must enable the appropriate options, e.g. lighting, depth
- * buffering, texturing.
- *****************************************************************************/
-
- static void
- DrawBaseTriangles(void)
- {
- static const GLfloat vertex[] =
- {
- 0.9, 0.0,
- 0.85, 0.1,
- 0.8, 0.0,
- 0.75, 0.1,
- 0.7, 0.0,
- 0.65, 0.1,
- 0.6, 0.0,
- 0.55, 0.1,
- 0.5, 0.0,
- 0.45, 0.1,
- 0.4, 0.0,
- 0.35, 0.1,
- 0.3, 0.0,
- 0.25, 0.1,
- 0.2, 0.0,
- 0.15, 0.1,
- 0.1, 0.0,
- 0.05, 0.1,
- 0.0, 0.0,
- -0.05, 0.1,
- -0.1, 0.0,
- -0.15, 0.1,
- -0.2, 0.0,
- -0.25, 0.1,
- -0.3, 0.0,
- -0.35, 0.1,
- -0.4, 0.0,
- -0.45, 0.1,
- -0.5, 0.0,
- -0.55, 0.1,
- -0.6, 0.0,
- -0.65, 0.1,
- -0.7, 0.0,
- -0.75, 0.1,
- -0.8, 0.0,
- -0.85, 0.1,
- -0.9, 0.0
- };
- register int i;
-
- glBegin(GL_TRIANGLE_STRIP);
- glNormal3f(0.0, 0.0, 1.0);
- for (i = 0; i < sizeof(vertex) / sizeof(vertex[0]); i += 2)
- glVertex2fv(vertex + i);
- glEnd();
- }
-
-
-
- /*****************************************************************************
- * DrawDisplayList - draw display list created by DisplayListTest
- *****************************************************************************/
-
- static void
- DrawDisplayList(void)
- {
- glCallList(1);
- }
-
-
-
- /*****************************************************************************
- * ImmediateModeIsFast - see if immediate-mode triangles are at least half as
- * fast as display-listed triangles
- *****************************************************************************/
-
- int
- ImmediateModeIsFast(void)
- {
- if (!RunTest(BaseTriangleTest, cBaseTriangle, &BaseTriangleRate,
- TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
- return 0;
-
- if (!RunTest(DisplayListTest, "DisplayList", &DisplayListRate,
- TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
- return 0;
-
- return BaseTriangleRate > 0.5 * DisplayListRate;
- }
-
-
-
- /*****************************************************************************
- * NoDepthBufferTest - draw triangles without depth buffering
- *****************************************************************************/
-
- static void
- NoDepthBufferTest(int width, int height)
- {
- Viewport(width, height);
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- glPushAttrib(GL_DEPTH_BUFFER_BIT);
- glDisable(GL_DEPTH_TEST);
-
- pdbMeasureRate(glFinish, DrawBaseTriangles, glFinish,
- &NoDepthBufferRate);
-
- glPopAttrib();
- tkExit();
- }
-
-
-
- /*****************************************************************************
- * RunTest - if performance data for a given test is in the database, return
- * it; otherwise create a window, measure the test's drawing rate,
- * and save the result in the database
- *****************************************************************************/
-
- static int
- RunTest
- (
- void (*testFunction)(int, int),
- const char* testName,
- double* rate,
- GLenum windowType
- )
- {
- if (pdbReadRate(NULL, cIsFast, testName, rate) == PDB_NO_ERROR)
- return 1;
-
- if (!Setup(windowType, testName, testFunction))
- return 0;
-
- tkExec();
- tkCloseWindow();
-
- pdbWriteRate(NULL, cIsFast, testName, *rate);
-
- return 1;
- }
-
-
-
- /*****************************************************************************
- * Setup - create a libtk window and set default OpenGL state
- *****************************************************************************/
-
- static int
- Setup
- (
- GLenum windowType,
- const char* windowTitle,
- void (*testFunc)(int, int)
- )
- {
- static const GLfloat diffuse[] = {0.5, 0.5, 0.5, 1.0};
- static const GLfloat specular[] = {0.5, 0.5, 0.5, 1.0};
- static const GLfloat direction[] = {1.0, 1.0, 1.0, 0.0};
- static const GLfloat matAmbient[] = {0.1, 0.1, 0.1, 1.0};
- static const GLfloat matSpecular[] = {0.5, 0.5, 0.5, 1.0};
-
- tkInitPosition(WINDOW_X, WINDOW_Y, WINDOW_W, WINDOW_H);
- tkInitDisplayMode(windowType);
- if (tkInitWindow((char*) windowTitle) == GL_FALSE)
- return 0;
-
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
-
- if (TK_HAS_DEPTH(windowType))
- {
- glEnable(GL_DEPTH_TEST);
- glClearDepth(1.0);
- }
-
- if (TK_HAS_STENCIL(windowType))
- glClearStencil(0);
-
- glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
- glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
- glLightfv(GL_LIGHT0, GL_POSITION, direction);
- glEnable(GL_LIGHT0);
- glEnable(GL_LIGHTING);
-
- glMaterialfv(GL_FRONT, GL_AMBIENT, matAmbient);
- glMaterialfv(GL_FRONT, GL_SPECULAR, matSpecular);
- glMateriali(GL_FRONT, GL_SHININESS, 128);
- glEnable(GL_COLOR_MATERIAL);
- glShadeModel(GL_SMOOTH);
-
- glMatrixMode(GL_PROJECTION);
- gluPerspective(45.0, 1.0, 2.4, 4.6);
- glMatrixMode(GL_MODELVIEW);
-
- gluLookAt(0.0,0.0,3.5, 0.0,0.0,0.0, 0.0,1.0,0.0);
-
- tkExposeFunc(testFunc);
-
- return 1;
- }
-
-
-
- /*****************************************************************************
- * StencillingIsFast - see if stencilled triangles are at least half as fast
- * as non-stencilled triangles
- *****************************************************************************/
-
- int
- StencillingIsFast(void)
- {
- if (!RunTest(BaseTriangleTest, cBaseTriangle, &BaseTriangleRate,
- TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
- return 0;
-
- if (!RunTest(StencillingTest, "Stencilling", &StencillingRate,
- TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH | TK_STENCIL))
- return 0;
-
- return StencillingRate > 0.5 * BaseTriangleRate;
- }
-
-
-
- /*****************************************************************************
- * StencillingTest - draw triangles with nontrivial stencil operations
- *****************************************************************************/
-
- static void
- StencillingTest(int width, int height)
- {
- Viewport(width, height);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
- | GL_STENCIL_BUFFER_BIT);
-
- glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- glDepthFunc(GL_LEQUAL);
-
- glStencilFunc(GL_EQUAL, 1, 1);
- glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
- glEnable(GL_STENCIL_TEST);
-
- pdbMeasureRate(glFinish, DrawBaseTriangles, glFinish,
- &StencillingRate);
-
- glPopAttrib();
-
- tkExit();
- }
-
-
-
- /*****************************************************************************
- * TextureMappingIsFast - see if texture-mapped triangles are at least half as
- * fast as ordinary shaded triangles
- *****************************************************************************/
-
- int
- TextureMappingIsFast(void)
- {
- if (!RunTest(BaseTriangleTest, cBaseTriangle, &BaseTriangleRate,
- TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
- return 0;
-
- if (!RunTest(TextureMappingTest, "TextureMapping", &TextureMappingRate,
- TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
- return 0;
-
- return TextureMappingRate > 0.5 * BaseTriangleRate;
- }
-
-
-
- /*****************************************************************************
- * TextureMappingTest - draw baseline triangles with texture mapping
- *****************************************************************************/
-
- static void
- TextureMappingTest(int width, int height)
- {
- GLubyte texture[8][8][3];
- int i;
- int j;
- int c;
-
- Viewport(width, height);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- for (i = 0; i < 8; ++i)
- for (j = 0; j < 8; ++j)
- {
- c = ((i & 0x1) ^ (j & 0x1))? 255: 0;
- texture[i][j][0] = c;
- texture[i][j][1] = texture[i][j][2] = 0;
- }
-
- glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_TEXTURE_BIT);
-
- glDepthFunc(GL_LEQUAL);
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 8, 8, GL_RGB,
- GL_UNSIGNED_BYTE, texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
- GL_NEAREST);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
- glEnable(GL_TEXTURE_2D);
-
- glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
-
- glMatrixMode(GL_TEXTURE);
- glPushMatrix();
- glLoadIdentity();
- glScalef(4.0, 4.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
-
- pdbMeasureRate(glFinish, DrawBaseTriangles, glFinish,
- &TextureMappingRate);
-
- glMatrixMode(GL_TEXTURE);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
-
- glPopAttrib();
-
- tkExit();
- }
-
-
-
- /*****************************************************************************
- * Viewport - force OpenGL viewport transformation to track window dimensions
- *
- * Maintains aspect ratio of image and avoids clipping pixels that would be
- * visible if the aspect ratio was 1.0. Does not need assistance from window
- * system to maintain aspect ratio.
- *****************************************************************************/
-
- static void
- Viewport(int width, int height)
- {
- int viewportX;
- int viewportY;
- int viewportW;
- int viewportH;
-
- if (width <= height)
- {
- viewportX = 0;
- viewportY = (height - width) / 2;
- viewportW = viewportH = width;
- }
- else
- {
- viewportX = (width - height) / 2;
- viewportY = 0;
- viewportW = viewportH = height;
- }
-
- glViewport(viewportX, viewportY, viewportW, viewportH);
- }
-