I'm displaying text from Bitmap Fonts on screen with OpenGL, and I'm creating a VBO for vertexes, another for indexes and one for UVs.
I get a string value, and I create a single vertex, uv and index data from all the characters so I only have 1 draw call.
Now I'm trying to figure what to do when that string changes.
If it's the same length of the previous string, I can use glBufferData() and glBufferSubData(), but what should I do if it's a different size?
Can I bind the VBO, call glBufferData() with a different size and upload the new data?
Or should I just delete the VBO and create a new one?
What's the proper way to deal with this?
Allocate a bigger buffer then you need and map subranges so the driver doesn't have to reallocate the memory every time the string changes.
Related
I'm writing a directx App and I want to resize my VertexBuffer as vertex's size and indices' size changes with each every frame.
I wonder if there are some special ways to handle with minimal costs. I think it is not awkward to create new constant buffer in every frame.
Is there any possible solution for me?
Cheers
What you can do without relocating is: create a VertexBuffer / IndexBuffer large enough for all the cases, and when drawing on the screen, use only the number of indices you will use.
Is there a method for binding only a single attribute of a VBO to a texture buffer object?
Problem is, I use an interleaved VBO for drawing spheres with the attributes position, radius and another one. Now, I want to use another shader which draws other stuff using instanced geometry at the positions in my sphere VBO.
What I could do is just texelFetch() the data I need which is really ugly concerning the needed alignment (VBO attributes have different size) and the unused space, which is bad because of the limited size of a texture buffer. Another way could be copying only the data I need from one VBO to a separate VBO, but that's not really satisfying either.
So... is there another possibility?
Buffer textures do not have attributes. So what you're talking about doesn't make sense.
Also, VBOs are not a thing; there is no such thing as a "VBO". There are simply buffer objects and different uses for them. glVertexAttribPointer does not modify the buffer object. It just tells OpenGL's vertex reading system how to fetch data from it. Other systems that fetch data from buffer objects use their own mechanisms for doing so, which are entirely separate.
Like buffer textures.
If you want to "draws other stuff using instanced geometry", why don't you just use instancing? Apply a divisor (presumably of 1) to those attributes, so that they will only get different values for different instances.
I'm a bit confused as to why you can set active an array of vertex buffers but only one index buffer? Could that one index buffer address the vertices from all the vertex buffers? And if so how would i specify which buffer which index belongs to?
Another question i have is that since i'm using indexed triangle lists, the index data is roughly the same size as vertex data per mesh. I was thinking about creating one index buffer per one vertex buffer. I will be dynamically adding meshes until one of the buffers runs out at which point another pair is created. Inevitably by doing this, one of the buffers in the pair will always fill up before the other one and that leftover space will never get used. Does that space actually get marked as reserved in the gpu?
Like for instance, could i fit 4 buffers that contain 32MB of data but are created with byte width of 64MB into 128MB of vram?
The same indices must be used with all vertex buffers at the same time. The purpose of this is to allow different vertex buffers to contain different components of the vertex data. For example, you might decide store the positions in one vertex buffer and the texture coordinates in a second buffer. The zeroth index would access the first position from the first vertex buffer and the first texture coordinate from the second.
This would save bandwidth if you wanted to update the texture coordinates every frame but never change the positions.
Multiple vertex buffers are also used in instancing.
When you create a vertex or index buffer, you specify the size of the buffer. This amount of memory is then reserved in video ram and cannot be used by anything else.
So if I understand your question, no you can't fit four 64mb buffers into 128 mb of ram.
It seems as though glTexSubImage2D requires a pointer to the full texture buffer. How does one make partial updates to a texture by only providing a pointer to the update region rather than the whole buffer?
For example if I want to overlay a second image onto an existing texture, rather than copy the image data onto my texture buffer then call glTexSubImage2D, I just get opengl to update the texture without having to copy data between RAM locations.
Where do you get the notion that glTexSubImage2D requires a pointer to the full texture buffer ?
From the documentation linked above, it seems to me that the last parameter is a pointer to the buffer containing your new data only. The other parameters are what you use to specify which texture object to update (just an OpenGL identifier, no pointer to the original data required) and the offset and size to copy your new data to.
TL;DR: glTexSubImage2D takes a pointer to your new data and does exactly what you think it should in your example :)
I have a question related to Buffer object performance. I have rendered a mesh using standard Vertex Arrays (not interleaved) and I wanted to change it to Buffer Object to get some performance boost. When I introduce buffers object I was in shock when I find out that using Buffers object lowers performance four times. I think that buffers should increase performance. Does it true? So, I think that I am doing something wrong...
I have render 3d tiled map and to reduce amount of needed memory I use only a single tile (vertices set) to render whole map. I change only texture coordinates and y value in vertex position for each tile of map. Buffers for position and texture coords are created with GL_DYNAMIC_DRAW parameter. The buffer for indices is created with GL_STATIC_DRAW because it doesn't change during map rendering. So, for each tile of map buffers are mapped and unmapped at least one time. Should I use only one buffer for texture coords and positions?
Thanks,
Try moving your vertex/texture coordinates with GL_MODELVIEW/GL_TEXTURE matrices, and leave buffer data alone (GL_STATIC_DRAW alone). e.g. if tile is of size 1x1, create rect (0, 0)-(1, 1) and set it's position in the world with glTranslate. Same with texture coordinates.
VBOs are not there to increase performance of drawing few quads. Their true power is seen when drawing meshes with thousands of polygons using shaders. If you don't need any forward compatibility with newer opengl versions, I see little use in using them to draw dynamically changing data.
If you need to update the buffer(s) each frame you should use GL_STREAM_DRAW (which hints that the buffer contents will likely be used only once) rather than GL_DYNAMIC_DRAW (which hints that they will be but used a couple of times before being updated).
As far as my experience goes, buffers created with GL_STREAM_DRAW will be treated similarly to plain ol' arrays, so you should expect about the same performance as for arrays when using it.
Also make sure that you call glMapBuffer with the access parameter set to GL_WRITE_ONLY, assuming you don't need to read the contents of the buffer. Otherwise, if the buffer is in video memory, it will have to be transferred from video memory to main memory and then back again (well, that's up to the driver really...) for each map call. Transferring to much data over the bus is a very real bottleneck that's quite easy to bump into.