home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / utilities / isfast / libisfast / isfast.c next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  12.2 KB  |  505 lines

  1. /*****************************************************************************
  2.  * isfast - routines for subjectively assessing performance of selected
  3.  *        OpenGL drawing operations
  4.  *
  5.  * History:
  6.  *
  7.  *    1.0    9/93    akin    Written.  See accompanying README for
  8.  *                rationale and examples.
  9.  *****************************************************************************/
  10.  
  11.  
  12.  
  13. #include "tk.h"
  14. #include "pdb.h"
  15. #include "isfast.h"
  16.  
  17. #define WINDOW_X    50
  18. #define WINDOW_Y    50
  19. #define WINDOW_W    400
  20. #define WINDOW_H    400
  21.  
  22.  
  23.  
  24. static double    BaseTriangleRate = 0.0;
  25. static double    DisplayListRate = 0.0;
  26. static double    NoDepthBufferRate = 0.0;
  27. static double    StencillingRate = 0.0;
  28. static double    TextureMappingRate = 0.0;
  29.  
  30. static const char* cIsFast = "IsFast";
  31. static const char* cBaseTriangle = "BaseTriangle";
  32.  
  33.  
  34.  
  35. static void    BaseTriangleTest    (int width,
  36.                      int height);
  37. static void    DisplayListTest        (int width,
  38.                      int height);
  39. static void    DrawBaseTriangles    (void);
  40. static void    DrawDisplayList        (void);
  41. static void    NoDepthBufferTest    (int width,
  42.                      int height);
  43. static int    RunTest            (void (*testFunction)(int, int),
  44.                      const char* testName,
  45.                      double* rate,
  46.                      GLenum windowType);
  47. static int    Setup            (GLenum windowType,
  48.                      const char* windowTitle,
  49.                      void (*testFunc)(int, int));
  50. static void    StencillingTest        (int width,
  51.                      int height);
  52. static void    TextureMappingTest    (int width,
  53.                      int height);
  54. static void    Viewport        (int width,
  55.                      int height);
  56.  
  57.  
  58.  
  59. /*****************************************************************************
  60.  * BaseTriangleTest - measure drawing rate for baseline triangles
  61.  *****************************************************************************/
  62.  
  63. static void
  64. BaseTriangleTest(int width, int height)
  65.     {
  66.     Viewport(width, height);
  67.  
  68.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  69.  
  70.     glPushAttrib(GL_DEPTH_BUFFER_BIT);
  71.     glDepthFunc(GL_LEQUAL);        /* force some drawing to occur */
  72.  
  73.     pdbMeasureRate(glFinish, DrawBaseTriangles, glFinish,
  74.         &BaseTriangleRate);
  75.     
  76.     glPopAttrib();
  77.     
  78.     tkExit();
  79.     }
  80.  
  81.  
  82.  
  83. /*****************************************************************************
  84.  * DepthBufferingIsFast - see if depth-buffered triangles are at least half as
  85.  *              fast as triangles without depth-buffering
  86.  *****************************************************************************/
  87.  
  88. int
  89. DepthBufferingIsFast(void)
  90.     {
  91.     if (!RunTest(BaseTriangleTest, cBaseTriangle, &BaseTriangleRate,
  92.         TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
  93.         return 0;
  94.  
  95.     if (!RunTest(NoDepthBufferTest, "NoDepthBuffer", &NoDepthBufferRate,
  96.         TK_RGB | TK_SINGLE | TK_DIRECT))
  97.         return 0;
  98.  
  99.     return BaseTriangleRate > 0.5 * NoDepthBufferRate;
  100.     }
  101.  
  102.  
  103.  
  104. /*****************************************************************************
  105.  * DisplayListTest - measure drawing rate for display-listed triangle strip
  106.  *****************************************************************************/
  107.  
  108. static void
  109. DisplayListTest(int width, int height)
  110.     {
  111.     Viewport(width, height);
  112.  
  113.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  114.  
  115.     glPushAttrib(GL_DEPTH_BUFFER_BIT);
  116.     glDepthFunc(GL_LEQUAL);        /* force some drawing to occur */
  117.  
  118.     glNewList(1, GL_COMPILE);
  119.         DrawBaseTriangles();
  120.     glEndList();
  121.  
  122.     pdbMeasureRate(glFinish, DrawDisplayList, glFinish, &DisplayListRate);
  123.  
  124.     glDeleteLists(1, 1);
  125.     glPopAttrib();
  126.     
  127.     tkExit();
  128.     }
  129.  
  130.  
  131.  
  132. /*****************************************************************************
  133.  * DrawBaseTriangles - draw a simple triangle strip
  134.  *
  135.  * The caller must enable the appropriate options, e.g. lighting, depth
  136.  * buffering, texturing.
  137.  *****************************************************************************/
  138.  
  139. static void
  140. DrawBaseTriangles(void)
  141.     {
  142.     static const GLfloat vertex[] =
  143.         {
  144.          0.9,  0.0,
  145.          0.85, 0.1,
  146.          0.8,  0.0,
  147.          0.75, 0.1,
  148.          0.7,  0.0,
  149.          0.65, 0.1,
  150.          0.6,  0.0,
  151.          0.55, 0.1,
  152.          0.5,  0.0,
  153.          0.45, 0.1,
  154.          0.4,  0.0,
  155.          0.35, 0.1,
  156.          0.3,  0.0,
  157.          0.25, 0.1,
  158.          0.2,  0.0,
  159.          0.15, 0.1,
  160.          0.1,  0.0,
  161.          0.05, 0.1,
  162.          0.0,  0.0,
  163.         -0.05, 0.1,
  164.         -0.1,  0.0,
  165.         -0.15, 0.1,
  166.         -0.2,  0.0,
  167.         -0.25, 0.1,
  168.         -0.3,  0.0,
  169.         -0.35, 0.1,
  170.         -0.4,  0.0,
  171.         -0.45, 0.1,
  172.         -0.5,  0.0,
  173.         -0.55, 0.1,
  174.         -0.6,  0.0,
  175.         -0.65, 0.1,
  176.         -0.7,  0.0,
  177.         -0.75, 0.1,
  178.         -0.8,  0.0,
  179.         -0.85, 0.1,
  180.         -0.9,  0.0
  181.         };
  182.     register int i;
  183.  
  184.     glBegin(GL_TRIANGLE_STRIP);
  185.         glNormal3f(0.0, 0.0, 1.0);
  186.         for (i = 0; i < sizeof(vertex) / sizeof(vertex[0]); i += 2)
  187.             glVertex2fv(vertex + i);
  188.     glEnd();
  189.     }
  190.  
  191.  
  192.  
  193. /*****************************************************************************
  194.  * DrawDisplayList - draw display list created by DisplayListTest
  195.  *****************************************************************************/
  196.  
  197. static void
  198. DrawDisplayList(void)
  199.     {
  200.     glCallList(1);
  201.     }
  202.  
  203.  
  204.  
  205. /*****************************************************************************
  206.  * ImmediateModeIsFast - see if immediate-mode triangles are at least half as
  207.  *             fast as display-listed triangles
  208.  *****************************************************************************/
  209.  
  210. int
  211. ImmediateModeIsFast(void)
  212.     {
  213.     if (!RunTest(BaseTriangleTest, cBaseTriangle, &BaseTriangleRate,
  214.         TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
  215.         return 0;
  216.  
  217.     if (!RunTest(DisplayListTest, "DisplayList", &DisplayListRate,
  218.         TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
  219.         return 0;
  220.     
  221.     return BaseTriangleRate > 0.5 * DisplayListRate;
  222.     }
  223.  
  224.  
  225.  
  226. /*****************************************************************************
  227.  * NoDepthBufferTest - draw triangles without depth buffering
  228.  *****************************************************************************/
  229.  
  230. static void
  231. NoDepthBufferTest(int width, int height)
  232.     {
  233.     Viewport(width, height);
  234.  
  235.     glClear(GL_COLOR_BUFFER_BIT);
  236.  
  237.     glPushAttrib(GL_DEPTH_BUFFER_BIT);
  238.     glDisable(GL_DEPTH_TEST);
  239.  
  240.     pdbMeasureRate(glFinish, DrawBaseTriangles, glFinish,
  241.        &NoDepthBufferRate);
  242.     
  243.     glPopAttrib();
  244.     tkExit();
  245.     }
  246.  
  247.  
  248.  
  249. /*****************************************************************************
  250.  * RunTest - if performance data for a given test is in the database, return
  251.  *         it; otherwise create a window, measure the test's drawing rate,
  252.  *         and save the result in the database
  253.  *****************************************************************************/
  254.  
  255. static int
  256. RunTest
  257.     (
  258.     void    (*testFunction)(int, int),
  259.     const char*    testName,
  260.     double*    rate,
  261.     GLenum    windowType
  262.     )
  263.     {
  264.     if (pdbReadRate(NULL, cIsFast, testName, rate) == PDB_NO_ERROR)
  265.         return 1;
  266.  
  267.     if (!Setup(windowType, testName, testFunction))
  268.         return 0;
  269.  
  270.     tkExec();
  271.     tkCloseWindow();
  272.     
  273.     pdbWriteRate(NULL, cIsFast, testName, *rate);
  274.  
  275.     return 1;
  276.     }
  277.  
  278.  
  279.  
  280. /*****************************************************************************
  281.  * Setup - create a libtk window and set default OpenGL state
  282.  *****************************************************************************/
  283.  
  284. static int
  285. Setup
  286.     (
  287.     GLenum    windowType,
  288.     const char*    windowTitle,
  289.     void    (*testFunc)(int, int)
  290.     )
  291.     {
  292.     static const GLfloat diffuse[] = {0.5, 0.5, 0.5, 1.0};
  293.     static const GLfloat specular[] = {0.5, 0.5, 0.5, 1.0};
  294.     static const GLfloat direction[] = {1.0, 1.0, 1.0, 0.0};
  295.     static const GLfloat matAmbient[] = {0.1, 0.1, 0.1, 1.0};
  296.     static const GLfloat matSpecular[] = {0.5, 0.5, 0.5, 1.0};
  297.  
  298.     tkInitPosition(WINDOW_X, WINDOW_Y, WINDOW_W, WINDOW_H);
  299.     tkInitDisplayMode(windowType);
  300.     if (tkInitWindow((char*) windowTitle) == GL_FALSE)
  301.         return 0;
  302.  
  303.     glEnable(GL_CULL_FACE);
  304.     glCullFace(GL_BACK);
  305.  
  306.     if (TK_HAS_DEPTH(windowType))
  307.         {
  308.         glEnable(GL_DEPTH_TEST);
  309.         glClearDepth(1.0);
  310.         }
  311.     
  312.     if (TK_HAS_STENCIL(windowType))
  313.         glClearStencil(0);
  314.  
  315.     glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  316.     glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
  317.     glLightfv(GL_LIGHT0, GL_POSITION, direction);
  318.     glEnable(GL_LIGHT0);
  319.     glEnable(GL_LIGHTING);
  320.  
  321.     glMaterialfv(GL_FRONT, GL_AMBIENT, matAmbient);
  322.     glMaterialfv(GL_FRONT, GL_SPECULAR, matSpecular);
  323.     glMateriali(GL_FRONT, GL_SHININESS, 128);
  324.     glEnable(GL_COLOR_MATERIAL);
  325.     glShadeModel(GL_SMOOTH);
  326.  
  327.     glMatrixMode(GL_PROJECTION);
  328.     gluPerspective(45.0, 1.0, 2.4, 4.6);
  329.     glMatrixMode(GL_MODELVIEW);
  330.  
  331.     gluLookAt(0.0,0.0,3.5, 0.0,0.0,0.0, 0.0,1.0,0.0);
  332.  
  333.     tkExposeFunc(testFunc);
  334.  
  335.     return 1;
  336.     }
  337.  
  338.  
  339.  
  340. /*****************************************************************************
  341.  * StencillingIsFast - see if stencilled triangles are at least half as fast
  342.  *               as non-stencilled triangles
  343.  *****************************************************************************/
  344.  
  345. int
  346. StencillingIsFast(void)
  347.     {
  348.     if (!RunTest(BaseTriangleTest, cBaseTriangle, &BaseTriangleRate,
  349.         TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
  350.         return 0;
  351.  
  352.     if (!RunTest(StencillingTest, "Stencilling", &StencillingRate,
  353.         TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH | TK_STENCIL))
  354.         return 0;
  355.  
  356.     return StencillingRate > 0.5 * BaseTriangleRate;
  357.     }
  358.  
  359.  
  360.  
  361. /*****************************************************************************
  362.  * StencillingTest - draw triangles with nontrivial stencil operations
  363.  *****************************************************************************/
  364.  
  365. static void
  366. StencillingTest(int width, int height)
  367.     {
  368.     Viewport(width, height);
  369.  
  370.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
  371.         | GL_STENCIL_BUFFER_BIT);
  372.  
  373.     glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  374.     glDepthFunc(GL_LEQUAL);
  375.  
  376.     glStencilFunc(GL_EQUAL, 1, 1);
  377.     glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
  378.     glEnable(GL_STENCIL_TEST);
  379.  
  380.     pdbMeasureRate(glFinish, DrawBaseTriangles, glFinish,
  381.         &StencillingRate);
  382.     
  383.     glPopAttrib();
  384.     
  385.     tkExit();
  386.     }
  387.  
  388.  
  389.  
  390. /*****************************************************************************
  391.  * TextureMappingIsFast - see if texture-mapped triangles are at least half as
  392.  *              fast as ordinary shaded triangles
  393.  *****************************************************************************/
  394.  
  395. int
  396. TextureMappingIsFast(void)
  397.     {
  398.     if (!RunTest(BaseTriangleTest, cBaseTriangle, &BaseTriangleRate,
  399.         TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
  400.         return 0;
  401.  
  402.     if (!RunTest(TextureMappingTest, "TextureMapping", &TextureMappingRate,
  403.         TK_RGB | TK_SINGLE | TK_DIRECT | TK_DEPTH))
  404.         return 0;
  405.  
  406.     return TextureMappingRate > 0.5 * BaseTriangleRate;
  407.     }
  408.  
  409.  
  410.  
  411. /*****************************************************************************
  412.  * TextureMappingTest - draw baseline triangles with texture mapping
  413.  *****************************************************************************/
  414.  
  415. static void
  416. TextureMappingTest(int width, int height)
  417.     {
  418.     GLubyte texture[8][8][3];
  419.     int i;
  420.     int j;
  421.     int c;
  422.  
  423.     Viewport(width, height);
  424.  
  425.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  426.  
  427.     for (i = 0; i < 8; ++i)
  428.         for (j = 0; j < 8; ++j)
  429.             {
  430.             c = ((i & 0x1) ^ (j & 0x1))? 255: 0;
  431.             texture[i][j][0] = c;
  432.             texture[i][j][1] = texture[i][j][2] = 0;
  433.             }
  434.  
  435.     glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_TEXTURE_BIT);
  436.  
  437.         glDepthFunc(GL_LEQUAL);
  438.  
  439.         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  440.         gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 8, 8, GL_RGB,
  441.             GL_UNSIGNED_BYTE, texture);
  442.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  443.             GL_NEAREST);
  444.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  445.             GL_NEAREST);
  446.         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  447.         glEnable(GL_TEXTURE_2D);
  448.  
  449.         glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  450.         glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  451.         glEnable(GL_TEXTURE_GEN_S);
  452.         glEnable(GL_TEXTURE_GEN_T);
  453.  
  454.         glMatrixMode(GL_TEXTURE);
  455.         glPushMatrix();
  456.         glLoadIdentity();
  457.         glScalef(4.0, 4.0, 1.0);
  458.         glMatrixMode(GL_MODELVIEW);
  459.  
  460.             pdbMeasureRate(glFinish, DrawBaseTriangles, glFinish,
  461.                 &TextureMappingRate);
  462.         
  463.         glMatrixMode(GL_TEXTURE);
  464.         glPopMatrix();
  465.         glMatrixMode(GL_MODELVIEW);
  466.  
  467.     glPopAttrib();
  468.     
  469.     tkExit();
  470.     }
  471.  
  472.  
  473.  
  474. /*****************************************************************************
  475.  * Viewport - force OpenGL viewport transformation to track window dimensions
  476.  *
  477.  * Maintains aspect ratio of image and avoids clipping pixels that would be
  478.  * visible if the aspect ratio was 1.0.  Does not need assistance from window
  479.  * system to maintain aspect ratio.
  480.  *****************************************************************************/
  481.  
  482. static void
  483. Viewport(int width, int height)
  484.     {
  485.     int viewportX;
  486.     int viewportY;
  487.     int viewportW;
  488.     int viewportH;
  489.  
  490.     if (width <= height)
  491.         {
  492.         viewportX = 0;
  493.         viewportY = (height - width) / 2;
  494.         viewportW = viewportH = width;
  495.         }
  496.     else
  497.         {
  498.         viewportX = (width - height) / 2;
  499.         viewportY = 0;
  500.         viewportW = viewportH = height;
  501.         }
  502.  
  503.     glViewport(viewportX, viewportY, viewportW, viewportH);
  504.     }
  505.