132001f49Smrg
232001f49Smrg/*
332001f49Smrg * Simple GLUT program to measure triangle strip rendering speed.
432001f49Smrg * Brian Paul  February 15, 1997  This file is in the public domain.
532001f49Smrg */
632001f49Smrg
732001f49Smrg#include <stdio.h>
832001f49Smrg#include <stdlib.h>
932001f49Smrg#include <math.h>
1032001f49Smrg#include <string.h>
1132001f49Smrg#include "glut_wrap.h"
1232001f49Smrg
1332001f49Smrg
1432001f49Smrgstatic float MinPeriod = 2.0;   /* 2 seconds */
1532001f49Smrgstatic float Width = 400.0;
1632001f49Smrgstatic float Height = 400.0;
1732001f49Smrgstatic int Loops = 1;
1832001f49Smrgstatic int Size = 50;
1932001f49Smrgstatic int Texture = 0;
2032001f49Smrg
2132001f49Smrg
2232001f49Smrg
2332001f49Smrgstatic void Idle( void )
2432001f49Smrg{
2532001f49Smrg   glutPostRedisplay();
2632001f49Smrg}
2732001f49Smrg
2832001f49Smrg
2932001f49Smrgstatic void Display( void )
3032001f49Smrg{
3132001f49Smrg   float x, y;
3232001f49Smrg   float xStep;
3332001f49Smrg   float yStep;
3432001f49Smrg   double t0, t1;
3532001f49Smrg   double triRate;
3632001f49Smrg   double pixelRate;
3732001f49Smrg   int triCount;
3832001f49Smrg   int i;
3932001f49Smrg   float red[3] = { 1.0, 0.0, 0.0 };
4032001f49Smrg   float blue[3] = { 0.0, 0.0, 1.0 };
4132001f49Smrg
4232001f49Smrg   xStep = yStep = sqrt( 2.0 * Size );
4332001f49Smrg
4432001f49Smrg   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
4532001f49Smrg
4632001f49Smrg   triCount = 0;
4732001f49Smrg   t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
4832001f49Smrg   if (Texture) {
4932001f49Smrg      float uStep = xStep / Width;
5032001f49Smrg      float vStep = yStep / Height;
5132001f49Smrg      float u, v;
5232001f49Smrg      for (i=0; i<Loops; i++) {
5332001f49Smrg	 for (y=1.0, v=0.0f; y<Height-yStep; y+=yStep, v+=vStep) {
5432001f49Smrg	    glBegin(GL_TRIANGLE_STRIP);
5532001f49Smrg	    for (x=1.0, u=0.0f; x<Width; x+=xStep, u+=uStep) {
5632001f49Smrg	       glColor3fv(red);
5732001f49Smrg	       glTexCoord2f(u, v);
5832001f49Smrg	       glVertex2f(x, y);
5932001f49Smrg	       glColor3fv(blue);
6032001f49Smrg	       glTexCoord2f(u, v+vStep);
6132001f49Smrg	       glVertex2f(x, y+yStep);
6232001f49Smrg	       triCount += 2;
6332001f49Smrg	    }
6432001f49Smrg	    glEnd();
6532001f49Smrg	    triCount -= 2;
6632001f49Smrg	 }
6732001f49Smrg      }
6832001f49Smrg   }
6932001f49Smrg   else {
7032001f49Smrg      for (i=0; i<Loops; i++) {
7132001f49Smrg	 for (y=1.0; y<Height-yStep; y+=yStep) {
7232001f49Smrg	    glBegin(GL_TRIANGLE_STRIP);
7332001f49Smrg	    for (x=1.0; x<Width; x+=xStep) {
7432001f49Smrg	       glColor3fv(red);
7532001f49Smrg	       glVertex2f(x, y);
7632001f49Smrg	       glColor3fv(blue);
7732001f49Smrg	       glVertex2f(x, y+yStep);
7832001f49Smrg	       triCount += 2;
7932001f49Smrg	    }
8032001f49Smrg	    glEnd();
8132001f49Smrg	    triCount -= 2;
8232001f49Smrg	 }
8332001f49Smrg      }
8432001f49Smrg   }
8532001f49Smrg   glFinish();
8632001f49Smrg   t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
8732001f49Smrg
8832001f49Smrg   if (t1-t0 < MinPeriod) {
8932001f49Smrg      /* Next time draw more triangles to get longer elapsed time */
9032001f49Smrg      Loops *= 2;
9132001f49Smrg      return;
9232001f49Smrg   }
9332001f49Smrg
9432001f49Smrg   triRate = triCount / (t1-t0);
9532001f49Smrg   pixelRate = triRate * Size;
9632001f49Smrg   printf("Rate: %d tri in %gs = %g tri/s  %d pixels/s\n",
9732001f49Smrg          triCount, t1-t0, triRate, (int)pixelRate);
987ec3b29aSmrg   fflush(stdout);
9932001f49Smrg
10032001f49Smrg   glutSwapBuffers();
10132001f49Smrg}
10232001f49Smrg
10332001f49Smrg
10432001f49Smrgstatic void Reshape( int width, int height )
10532001f49Smrg{
10632001f49Smrg   Width = width;
10732001f49Smrg   Height = height;
10832001f49Smrg   glViewport( 0, 0, width, height );
10932001f49Smrg   glMatrixMode( GL_PROJECTION );
11032001f49Smrg   glLoadIdentity();
11132001f49Smrg   glOrtho(0.0, width, 0.0, height, -1.0, 1.0);
11232001f49Smrg   glMatrixMode( GL_MODELVIEW );
11332001f49Smrg   glLoadIdentity();
11432001f49Smrg}
11532001f49Smrg
11632001f49Smrg
11732001f49Smrgstatic void Key( unsigned char key, int x, int y )
11832001f49Smrg{
11932001f49Smrg   (void) x;
12032001f49Smrg   (void) y;
12132001f49Smrg   switch (key) {
12232001f49Smrg      case 27:
12332001f49Smrg         exit(0);
12432001f49Smrg         break;
12532001f49Smrg   }
12632001f49Smrg   glutPostRedisplay();
12732001f49Smrg}
12832001f49Smrg
12932001f49Smrg
13032001f49Smrgstatic void LoadTex(int comp, int filter)
13132001f49Smrg{
13232001f49Smrg   GLubyte *pixels;
13332001f49Smrg   int x, y;
13432001f49Smrg   pixels = (GLubyte *) malloc(4*256*256);
13532001f49Smrg   for (y = 0; y < 256; ++y)
13632001f49Smrg      for (x = 0; x < 256; ++x) {
13732001f49Smrg	 pixels[(y*256+x)*4+0] = (int)(128.5 + 127.0 * cos(0.024544 * x));
13832001f49Smrg	 pixels[(y*256+x)*4+1] = 255;
13932001f49Smrg	 pixels[(y*256+x)*4+2] = (int)(128.5 + 127.0 * cos(0.024544 * y));
14032001f49Smrg	 pixels[(y*256+x)*4+3] = 255;
14132001f49Smrg      }
14232001f49Smrg   glEnable(GL_TEXTURE_2D);
14332001f49Smrg   glTexImage2D(GL_TEXTURE_2D, 0, comp, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
14432001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
14532001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
14632001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
14732001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
14832001f49Smrg   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
14932001f49Smrg   printf("Texture: GL_MODULATE, %d comps, %s\n", comp, filter == GL_NEAREST ? "GL_NEAREST" : "GL_LINEAR");
15032001f49Smrg}
15132001f49Smrg
15232001f49Smrg
15332001f49Smrgstatic void Init( int argc, char *argv[] )
15432001f49Smrg{
15532001f49Smrg   GLint shade;
15632001f49Smrg   GLint rBits, gBits, bBits;
15732001f49Smrg   int filter = GL_NEAREST, comp = 3;
15832001f49Smrg
15932001f49Smrg   int i;
16032001f49Smrg   for (i=1; i<argc; i++) {
16132001f49Smrg      if (strcmp(argv[i],"-dither")==0)
16232001f49Smrg         glDisable(GL_DITHER);
16332001f49Smrg      else if (strcmp(argv[i],"+dither")==0)
16432001f49Smrg         glEnable(GL_DITHER);
16532001f49Smrg      else if (strcmp(argv[i],"+smooth")==0)
16632001f49Smrg         glShadeModel(GL_SMOOTH);
16732001f49Smrg      else if (strcmp(argv[i],"+flat")==0)
16832001f49Smrg         glShadeModel(GL_FLAT);
16932001f49Smrg      else if (strcmp(argv[i],"+depth")==0)
17032001f49Smrg         glEnable(GL_DEPTH_TEST);
17132001f49Smrg      else if (strcmp(argv[i],"-depth")==0)
17232001f49Smrg         glDisable(GL_DEPTH_TEST);
17332001f49Smrg      else if (strcmp(argv[i],"-size")==0) {
17432001f49Smrg         Size = atoi(argv[i+1]);
17532001f49Smrg         i++;
17632001f49Smrg      }
17732001f49Smrg      else if (strcmp(argv[i],"-texture")==0)
17832001f49Smrg	 Texture = 0;
17932001f49Smrg      else if (strcmp(argv[i],"+texture")==0)
18032001f49Smrg	 Texture = 1;
18132001f49Smrg      else if (strcmp(argv[i],"-linear")==0)
18232001f49Smrg	 filter = GL_NEAREST;
18332001f49Smrg      else if (strcmp(argv[i],"+linear")==0)
18432001f49Smrg	 filter = GL_LINEAR;
18532001f49Smrg      else if (strcmp(argv[i],"-persp")==0)
18632001f49Smrg	 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
18732001f49Smrg      else if (strcmp(argv[i],"+persp")==0)
18832001f49Smrg	 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
18932001f49Smrg      else if (strcmp(argv[i],"-comp")==0) {
19032001f49Smrg	 comp = atoi(argv[i+1]);
19132001f49Smrg	 i++;
19232001f49Smrg      }
19332001f49Smrg      else
19432001f49Smrg         printf("Unknown option: %s\n", argv[i]);
19532001f49Smrg   }
19632001f49Smrg
19732001f49Smrg   glGetIntegerv(GL_SHADE_MODEL, &shade);
19832001f49Smrg
19932001f49Smrg   printf("Dither: %s\n", glIsEnabled(GL_DITHER) ? "on" : "off");
20032001f49Smrg   printf("ShadeModel: %s\n", (shade==GL_FLAT) ? "flat" : "smooth");
20132001f49Smrg   printf("DepthTest: %s\n", glIsEnabled(GL_DEPTH_TEST) ? "on" : "off");
20232001f49Smrg   printf("Size: %d pixels\n", Size);
20332001f49Smrg
20432001f49Smrg   if (Texture)
20532001f49Smrg      LoadTex(comp, filter);
20632001f49Smrg
20732001f49Smrg   glGetIntegerv(GL_RED_BITS, &rBits);
20832001f49Smrg   glGetIntegerv(GL_GREEN_BITS, &gBits);
20932001f49Smrg   glGetIntegerv(GL_BLUE_BITS, &bBits);
21032001f49Smrg   printf("RedBits: %d  GreenBits: %d  BlueBits: %d\n", rBits, gBits, bBits);
21132001f49Smrg}
21232001f49Smrg
21332001f49Smrg
21432001f49Smrgstatic void Help( const char *program )
21532001f49Smrg{
21632001f49Smrg   printf("%s options:\n", program);
21732001f49Smrg   printf("  +/-dither      enable/disable dithering\n");
21832001f49Smrg   printf("  +/-depth       enable/disable depth test\n");
21932001f49Smrg   printf("  +flat          flat shading\n");
22032001f49Smrg   printf("  +smooth        smooth shading\n");
22132001f49Smrg   printf("  -size pixels   specify pixels/triangle\n");
22232001f49Smrg   printf("  +/-texture     enable/disable texture\n");
22332001f49Smrg   printf("  -comp n        texture format\n");
22432001f49Smrg   printf("  +/-linear      bilinear texture filter\n");
22532001f49Smrg   printf("  +/-persp       perspective correction hint\n");
22632001f49Smrg}
22732001f49Smrg
22832001f49Smrg
22932001f49Smrgint main( int argc, char *argv[] )
23032001f49Smrg{
23132001f49Smrg   glutInitWindowSize( (int) Width, (int) Height );
23232001f49Smrg   glutInit( &argc, argv );
23332001f49Smrg   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
23432001f49Smrg   glutCreateWindow( argv[0] );
23532001f49Smrg
23632001f49Smrg   printf("For options:  %s -help\n", argv[0]);
23732001f49Smrg   if (argc==2 && strcmp(argv[1],"-help")==0) {
23832001f49Smrg      Help(argv[0]);
23932001f49Smrg      return 0;
24032001f49Smrg   }
24132001f49Smrg
24232001f49Smrg   Init( argc, argv );
24332001f49Smrg
24432001f49Smrg   glutReshapeFunc( Reshape );
24532001f49Smrg   glutKeyboardFunc( Key );
24632001f49Smrg   glutDisplayFunc( Display );
24732001f49Smrg   glutIdleFunc( Idle );
24832001f49Smrg
24932001f49Smrg   glutMainLoop();
25032001f49Smrg   return 0;
25132001f49Smrg}
252