PDA

View Full Version : rotating large models



wmelgaard
01-17-2014, 05:27 AM
I am writing what I intend to be an Open Source implementation of NASTRAN. My sample model has 5,000 lines, 5,000 triangles, 10,000 quadrilaterals and 10,000 points. I am trying to rotate the model by dragging the mouse. It works very nicely for small models: I can rotate the model to the desired viewing angle prior to releasing the mouse. My problem is that the program tries to write the entire model for each glutMotionFunc() call.

Is there some way to force a swapbuffer/purge at the instant of glutMotionFunc() call? The model will still be incomplete, but the viewer can still get feedback on the current rotation angles.

joehot200
01-17-2014, 01:56 PM
Am i being stupid or are you unable to just use glRotate(); to rotate the model to the desired angle?

wmelgaard
01-17-2014, 07:05 PM
void move(int x, int y){ // creates dynamic display from mouse drag
int dx, dy, dz;
dx = downx -x; dy = downy - y;
glutSwapBuffers();
glMatrixMode(GL_MODELVIEW);
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glColor3f(1.0, 0.3, 0.3);
glOrtho( ...
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glTranslatef(ctrx, ctry, ctrz);

glRotatef((theta -90*dy/WindowHeight), 0.0, 1.0, 0.0);
glRotatef((phi -90*dx/WindowWidth), 1.0, 0.0, 0.0)

glTranslatef(-ctrx, -ctry, -ctrz);
model(); //generates model
glPopMatrix();
glutSwapBuffers();
}
int main(...
glutMotionFunc(move);

As I said, the problem is the size of the model. On my machine, it takes about two seconds to generate the model. With a smaller model (e.g. the teapot), it rotates in real time as I drag the mouse.


Am i being stupid or are you unable to just use glRotate(); to rotate the model to the desired angle?

malexander
01-18-2014, 12:15 PM
It looks from your code like you're rebuilding the model every time you move it. You don't need to do this unless the model itself is deforming, and this is the source of your performance loss. Generate the model once and store it in vertex buffer objects (VBOs; modern way), or a display list (older GL way). Then just do your matrix transformations, draw using the buffers or list, and it should transform much faster.

wmelgaard
01-20-2014, 10:08 AM
I have not learned to use VBOs, Example 2-28 in OpenGL Programming Guide 7th ed. mentions VBOs, but what I see is VAOs loaded into the kernel via glDrawElements(PrimType[i], NumElements[i], GL_UNSIGNED_BYTE, BUFFER_OFFSET(0); Am I on the right track?


It looks from your code like you're rebuilding the model every time you move it. You don't need to do this unless the model itself is deforming, and this is the source of your performance loss. Generate the model once and store it in vertex buffer objects (VBOs; modern way), or a display list (older GL way). Then just do your matrix transformations, draw using the buffers or list, and it should transform much faster.

nenad*
01-21-2014, 06:11 AM
Let's see what's happening inside the model() function

wmelgaard
01-21-2014, 07:52 AM
My model() function is very efficient in terms of memory, but not speed. That was not a problem until I tried to rotate it. if I generate a Vertex Buffer Object as malexander suggests, that would probably cure my problem. I can even create the VBO in background. However, I have never created a VBO before, and the example in the Red Book is rather cryptic.


Let's see what's happening inside the model() function

malexander
01-21-2014, 08:20 AM
Try reading this tutorial on drawing with VBOs:

http://www.arcsynthesis.org/gltut/Basics/Tutorial%2001.html

It draws a single triangle, and is quite good at introducing the concept of drawing with buffer objects.

wmelgaard
01-21-2014, 11:21 AM
Thank you. It will take me a few days experimenting, but it looks rather straight forward.

Is there a callback function that will tell me how much buffer array space I have in the GPU?
My sample model *only* has 30,000 objects. My program is intended to be able to handle much larger models. If the GPU doesn't have enough memory, I can skip (1 out of 3)(4 out of 5) (whatever) objects while building the VBO, and then build the entire model when the user has finished spinning the model to the desired orientation.

malexander
01-21-2014, 11:31 AM
There's no standard gl call to query memory or memory use, but you can try the AMD and Nvidia specific extensions:

http://www.opengl.org/registry/specs/ATI/meminfo.txt
http://www.opengl.org/registry/specs/NVX/gpu_memory_info.txt

If you run out of space on the GPU (VRAM), the driver will start swapping buffers to and from main memory as it needs them at a performance penalty - as long as all the buffers for a single draw call can fit in VRAM alongside the framebuffer resources. Generally you don't want to create massive buffer objects (>100MB) as this can cause trouble for the driver's memory management and drawing performance. Just create several smaller buffers, and draw your model in smaller batches. However, your OP mentioned sizes that should easily be handled on any GPU made in the past 5 years (possibly more).

nenad*
01-21-2014, 01:57 PM
My model() function is very efficient in terms of memory, but not speed. That was not a problem until I tried to rotate it. if I generate a Vertex Buffer Object as malexander suggests, that would probably cure my problem. I can even create the VBO in background. However, I have never created a VBO before, and the example in the Red Book is rather cryptic.

The question is why do you generate stuff every frame if there are no animated deformations applied to geometry? As malexander already said - pre-generate it once at startup, store the data and then draw each frame using that data. You can draw from the same data via ram arrays or VBO arrays or even in immediate mode. If you continue to generate the data each frame, no VBOs will help you. In fact they'll make things worse as you'll need additional frame-time to upload the data to VRAM.

VBO code is very similar to ram arrays code. So get ram arrays working first (glDrawElements() etc.). Switching to VBOs from there is rather trivial. Same data just needs to be uploaded to the gpu memory.

CarstenT
01-24-2014, 02:15 PM
The limit could turn out to be the indices-buffer .. if you draw indexed.
I swing 1.4 mill vertices flavlessly on a modest pc using a setup almost identical to this:

http://www.mbsoftworks.sk/index.php?page=tutorials&series=1&tutorial=8

On the other hand .. it's a plain height-field.
I do have to use 4 draw-calls and reuse the indices with a new base-offset each time.