How can I resize dynamic vertex buffer in Directx 12 - c++

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.

Related

glDrawArrays does not render entire point cloud

I'm trying to render huge point clouds (~150M) but OpenGL only renders part (~52M) of it. When rendering smaller datasets (<40M) everything works fine. I'm using single VBO. When using multiple VBOs, points get rendered but rendering is awfully slow, which is expected. My element has a size of 44bytes and GPU has 3GB of memory available. This should be enough for nearly ~70M points but I can render as much as 100M points with multiple VBOs. Is there any OpenGL specific limitation per VBO I'm not aware of?.
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, cloud.size() * sizeof(Point), cloud.data(), GL_STATIC_DRAW);
// lot of other code
glDrawArrays(GL_POINTS, 0, cloud.size());
It looks like some part of your system uses 32-bit unsigned integers to store the size of the buffers, thus passing 148M*44bytes overflows and gets converted to about 54.9M or 50.4M depending on whether your megabytes are binary or decimal. I'd start with checking your OpenGL binding library to see that the prototypes it declares correctly use 64-bit types. If it does then the bug must be in the OpenGL drivers.
To transfer more than 4GB data to the buffer you may try using one of the other available functions: glBufferSubData and glBufferStorage, or memory-map the buffer with glMapBufferRange, which might workaround the limitation of 4GB.
Another thing to consider is to use one VAO but split the data between multiple buffers. Presumably your Point consists of different attributes, like position, color, etc... You can put each of them in a separate buffer and still use one VAO and one draw call. You can also optimize the types of the attributes you use (e.g. don't use floats where shorts or bytes would do) and the layout of the structure (check that there's no unnecessary padding between the fields).
I don't think memory is a problem in fact i'd say your program makes too many drawing calls . You should try with glDrawArraysInstanced() . For that you need to provide new position for every instance in the vertex shader... maybe that will solve your problem :D.
I'm sorry if i cannot provide you with details ,my skills in OpenGL got a bit dull , but i am planning on recovering asap :D .i hope it helps .

Cost of large buffer switch vs. small buffer switch

I'm creating a tile-based renderer where each tile has a vertex model. However, from each vertex model only a small portion is rendered in one frame. These subsets change every frame.
What would be the fastest way to render this? I can think of the following options:
Make one draw call for every model. Every model is stored in full on the gpu. For every draw call, the full vbo is switched every time. Indices are then used to pick the appropriate small portion for the actual rendering.
Make one draw call with one vbo which gets assembled every frame by copying the necessary (small) subset of all the other vbos (the data is copied within vram).
Make one draw call with one vbo, but the vbo is recreated every frame with the (small) subset from CPU data using glBufferData.
Which do you think is fastest, or can you think of something faster?
One deciding factor is obviously if switching between larger VBOs is more expensive than switching between smaller VBOs.
It is a bad idea to make a lot of drawcalls. In OpenGL,you will be CPU bound by this method, so it is better to batch a lot of models.
Actually, I would go for this method. All static geometry is inside one and only one VBO and one VAO. It does not mean that you only have "one draw call". However, you should use glMultiDraw*Indirect.
The idea burried that is you have to use compute shaders to perform culling on GPU, and use something like GL_INDIRECT_PARAMETERS extensions with your multi indirect draw call.
Indirect Drawing
For all dynamic geometry, you can use a persistent buffer.
To answer your question about changing vao/vbo. Change VAO, or use glBindVertexBuffer should not make a big overhead.
But you should profile it, it can depends on your driver / hardware :)

Do VBOs boost performance even when all data changes frequently

I'm doing a 2D turn based RTS game with 32x32 tiles (400-500 tiles per frame). I could use a VBO for this, but I may have to change almost all the VBO data each frame, as the background is a scrolling one and the visible tiles will change every time the map scrolls. Will using VBOs rather than client side vertex arrays still yield a performance benefit here? Also if using VBOs which data format is most efficient (float, or int16, or ...)?
If you are simply scrolling, you can use the vertex shader to manipulate the position rather than update the vertices themselves. Pass in a 'scroll' value as a uniform to your background and simply add that value to the x (or y, or whatever applies to your case) value of each vertex.
Update:
If you intend to modify the VBO often, you can tell the driver this using the usage param of glBufferData. This page has a good description of how that works: http://www.opengl.org/wiki/Vertex_Buffer_Object, under Accessing VBOs. In your case, it looks like you should specify GL_DYNAMIC_DRAW to glBufferData so that the driver puts your VBO in the best place in memory for your application.
The regular approach is to move the camera and perform culling instead of updating the content of the VBOs. For a 2d game culling will use simple rectangle intersection algorithm, which you will need anyway for unit selection in the game. As a bonus, manipulating the camera will allow to rate the camera and zoom in and zoom out. Also you could combine several tiles (4, 9 or 16) into one VBO.
I would strongly advise against writing logic to move the tiles instead of the camera. It will take you longer, have more bugs, and be less flexible.
The format will depend on what data you are storing in the VBOs. When in doubt, just use uint8 for color and float32 for everything else. Though for a 2d game your VBOs or vertex array are going to be very small compared to 3d applications, so it's highly unlikely VBO will make any difference.

Better to create new VBOs or just swap the data? (OpenGL)

So in a OpenGL rendering application, is it usually better to create and maintain a vertex buffer throughout the life of an application and just swap out the data every frame with glBufferData, or is it better to just delete the VBO and recreate it every frame?
Intuition tells me it's better to swap out data, but a few sample programs I've seen does the latter, so I'm kind of confused.
I read Nvidia's whitepaper on VBOs, but as I'm a newbie to opengl, it didn't make a whole lot of sense.
Thanks in advance for and advice
Since you're generating a whole new set of data each frame the documentation seems to indicate that GL_STREAM_DRAW is the Right Way to go about things.
The significant thing about VBOs is that they are render data buffers that are stored in graphics memory and not in the computer's main memory. That makes their usage very efficient when the data in them isn't being updated (too) frequently, because every time you do that, the computer will have to transfer (potentially huge amounts of) data from main to graphics memory - which is slow.
So the ideal case is to put all required render data into VBOs once and then only manipulate them via OpenGL functions like matrix transformation or via shaders.
So you would e.g. put each mesh's world space coordinates and texture coordinates into VBOs and never directly touch them again; you'd use the modelview matrix, lighting functions and shaders to render them.
You can do more to optimize VBO usage, but that's the basics as I have understood them.
Find some good hints and more details here: How do I use OpenGL 3.x VBOs to render a dynamic world?

OpenGL: Buffer object performance issue

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.