Re: Scene Density Requirements

New Message Reply Date view Thread view Subject view Author view

Ran Yakir (rany++at++rtset.co.il)
Wed, 15 Jan 1997 19:50:38 +0000


On Jan 15, 11:08am, Jude Anthony wrote:
> Subject: Re: Scene Density Requirements
>
> The machine is an RE2 with 2RM4s. The application runs in a 1024x768 screen.
> From all calculations I've seen so far, the test scene I'm trying to render
> should go at 30Hz; yet it has a draw time of 33.1ms, and runs no faster than
> 20Hz. (Statistics from perfly or vega application.)
>
> The scene consists of strips of tris, overlapped so that none are completely
> obscured, sometimes up to six deep. The scene was created with MultiGen,
> and I arranged the objects so that they are sorted back-to-front, since they
> all have the same Z. The strips are meshed for their entire length. In
> short, it looks something like this:
>
> +----------------+
> | +----------------+
> | | +----------------+
> + | | |
> + | |
> +----------------+
>
> The strips are placed at a distance from the observer such that one database
> unit is one pixel. The strips constitute the following numbers and sizes of
> triangles:
> 150 tris, 101x101
> 1350 tris, 51x51
> 1500 tris, 10x10
>
> None of the above is negotiable; it's all set out in the test document.
>
> Our average depth complexity for the scene is somewhere between 3.31 and
> 3.33. (Perfly/Vega statistics again.)
>
> The rated pixel fill rate for 2 RM4s is 110Mpix/sec. Our scene contains:
> 150 x 101 x 101 / 2 = 765,075
> + 1350 x 51 x 51 / 2 = 1,755,675
> + 1500 x 10 x 10 / 2 = 75,000
> --------------------------------
> 2,595,750 pixels.
> At 30Hz, that makes 2,595,750 * 30 = 77,872,500pix/sec, which is below the
> rated fill rate, so shouldn't be causing a problem.

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


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:54:21 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.