Ran Yakir (rany++at++rtset.co.il)
Wed, 15 Jan 1997 19:50:38 +0000
Jude,
I've written a small GL benchmark (not using Performer), for testing your
scene. It allows you to set some options and see how they affect graphics.
>From what I see on a 2RM RE, you should be OK if you are using 16 bit textures.
You can either include the clear time in your measurements or not. Including
the clear, I get about 25 milisec, when using 16 bit textures.
Using this program you can see how to tune your Performer app, in terms of
graphics states.
I've written the program in haste, so I must appologize for the unfriendly
interface.
you run the program as follows :
./fill options texture_name
options :
-z : turns zbuffer on
-m : turns multisampling on
-t : draws textured geometry
-l : uses display lists (less CPU work)
-c : includes the clear in measurements
-b : enables backface culling
-f : enables flat shading
-5 : defines 16 bit texture
The defaults are :
zbuffer off
multisampling off
texture off
immediate mode (no display lists)
no clear
no backface culling
gouraud shading
32 bit texture
Good luck
Ran
--
__ | Ran Yakir
/_) _ __ \ / _ / o __ | RT-SET Ltd.
/ )_ (_(_) ) \/ (_(_/<_(_)( |
_/ |
-------------------------------------+--------------------------------
Phone : | E-mail : rany++at++rtset.co.il
Work : 972-9-9552236 | rany++at++netvision.net.il
Res. : 972-9-7489974 |
Fax : 972-9-9552239 |
/**********************************************************************
* Compile with :
* cc fill.c -o fill -limage -lGLU -lGL -lX11
********************************************************************/
#include <stdio.h>
#include <X11/X.h>
#include <X11/keysym.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glx.h>
#include <malloc.h>
#include <sys/time.h>
#include <math.h>
#include <gl/image.h>
Display *xdisp;
Window win;
int done = 0;
float azimuth = 0, elevation = 0, distance = 100.0;
char *tex_name = NULL;
int tex = 1;
int is_dlist = 0, is_zbuffer = 0;
int is_texture = 0, is_multisample = 0;
int is_clear = 0, is_cullface = 0, is_flat = 0;
int is_rgb5 = 0;
double total_time = 0.0;
int count = 0;
uint tex_geom, geom;
/*** WM hints for noborder GLX windows ***/
/*
** The following structure is actually defined in MOTIF's Xm/MwmUtils.h, but
** we don't want to require header file.
*/
typedef struct MWMHints {
long flags;
long functions;
long decorations;
long input_mode;
} MWMHints;
#define MWM_HINTS_FUNCTIONS 1
#define MWM_HINTS_DECORATIONS 2
#define MWM_HINTS_INPUT_MODE 4
static Atom mwm_hints_atom = 0;
static void
getMWMHints(Display *dsp, Window w, MWMHints *pHints)
{
MWMHints *hp;
int type, fmt;
unsigned long nitems, bytes_after;
/* get special atom for 4DWM motif window manager */
if (!mwm_hints_atom)
mwm_hints_atom = XInternAtom(dsp, "_MOTIF_WM_HINTS", 0);
XGetWindowProperty(dsp, w, mwm_hints_atom, 0, 4, False, mwm_hints_atom,
(unsigned long *)&type, &fmt, &nitems, &bytes_after, (unsigned char**)&hp);
if (hp) {
*pHints = *hp;
XFree((void *)hp);
} else
bzero(pHints, sizeof *pHints);
}
static void noXWindowDecoration(Display *dsp, Window w)
{
MWMHints hints;
/* get special atom for 4DWM motif window manager */
if (!mwm_hints_atom)
mwm_hints_atom = XInternAtom(dsp, "_MOTIF_WM_HINTS", 0);
getMWMHints(dsp, w, &hints);
hints.decorations = 0x0;
hints.flags |= MWM_HINTS_DECORATIONS;
XChangeProperty(dsp, w, mwm_hints_atom, mwm_hints_atom, 32,
PropModeReplace, (unsigned char *)&hints, 4);
}
open_window (char *name, int visual_id)
{
int nred, ngreen, nblue, nalpha, nsamples, ndepth;
int vinfo_ms[] =
{
GLX_RGBA,
GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 0,
GLX_SAMPLES_SGIS, 8,
GLX_DEPTH_SIZE, 1,
None
};
int vinfo_noms[] =
{
GLX_RGBA,
GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 0,
GLX_DEPTH_SIZE, 1,
None
};
XVisualInfo vtemplate;
XVisualInfo *v;
GLXContext c;
XSetWindowAttributes wa;
Colormap cmap;
XEvent event;
float j;
int fmt;
int n;
unsigned long nitems, byaf;
XSizeHints sh;
struct hints_struct
{
long flags,functions,decorations,input_mode;
} *hints;
Atom type, mwmhints;
int multibuffer;
xdisp = XOpenDisplay (0);
if (visual_id < 0)
{
v = glXChooseVisual(xdisp, DefaultScreen(xdisp), vinfo_ms);
if (v == 0)
v = glXChooseVisual(xdisp, DefaultScreen(xdisp), vinfo_noms);
if (v == 0)
{
fprintf(stderr, "glXChooseVisual failed\n");
exit(8);
}
}
else
{
vtemplate.visualid = visual_id;
vtemplate.screen = DefaultScreen(xdisp);
v = XGetVisualInfo (xdisp,
VisualIDMask | VisualScreenMask,
&vtemplate, &n);
if (n == 0)
{
fprintf(stderr,
"XGetVisualInfo failed on VisualID %d\n", visual_id);
exit (8);
}
}
if ((c = glXCreateContext(xdisp, v, 0, GL_TRUE)) == 0)
{
fprintf(stderr, "glXCreateContext failed\n");
exit(3);
}
wa.colormap = XCreateColormap (xdisp, RootWindow(xdisp,v->screen),
v->visual, AllocNone);
wa.border_pixel = 0;
wa.event_mask = StructureNotifyMask
| KeyPressMask
| ButtonReleaseMask
| KeyReleaseMask
| ButtonPressMask;
win = XCreateWindow(xdisp, RootWindow(xdisp, v->screen),
0, 0, 1280, 1024, 0, v->depth,
InputOutput, v->visual,
CWBorderPixel|CWEventMask|CWColormap, &wa);
noXWindowDecoration (xdisp, win);
sh.flags = USPosition | USSize;
XmbSetWMProperties(xdisp, win, &name[0],0,0,0,&sh, 0, 0);
XMapWindow(xdisp, win);
if(! glXMakeCurrent(xdisp, win, c))
{
printf ("error: gfxMakeCurrent failed\n");
exit(1);
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
XFlush (xdisp);
glGetIntegerv (GL_RED_BITS, &nred);
glGetIntegerv (GL_GREEN_BITS, &ngreen);
glGetIntegerv (GL_BLUE_BITS, &nblue);
glGetIntegerv (GL_ALPHA_BITS, &nalpha);
glGetIntegerv (GL_SAMPLES_SGIS, &nsamples);
glGetIntegerv (GL_DEPTH_BITS, &ndepth);
printf ("rgba size : %d %d %d %d\n", nred, ngreen, nblue, nalpha);
printf ("samples : %d\n", nsamples);
printf ("depth : %d\n", ndepth);
return win;
}
main (int argc, char *argv[])
{
char *sw;
int visual_id = -1;
int i;
double frame_time;
while (*++argv)
{
if (**argv == '-')
{
sw = *argv;
while (*++sw)
{
switch (*sw)
{
case 'v' :
argv ++;
if (strncmp (*argv, "0x", 2) == 0)
sscanf (*argv, "%x", &visual_id);
else
sscanf (*argv, "%d", &visual_id);
break;
case 'z' :
is_zbuffer = 1;
break;
case 'm' :
is_multisample = 1;
break;
case 't' :
is_texture = 1;
break;
case 'l' :
is_dlist = 1;
break;
case 'c' :
is_clear = 1;
break;
case 'b' :
is_cullface = 1;
break;
case 'f' :
is_flat = 1;
break;
case '5' :
is_rgb5 = 1;
break;
}
}
}
else
{
if (!tex_name)
tex_name = strdup (*argv);
}
}
open_window ("fill rate", visual_id);
make_textures();
make_lists();
for (i = 0; i < 1000; i ++)
{
redraw();
glXSwapBuffers (xdisp, win);
glFlush();
}
frame_time = total_time / (double) count;
printf ("texture : %s\n", is_texture ? "on" : "off");
printf ("multisample : %s\n", is_multisample ? "on" : "off");
printf ("display lists : %s\n", is_dlist ? "on" : "off");
printf ("zbuffer : %s\n", is_zbuffer ? "on" : "off");
printf ("clear : %s\n", is_clear ? "on" : "off");
printf ("flat shading : %s\n", is_flat ? "on" : "off");
printf ("backface culling : %s\n", is_cullface ? "on" : "off");
printf ("16 bit texture : %s\n", is_rgb5 ? "on" : "off");
printf ("frame time : %.3f milisec\n", (float) frame_time);
printf ("fill rate : %.3f Mpixels/sec\n", 2595750.0 / frame_time * 1000.0 / 1024.0 / 1024.0);
}
static void read_image (char *name, unsigned int **image, int *xsize, int *ysize)
{
IMAGE *image_fp;
int x, y;
unsigned short *rbuf, *gbuf, *bbuf, *abuf;
unsigned char *cp;
int i, size;
if ((image_fp = iopen (name, "r")) == NULL)
{
perror (name);
exit (1);
}
*xsize = image_fp->xsize;
*ysize = image_fp->ysize;
rbuf = malloc (image_fp->xsize * sizeof (short));
gbuf = malloc (image_fp->xsize * sizeof (short));
bbuf = malloc (image_fp->xsize * sizeof (short));
abuf = malloc (image_fp->xsize * sizeof (short));
size = image_fp->xsize * image_fp->ysize * sizeof (int);
*image = malloc (size);
cp = *image;
for (y = 0; y < image_fp->ysize; y ++)
{
getrow (image_fp, rbuf, y, 0);
getrow (image_fp, gbuf, y, 1);
getrow (image_fp, bbuf, y, 2);
for (x = 0; x < image_fp->xsize; x ++)
{
*cp ++ = rbuf[x];
*cp ++ = gbuf[x];
*cp ++ = bbuf[x];
*cp ++ = 0xff;
}
}
}
make_textures()
{
unsigned int *image, *p;
int xsize, ysize;
int i, j;
glEnable (GL_TEXTURE_2D);
glBindTextureEXT (GL_TEXTURE_2D, tex);
if (tex_name)
read_image (tex_name, &image, &xsize, &ysize);
else
{
xsize = 128;
ysize = 128;
p = image = malloc (xsize * ysize * sizeof (int));
for (i = 0; i <xsize * ysize; i ++)
*p ++ = 0x808080ff;
}
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_DETAIL_TEXTURE_MODE_SGIS, GL_MODULATE);
glTexImage2D (GL_TEXTURE_2D, 0, is_rgb5 ? GL_RGB5_EXT : GL_RGBA8_EXT,
xsize, ysize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
}
make_lists()
{
tex_geom = glGenLists (1);
glNewList (tex_geom, GL_COMPILE);
draw_tex_geom();
glEndList();
geom = glGenLists (1);
glNewList (geom, GL_COMPILE);
draw_geom();
glEndList();
}
redraw()
{
int i;
float x, dx;
float scale[4];
struct timeval t0, t1;
float frame_time;
if (is_clear)
{
glClearColor (0.0, 0.0, 0.0, 1.0);
glClearDepth (1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
glColor3f (1, 1, 1);
glFinish();
gettimeofday (&t0, 0);
glShadeModel (is_flat ? GL_FLAT : GL_SMOOTH);
glCullFace (is_cullface ? GL_BACK : GL_FRONT_AND_BACK);
if (is_zbuffer)
glEnable (GL_DEPTH_TEST);
else
glDisable (GL_DEPTH_TEST);
if (is_multisample)
glEnable (GL_MULTISAMPLE_SGIS);
else
glDisable (GL_MULTISAMPLE_SGIS);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluOrtho2D (0.0, 1279.0, 0.0, 1023.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
if (is_texture)
{
glEnable (GL_TEXTURE_2D);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTextureEXT (GL_TEXTURE_2D, tex);
}
else
glDisable (GL_TEXTURE_2D);
if (is_dlist)
{
glColor3f (1.0, 1.0, 1.0);
if (is_texture)
glCallList (tex_geom);
else
glCallList (geom);
}
else
{
glColor3f (1.0, 0.0, 1.0);
if (is_texture)
draw_tex_geom();
else
draw_geom();
}
glFinish();
gettimeofday (&t1, 0);
frame_time = (float) (t1.tv_sec - t0.tv_sec) * 1000.0 +
(float) (t1.tv_usec - t0.tv_usec) / 1000.0;
total_time += frame_time;
count ++;
}
draw_tex_geom()
{
int i, j;
for (j = 0; j < 30; j ++)
{
glBegin (GL_TRIANGLE_STRIP);
for (i = 0; i <= 25; i ++)
{
glTexCoord2f (i, 0.0);
glVertex2f (i * 10, j * 10);
glTexCoord2f (i, 1.0);
glVertex2f (i * 10, (j + 1) * 10);
}
glEnd();
}
for (j = 0; j < 27; j ++)
{
glBegin (GL_TRIANGLE_STRIP);
for (i = 0; i <= 25; i ++)
{
glTexCoord2f (i, 0.0);
glVertex2f (i * 51, j * 51);
glTexCoord2f (i, 1.0);
glVertex2f (i * 51, (j + 1) * 51);
}
glEnd();
}
for (j = 0; j < 10; j ++)
{
glBegin (GL_TRIANGLE_STRIP);
for (i = 0; i <= 8; i ++)
{
glTexCoord2f (i, 0.0);
glVertex2f (i * 101, j * 101);
glTexCoord2f (i, 1.0);
glVertex2f (i * 101, (j + 1) * 101);
}
glEnd();
}
}
draw_geom()
{
int i, j;
for (j = 0; j < 30; j ++)
{
glBegin (GL_TRIANGLE_STRIP);
for (i = 0; i <= 25; i ++)
{
glVertex2f (i * 10, j * 10);
glVertex2f (i * 10, (j + 1) * 10);
}
glEnd();
}
for (j = 0; j < 27; j ++)
{
glBegin (GL_TRIANGLE_STRIP);
for (i = 0; i <= 25; i ++)
{
glVertex2f (i * 51, j * 51);
glVertex2f (i * 51, (j + 1) * 51);
}
glEnd();
}
for (j = 0; j < 10; j ++)
{
glBegin (GL_TRIANGLE_STRIP);
for (i = 0; i <= 8; i ++)
{
glVertex2f (i * 101, j * 101);
glVertex2f (i * 101, (j + 1) * 101);
}
glEnd();
}
}
=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
Submissions: info-performer++at++sgi.com
Admin. requests: info-performer-request++at++sgi.com
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:54:21 PDT