Advertisement

Dynamic Vertex buffer

Started by June 12, 2018 09:20 PM
4 comments, last by ChuckNovice 6 years, 7 months ago

Hello everyone,

After a few years of break from coding and my planet render game I'm giving it a go again from a different angle. What I'm struggling with now is that I have created a Frustum that works fine for now atleast, it does what it's supose to do alltho not perfect. But with the frustum came very low FPS, since what I'm doing right now just to see if the Frustum worked is to recreate the vertex buffer every frame that the camera detected movement. This is of course very costly and not the way to do it. Thats why I'm now trying to learn how to create a dynamic vertexbuffer instead and to map and unmap the vertexes, in the end my goal is to update only part of the vertexbuffer that is needed, but one step at a time ^^

So below is my code which I use to create the Dynamic buffer. The issue is that I want the size of the vertex buffer to be big enough to handle bigger vertex buffers then just mPlanetMesh.vertices.size() due to more vertices being added later when I start to do LOD and stuff, the first render isn't the biggest one I will need.


		vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
		vertexBufferDesc.ByteWidth = mPlanetMesh.vertices.size();
		vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
		vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
		vertexBufferDesc.MiscFlags = 0;
		vertexBufferDesc.StructureByteStride = 0;

		vertexData.pSysMem = &mPlanetMesh.vertices[0];
		vertexData.SysMemPitch = 0;
		vertexData.SysMemSlicePitch = 0;

		result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &mVertexBuffer);
		if (FAILED(result))
		{
			return false;
		}

What happens is that the 


result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &mVertexBuffer);

Makes it crash due to Access Violation. When I put the vertices.size() in it works without issues, but when I try to set it to like vertices.size() * 2 it crashes.

I googled my eyes dry tonight but doesn't seem to find people with the same kind of issue, I've read that the vertex buffer can be bigger if needed. What I'm I doing wrong here?

 

Best Regards and Thanks in advance

Toastmastern

Is mPlanetMesh.vertices a std::vector? If so, one thing that you need to be careful about is that "ByteWidth" expects the vertex buffer size in bytes. size() returns the number of elements in the vector, not the size in bytes. For the size in bytes, you want something like "vertices.size() * sizeof(T)", where "T" is the type that the vector is templated on.

The other thing to watch out for is the data that you're using to initialize the buffer, which is passed via vertexData.pSysMem. The pointer that you pass here has to point to a block of data that's at least as large as ByteWidth. So if you create the buffer for 1024 vertices but pass a pointer to an array of 512 vertices, then CreateBuffer will access memory past the bounds of that array and potentially cause an access violation. Keep in mind that initializing a buffer with data is optional: you can skip that if you want, and partially update the buffer later on by calling Map() to update its contents. If you want to skip initializing the buffer data, just pass nullptr as the second parameter to CreateBuffer.

Advertisement

Turned out the second part of what you said is what I did wrong :) I now dont set any data in the buffer when I initialize the buffers. Before rendering I then map and unmap the vertex and index buffer to update it.

I did it cause I thought the bottleneck of my game was that it reinitalized the buffers before instead of having them dynamic. Turns out that wasn’t the issue, the FPS is still really low for 15k vertices.

Im thinking it has to do with the way I subdivison my sphere every time the camera is moved. Anyone have any idea on what way to move forward? Maybe I should implement a way to check if all of the vertex really need to be updated. No idea how to do that yet tho

also going to use profiler tonight to try and see were my bottleneck actually lies

 

//Toastmastern

Why do you need to update vertices in the first place? Have you tried looking for a way to keep the buffers the same, and do all necessary calculations/updates on GPU side?

I will second what @d07RiV said.

 

Many terrain techniques exist where the mesh structure is initialized only once and never changes. That mesh follows the camera, it is usually initialized with a height of 0 and a shader is in charge of altering the height of each vertex on the fly by sampling a height map texture.

 

I would recommend moving to similar technique that rely a little more on the GPU. Doing all the terrain work on the CPU has never really worked well for me either in the past.

 

Here's a visual example of the mesh structure that I am talking about (although the edge are wrong between the levels of detail it still give the basic idea) 

 

clipmaps1.png

 

This one is a 10 years old screenshot from my old planet renderer which had way too many triangles (I was doing a performance test) but also give a good idea of what it would look like as a sphere. The center of the mesh still follow the camera and is never updated on the CPU side.

 

25DEaHS.jpg

 

 

This topic is closed to new replies.

Advertisement