Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You didn't pointed out on how you have implemented your openGLobj->Arrow method, but if you are using 100% CPU time on this, you are probably painting the arrows with <a href="https://stackoverflow.com/questions/6733934/what-does-immediate-mode-mean-in-opengl">immediate mode</a>. This is really CPU intensive, because you have to transfer data from CPU to the GPU for every single instruction inside glBegin() and glEnd(). If you are using GLUT to draw your data, it's really ineficient too.</p> <p>The way to go here is use GPU memory and processing power to dipslay your data. Phyatt has already pointed you some directions, but I will try to be more specific: use a <a href="http://www.songho.ca/opengl/gl_vbo.html" rel="nofollow noreferrer">Vertex Buffer Object (VBO)</a>. </p> <p>The idea is to pre-allocate the needed memory for display your data on GPU and just update this chunk of memory when needed. This will probably make a huge difference on the efficience of your code, because you will use the efficient video card driver to handle the CPU->GPU transfers.</p> <p>To illustrate the concept, I will show you just some pseudo-code in the end of the answer, but it's by no means completely correct. I didn't tested it and didn't had time to implement the drawing for you, but's it's a concept that can clarify your mind.</p> <pre><code>class Form { public: Form() { // generate a new VBO and get the associated ID glGenBuffers(1, &amp;vboId); // bind VBO in order to use glBindBuffer(GL_ARRAY_BUFFER, vboId); //Populate the buffer vertices. generateVertices(); // upload data to VBO glBufferData(GL_ARRAY_BUFFER_ARB, vertices.size(), vertices.data(), GL_STATIC_DRAW_ARB); } ~Form() { // it is safe to delete after copying data to VBO delete [] vertices; // delete VBO when program terminated glDeleteBuffersARB(1, &amp;vboId); } //Implementing as virtual, because if you reimplement it on the child class, it will call the child method :) //Generally you will not need to reimplement this class virtual void draw() { glBindBuffer(GL_ARRAY_BUFFER, vboId); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, 0); //I am drawing the form as triangles, maybe you want to do it in your own way. Do it as you need! :) //Look! I am not using glBegin() and glEnd(), I am letting the video card driver handle the CPU-&gt;GPU //transfer in a single instruction! glDrawElements(GL_TRIANGLES, vertices.size(), GL_UNSIGNED_BYTE, 0); glDisableClientState(GL_VERTEX_ARRAY); // bind with 0, so, switch back to normal pointer operation glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } private: //Populate the vertices vector with the form vertices. //Remember, any geometric form in OpenGL is rendered as primitives (points, quads, triangles, etc). //The common way of rendering this is to use multiple triangles. //You can draw it using glBegin() and glEnd() just to debug. After that, instead of rendering the triangles, just put //the generated vertices inside the vertices buffer. //Consider that it's at origin. You can use push's and pop's to apply transformations to the form. //Each form(cone or cilinder) will have its own way of drawing. virtual void generateVertices() = 0; GLuint vboId; std::vector&lt;GLfloat&gt; vertices; } class Cone : public Form { public: Cone() : Form() {} ~Cone() : ~Form() {} private: void generateVertices() { //Populate the vertices with cone's formula. Good exercise :) //Reference: http://mathworld.wolfram.com/Cone.html } GLuint vboId; std::vector&lt;GLfloat&gt; vertices; } class Cilinder : public Form { public: Cone() : Form() {} ~Cone() : ~Form() {} private: void generateVertices() { //Populate the vertices with cilinders's formula. Good exercise :) //Reference: http://math.about.com/od/formulas/ss/surfaceareavol_3.htm } GLuint vboId; std::vector&lt;GLfloat&gt; vertices; } class Visualizer : public QOpenGLWidget { public: //Reimplement the draw function to draw each arrow for each data using the classes below. void updateGL() { for(uint i = 0; i&lt;data.size(); i++) { //I really don't have a clue on how you position your arrows around your world model. //Keep in mind that those functions glPush, glPop and glMatrix are deprecated. I recommend you reading //http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Chapter-3:-3D-transformation-and-projection.html if you want to implement this in the most efficient way. glPush(); glMatrix(data[i].transform()); cilinder.draw(); cone.draw(); glPop(); } } private: Cone cone; Cilinder cilinder; std::vector&lt;Data&gt; data; } </code></pre> <p>As a final note, I can't assure you that this is the most efficient way of doing things. Probably, if you have a HUGE ammount of data, you would need some data-structure like <a href="http://en.wikipedia.org/wiki/Octree" rel="nofollow noreferrer">Octrees</a> or <a href="http://en.wikipedia.org/wiki/Scene_graph" rel="nofollow noreferrer">scene-graphs</a> to optimize your code. </p> <p>I recommend you taking a look at <a href="http://www.openscenegraph.org/projects/osg" rel="nofollow noreferrer">OpenSceneGraph</a> or <a href="http://www.vtk.org/" rel="nofollow noreferrer">Visualization ToolKit</a> to see if that methods are not already implemented for you, what would save you a lot of time.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload