Sign in to follow this  

OpenGL Multiples VBO for large CAD models

Recommended Posts


I have programmed a working CAD vizualisation engine for my work. The goal is to load very large models and display them at interactive rates.
The models have the following traits:
   - amount of vertices ranges from small (150 vertices) to very large (16 million or more). The 2 to 4 millions vertices are very common
   - large amount of different models (in the thousands range, until 100000...)

The engine I have made so far has the following characteritics:
   - standard culling possibility (Kd-Tree + Frustum + pixel culling)
   - unified vertex format to limit state change
        28 bytes per vertex : 2 floats for position, 3 floats for normals, 4 bytes for colour RGBA.
     More vertex format are supported, but actual scenario are using this one
   - state caching already implemented (no call to glBindBuffer if the buffer to bind is already the current one)
   - done in OpenGL & C++
   - Fixed Function Pipeline or Shader + VBO + IBO are used
   - Mesh optimisation : all duplicates vertices are removed, and each mesh is drawn using 1 single call to glDrawElements
   - each Mesh has only 1 VBO and only 1 IBO (both static)
   - geometry is mostly static

Now on NVidia Quadro cards (1 Gb VRAM) I have:
   - the theoretical limit for vertex buffer size is 1 million vertices (result from glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &iMaxVertex))
   - some VBOs are already over this limit, but it seems to be fine (some are 16 times this limit). I typically get a 20 to 60 FPS with more than 5 million vertices
   - I have already filled up 1 GB with VBOs and IBOs on the graphic card (yes, the models are THAT big).

The problems I face are :
   - When the amount of models increase, the FPS drops to 10 => probably due to too many VBO & IBO switching
   - the worst problem : after loading many models OR a few very large models, the FPS behaves strangely : it FREEZES for 3 seconds, and then shot back up to 15 or more FPS. And 15 seconds later, it freezes again. So in summary, the problem is "it is sometimes slow, sometimes fast".

Now my 2 questions are:
  Question 1 : what can be the cause of the freezing of the FPS ? It does not happen on ATI cards Radeon 6550M HG

  Question 2 : for optimization, I have a dilemma. I can either:
                a pack everything in 1 VBO and 1 IBO => I will save on glBindBuffer calls, but I will have 2 monstrous buffers on the GPU, clearly over the maximal size returned by glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &iMaxVertex)
                b pack all data in several VBOs and IBOs, with each VBO and IBO having 95% of the max size returned by glGetInteger. I will have more state switching than with the 1st option, but less than currently.               Since both options are rather heavy to implement, I would like to know if some among you have experience with this

situation. I am more leaning on option b, but it is no so convenient to split big meshes.

Thanks in advance for the help !


Share this post

Link to post
Share on other sites
You say you've implemented KD tree, but what are the constraints on your view? I mean give us a bit of a clue about the use case for your engine.

Share this post

Link to post
Share on other sites
OK, so here is one use case (where freezing occurs):
- largest model : 16 051 900 vertices, 17 081 685 triangles (drawn with GL_TRIANGLES => 51 245 055 indices)
=> largest VBO : 428 Mo (28 bytes per vertex)
largest IBO : 195 Mo (4 bytes per indice)
You can see that the model is optimized : there are more triangles than vertices => most of vertices are shared.

- 410 models loaded (410 VBOs + 410 IBOs) : see gDEBugger GL extract attached for a list. You will see there are very big models, and small ones
- 1 Gb memory used...

For the engine, here is how it works:
- draw loop :
For each frame
Compute frustum planes
Do Frustum Culling (with KdTree), using bounding sphere tests against plane (very fast)
Do Pixel culling (with Bounding sphere) => 1 distance calculation (ouch : sqrt), 2 multiplications, 1 division, 1 comparison
Draw the remaining meshes : draw opaques, draw transparents, draw lines

- For frustum culling : I start with the KdTree root node, and recursively traverse the tree until a leaf node is found in the viewing frustum. I use plane / sphere distance calculation.

- For KdTree generation : I use the Surface Area Heuristic. It is done on model level (the meshes are not splitted)

- performance : at first, my models were composed of 1 or more VBOs. I have quickly seen it was leading to a performance bottleneck => I solved the problem by merging all VBOs into 1, removing duplicated & ununsed vertices. So I know for sure that too many VBOs are provoking a performance bottleneck

- pixel culling: it is clearly a performance boost, expecially when many small models are loaded (screws, nuts, ...)
For pixel culling, the minimal size is different if the camera is moving or if it is static.

- multipass rendering : after culling, I draw in this order: opaques triangles, transparent triangles, edges of the meshes. When moving, edges are not drawned.

I will try first anyway to pack everything in 1 VBO and 1 IBO : it is the simplest to implement, and it might just work.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Partner Spotlight

  • Forum Statistics

    • Total Topics
    • Total Posts
  • Similar Content

    • By xhcao
      Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness. 
    • By cebugdev
      hi guys, 
      are there any books, link online or any other resources that discusses on how to build special effects such as magic, lightning, etc. in OpenGL? i mean, yeah most of them are using particles but im looking for resources specifically on how to manipulate the particles to look like an effect that can be use for games,. i did fire particle before, and I want to learn how to do the other 'magic' as well.
      Like are there one book or link(cant find in google) that atleast featured how to make different particle effects in OpenGL (or DirectX)? If there is no one stop shop for it, maybe ill just look for some tips on how to make a particle engine that is flexible enough to enable me to design different effects/magic 
      let me know if you guys have recommendations.
      Thank you in advance!
    • By dud3
      How do we rotate the camera around x axis 360 degrees, without having the strange effect as in my video below? 
      Mine behaves exactly the same way spherical coordinates would, I'm using euler angles.
      Tried googling, but couldn't find a proper answer, guessing I don't know what exactly to google for, googled 'rotate 360 around x axis', got no proper answers.
      The video shows the difference between blender and my rotation:
    • By Defend
      I've had a Google around for this but haven't yet found some solid advice. There is a lot of "it depends", but I'm not sure on what.
      My question is what's a good rule of thumb to follow when it comes to creating/using VBOs & VAOs? As in, when should I use multiple or when should I not? My understanding so far is that if I need a new VBO, then I need a new VAO. So when it comes to rendering multiple objects I can either:
      * make lots of VAO/VBO pairs and flip through them to render different objects, or
      * make one big VBO and jump around its memory to render different objects. 
      I also understand that if I need to render objects with different vertex attributes, then a new VAO is necessary in this case.
      If that "it depends" really is quite variable, what's best for a beginner with OpenGL, assuming that better approaches can be learnt later with better understanding?
    • By test opty
      Hello all,
      On my Windows 7 x64 machine I wrote the code below on VS 2017 and ran it.
      #include <glad/glad.h>  #include <GLFW/glfw3.h> #include <std_lib_facilities_4.h> using namespace std; void framebuffer_size_callback(GLFWwindow* window , int width, int height) {     glViewport(0, 0, width, height); } //****************************** void processInput(GLFWwindow* window) {     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)         glfwSetWindowShouldClose(window, true); } //********************************* int main() {     glfwInit();     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);     //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);     GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);     if (window == nullptr)     {         cout << "Failed to create GLFW window" << endl;         glfwTerminate();         return -1;     }     glfwMakeContextCurrent(window);     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))     {         cout << "Failed to initialize GLAD" << endl;         return -1;     }     glViewport(0, 0, 600, 480);     glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);     glClearColor(0.2f, 0.3f, 0.3f, 1.0f);     glClear(GL_COLOR_BUFFER_BIT);     while (!glfwWindowShouldClose(window))     {         processInput(window);         glfwSwapBuffers(window);         glfwPollEvents();     }     glfwTerminate();     return 0; }  
      The result should be a fixed dark green-blueish color as the end of here. But the color of my window turns from black to green-blueish repeatedly in high speed! I thought it might be a problem with my Graphics card driver but I've updated it and it's: NVIDIA GeForce GTX 750 Ti.
      What is the problem and how to solve it please?
  • Popular Now