/*
* Simple benchmark program to measure texturing performance of OpenGL.
* Complie:
* gcc glfwTexture.c -lpthread -lXrandr -lm -lGL -lGLU -lglfw -lX11
*
* Requires packages (on Ubuntu Karmic default install):
* libglfw-dev freeglut-dev libxrandr-dev
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <GL/glfw.h>
// Size of the textures drawn on the screen
#define WIDTH 50
#define HEIGHT 140
// Size of the becnhmark application screen
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 768
// Number of rectangles drawn
#define N 1000
// Number of textures used on rectangles. The same texture is never used twice in a row
#define K 1000
int screenWidth;
int screenHeight;
GLuint * textures;
/**
* Create a GL texture and fill with random values.
* The texture's size is controlled by the WIDTH and HEIGHT constants.
*/
GLuint createTexture()
{
GLuint handle;
int l=WIDTH*HEIGHT*4;
GLubyte * ptr=malloc(l);
GLubyte * p=ptr;
int i=0;
for(i=0;i<l;++i)
{
*(ptr+i)=(GLubyte)(random()%256);
}
glGenTextures(1, &handle);
printf("Create texture: %d\n", handle);
glBindTexture(GL_TEXTURE_2D, handle);
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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, WIDTH, HEIGHT, 0, GL_RGBA,
GL_UNSIGNED_BYTE, ptr);
free(ptr);
return handle;
}
/**
* Set the projection matrices. Use orthogonal projection to emulate 2D.
*/
static void
Init(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-screenWidth/2, screenWidth/2, -screenHeight/2, screenHeight/2, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int lastPrint;
int ctr;
int nPixel;
int renderTime;
/**
* Separate method is created so that we see time consumed in profiler.
*/
void myBindTexture(int i)
{
glBindTexture(GL_TEXTURE_2D, textures[i%K]);
}
/**
* Draw the i. textured rectangle.
* The rectangle will be textured with texture number i%K
* The rectangles are positioned on the screen a way that they fill the whole area
*
*/
void drawRectangle(int i)
{
int width=50;
int height=140;
int x=(i*50)%(screenWidth-width);
int y=(i*63)%(screenHeight-height);
x-=screenWidth/2;
y=(screenHeight/2-y);
// activate the image texture
myBindTexture(i);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(x, y, 0.0);
glTexCoord2f(1, 0);
glVertex3f(x+width, y, 0.0);
glTexCoord2f(1, 1);
glVertex3f(x+width, y-height, 0.0);
glTexCoord2f(0, 1);
glVertex3f(x, y-height, 0.0);
glEnd();
nPixel+=width*height;
}
/**
* Render a single frame of the benchmark.
*/
static void
Draw(void)
{
nPixel=0;
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
int i=0;
Init();
glEnable(GL_TEXTURE_2D);
glColor4f(1, 1, 1, 1); // no color
glDisable(GL_LIGHTING); // no lighting
glDisable(GL_DEPTH_TEST); // no depth test
glEnable(GL_BLEND); // enable transparency
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for(i=0;i<N;++i)
{
drawRectangle(i);
}
int time;
time = (int)(glfwGetTime( )*1000);
ctr++;
if(time>lastPrint+1000)
{
printf("\nPerformance counters:\n current time: %d\nframes in last second: %d\npixels drawn: %d \ncurrent screen size: %dX%d.\nglFinish() time per frame(millis): %lf \n",
time, ctr, nPixel,
screenWidth, screenHeight, ((double)renderTime)/ ((double)ctr));
ctr=0;
lastPrint=lastPrint+1000;
renderTime=0;
}
glFlush();
glFinish();
int afterFinish=(int)(glfwGetTime()*1000);
renderTime+=afterFinish-time;
}
int
main(int argc, char **argv)
{
int running = GL_TRUE;
// Initialize GLFW
srandom(0);
glfwInit();
renderTime=0;
lastPrint=0;
ctr=0;
screenWidth=SCREEN_WIDTH;
screenHeight=SCREEN_HEIGHT;
// Open an OpenGL window
if( !glfwOpenWindow( screenWidth, screenHeight, 0,0,0,0,0,0, GLFW_WINDOW ) )
{
glfwTerminate();
return 0;
}
int i;
textures=calloc(sizeof(GLuint), N);
for(i=0;i<K;++i)
{
textures[i]=createTexture();
}
glfwSetWindowTitle( "GLFW Textures performance test" );
// glfwSwapInterval(1);
while( running )
{
// OpenGL rendering goes here...
glClear( GL_COLOR_BUFFER_BIT );
Init();
Draw();
// Swap front and back rendering buffers
glfwSwapBuffers();
// Check if ESC key was pressed or window was closed
running = !glfwGetKey( GLFW_KEY_ESC ) &&
glfwGetWindowParam( GLFW_OPENED );
}
// Close window and terminate GLFW
glfwTerminate();
return 0;
}