Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Performance Issue: Drawing many primitives (>1M)

  1. #1
    Junior Member Newbie
    Join Date
    Apr 2015
    Posts
    5

    Performance Issue: Drawing many primitives (>1M)

    Hi all,

    I'm developing 2D real-time data visualization application. My application shows data using OpenGL primitive types (e.g. GL_POINTS, GL_LINE_STRIP...).
    I tried VBO, but, since I do not know number of point data, creating vertex buffers repeteadly become inefficient. Also, I thought, drawing 1M GL_POINTS in 1000px-900px screen does not make sense.

    Is there any reducing technique for calculating if same pixel to be drawn already? If there is I could ignore many of them, because already I'll not be able to show them on screen.

    To sum up, I actually need some advices to draw big primitive type data. Any help would be appreciated.

    Thanks.

  2. #2
    Senior Member Regular Contributor
    Join Date
    Mar 2015
    Posts
    296
    Quote Originally Posted by alicana View Post
    Hi all,

    I'm developing 2D real-time data visualization application. My application shows data using OpenGL primitive types (e.g. GL_POINTS, GL_LINE_STRIP...).
    I tried VBO, but, since I do not know number of point data, creating vertex buffers repeteadly become inefficient. Also, I thought, drawing 1M GL_POINTS in 1000px-900px screen does not make sense.

    Is there any reducing technique for calculating if same pixel to be drawn already? If there is I could ignore many of them, because already I'll not be able to show them on screen.

    To sum up, I actually need some advices to draw big primitive type data. Any help would be appreciated.

    Thanks.
    Im afraid your description may be vague, How many primitives will you draw a time? for a one frame you may be not draw as many vertices as 1M, uniform shader can calculate them automatically.

    are you meaning draw no the same points or store no the same points in vbo?
    if you use depth test, that will increase display speed, as well as index list, but you cant reduce vertices number.

  3. #3
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,674
    I tried VBO, but, since I do not know number of point data, creating vertex buffers repeteadly become inefficient.
    Generally speaking, you would allocate a buffer that is "big enough" to handle some maximum amount of data. You don't allocate based on what your variable data currently is; you allocate based on what it will ever be.

    And if you go over the limit... do whatever should happen when you run out of memory.

    Also, I thought, drawing 1M GL_POINTS in 1000px-900px screen does not make sense.
    First, what resolution are you rendering to that only has 1000 pixels? Even a 100x100 image exceeds that.

    More importantly... what does it matter? GPUs are very good at rendering stuff. And a million points, all rendered in a single draw call, is nothing to them. It's when you try to render that in multiple draw calls that you have a problem.

    Performance-wise, I'd be far more concerned about the cost of uploading a million points before the cost of drawing them. Using proper streaming techniques and such.

    Don't optimize before you have profiled. Before bothering to "optimize" this, you should make certain that it is your performance bottleneck.

    Because odds are good that it isn't.

  4. #4
    Junior Member Newbie
    Join Date
    Apr 2015
    Posts
    5
    Quote Originally Posted by reader1 View Post
    Im afraid your description may be vague, How many primitives will you draw a time? for a one frame you may be not draw as many vertices as 1M, uniform shader can calculate them automatically.

    are you meaning draw no the same points or store no the same points in vbo?
    if you use depth test, that will increase display speed, as well as index list, but you cant reduce vertices number.
    Assume that an application, which is placed outside, sends point data sequentially. Point structure contains ID, (X,Y) position, color and point size information.
    Also, this data can be reach 2 million. Obviously, its impossible that drawing 2M glVertex2f() between glBegin()/glEnd(). So, I tried to use VBO with initial capacity by giving 2M.

    But, VBO approach does not allow me to add (resizing capacity), update or removing data from itself. (maybe VBO can be updated but I don't know?)

    Then, I thought that, insignificant to draw 2M point in a window. Most of them will not able to be shown (am I still right here?)

    My following question is now:

    1) What would you do if you have big number of data to be drawn, that are added-removed sequentially?
    2) Is Fragment shader or vertex shader is vital in this situation ?

    I really need some advice

  5. #5
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    3,103
    Quote Originally Posted by alicana View Post
    But, VBO approach does not allow me to add (resizing capacity), update or removing data from itself. (maybe VBO can be updated but I don't know?)
    The attribute arrays must be large enough to hold the data, but they can also be larger. The number of primitives drawn is determined by the "count" parameter to the draw call (glDrawArrays etc), not the size of the attribute array.

    So, allocate a buffer which is "large enough". If you ever find that it isn't actually large enough, allocate a new, larger buffer.

    If rendering order doesn't matter, you can add a point by appending it to the end of the array and incrementing the variable holding the number of points, and can remove a point by copying the data for the last point over the data for the removed point then decrementing the variable holding the number of points.

    If rendering order does matter, then you can use the above approach in conjunction with vertex indices (glDrawElements rather than glDrawArrays), so that you only need to order the indices rather than all of the attribute data. It may also help to segment the data by using e.g. glMultiDrawArrays (if each segment contains some free space, you only need to move other elements within the segments which are modified). Inserting or removing multiple elements at once is likely to be more efficient than operating one at a time (typically, you sort the modifications so that the memory can be accessed sequentially rather than randomly).

    Quote Originally Posted by alicana View Post
    2) Is Fragment shader or vertex shader is vital in this situation ?
    Not necessarily. From the few details you've provided, it doesn't seem that shaders would even be useful.

    Shaders can sometimes be useful for reducing the size of the data by eliminating redundancy, but that doesn't appear to be the issue here.

  6. #6
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,674
    But, VBO approach does not allow me to add (resizing capacity), update or removing data from itself. (maybe VBO can be updated but I don't know?)
    Data in a buffer object can be updated like this. Again, streaming techniques will be of benefit to you.

    Then, I thought that, insignificant to draw 2M point in a window. Most of them will not able to be shown (am I still right here?)
    I feel that you are far too concerned about what doesn't get shown without having a profiling test to prove that what isn't being shown is a performance problem. Do not optimize without proof.

    What would you do if you have big number of data to be drawn, that are added-removed sequentially?
    I would draw them, then measure the performance of the rendering. If the performance is adequate, I'm done. If not, profile it to find out where the performance is a problem.

    2) Is Fragment shader or vertex shader is vital in this situation ?
    Vital? No. But I don't consider them optional regardless of the circumstance.

    Also, there are cases where they could conceivably ease your performance burden, for certain kinds of performance issues. For example, if memory transfer is a problem, you can use shaders to reduce your data size. Instead of giving each vertex an independent color, you could have a palette of colors (in a UBO, not a texture), and your per-vertex data only contains an unsigned byte per vertex containing that color's index. This requires that the number of individual colors in the dataset is relatively small. And even then, it's not clear without testing it if that would help.

    But testing things like that is easier if you're already using shaders than if you need to suddenly introduce them.

  7. #7
    Senior Member Regular Contributor
    Join Date
    Mar 2015
    Posts
    296
    Quote Originally Posted by Alfonse Reinheart View Post
    First, what resolution are you rendering to that only has 1000 pixels? Even a 100x100 image exceeds that.
    .
    Ridiculous, What resolution are you sure to make up to recognize 1000pixels?
    Typo or Sypo? not kidding? well, you must change your glasses you are wearing, or magnify letter M more larger, to see it is not K order.

    More importantly... what does it matter? GPUs are very good at rendering stuff. And a million points, all rendered in a single draw call, is nothing to them. It's when you try to render that in multiple draw calls that you have a problem.
    Perfect English are you, but direct to another way. I like to hear about gpu as well.

  8. #8
    Senior Member Regular Contributor
    Join Date
    Mar 2015
    Posts
    296
    Quote Originally Posted by alicana View Post
    Assume that an application, which is placed outside, sends point data sequentially. Point structure contains ID, (X,Y) position, color and point size information.
    Also, this data can be reach 2 million. Obviously, its impossible that drawing 2M glVertex2f() between glBegin()/glEnd(). So, I tried to use VBO with initial capacity by giving 2M.
    To draw 2M or 20M or 200M into memory is not a problem for todays device.
    glBegin()/glEng() is really inefficient. instead you can use vbo as you said. which can add, delete and modify contents.
    In fact, you could assign several vbo to content your big data requirement flexibly.
    But, VBO approach does not allow me to add (resizing capacity), update or removing data from itself. (maybe VBO can be updated but I don't know?)
    To draw 2M or 20M or 200M into memory is not a problem for todays device.
    glBegin()/glEng() or list is really inefficient or inconvinient. instead you can use vbo. which can add, delete and modify contents.
    you may refer to glBufferData(), glMapBuffer(),etc.
    Then, I thought that, insignificant to draw 2M point in a window. Most of them will not able to be shown (am I still right here?)

    My following question is now:

    1) What would you do if you have big number of data to be drawn, that are added-removed sequentially?
    I really need some advice
    you do certainly not draw up to 2M points in a window, you may make an error calculation, or they are not in a window(or frame). even if for 4k definition, you can not.
    suppose you fill all the screen with primitives, the points will be far less than 300k at most.
    But you hve to know, to draw them and to show them on the screen is totally not a same concept.
    for example, if you would have two triangles, a vertex of one is covered by another one, you do certainly not lose this vertex for imagine to reduce store size. otherwise, the computer or gl will not construct this triangle. you will be shown only two points, or get another different one, or get a warning in build.
    2) Is Fragment shader or vertex shader is vital in this situation ?
    of cuase not, agree to above fellows idea. if you don't deal with rendering, ignore it.

  9. #9
    Junior Member Newbie
    Join Date
    Apr 2015
    Posts
    5

    First of all, thank you all for informative posts. I'm implementing vbo by expanding my vbo buffer. You all guys gave me very useful ideas.

    I realized that, lets say I have allocated a buffer for 2 million:

    ==> 2*10e6 (data objects) * 2 (x, y position) * SIZEOF_DOUBLE (position value type)

    And, I did not put any single value to the buffer. The following code still try to draw:

    ...
    glBindBuffer(GL2.GL_ARRAY_BUFFER, vertexBufferIndices);
    glEnableClientState(GL2.GL_VERTEX_ARRAY);
    glVertexPointer(2, GL2.GL_DOUBLE, 3 * Buffers.SIZEOF_DOUBLE, 0);
    glDrawArrays(GL2.GL_POINTS, 0, vertices[0]);
    ...

    This is expected behaviour, isnt it ? Give me some courage

  10. #10
    Junior Member Newbie
    Join Date
    Apr 2015
    Posts
    5
    Quote Originally Posted by reader1 View Post
    glBegin()/glEng() or list is really inefficient or inconvinient. instead you can use vbo. which can add, delete and modify contents.
    I read some other users benchmark tests vbo vs immidiate mode they concluded there is no extreme difference.

    http://stackoverflow.com/questions/4...itives-glbegin



    http://www.gamedev.net/topic/574242-...ate-benchmark/

Page 1 of 2 12 LastLast

Similar Threads

  1. drawing text and primitives at the same time
    By insanebits in forum OpenGL: Basic Coding
    Replies: 3
    Last Post: 05-17-2013, 06:41 PM
  2. low performance in drawing primitives
    By atteal in forum OpenGL: macOS
    Replies: 1
    Last Post: 08-03-2012, 12:45 PM
  3. drawing stationary 2d primitives & using gluLookAt
    By Choff04 in forum OpenGL: Basic Coding
    Replies: 4
    Last Post: 11-29-2009, 12:46 AM
  4. Drawing primitives:
    By anoop4real in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 10-01-2009, 05:34 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean