mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-16 22:30:42 +02:00
more correct use of BufferView in GeometryCache
This commit is contained in:
parent
160be95081
commit
026195223a
2 changed files with 47 additions and 36 deletions
|
@ -84,67 +84,83 @@ std::vector<vec3> polygon() {
|
|||
}
|
||||
|
||||
void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const geometry::VertexVector& vertices) {
|
||||
gpu::Buffer::Size offset = vertexBuffer->getSize();
|
||||
vertexBuffer->append(vertices);
|
||||
|
||||
_positionView = gpu::BufferView(vertexBuffer, 0,
|
||||
vertexBuffer->getSize(), SHAPE_VERTEX_STRIDE, POSITION_ELEMENT);
|
||||
_normalView = gpu::BufferView(vertexBuffer, SHAPE_NORMALS_OFFSET,
|
||||
vertexBuffer->getSize(), SHAPE_VERTEX_STRIDE, NORMAL_ELEMENT);
|
||||
gpu::Buffer::Size viewSize = vertices.size() * 2 * sizeof(glm::vec3);
|
||||
|
||||
_positionView = gpu::BufferView(vertexBuffer, offset,
|
||||
viewSize, SHAPE_VERTEX_STRIDE, POSITION_ELEMENT);
|
||||
_normalView = gpu::BufferView(vertexBuffer, offset + SHAPE_NORMALS_OFFSET,
|
||||
viewSize, SHAPE_VERTEX_STRIDE, NORMAL_ELEMENT);
|
||||
}
|
||||
|
||||
void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices) {
|
||||
_indices = indexBuffer;
|
||||
gpu::Buffer::Size offset = indexBuffer->getSize();
|
||||
if (!indices.empty()) {
|
||||
_indexOffset = indexBuffer->getSize() / SHAPE_INDEX_SIZE;
|
||||
_indexCount = indices.size();
|
||||
indexBuffer->append(indices);
|
||||
for (uint32_t i = 0; i < indices.size(); ++i) {
|
||||
indexBuffer->append((uint16_t)indices[i]);
|
||||
}
|
||||
}
|
||||
gpu::Size viewSize = indices.size() * sizeof(uint16_t);
|
||||
_indicesView = gpu::BufferView(indexBuffer, offset, viewSize, gpu::Element::INDEX_UINT16);
|
||||
|
||||
offset = indexBuffer->getSize();
|
||||
if (!wireIndices.empty()) {
|
||||
_wireIndexOffset = indexBuffer->getSize() / SHAPE_INDEX_SIZE;
|
||||
_wireIndexCount = wireIndices.size();
|
||||
indexBuffer->append(wireIndices);
|
||||
for (uint32_t i = 0; i < wireIndices.size(); ++i) {
|
||||
indexBuffer->append((uint16_t)wireIndices[i]);
|
||||
}
|
||||
}
|
||||
viewSize = wireIndices.size() * sizeof(uint16_t);
|
||||
_wireIndicesView = gpu::BufferView(indexBuffer, offset, viewSize, gpu::Element::INDEX_UINT16);
|
||||
}
|
||||
|
||||
void GeometryCache::ShapeData::setupBatch(gpu::Batch& batch) const {
|
||||
batch.setInputBuffer(gpu::Stream::POSITION, _positionView);
|
||||
batch.setInputBuffer(gpu::Stream::NORMAL, _normalView);
|
||||
batch.setIndexBuffer(SHAPE_INDEX_TYPE, _indices, 0);
|
||||
batch.setIndexBuffer(_indicesView);
|
||||
}
|
||||
|
||||
void GeometryCache::ShapeData::draw(gpu::Batch& batch) const {
|
||||
if (_indexCount) {
|
||||
gpu::Buffer::Size numIndices = _indicesView.getNumElements();
|
||||
if (numIndices > 0) {
|
||||
setupBatch(batch);
|
||||
batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)_indexCount, (gpu::uint32)_indexOffset);
|
||||
batch.drawIndexed(gpu::TRIANGLES, numIndices, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryCache::ShapeData::drawWire(gpu::Batch& batch) const {
|
||||
if (_wireIndexCount) {
|
||||
setupBatch(batch);
|
||||
batch.drawIndexed(gpu::LINES, (gpu::uint32)_wireIndexCount, (gpu::uint32)_wireIndexOffset);
|
||||
gpu::Buffer::Size numIndices = _wireIndicesView.getNumElements();
|
||||
if (numIndices > 0) {
|
||||
batch.setInputBuffer(gpu::Stream::POSITION, _positionView);
|
||||
batch.setInputBuffer(gpu::Stream::NORMAL, _normalView);
|
||||
batch.setIndexBuffer(_wireIndicesView);
|
||||
batch.drawIndexed(gpu::LINES, numIndices, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryCache::ShapeData::drawInstances(gpu::Batch& batch, size_t count) const {
|
||||
if (_indexCount) {
|
||||
gpu::Buffer::Size numIndices = _indicesView.getNumElements();
|
||||
if (numIndices > 0) {
|
||||
setupBatch(batch);
|
||||
batch.drawIndexedInstanced((gpu::uint32)count, gpu::TRIANGLES, (gpu::uint32)_indexCount, (gpu::uint32)_indexOffset);
|
||||
batch.drawIndexedInstanced((gpu::uint32)count, gpu::TRIANGLES, numIndices, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryCache::ShapeData::drawWireInstances(gpu::Batch& batch, size_t count) const {
|
||||
if (_wireIndexCount) {
|
||||
setupBatch(batch);
|
||||
batch.drawIndexedInstanced((gpu::uint32)count, gpu::LINES, (gpu::uint32)_wireIndexCount, (gpu::uint32)_wireIndexOffset);
|
||||
gpu::Buffer::Size numIndices = _wireIndicesView.getNumElements();
|
||||
if (numIndices > 0) {
|
||||
batch.setInputBuffer(gpu::Stream::POSITION, _positionView);
|
||||
batch.setInputBuffer(gpu::Stream::NORMAL, _normalView);
|
||||
batch.setIndexBuffer(_wireIndicesView);
|
||||
batch.drawIndexedInstanced((gpu::uint32)count, gpu::LINES, numIndices, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static const size_t ICOSAHEDRON_TO_SPHERE_TESSELATION_COUNT = 3;
|
||||
|
||||
size_t GeometryCache::getShapeTriangleCount(Shape shape) {
|
||||
return _shapes[shape]._indexCount / VERTICES_PER_TRIANGLE;
|
||||
return _shapes[shape]._indicesView.getNumElements() / VERTICES_PER_TRIANGLE;
|
||||
}
|
||||
|
||||
size_t GeometryCache::getSphereTriangleCount() {
|
||||
|
@ -168,7 +184,6 @@ static IndexPair indexToken(geometry::Index a, geometry::Index b) {
|
|||
template <size_t N>
|
||||
void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid<N>& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) {
|
||||
using namespace geometry;
|
||||
Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE);
|
||||
VertexVector vertices;
|
||||
IndexVector solidIndices, wireIndices;
|
||||
IndexPairs wireSeenIndices;
|
||||
|
@ -179,6 +194,7 @@ void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid<N
|
|||
vertices.reserve(N * faceCount * 2);
|
||||
solidIndices.reserve(faceIndexCount * faceCount);
|
||||
|
||||
Index baseVertex = 0;
|
||||
for (size_t f = 0; f < faceCount; f++) {
|
||||
const Face<N>& face = shape.faces[f];
|
||||
// Compute the face normal
|
||||
|
@ -219,7 +235,6 @@ void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid<N
|
|||
template <size_t N>
|
||||
void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid<N>& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) {
|
||||
using namespace geometry;
|
||||
Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE);
|
||||
|
||||
VertexVector vertices;
|
||||
vertices.reserve(shape.vertices.size() * 2);
|
||||
|
@ -236,6 +251,7 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid
|
|||
|
||||
solidIndices.reserve(faceIndexCount * faceCount);
|
||||
|
||||
Index baseVertex = 0;
|
||||
for (size_t f = 0; f < faceCount; f++) {
|
||||
const Face<N>& face = shape.faces[f];
|
||||
// Create the wire indices for unseen edges
|
||||
|
@ -265,7 +281,6 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid
|
|||
template <uint32_t N>
|
||||
void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer, bool isConical = false) {
|
||||
using namespace geometry;
|
||||
Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE);
|
||||
VertexVector vertices;
|
||||
IndexVector solidIndices, wireIndices;
|
||||
|
||||
|
@ -286,6 +301,7 @@ void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& ver
|
|||
vertices.push_back(vec3(v.x, -0.5f, v.z));
|
||||
vertices.push_back(vec3(0.0f, -1.0f, 0.0f));
|
||||
}
|
||||
Index baseVertex = 0;
|
||||
for (uint32_t i = 2; i < N; i++) {
|
||||
solidIndices.push_back(baseVertex + 0);
|
||||
solidIndices.push_back(baseVertex + i);
|
||||
|
@ -343,7 +359,6 @@ void drawCircle(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexB
|
|||
// Draw a circle with radius 1/4th the size of the bounding box
|
||||
using namespace geometry;
|
||||
|
||||
Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE);
|
||||
VertexVector vertices;
|
||||
IndexVector solidIndices, wireIndices;
|
||||
const int NUM_CIRCLE_VERTICES = 64;
|
||||
|
@ -354,6 +369,7 @@ void drawCircle(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexB
|
|||
vertices.push_back(vec3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
Index baseVertex = 0;
|
||||
for (uint32_t i = 2; i < NUM_CIRCLE_VERTICES; i++) {
|
||||
solidIndices.push_back(baseVertex + 0);
|
||||
solidIndices.push_back(baseVertex + i);
|
||||
|
@ -403,7 +419,6 @@ void GeometryCache::buildShapes() {
|
|||
|
||||
// Line
|
||||
{
|
||||
Index baseVertex = (Index)(_shapeVertices->getSize() / SHAPE_VERTEX_STRIDE);
|
||||
ShapeData& shapeData = _shapes[Line];
|
||||
shapeData.setupVertices(_shapeVertices, VertexVector {
|
||||
vec3(-0.5f, 0.0f, 0.0f), vec3(-0.5f, 0.0f, 0.0f),
|
||||
|
@ -411,8 +426,8 @@ void GeometryCache::buildShapes() {
|
|||
});
|
||||
IndexVector wireIndices;
|
||||
// Only two indices
|
||||
wireIndices.push_back(0 + baseVertex);
|
||||
wireIndices.push_back(1 + baseVertex);
|
||||
wireIndices.push_back(0);
|
||||
wireIndices.push_back(1);
|
||||
shapeData.setupIndices(_shapeIndices, IndexVector(), wireIndices);
|
||||
}
|
||||
|
||||
|
|
|
@ -339,14 +339,10 @@ public:
|
|||
void useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend = false);
|
||||
|
||||
struct ShapeData {
|
||||
size_t _indexOffset{ 0 };
|
||||
size_t _indexCount{ 0 };
|
||||
size_t _wireIndexOffset{ 0 };
|
||||
size_t _wireIndexCount{ 0 };
|
||||
|
||||
gpu::BufferView _positionView;
|
||||
gpu::BufferView _normalView;
|
||||
gpu::BufferPointer _indices;
|
||||
gpu::BufferView _indicesView;
|
||||
gpu::BufferView _wireIndicesView;
|
||||
|
||||
void setupVertices(gpu::BufferPointer& vertexBuffer, const geometry::VertexVector& vertices);
|
||||
void setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices);
|
||||
|
|
Loading…
Reference in a new issue