Don Hatch (hatch++at++hell.engr.sgi.com)
Mon, 4 Jan 1999 22:44:42 -0800
I'd suspect one of the following problems:
1. Cull sorting may be scrambling the order of
the geodes with respect to the LOD Offset calls to OpenGL.
If this is the problem, you should be able to verify
that it goes away when you set Cull Mode to "None" (if you
have a perfly- or clipfly-based application).
The most common cause of this is if you forgot
to do the following on each of the geodes,
as explained in the HowToDoVirtual.html doc:
geode->setTravMode(PFTRAV_CULL,
PFTRAV_CULL_SORT,
PFN_CULL_SORT_CONTAINED);
2. If the clipsize/2-sized level is not loaded all in one
piece, it comes out as garbage.
(This is an OpenGL bug, described in section 2.4
in the IRClipmapBugs.html doc).
If this is the problem, you should be able to verify that it's
only happening on that one level by turning on Gridify
(to color-code the levels) and fiddling
with the Min&Max LOD sliders to isolate the levels being viewed.
If this is the problem, you need to change your configuration files
so that that level consists of only a single image tile
(either make that level actually be an image tile, or make that level
be an image cache consisting of a single image tile).
Unfortunately this is incompatible with the new "no-.ic" .ct
configuration files if you want to use a global tile
size that's smaller than clipsize/2.
The possible workarounds are to switch to a global tile size
of clipsize/2 or bigger,
or use the old .ct format that lets you configure each
level separately and make that "problem" level's tile size
be equal to its level size
(of course, you will have to regenerate your image tile files
to use the larger tile size for at least that level,
or for all the levels, depending on which workaround you use).
Actually, now that I think about it, you may be
able to get around this and still use the simpler no-.ic format,
by setting smallest_icache to be equal to
clip_size; hopefully this will force
all smaller levels (in particular the problem level),
to consist of a single image tile per level.
If you try this, and it works, please report back--
it will make a lot of peoples' lives easier!
3. One or more levels may be configured badly or have bad data.
Again, you should be able to verify/test this
by turning on Gridify and using the Min&Max LOD sliders
to isolate the bad level(s).
4. The Granularity vs. number of Good levels problem you mentioned.
Sorry, upon re-reading that section I see that it doesn't
reflect the current situation very well.
The IR OpenGL patches described in 2.1 use a heuristic
that makes things work in most situations,
but it's still wacky, and I've seen it mess up.
If this is the cause of your problem,
it should go away if you increase the invalid border,
strange as that sounds. Increase it from 8 to 16, 32, 64, ...
the smallest value that fixes your problem, if any.
This workaround is probably the best you are going to be able to get
if this is the problem.
While debugging this,
y ou might want to run "trashtexmem" or a similar program
that clears texture memory between your program runs,
so that you don't see leftover texture data from previous runs,
which can be confusing and misleading.
I'm including the program trashtexmem.c as an attachment.
Don
-- Don Hatch hatch++at++sgi.com (650) 933-5150 Silicon Graphics, Inc.
/* * file: trashtexmem.c * ------------------- * * A testing utility to all of trash texture memory. * Default behavior is to compute max texture size for a * 3 component texture and then to create, apply, and * display a red RGB bilinear texture. * * $Revision: 1.5 $ * $Date: 1998/04/30 21:34:19 $ * * cmdline-time controls: * -c numComp - set number of components * -d - toggle display mode (default is on) * -p r,g,b,a - specify all 4 rgba colors in hex [0,255] * -s sx,sy - set size of texture * */
#include <stdio.h> #include <stdlib.h> #include <getopt.h> /* for cmdline handler */ #include <ctype.h>
#include <Performer/pr.h>
#define MAX_TEX 64
int showTex = 1; int cmp = 4; int sx[MAX_TEX] = {-1}, sy[MAX_TEX] = {-1}; int wsx=10, wsy=10; pfTexture *tex[MAX_TEX]; unsigned char clr[4] = {0xff, 0, 0, 0xff};
pfVec4 white = {1, 1, 1, 1}; pfVec4 black = {0, 0, 0, 1};
pfVec3 coords[] ={ {-1.0f, -1.0f, 0.0f }, { 1.0f, -1.0f, 0.0f }, { 1.0f, 1.0f, 0.0f }, {-1.0f, 1.0f, 0.0f } };
static char ProgName[PF_MAXSTRING];
static void usage(void) { fprintf(stderr,"%s: [-p r,g,b,a] [-c cmp] [-s sx,sy] [-d]", ProgName); }
static int findTexSize(int bytes, int cmp, int *sx, int *sy) { int x=1, y=1, max;
/* assuming 2 bytes per texel, find max texture bytes */ max = bytes >> 1; if (!max) return 0;
/* find bigest square texture */ *sx = x; *sy = y; while (x * y <= max) { *sx = x; *sy = y; x <<= 1; y <<= 1; /*pfNotify(PFNFY_NOTICE,PFNFY_PRINT, "SQUARE: %d %d %d %d", x, y, x*y, max);*/ } pfNotify(PFNFY_NOTICE,PFNFY_PRINT, "FINAL: %d %d %d %d", *sx, *sy, *sx * *sy, max); return (*sx * *sy * 2); }
static void doShowTex(pfTexture *tex) { pfFrustum *frust; pfGeoSet *gset;
frust = pfNewFrust(NULL); pfMakeOrthoFrust(frust, -1, 1, -1, 1); pfFrustNearFar(frust, -1, 1); pfApplyFrust(frust); pfDelete(frust);
pfClear(PFCL_COLOR | PFCL_DEPTH, black);
/* Set up a geoset */ gset = pfNewGSet(NULL); pfGSetAttr(gset, PFGS_COORD3, PFGS_PER_VERTEX, coords, NULL); pfGSetAttr(gset, PFGS_COLOR4, PFGS_OVERALL, white, NULL); pfGSetPrimType(gset, PFGS_QUADS); pfGSetNumPrims(gset, 1);
pfDrawGSet(gset); }
static int docmdline(int argc, char *argv[]) { int opt; int lclr[4];
strcpy(ProgName, argv[0]);
/* process command-line arguments */ while ((opt = getopt(argc, argv, "c:dp:s:?")) != -1) { switch (opt) { case 'c': cmp = atoi(optarg); break; case 'd': showTex ^= 1; break; case 'p': sscanf(optarg,"0x%x,0x%x,0x%x,0x%x",&lclr[0], &lclr[1], &lclr[2], &lclr[3]); clr[0] = lclr[0]; clr[1] = lclr[1]; clr[2] = lclr[2]; clr[3] = lclr[3]; break; case 's': sscanf(optarg,"%d,%d", &sx, &sy); break; case '?': usage(); break; } } return optind; }
int main (int argc, char **argv) { unsigned char *data; unsigned int *ptr, *end; unsigned int clr_int; pfWindow *win; int s, b; int i; int numTex = 0;
docmdline(argc, argv);
/* Initialize Performer */ pfInit(); pfInitState(NULL);
pfNotify(PFNFY_NOTICE,PFNFY_MORE,"Mach String: %s", pfGetMachString());
pfQuerySys(PFQSYS_TEXTURE_MEMORY_BYTES,&b); pfNotify(PFNFY_NOTICE,PFNFY_MORE,"\tTEXTURE_MEMORY_BYTES: %d", b);
pfQuerySys(PFQSYS_MAX_TEXTURE_SIZE,&s); pfNotify(PFNFY_NOTICE,PFNFY_MORE,"\tMAX_TEXTURE_SIZE: %d", s);
if (sx[0] < 0) { while(b) { int t; t = findTexSize(b, cmp, &sx[numTex], &sy[numTex]); if (!t) { pfNotify(PFNFY_NOTICE,PFNFY_PRINT, "Woops - %d bytes NOT trashed", b); b = 0; continue; } pfNotify(PFNFY_NOTICE,PFNFY_PRINT, "Making %d comp texture of size %dx%d", cmp, sx[numTex], sy[numTex]); tex[numTex] = pfNewTex(NULL); pfTexFilter(tex[numTex], PFTEX_MINFILTER, PFTEX_BILINEAR); numTex++; b -= t; if (b < 0) { pfNotify(PFNFY_NOTICE,PFNFY_PRINT, "Woops - negative bytes: %d", b); b = 0; } } pfNotify(PFNFY_NOTICE,PFNFY_PRINT, "Made %d textures", numTex); }
s = sx[0]*sy[0]; data = pfMalloc(s*sizeof(unsigned int), NULL); ptr = (unsigned int *)data; /* Don't worry, the div by 4 will get lowered to a shift by the compiler */ end = ptr + s; clr_int = *(unsigned int *)clr; while (ptr < end) { /* I'm assuming that the color has 4 components, but this assumption exists elsewhere in this code. */ *ptr = clr_int; ptr++; } for (i=0; i < numTex; i++) pfTexImage(tex[i], (uint*) data, cmp, sx[i], sy[i], 0);
/* Initialize GL */ win = pfNewWin(NULL); pfWinName(win, "Iris Performer"); pfWinType(win, PFWIN_TYPE_X); if (showTex) { int maxX, maxY; pfGetScreenSize(-1, &maxX, &maxY); wsx = sx[0]; wsy = sy[0]; if (wsx > maxX) wsx = maxX; if (wsy > maxY) wsy = maxY; } pfWinOriginSize(win, 0, 0, wsx, wsy); pfOpenWin(win);
pfEnable(PFEN_TEXTURE); pfApplyTEnv(pfNewTEnv(NULL));
for (i=0; i < numTex; i++) { pfNotify(PFNFY_NOTICE,PFNFY_PRINT,"Loading tex %d", i); pfApplyTex(tex[i]); }
for (i=0; i < numTex; i++) { if (!pfIsTexLoaded(tex[i])) pfNotify(PFNFY_NOTICE,PFNFY_PRINT,"WOOPS - tex %d is NOT resident", i); if (showTex) doShowTex(tex[i]); }
#ifndef IRISGL { int err; if ((err = glGetError()) != GL_NO_ERROR) pfNotify(PFNFY_NOTICE,PFNFY_USAGE,"OpenGL Error 0x%x - %s",err, gluErrorString(err)); } #endif /* GL Type */
if (showTex) { pfSwapWinBuffers(win); sleep(1); } exit(0); }
This archive was generated by hypermail 2.0b2 on Mon Jan 04 1999 - 22:44:46 PST