PDA

View Full Version : VertexBufferOBJTS Questions



Septimra
04-04-2015, 02:01 PM
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(double) * i_len_ * 3, formtd_verts_, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, 0, 0);

So what this is saying that the current array buffer is VBO.
Then it is saying allocate space for this VBO with DYNAMIC DRAW? Is this line also saying push formtd_verts_ to the GPU?
Then I am describing to OpenGL the type of data that is in the buffer with vertexattribpointer.

My second question is for the bufferdata; GL_DYNAMIC_DRAW--how can it optimize anything if we are telling it per frame to DYNAMICALLY DRAW? Is there 1 function to allocate space for the array then another function to push new formtd_verts_ data to the GPU, without saying GL_DYNAMIC_DRAW each frame?

Hopefully the questions clear enough

GClements
04-04-2015, 02:37 PM
Is this line also saying push formtd_verts_ to the GPU?
Yes. Well, it's saying to copy the data from client memory into the buffer's storage; exactly where that data is stored at any point in time is up to the implementation.


Then I am describing to OpenGL the type of data that is in the buffer with vertexattribpointer.
Not quite. You're telling GL how to obtain the data for attribute zero. That call says that the data for attribute zero consists of 3 values for each vertex, the values are of type GLdouble, the stride between data for consecutive vertices is the same as the size of the data for each vertex, and the start of the data for the first vertex is at the start of the currently-bound array buffer (zero offset). The normalized parameter is ignored for floating-point data.

A buffer can contain a mix of different types of data (e.g. the data for multiple attributes can be interleaved, or in separate arrays stored in different regions of the buffer). A single glVertexAttribPointer() call only describes the data for a single attribute; it says nothing about what else may be in the buffer.


Is there 1 function to allocate space for the array then another function to push new formtd_verts_ data to the GPU, without saying GL_DYNAMIC_DRAW each frame?
You can modify the contents of an existing buffer store with glBufferSubData(), or by mapping the buffer with glMapBuffer() or glMapBufferRange() then modifying the mapped region.

glBufferData() behaves somewhat like a combination of glBufferStorage() (which only allocates a buffer's storage) and glBufferSubData() (which uploads new data). Except that buffers allocated with glBufferStorage() cannot be reallocated, while those created with glBufferData() can.

Alfonse Reinheart
04-04-2015, 02:50 PM
glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, 0, 0);

It should be noted that you should never use this. While it is legal, it won't do what you want. Specifically, I'm referring to the use of "GL_DOUBLE".

That means that your data consists of 64-bit floating-point values. However, by using glVertexAttribPointer, you're telling OpenGL that you're transmitting that data to a vertex shader that expects 32-bit floats. So somewhere along the line, a conversion must happen. And odds are good that this conversion will be slow.

If you don't intend to send 64-bit floating-point data to the shader, then you should convert your data yourself before sticking it into the buffer. And if you do intend to send 64-bit float data, then you probably intend for the shader to actually use 64-bit float operations on it. So your vertex shader input for attribute 0 should be a dvec3. Which means you must use glVertexAttribLPointer (https://www.opengl.org/wiki/Vertex_Specification#Vertex_format), which is specifically for sending data as 64-bit floats.

It also requires OpenGL 4.0 or better.

As for:


My second question is for the bufferdata; GL_DYNAMIC_DRAW--how can it optimize anything if we are telling it per frame to DYNAMICALLY DRAW? Is there 1 function to allocate space for the array then another function to push new formtd_verts_ data to the GPU, without saying GL_DYNAMIC_DRAW each frame?

You should investigate buffer object streaming techniques (https://www.opengl.org/wiki/Buffer_Object_Streaming) if performance matters to you.

Septimra
04-05-2015, 04:28 AM
Alright. I hear what you guys are saying. Thanks. And using glVertexAttribLPointer did fix somethings for me. But I guess this question belongs to a different post: But how would you go about rendering using a comp with only 32mg of VRAM? I am considering using GL_FLOATS instead of GL_DOUBLE, GPU skinning, and buffer object stream techniques from the link provided above. Becuase Blender3D animates just fine and it uses OpenGL, but my animation in my engine gets some popping vertices in random places at random times. Using VBOs helped it and using glVertexAttribLPointer helped even more. Now I just get slow down and very few popping/sticking vertices at random moments at random times. I would prefer just slow down as apposed to this weird behavior described.



Also where could I find a reference as to what each index for glVertexAttribLPointer points to. I know index 0 is the position attrib array.

Alfonse Reinheart
04-05-2015, 05:23 AM
I am considering using GL_FLOATS instead of GL_DOUBLE

Generally speaking, you should only use doubles when you absolutely need the extra precision.


Also where could I find a reference as to what each index for glVertexAttribLPointer points to. I know index 0 is the position attrib array.

It isn't the "position attrib array". There is no "position attrib array". Since you're using shaders, attribute indices mean exactly and only what you choose for them to mean (https://www.opengl.org/wiki/Vertex_Attribute). Odds are good that if you're not aware of selecting your attribute, the implementation may have assigned attribute index 0 to the first user-defined vertex attribute for you.

GClements
04-05-2015, 01:15 PM
But how would you go about rendering using a comp with only 32mg of VRAM? I am considering using GL_FLOATS instead of GL_DOUBLE,
If you're short on memory, consider using GL_SHORT or GL_UNSIGNED_SHORT instead of GL_FLOAT. Or even GL_INT_2_10_10_10_REV (or the unsigned version). In some cases, even bytes may be sufficient.


Also where could I find a reference as to what each index for glVertexAttribLPointer points to. I know index 0 is the position attrib array.
Indices are allocated to attributes by the GLSL compiler. You can either

1. specify the attribute index, either by
a) using layout qualifiers on the attribute declarations in the GLSL source code, or
b) using glBindAttribLocation() prior to linking the program, or

2. allow the GLSL compiler to allocate indices and query them using glGetAttribLocation() after linking the program.