Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 9 of 9

Thread: how to create an attribute array for primitves

  1. #1
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    20

    how to create an attribute array for primitves

    Hello,

    I use VBOs with an element array and Shader to render my data. In the fragment shader I want to have access to an array which stores information for every primitive (visible, selected, ...). I've tried to stores these information as part of the vertex array, but there is the problem, that I can't set informations for the primitives, only for the vertices.
    My idea now is, to write an array with integers in the GPU memory and access to the values in the fragment shader with the help of the GL_PRIMITIVE_ID.

    My problem is, that I don't know which technology is the best way to implement this functionality. I think a good way is to use one of the possible Buffer Objects (TBO, UBO,...) or to create a texture an access to the information. I want to know which technique I have to use or is there a way to send an array to GPU memory an access them like to VBOs (glMapBuffer). Or is there an easier way to solve the problem?

  2. #2
    Member Regular Contributor
    Join Date
    Jan 2012
    Location
    Germany
    Posts
    302

    Re: how to create an attribute array for primitves

    If this array would not be too large, a UBO would work (i think 64k is the minimum size limit), you can also update a UBO with MapBuffer/UnmapBuffer. If the data gets larger, texture would also work. There are performance differences here depending on the access pattern (afaik texture access is slower than UBO access in general, but if you have a lot of texture cache hits that can be as fast as UBOs.
    You could fetch your information in a geometry shader, so you only have to fetch it once per primitive instead of once per fragment.

  3. #3
    Junior Member Regular Contributor Kopelrativ's Avatar
    Join Date
    Apr 2011
    Posts
    212

    Re: how to create an attribute array for primitves

    Quote Originally Posted by miujin
    In the fragment shader I want to have access to an array which stores information for every primitive (visible, selected, ...). I've tried to stores these information as part of the vertex array, but there is the problem, that I can't set informations for the primitives, only for the vertices.
    Storing data for vertices instead of primitives would duplicate information. It is a classical problem for normals. If you are using GL_TRIANGLES, you would duplicate every primitive data times 3.

    However, that is the simple solution that can work quite well. If you combine it with indexed drawing (e.g. glDrawElements), the actual number of vertices can be reduced. It depends on your performance requirements.

  4. #4
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    20

    Re: how to create an attribute array for primitves

    Quote Originally Posted by menzel
    If this array would not be too large, a UBO would work (i think 64k is the minimum size limit), you can also update a UBO with MapBuffer/UnmapBuffer. If the data gets larger, texture would also work. There are performance differences here depending on the access pattern (afaik texture access is slower than UBO access in general, but if you have a lot of texture cache hits that can be as fast as UBOs.
    You could fetch your information in a geometry shader, so you only have to fetch it once per primitive instead of once per fragment.
    Ok with the 64 kB the UBO is not so good. I visualize models with millions of triangles and so the UBO is to small. Implement a geometry shader would also be a option, but at the moment I have no need for a geometry shader. If I have a 3 million triangle model i have more fetches in the geometry shader than in den fragment shader. So this would also be not so good.

    Quote Originally Posted by Kopelrativ
    Storing data for vertices instead of primitives would duplicate information. It is a classical problem for normals. If you are using GL_TRIANGLES, you would duplicate every primitive data times 3.
    However, that is the simple solution that can work quite well. If you combine it with indexed drawing (e.g. glDrawElements), the actual number of vertices can be reduced. It depends on your performance requirements.
    I know that problem. I get the data from a STL file, so every triangle stores information for 3 vertices. So I have duplicate information. I have a function which remove all duplicate vertices and create an index array, so I use indexed drawing. The problem now is, that I can only store information for the vertices, for example if I store the information 'selected' to the 3 vertices of a triangle, all triangles which have one of these vertices get 'half-selected'. So now I need something to store information (e.g. in the form of an integer array) for every triangle independent from the vertices.

  5. #5
    Junior Member Regular Contributor Kopelrativ's Avatar
    Join Date
    Apr 2011
    Posts
    212

    Re: how to create an attribute array for primitves

    Quote Originally Posted by miujin
    The problem now is, that I can only store information for the vertices, for example if I store the information 'selected' to the 3 vertices of a triangle, all triangles which have one of these vertices get 'half-selected'. So now I need something to store information (e.g. in the form of an integer array) for every triangle independent from the vertices.
    I see, if you need all this information with the vertex data, every vertex can only be used for one triangle, and the meaning of using indexed drawing is lost?

    Do you want the ability to select one, or more, primitives, that shall then be highlighted some way in the fragment shader?

    One way to do this could be to:
    • Include a triangle ID (number) with each vertex.
    • All vertices would be unique, meaning indexed drawing doesn't help. Use glDrawBuffer() instead.
    • The triangle ID is forwarded from the vertex shader to the fragment shader.
    • A uniform is used to tell the fragment shader the ID of the triangle currently selected.

  6. #6
    Advanced Member Frequent Contributor
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    720

    Re: how to create an attribute array for primitves

    Have you looked at glTexBuffer. I am looking at it at the moment for a similar problem.

  7. #7
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    20

    Re: how to create an attribute array for primitves

    What I want is to have some information about every triangle in the fragment shader, but furthermore I want to use indexed drawing.

    Now I have a way how it works, but not perfect. I use the texture buffer to store the information in the R value. The problem now is, that I cannot write an integer in the value. I've read somewhere that this is a driver implementation error and that only float values work with texture buffer. Does anybody know something about the error and know if there is a way to fix it?
    The reason why I want to have integers there is, that I want to set the several bits to an information e.g. Bit1 - Selected, Bit2 - Invisible, Bit3 - Transparent, ...

  8. #8
    Senior Member OpenGL Pro Ilian Dinev's Avatar
    Join Date
    Jan 2008
    Location
    Watford, UK
    Posts
    1,261

    Re: how to create an attribute array for primitves

    Because the per-triangle data can change often, and there are many triangles, TBOs are the way to go.
    To go around the driver-bug, meanwhile just use GL_RED8 and

    float fval = texelFetch(texbuf, gl_PrimitiveID).r;
    int ival = int(fval * 255.0);

  9. #9
    Advanced Member Frequent Contributor
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    720

    Re: how to create an attribute array for primitves

    Have you thought of creating a float texture so no normalising is done but storing the int value without conversion

    eg
    union FloatInt
    {
    int i;
    float f;
    };


    then use floatBitsToInt to read the texture in the shader

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •