From 984a48316d742b8bbcfd182c69dc1f4ccdb0813b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 16 Mar 2018 10:56:56 -0700 Subject: [PATCH] CR --- libraries/render-utils/src/GeometryCache.cpp | 145 +++++-------------- libraries/render-utils/src/GeometryCache.h | 11 +- 2 files changed, 45 insertions(+), 111 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index edd68603cb..693e288d5d 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -135,10 +135,10 @@ static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT; static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT; static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT; -static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 3 + sizeof(glm::vec2); // position, normal, texcoords, tangent -static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3); -static const uint SHAPE_TEXCOORD0_OFFSET = sizeof(glm::vec3) * 2; -static const uint SHAPE_TANGENT_OFFSET = sizeof(glm::vec3) * 2 + sizeof(glm::vec2); +static const uint SHAPE_VERTEX_STRIDE = sizeof(GeometryCache::ShapeVertex); // position, normal, texcoords, tangent +static const uint SHAPE_NORMALS_OFFSET = offsetof(GeometryCache::ShapeVertex, normal); +static const uint SHAPE_TEXCOORD0_OFFSET = offsetof(GeometryCache::ShapeVertex, uv); +static const uint SHAPE_TANGENT_OFFSET = offsetof(GeometryCache::ShapeVertex, tangent); void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, const glm::vec3 &entityExtents, QVector &outPointList) { @@ -197,22 +197,11 @@ std::vector polygon() { return result; } -void addVec3ToVector(std::vector& vertices, glm::vec3 vec) { - vertices.push_back(vec.x); - vertices.push_back(vec.y); - vertices.push_back(vec.z); -} - -void addVec2ToVector(std::vector& vertices, glm::vec2 vec) { - vertices.push_back(vec.x); - vertices.push_back(vec.y); -} - -void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices) { +void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices) { gpu::Buffer::Size offset = vertexBuffer->getSize(); vertexBuffer->append(vertices); - gpu::Buffer::Size viewSize = vertices.size() * sizeof(glm::vec3); + gpu::Buffer::Size viewSize = vertices.size() * sizeof(ShapeVertex); _positionView = gpu::BufferView(vertexBuffer, offset, viewSize, SHAPE_VERTEX_STRIDE, POSITION_ELEMENT); @@ -315,14 +304,14 @@ static IndexPair indexToken(geometry::Index a, geometry::Index b) { template void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - std::vector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; IndexPairs wireSeenIndices; size_t faceCount = shape.faces.size(); size_t faceIndexCount = triangulatedFaceIndexCount(); - vertices.reserve(N * faceCount * 2); + vertices.reserve(N * faceCount); solidIndices.reserve(faceIndexCount * faceCount); Index baseVertex = 0; @@ -359,10 +348,7 @@ void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - std::vector vertices; - vertices.reserve(shape.vertices.size() * SHAPE_VERTEX_STRIDE / sizeof(float)); + std::vector vertices; + vertices.reserve(shape.vertices.size()); for (const auto& vertex : shape.vertices) { - addVec3ToVector(vertices, vertex); - addVec3ToVector(vertices, vertex); - addVec2ToVector(vertices, calculateSphereTexCoord(vertex)); // We'll fill in the correct tangents later, once we correct the UVs - addVec3ToVector(vertices, vec3(0.0f)); + vertices.emplace_back(vertex, vertex, calculateSphereTexCoord(vertex), vec3(0.0f)); } // We need to fix up the sphere's UVs because it's actually a tesselated icosahedron. See http://mft-dev.dk/uv-mapping-sphere/ @@ -424,9 +409,9 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid for (size_t f = 0; f < faceCount; f++) { // Fix zipper { - float& u1 = vertices[shape.faces[f][0] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; - float& u2 = vertices[shape.faces[f][1] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; - float& u3 = vertices[shape.faces[f][2] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + float& u1 = vertices[shape.faces[f][0]].uv.x; + float& u2 = vertices[shape.faces[f][1]].uv.x; + float& u3 = vertices[shape.faces[f][2]].uv.x; if (glm::isnan(u1)) { u1 = (u2 + u3) / 2.0f; @@ -461,21 +446,19 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid if (shape.vertices[originalIndex].y == 1.0f || shape.vertices[originalIndex].y == -1.0f) { float uSum = 0.0f; for (Index i2 = 1; i2 <= N - 1; i2++) { - float u = vertices[shape.faces[f][(i + i2) % N] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + float u = vertices[shape.faces[f][(i + i2) % N]].uv.x; uSum += u; } uSum /= (float)(N - 1); - vertices[originalIndex * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)] = uSum; + vertices[originalIndex].uv.x = uSum; break; } } // Fill in tangents for (Index i = 0; i < N; i++) { - vec3 tangent = calculateSphereTangent(vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]); - vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float)] = tangent.x; - vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float) + 1] = tangent.y; - vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float) + 2] = tangent.z; + vec3 tangent = calculateSphereTangent(vertices[shape.faces[f][i]].uv.x); + vertices[shape.faces[f][i]].tangent = tangent; } } @@ -516,31 +499,22 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid template void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer, bool isConical = false) { using namespace geometry; - std::vector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; // Top (if not conical) and bottom faces std::vector shape = polygon(); if (isConical) { for (uint32_t i = 0; i < N; i++) { - addVec3ToVector(vertices, vec3(0.0f, 0.5f, 0.0f)); - addVec3ToVector(vertices, vec3(0.0f, 1.0f, 0.0f)); - addVec2ToVector(vertices, vec2(i / (float)N, 1.0f)); - addVec3ToVector(vertices, vec3(0.0f)); + vertices.emplace_back(vec3(0.0f, 0.5f, 0.0f), vec3(0.0f, 1.0f, 0.0f), vec2((float)i / (float)N, 1.0f), vec3(0.0f)); } } else { for (const vec3& v : shape) { - addVec3ToVector(vertices, vec3(v.x, 0.5f, v.z)); - addVec3ToVector(vertices, vec3(0.0f, 1.0f, 0.0f)); - addVec2ToVector(vertices, vec2(v.x, v.z) + vec2(0.5f)); - addVec3ToVector(vertices, vec3(1.0f, 0.0f, 0.0f)); + vertices.emplace_back(vec3(v.x, 0.5f, v.z), vec3(0.0f, 1.0f, 0.0f), vec2(v.x, v.z) + vec2(0.5f), vec3(1.0f, 0.0f, 0.0f)); } } for (const vec3& v : shape) { - addVec3ToVector(vertices, vec3(v.x, -0.5f, v.z)); - addVec3ToVector(vertices, vec3(0.0f, -1.0f, 0.0f)); - addVec2ToVector(vertices, vec2(-v.x, v.z) + vec2(0.5f)); - addVec3ToVector(vertices, vec3(-1.0f, 0.0f, 0.0f)); + vertices.emplace_back(vec3(v.x, -0.5f, v.z), vec3(0.0f, -1.0f, 0.0f), vec2(-v.x, v.z) + vec2(0.5f), vec3(-1.0f, 0.0f, 0.0f)); } Index baseVertex = 0; for (uint32_t i = 2; i < N; i++) { @@ -572,25 +546,13 @@ void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& ver vec3 tangent = glm::normalize(bottomLeft - bottomRight); // Our tex coords go in the opposite direction as our vertices - float u = 1.0f - i / (float)N; - float u2 = 1.0f - (i + 1) / (float)N; + float u = 1.0f - (float)i / (float)N; + float u2 = 1.0f - (float)(i + 1) / (float)N; - addVec3ToVector(vertices, topLeft); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u, 0.0f)); - addVec3ToVector(vertices, tangent); - addVec3ToVector(vertices, bottomLeft); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u, 1.0f)); - addVec3ToVector(vertices, tangent); - addVec3ToVector(vertices, topRight); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u2, 0.0f)); - addVec3ToVector(vertices, tangent); - addVec3ToVector(vertices, bottomRight); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u2, 1.0f)); - addVec3ToVector(vertices, tangent); + vertices.emplace_back(topLeft, normal, vec2(u, 0.0f), tangent); + vertices.emplace_back(bottomLeft, normal, vec2(u, 1.0f), tangent); + vertices.emplace_back(topRight, normal, vec2(u2, 0.0f), tangent); + vertices.emplace_back(bottomRight, normal, vec2(u2, 1.0f), tangent); solidIndices.push_back(baseVertex + 0); solidIndices.push_back(baseVertex + 2); @@ -609,43 +571,6 @@ void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& ver shapeData.setupIndices(indexBuffer, solidIndices, wireIndices); } -void drawCircle(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { - // Draw a circle with radius 1/4th the size of the bounding box - using namespace geometry; - - std::vector vertices; - IndexVector solidIndices, wireIndices; - const int NUM_CIRCLE_VERTICES = 64; - - std::vector shape = polygon(); - for (const vec3& v : shape) { - addVec3ToVector(vertices, vec3(v.x, 0.0f, v.z)); - addVec3ToVector(vertices, vec3(0.0f, 0.0f, 0.0f)); - addVec2ToVector(vertices, vec2(v.x, v.z) + vec2(0.5f)); - addVec3ToVector(vertices, vec3(1.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); - solidIndices.push_back(baseVertex + i - 1); - solidIndices.push_back(baseVertex + NUM_CIRCLE_VERTICES); - solidIndices.push_back(baseVertex + i + NUM_CIRCLE_VERTICES - 1); - solidIndices.push_back(baseVertex + i + NUM_CIRCLE_VERTICES); - } - - for (uint32_t i = 1; i <= NUM_CIRCLE_VERTICES; i++) { - wireIndices.push_back(baseVertex + (i % NUM_CIRCLE_VERTICES)); - wireIndices.push_back(baseVertex + i - 1); - wireIndices.push_back(baseVertex + (i % NUM_CIRCLE_VERTICES) + NUM_CIRCLE_VERTICES); - wireIndices.push_back(baseVertex + (i - 1) + NUM_CIRCLE_VERTICES); - } - - shapeData.setupVertices(vertexBuffer, vertices); - shapeData.setupIndices(indexBuffer, solidIndices, wireIndices); -} - // FIXME solids need per-face vertices, but smooth shaded // components do not. Find a way to support using draw elements // or draw arrays as appropriate @@ -678,9 +603,9 @@ void GeometryCache::buildShapes() { // Line { ShapeData& shapeData = _shapes[Line]; - shapeData.setupVertices(_shapeVertices, std::vector { - -0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f + shapeData.setupVertices(_shapeVertices, std::vector { + ShapeVertex(vec3(-0.5f, 0.0f, 0.0f), vec3(-0.5f, 0.0f, 0.0f), vec2(0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f)), + ShapeVertex(vec3(0.5f, 0.0f, 0.0f), vec3(0.5f, 0.0f, 0.0f), vec2(0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f)) }); IndexVector wireIndices; // Only two indices diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index b0caaf113c..63154398a4 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -354,6 +354,15 @@ public: /// Set a batch to the simple pipeline, returning the previous pipeline void useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend = false); + struct ShapeVertex { + ShapeVertex(const vec3& pos, const vec3& normal, const vec2& uv, const vec3& tangent) : pos(pos), normal(normal), uv(uv), tangent(tangent) {} + + vec3 pos; + vec3 normal; + vec2 uv; + vec3 tangent; + }; + struct ShapeData { gpu::BufferView _positionView; gpu::BufferView _normalView; @@ -362,7 +371,7 @@ public: gpu::BufferView _indicesView; gpu::BufferView _wireIndicesView; - void setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices); + void setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices); void setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices); void setupBatch(gpu::Batch& batch) const; void draw(gpu::Batch& batch) const;