PDA

View Full Version : What does a buffer object, and attribute pointer look like for changing vertex data



Cubby208
12-27-2015, 09:43 PM
So I was wondering what the proper practice doing the following would be.

So basically all I have is a array holding the coordinates of a cube. Then as time goes on I change the values of the coordinates however do not change the size of the array. I am trying to get things going as efficiently as possible!

A lot of places have talked theoretically about what something like this would look like. However they never include data about passing attributes to the shader. I have never understood how the attribute passing thing knows what buffer to look at.

Also please note that at the end of drawing I need to make things so all the streaming things and buffers that would get in the way of other drawing are properly disabled. Here is what I have so far I think it is probably not the most efficient.

Also I have noticed that if I turn down the amount I allocate in the buffer it significantly decreases the time it spends on that functions. Perhaps if I can preallocate the buffer only once?


var locArray:[GLfloat] = []
var colArray:[GLfloat] = []
var sizeArray:[GLfloat] = []
var bObjColor:GLuint = 0
var bObjSize:GLuint = 0
var bObjVertex:GLuint = 0

var aLocColor:GLuint = 0
var aLocSize:GLuint = 0
var aLocVertex:GLuint = 0
func init() //Called on initializations
{
glGenBuffers(1, &bObjColor)
glGenBuffers(1, &bObjSize)
glGenBuffers(1, &bObjVertex)

aLocColor = GLuint(glGetAttribLocation(pointShader, "color"))
aLocSize = GLuint(glGetAttribLocation(pointShader, "size"))
aLocVertex = GLuint(glGetAttribLocation(pointShader, "vertex"))
}
func draw() //Called on each frame
{
editTheVertexData() // I didnt show because it does what it says
build()
draw()
cleanup()
}
func build()
{
glUseProgram(pointShader)
glUniformMatrix4fv(uLocOrtho, 1, GLboolean(GL_FALSE), &matrix)

glBindBuffer(GLenum(GL_ARRAY_BUFFER), bObjColor)
glBufferData(GLenum(GL_ARRAY_BUFFER), sizeof(GLfloat) * maxParticles * 8, colArray, GLenum(GL_DYNAMIC_DRAW))
glEnableVertexAttribArray(aLocColor)
glVertexAttribPointer(aLocColor, 4, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 0, BUFFER_OFFSET(0))


glBindBuffer(GLenum(GL_ARRAY_BUFFER), bObjSize)
glBufferData(GLenum(GL_ARRAY_BUFFER), sizeof(GLfloat) * maxParticles * 2, sizeArray, GLenum(GL_DYNAMIC_DRAW))
glEnableVertexAttribArray(aLocSize)
glVertexAttribPointer(aLocSize, 1, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 0, BUFFER_OFFSET(0))

glBindBuffer(GLenum(GL_ARRAY_BUFFER), bObjVertex)
glBufferData(GLenum(GL_ARRAY_BUFFER), sizeof(GLfloat) * maxParticles * 6, locArray, GLenum(GL_DYNAMIC_DRAW))
glEnableVertexAttribArray(aLocVertex)
glVertexAttribPointer(aLocVertex, 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 0, BUFFER_OFFSET(0))


}
func draw()
{
glDrawArrays(GLenum(GL_POINTS), 0, 1000)
}
func cleanup()
{
glDisableVertexAttribArray(aLocVertex)
glDisableVertexAttribArray(aLocSize)
glDisableVertexAttribArray(aLocColor)
}

How am I doing? I am guessing that somehow OpenGL can hold a pointer to the array and so I dont need to call glBuffer data each frame. But I really dont know!

GClements
12-28-2015, 02:18 AM
A lot of places have talked theoretically about what something like this would look like. However they never include data about passing attributes to the shader. I have never understood how the attribute passing thing knows what buffer to look at.

A call to glVertexAttribPointer() stores the current GL_ARRAY_BUFFER binding along with the parameters.as the source for the attribute.

If you want to minimise the number of calls required for drawing, use vertex array objects (VAOs: glGenVertexArrays, glBindVertexArray, etc). All of the state associated with attribute arrays (along with the current GL_ELEMENT_ARRAY_BUFFER binding) is stored in the currently-bound VAO. Thus, you can swap all of the associated state with a single glBindVertexArray() call.



I am guessing that somehow OpenGL can hold a pointer to the array and so I dont need to call glBuffer data each frame.
You don't need to call glBufferData() unless the data has changed. If the data has changed, you can either use glBufferSubData() to replace some or all of the data, or use glBufferData() to release the buffer's existing memory and allocate new memory containing the new data.

The latter has the advantage that it doesn't have to wait until the GPU has finished using the existing data. The implementation can allocate and initialise the new memory immediately while keeping the old memory around until the GPU has finished using it.