how to handle 1 million triangles?

I have a program which represent an image by about 1 million triangles. I use a displaylist to store these triangles.

The problem is, I want to interpolate within the triangles when I use the scalef function to scale the image (by using the glShadeModel(GL_SMOOTH)). It works if the triangles are made every loop in the RenderScene function. But it seems didn’t work if I call the displaylist.

Could anyone please tell me how to do this? Any if possible, how to increase the performance? Because I didn’t see much difference by using a displaylist, it is still slow. Thank you very much.

First of all, I don’t quite get if you made the display lists to work. First you say that they don’t work, then that they are working, but are slow.

Secondly, display lists are only good for writing less code when you want to do the same thing. They are not in anyway faster (if I am mistaking please correct me). So, if you draw the same object 10 times in your scene, you make a display list to draw the object and than call that list for 10 times.

if i am understanding your post, selecting a smooth shade model will not scale your geometry. you need to use glScalef to scale. second, you can’t change data in a display list. they contain static data only. now, you may be able to call glScalef and THEN call your display list, but unles you scale back, everything you display after it will also be scaled. as far as it being slow, unless you are rendering it way more than you need, that may be a video card/system issue. post some code for more in-depth help.

jebus

I’m not too sure on this subject, but i think that vertex arrays are much faster than display lists.

  • Halcyon

I remember that some time ago this had been discussed here. It was said that for 500,000 tris, display lists were in fact slower than nothing.

Also, remember that display lists and vertex arrays are not mutually exclusive.

I’d use an Interleaved Vertex Array personnally.

Display lists are guaranteed not to be slower than using immediate mode (lots of glVertex commands, etc). Usually display lists are infact a lot quicker than immediate mode, and most drivers actually make display lists faster than any other method.

Whether vertex arrays or display lists turn out quicker will be an application specific issue. Either is better than nothing, but which is better overall is down to testing (remember that it could be different results running the same code on another machine).

Originally posted by Morglum:
Also, remember that display lists and vertex arrays are not mutually exclusive.

If you create a display list using a vertex array, the vertex data is “compiled” into the display list. Using the display list will not use the vertex array again.

[This message has been edited by T (edited 01-08-2003).]

>Display lists are guaranteed not to be slower than using immediate mode

Where did you see that ? Is it in the ogl specs ? I think that’s up to the driver.

Regarding your second post : all what I meant is that if you draw a vertex array within a display list, not only will it perfectly work, but you can even expect a nonzero (I’ve had 1%) performance increase. That’s what I called ‘not being mutually exclusive’.

I don’t remember where I first read it, but I just found this in the redbook:

“…the execution of display lists isn’t slower than executing the commands contained within them individually.”

However it does go on to say:

“There is some overhead, however, involved in jumping to a display list. If a particular list is small, this overhead could exceed any execution advantage.”

So it would seem really small lists could prove slower.

Morglum, I only intended to ellaborate on what you said about display lists and vertex arrays, not to accuse you of being wrong.

Thanks for every reply and sorry for the confusing in my post. Actually what I need is to triangulation an image, then represent this triangulation by opengl. Because there is about 1m triangles, so it is relatively slow when I want to do some operations such as scale. So I use a displaylist to save these triangles and then call the list instead of calculating the triangulation everytime it loops. But the problem is if I use displaylist and then scale it, it won’t interpolate within the triangles. But if i simply calculate the triangulation in the RederScene function, when I scale it, it interpolate within the triangles which is what I want.

void cbRenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glShadeModel(GL_SMOOTH);
glScalef(X_Off, Y_Off, 1.0);
glCallList(alist);
glutSwapBuffers();
}

That’s my code. If i replace the glCallList(alist) with my code of triangulation the image, it works fine (I mean, if I scale it by the keyborad, it interpolates within the triangles). But it didn’t by using the displaylist.

Another question is as I understand, everyloop the list is sent to the graphics card. Is there a way that in the intialising stage send the triangulation to the graphics card and it will hold the triangulation (save it in its memory?). So it will only do something when keyboard function is pressed?

I’m afraid I don’t entirely understand what you are trying to do. However, regarding your last question. The driver will decide where to store the display list - I think if it will fit into the graphics card’s memory it would get stored there - but I don’t know for certain. Perhaps your list is too large.

From what I understand from your post, you are needing to modify the list in response to keyboard events. Given the size issue and frequent updates, perhaps vertex arrays would be more appropriate.

Just a quick check: You are updating (with glNewList) the list every time you modify it, right? Cause if you are not, you naturally won’t see the change.

Another thing, are you sure you need a million triangles and not, say, a texture…?

-Ilkka

Yeah, the number of the triangles is nessary.
The main issue is I want to scale the whole triangulation, which means the interpolation will be done within the triangles. But if I use display list, it seems opengl didn’t interpolate within the triangles.

Also, no matter which ever method I am using now, it is slow when I press a key to scale it. I am wondering is there a way to improve the performance.

Here is my code. Basically it just initialsing a display list and then when I press the ‘Z’, it magnify the image by a factor of two.

void render()
{
// the function which actually generate the triangles
}

void setup()
{
alist = nlist;

glNewList(alist, GL_COMPILE);
render();
glEndList();
}

void cbRenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glShadeModel(GL_SMOOTH);
glScalef(X_Off, Y_Off, 1.0);
glCallList(alist);
glutSwapBuffers();
wait(1);
}
void cbKeyPressed(unsigned char key,
int x, int y)
{
switch (key)
{
case 113: case 81: case 27: // Q (Escape) - We’re outta here.
glutDestroyWindow(Window_ID);
exit(1);
break; // exit doesn’t return, but anyway…

 case 122:   // z
   if(X_Off > 1 && Y_Off > 1)
 {
   X_Off = X_Off / 2;
   Y_Off = Y_Off / 2;
 }
   break;
   
 case 90:  // Z, magnify it by two
   X_Off = X_Off * 2;     
   Y_Off = Y_Off * 2;
   break;
   
 default:
   printf ("KP: No action for %d.

", key);
break;
}
}

void cbResizeScene(
int Width, int Height)
{
if (Height == 0)
Height = 1;

glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective((Width/8),(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
Window_Width = Width;
Window_Height = Height;
}
void ourInit( int Width,int Height
)
{
glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
glClearDepth(1.0);
glDepthFunc(GL_LESS);
cbResizeScene(Width,Height);

}

int main(int argc, char* argv[])
{
glutInit(&argc, argv);
Window_Width = inputw2;
Window_Height = inputh
2;

glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(Window_Width, Window_Height);

Window_ID = glutCreateWindow( PROGRAM_TITLE );

glutDisplayFunc(&cbRenderScene);
glutIdleFunc(&cbRenderScene);
glutReshapeFunc(&cbResizeScene);
glutKeyboardFunc(&cbKeyPressed);
ourInit(Window_Width, Window_Height);
nlist = glGenLists(1);
setup();
glutMainLoop();
glDeleteLists(nlist,1);
return 1;
}

Sorry for all the confuing cased and thanks for the help. Hope this time my problem is clear.

I made a triangulation which consist 1m triangles (about 20k TrianglesStrip). I want to scale this image. If i put the triangulation process on the RenderScene function (generate the triangles every time call this function), when I scale it, it interpolates from the triangles. However, if I use a displaylist to save these triangles and then scale it, it didn’t interpolates from the triangles( I guess it simply use a pixel-replication method).

That’s my main problem, of course, performance is another problem.

Displaylist is used for tell opengl somthing like “draw again the last scene”

When the object is rendered the first time it could involve to do some loops and calc maths (so time processor is used), but after doing that and if you compiled that process in a display list then using calldisplay list will render the same object but this time with not need to do the loops and calcs as previusly becouse opengl “remember” the model.

This is very usefull to show a model on each frame where the model polys was not changed at all, only the camera position, model position, or some other opengl states.

If the model was changed even a bit then you will need to call again the draw model rutine and update your display list.


If the zoom in/out model is to slow i recomend to use a bigger zoom factor value, trying to zoom one milions model one pixel by one pixel each frame is really slow.

Also if you are using keyboard for zoom in/ out then you have to be sure to use “if key down” and “if key up” event for do that, but if youre using a input char for ask if char was “+” or “-” then it will be soooo slow cose it is using the keyboard type rate speed.

glShadeModel(GL_SMOOTH) this is used to allow using different color on each vertex or for show a normalized solid model, is not related with scale, and don’t need to be call each frame.

good luck.

tp.

Thanks tp. I see, glShadeModel(GL_SMOOTH) can be put in init stage. As you mentioned, I call this displaylist actually means I load these triangles again. The triangles model didn’t change. Then if scale it, it should interpolate from these triangles, right?
But it seems not working this way. What’s the reason?

I think I didn’t make it clear why I need triangles. I model an image as triangles so that the three vertex of any triangle corespond to three pixels in the image.
So for a 768 * 512 image, there are
767 * 511 * 2 triangles.
So, each vertex will be assigned the color of that pixel and the whole image is represented by this triangulation.

Then if you scale it, magnify it by a factor of two using glScalef function. The opengl should do some interpolation.

If I put the triangulation process in the RenderScene process, when scaling, the openGL is interpolating within the triangles so I get smooth results. However if I simply call the displaylist and then scale it, seems openGL takes the pixel-replication method and the results looks very bad!

The best way to handle 1 million triangles is to use the method you use for 999,999 triangles and adjust for one more.

Originally posted by mapds:
[b]I think I didn’t make it clear why I need triangles. I model an image as triangles so that the three vertex of any triangle corespond to three pixels in the image.
So for a 768 * 512 image, there are
767 * 511 * 2 triangles.

Each 3 vertex for any triangle represent 3 pixels in the rendered image ??
Not sure what you mean, but it sound like if you are trying to draw a solid model filling it with thousands of wireframe triangles (!!!??), i guess you known what are you doing and what effect are you trying to do.
(Just in case…there is a solid mode state where each triangle rendered is automatically filled)

About displaylist, note that ALL opengl commands are remembered and executed in the display list, so is safer to use just opengl command for draw the model.

if Calldisplaylist resul is not the same as when you call normal draw model, then it mean that some states opengl commands like matrix operations, modelprojection or view projection,glLoadIdentity() etc, are wrongly compiled inside the displaylist and they are overwriting your setuped states done before the calldisplaylist.

good luck,

Turbo Pascal.