Jump to content

  • Log In with Google      Sign In   
  • Create Account

use of DynamicVertexBuffer's for hardware instancing


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 bombshell93   Members   -  Reputation: 205

Like
0Likes
Like

Posted 22 March 2013 - 07:15 PM

one of my friends is on a Game Dev course in collage and his final exam is to make a game, hes allowed help on art assets and specific parts of an engine (in this case the graphics) so long as he designs and programs the player interaction and gameplay, So I'm writing him a Renderer (in XNA as its what he'd prefer to use)

The game will essentially be a vertical scrolling bullet-hell shooter, that said efficient drawing of multiple similar units is a must, so I've turned to hardware instancing but I'm a bit hesitant to continue to approach it the way I that I have.

I've set up a basic entity / component system to build around. The DrawComponents on creation register themselves with the DrawManager, which then sorts them via the model and texture they reference. When drawing time comes around it checks if there are the same number of instances as the last frame or if there is an instance buffer at all.

if there is not the same number of instances or there isnt a buffer then a new DynamicVertexBuffer is made and filled up (if there was a buffer it is disposed before doing this), if there was a suitable buffer then its data is simple regathered and set (for instances which may have moved or rotated or whatever).

It feels a bit dirty creating a new buffer whenever I need it resized but there doesn't seem to be a way to resize it. I'm not getting any performance issues I'm just wondering if there might be a preferred way to approach hardware instancing for objects which may or may not exist consistently?

Thanks in Advanced,
Bombshell



Sponsor:

#2 phil_t   Crossbones+   -  Reputation: 3921

Like
2Likes
Like

Posted 22 March 2013 - 07:29 PM

It can be larger than you need. Just make it initially large enough to handle the max number of instances you think you'll need (and either keep the "resize" logic for when you go over, or just fail to draw any additional instances).



#3 bombshell93   Members   -  Reputation: 205

Like
0Likes
Like

Posted 24 March 2013 - 05:05 PM

okay I've given it a go and expanded the rendering engine in general, but I have a problem, for sake of testing I'm drawing 27 instances of a single model (which is fairly low poly), and my framerate is through the floor at 16 FPS.
the problem seems to be updating the vertex buffer (per second taking up over half of the second)
Here is the part taking up the most time, though its worth noting both rendering the shadow map and rendering the scene itself is taking up 12% of the second each too.


				Model model = assetManager.getModel(m);
				if (!buffers.ContainsKey(m) || models[m].Count > modelCount[m])
				{
					if (!buffers.ContainsKey(m))
					{
						buffers.Add(m, null);
						modelCount.Add(m, 0);
					}
					else
						buffers[m].Dispose();

					modelCount[m] = models[m].Count;
					if (modelCount[m] < 10)
						modelCount[m] = 10;
					buffers[m] = new DynamicVertexBuffer(graphicsDevice, vertexDeclaration, 
						modelCount[m], BufferUsage.None);
					instances.Add(m, new Instance[modelCount[m]]);
					int i;
					for (i = 0; i < models[m].Count; i++)
					{
						instances[m][i] = new Instance(models[m][i].transform, 
							camera, models[m][i].textureCoord);
						models[m][i].index = i;
					}
					for (; i < modelCount[m]; i++)
					{
						instances[m][i] = new Instance(Matrix.CreateScale(0), 
							camera, Vector2.Zero);
					}
					buffers[m].SetData(instances[m]);
				}
				else
				{
					int i = 0;
					for (i = 0; i < models[m].Count; i++)
					{
						instances[m][i].transform = 
							Matrix.Transpose(models[m][i].transform);
						instances[m][i].worldViewIT = 
							Matrix.Transpose(Matrix.Invert(instances[m][i].transform * camera.View));
						models[m][i].index = i;
					}
					//for (; i < modelCount[m]; i++)
					//{
					//	instances[i] = new Instance(Matrix.CreateScale(0), camera, Vector2.Zero);
					//}

					buffers[m].SetData(instances[m]);
				}
			}

 


I'm obviously doing something wrong but I'm not all that familiar with how to efficiently use instancing,
if anyone can spare some advice or references on the matter it would be a great help.

My mistake, my stopwatch was placed awkwardly giving me false times, I was also sending a bad value to the draw call telling it to draw thousands of instances.


Edited by bombshell93, 24 March 2013 - 07:58 PM.


#4 phil_t   Crossbones+   -  Reputation: 3921

Like
1Likes
Like

Posted 24 March 2013 - 10:53 PM

I can't tell from your code, but make sure you aren't creating new vertex buffers each frame. Just create one (or however many you need) at startup. Then SetData the necessary (changing) data each frame.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS