crappy "fix" for vertex buffer sizing problem - manually track the "real" count of vertices

Need to properly fix this in VertexBuffer itself, problems with how
the extending / remaining space calculations work (or at least, our
current usage of them)
This commit is contained in:
Gered 2013-08-25 22:28:08 -04:00
parent c8be3f5c8f
commit 7fcf8d88a0
3 changed files with 58 additions and 11 deletions

View file

@ -20,7 +20,7 @@ namespace Blarg.GameFramework.TileMap
_defaultBlendState.Apply(Framework.GraphicsDevice); _defaultBlendState.Apply(Framework.GraphicsDevice);
Framework.GraphicsDevice.BindTexture(texture); Framework.GraphicsDevice.BindTexture(texture);
Framework.GraphicsDevice.BindVertexBuffer(chunk.Mesh); Framework.GraphicsDevice.BindVertexBuffer(chunk.Mesh);
Framework.GraphicsDevice.RenderTriangles(); Framework.GraphicsDevice.RenderTriangles(0, chunk.NumMeshVertices / 3);
Framework.GraphicsDevice.UnbindVertexBuffer(); Framework.GraphicsDevice.UnbindVertexBuffer();
} }
@ -35,7 +35,7 @@ namespace Blarg.GameFramework.TileMap
_alphaBlendState.Apply(Framework.GraphicsDevice); _alphaBlendState.Apply(Framework.GraphicsDevice);
Framework.GraphicsDevice.BindTexture(texture); Framework.GraphicsDevice.BindTexture(texture);
Framework.GraphicsDevice.BindVertexBuffer(chunk.AlphaMesh); Framework.GraphicsDevice.BindVertexBuffer(chunk.AlphaMesh);
Framework.GraphicsDevice.RenderTriangles(); Framework.GraphicsDevice.RenderTriangles(0, chunk.NumAlphaMeshVertices / 3);
Framework.GraphicsDevice.UnbindVertexBuffer(); Framework.GraphicsDevice.UnbindVertexBuffer();
} }

View file

@ -14,7 +14,7 @@ namespace Blarg.GameFramework.TileMap
{ {
var buffer = new VertexBuffer(Framework.GraphicsDevice, var buffer = new VertexBuffer(Framework.GraphicsDevice,
VertexAttributeDeclarations.TextureColorNormalPosition3D, VertexAttributeDeclarations.TextureColorNormalPosition3D,
128, 1,
BufferObjectUsage.Static); BufferObjectUsage.Static);
return buffer; return buffer;
} }
@ -24,6 +24,9 @@ namespace Blarg.GameFramework.TileMap
VertexBuffer mesh = null; VertexBuffer mesh = null;
VertexBuffer alphaMesh = null; VertexBuffer alphaMesh = null;
int numMeshVertices = 0;
int numAlphaVertices = 0;
for (int y = 0; y < chunk.Height; ++y) for (int y = 0; y < chunk.Height; ++y)
{ {
for (int z = 0; z < chunk.Depth; ++z) for (int z = 0; z < chunk.Depth; ++z)
@ -67,18 +70,24 @@ namespace Blarg.GameFramework.TileMap
else else
color = tileMesh.Color; color = tileMesh.Color;
int numVertices = 0;
if (tileMesh is CubeTileMesh) if (tileMesh is CubeTileMesh)
HandleCubeMesh(buffer, x, y, z, tile, chunk, (CubeTileMesh)tileMesh, ref position, transform, ref color); numVertices = HandleCubeMesh(buffer, x, y, z, tile, chunk, (CubeTileMesh)tileMesh, ref position, transform, ref color);
else else
HandleGenericMesh(buffer, x, y, z, tile, chunk, tileMesh, ref position, transform, ref color); numVertices = HandleGenericMesh(buffer, x, y, z, tile, chunk, tileMesh, ref position, transform, ref color);
if (tileMesh.Alpha)
numAlphaVertices += numVertices;
else
numMeshVertices += numVertices;
} }
} }
} }
chunk.SetMeshes(mesh, alphaMesh); chunk.SetMeshes(mesh, numMeshVertices, alphaMesh, numAlphaVertices);
} }
private void HandleCubeMesh(VertexBuffer buffer, private int HandleCubeMesh(VertexBuffer buffer,
int x, int x,
int y, int y,
int z, int z,
@ -97,6 +106,8 @@ namespace Blarg.GameFramework.TileMap
Tile down = chunk.GetWithinSelfOrNeighbourSafe(x, y - 1, z); Tile down = chunk.GetWithinSelfOrNeighbourSafe(x, y - 1, z);
Tile up = chunk.GetWithinSelfOrNeighbourSafe(x, y + 1, z); Tile up = chunk.GetWithinSelfOrNeighbourSafe(x, y + 1, z);
int numVertices = 0;
// evaluate each face's visibility and add it's vertices if needed one at a time // evaluate each face's visibility and add it's vertices if needed one at a time
if ((left == null || left.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(left).IsOpaque(TileMesh.SIDE_RIGHT)) && mesh.HasFace(TileMesh.SIDE_LEFT)) { if ((left == null || left.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(left).IsOpaque(TileMesh.SIDE_RIGHT)) && mesh.HasFace(TileMesh.SIDE_LEFT)) {
// left face is visible // left face is visible
@ -109,6 +120,7 @@ namespace Blarg.GameFramework.TileMap
ref color, ref color,
mesh.LeftFaceVertexOffset, mesh.LeftFaceVertexOffset,
TileMesh.CUBE_VERTICES_PER_FACE); TileMesh.CUBE_VERTICES_PER_FACE);
numVertices += TileMesh.CUBE_VERTICES_PER_FACE;
} }
if ((right == null || right.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(right).IsOpaque(TileMesh.SIDE_LEFT)) && mesh.HasFace(TileMesh.SIDE_RIGHT)) { if ((right == null || right.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(right).IsOpaque(TileMesh.SIDE_LEFT)) && mesh.HasFace(TileMesh.SIDE_RIGHT)) {
// right face is visible // right face is visible
@ -121,6 +133,7 @@ namespace Blarg.GameFramework.TileMap
ref color, ref color,
mesh.RightFaceVertexOffset, mesh.RightFaceVertexOffset,
TileMesh.CUBE_VERTICES_PER_FACE); TileMesh.CUBE_VERTICES_PER_FACE);
numVertices += TileMesh.CUBE_VERTICES_PER_FACE;
} }
if ((forward == null || forward.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(forward).IsOpaque(TileMesh.SIDE_BACK)) && mesh.HasFace(TileMesh.SIDE_FRONT)) { if ((forward == null || forward.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(forward).IsOpaque(TileMesh.SIDE_BACK)) && mesh.HasFace(TileMesh.SIDE_FRONT)) {
// front face is visible // front face is visible
@ -133,6 +146,7 @@ namespace Blarg.GameFramework.TileMap
ref color, ref color,
mesh.FrontFaceVertexOffset, mesh.FrontFaceVertexOffset,
TileMesh.CUBE_VERTICES_PER_FACE); TileMesh.CUBE_VERTICES_PER_FACE);
numVertices += TileMesh.CUBE_VERTICES_PER_FACE;
} }
if ((backward == null || backward.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(backward).IsOpaque(TileMesh.SIDE_FRONT)) && mesh.HasFace(TileMesh.SIDE_BACK)) { if ((backward == null || backward.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(backward).IsOpaque(TileMesh.SIDE_FRONT)) && mesh.HasFace(TileMesh.SIDE_BACK)) {
// back face is visible // back face is visible
@ -145,6 +159,7 @@ namespace Blarg.GameFramework.TileMap
ref color, ref color,
mesh.BackFaceVertexOffset, mesh.BackFaceVertexOffset,
TileMesh.CUBE_VERTICES_PER_FACE); TileMesh.CUBE_VERTICES_PER_FACE);
numVertices += TileMesh.CUBE_VERTICES_PER_FACE;
} }
if ((down == null || down.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(down).IsOpaque(TileMesh.SIDE_TOP)) && mesh.HasFace(TileMesh.SIDE_BOTTOM)) { if ((down == null || down.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(down).IsOpaque(TileMesh.SIDE_TOP)) && mesh.HasFace(TileMesh.SIDE_BOTTOM)) {
// bottom face is visible // bottom face is visible
@ -157,6 +172,7 @@ namespace Blarg.GameFramework.TileMap
ref color, ref color,
mesh.BottomFaceVertexOffset, mesh.BottomFaceVertexOffset,
TileMesh.CUBE_VERTICES_PER_FACE); TileMesh.CUBE_VERTICES_PER_FACE);
numVertices += TileMesh.CUBE_VERTICES_PER_FACE;
} }
if ((up == null || up.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(up).IsOpaque(TileMesh.SIDE_BOTTOM)) && mesh.HasFace(TileMesh.SIDE_TOP)) { if ((up == null || up.TileIndex == Tile.NO_TILE || !chunk.TileMap.TileMeshes.Get(up).IsOpaque(TileMesh.SIDE_BOTTOM)) && mesh.HasFace(TileMesh.SIDE_TOP)) {
// top face is visible // top face is visible
@ -169,10 +185,13 @@ namespace Blarg.GameFramework.TileMap
ref color, ref color,
mesh.TopFaceVertexOffset, mesh.TopFaceVertexOffset,
TileMesh.CUBE_VERTICES_PER_FACE); TileMesh.CUBE_VERTICES_PER_FACE);
} numVertices += TileMesh.CUBE_VERTICES_PER_FACE;
} }
private void HandleGenericMesh(VertexBuffer buffer, return numVertices;
}
private int HandleGenericMesh(VertexBuffer buffer,
int x, int x,
int y, int y,
int z, int z,
@ -214,6 +233,8 @@ namespace Blarg.GameFramework.TileMap
ref color, ref color,
0, 0,
mesh.Vertices.NumElements); mesh.Vertices.NumElements);
return mesh.Vertices.NumElements;
} }
protected void AddMesh(VertexBuffer buffer, protected void AddMesh(VertexBuffer buffer,
@ -226,6 +247,15 @@ namespace Blarg.GameFramework.TileMap
int firstVertex, int firstVertex,
int numVertices) int numVertices)
{ {
// ensure there is enough space in the destination buffer
int verticesToAdd = numVertices;
if (buffer.RemainingElements < verticesToAdd)
{
// not enough space, need to resize the destination buffer
// resize by the exact amount needed making sure there's no wasted space at the end
buffer.Extend(verticesToAdd - buffer.RemainingElements);
}
// adjust position by the tilemesh offset. TileMesh's are modeled using the // adjust position by the tilemesh offset. TileMesh's are modeled using the
// origin (0,0,0) as the center and are 1 unit wide/deep/tall. So, their // origin (0,0,0) as the center and are 1 unit wide/deep/tall. So, their
// max extents are from -0.5,-0.5,-0.5 to 0.5,0.5,0.5. For rendering // max extents are from -0.5,-0.5,-0.5 to 0.5,0.5,0.5. For rendering
@ -236,6 +266,9 @@ namespace Blarg.GameFramework.TileMap
offset.Y += (float)position.Y; offset.Y += (float)position.Y;
offset.Z += (float)position.Z; offset.Z += (float)position.Z;
bool needsTransform = (transform != null);
var transformMatrix = transform.GetValueOrDefault();
var sourceVertices = sourceMesh.Vertices; var sourceVertices = sourceMesh.Vertices;
sourceVertices.MoveTo(firstVertex); sourceVertices.MoveTo(firstVertex);
@ -244,9 +277,8 @@ namespace Blarg.GameFramework.TileMap
Vector3 v = sourceVertices.GetCurrentPosition3D(); Vector3 v = sourceVertices.GetCurrentPosition3D();
Vector3 n = sourceVertices.GetCurrentNormal(); Vector3 n = sourceVertices.GetCurrentNormal();
if (transform != null) if (needsTransform)
{ {
var transformMatrix = transform.Value;
// need to transform the vertex + normal first before copying it // need to transform the vertex + normal first before copying it
v = Matrix4x4.Transform(transformMatrix, v); v = Matrix4x4.Transform(transformMatrix, v);
n = Matrix4x4.TransformNormal(transformMatrix, n); n = Matrix4x4.TransformNormal(transformMatrix, n);

View file

@ -14,7 +14,9 @@ namespace Blarg.GameFramework.TileMap
readonly int _depth; readonly int _depth;
readonly Vector3 _position; readonly Vector3 _position;
readonly BoundingBox _bounds; readonly BoundingBox _bounds;
int _numMeshVertices;
VertexBuffer _mesh; VertexBuffer _mesh;
int _numAlphaMeshVertices;
VertexBuffer _alphaMesh; VertexBuffer _alphaMesh;
public readonly TileMap TileMap; public readonly TileMap TileMap;
@ -79,11 +81,21 @@ namespace Blarg.GameFramework.TileMap
get { return _bounds; } get { return _bounds; }
} }
public int NumMeshVertices
{
get { return _numMeshVertices; }
}
public VertexBuffer Mesh public VertexBuffer Mesh
{ {
get { return _mesh; } get { return _mesh; }
} }
public int NumAlphaMeshVertices
{
get { return _numAlphaMeshVertices; }
}
public VertexBuffer AlphaMesh public VertexBuffer AlphaMesh
{ {
get { return _alphaMesh; } get { return _alphaMesh; }
@ -120,7 +132,7 @@ namespace Blarg.GameFramework.TileMap
generator.Generate(this); generator.Generate(this);
} }
internal void SetMeshes(VertexBuffer mesh, VertexBuffer alphaMesh) internal void SetMeshes(VertexBuffer mesh, int numMeshVertices, VertexBuffer alphaMesh, int numAlphaMeshVertices)
{ {
if (_mesh != null) if (_mesh != null)
_mesh.Dispose(); _mesh.Dispose();
@ -129,6 +141,9 @@ namespace Blarg.GameFramework.TileMap
if (_alphaMesh != null) if (_alphaMesh != null)
_alphaMesh.Dispose(); _alphaMesh.Dispose();
_alphaMesh = alphaMesh; _alphaMesh = alphaMesh;
_numMeshVertices = numMeshVertices;
_numAlphaMeshVertices = numAlphaMeshVertices;
} }
public Tile GetWithinSelfOrNeighbour(int x, int y, int z) public Tile GetWithinSelfOrNeighbour(int x, int y, int z)