From c88e0360b3714890b9f6ba1774514f246b27a672 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 31 Jul 2015 14:46:43 -0700 Subject: [PATCH 1/8] Change the inspect.js pan direction and rate This makes camera zoom, orbit, and panning more similar to Second Life. --- examples/inspect.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/inspect.js b/examples/inspect.js index 0df90fbac3..555b4105b7 100644 --- a/examples/inspect.js +++ b/examples/inspect.js @@ -23,7 +23,7 @@ var RAD_TO_DEG = 180.0 / PI; var AZIMUTH_RATE = 90.0; var ALTITUDE_RATE = 200.0; var RADIUS_RATE = 1.0 / 100.0; -var PAN_RATE = 50.0; +var PAN_RATE = 250.0; var Y_AXIS = { x: 0, @@ -139,7 +139,7 @@ function handlePanMode(dx, dy) { var right = Quat.getRight(Camera.getOrientation()); var distance = Vec3.length(vector); - var dv = Vec3.sum(Vec3.multiply(up, -distance * dy / PAN_RATE), Vec3.multiply(right, distance * dx / PAN_RATE)); + var dv = Vec3.sum(Vec3.multiply(up, distance * dy / PAN_RATE), Vec3.multiply(right, -distance * dx / PAN_RATE)); center = Vec3.sum(center, dv); position = Vec3.sum(position, dv); From 1dd6c1117d434ef1555ca7f5b698b6b557fea153 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 1 Aug 2015 11:29:28 -0700 Subject: [PATCH 2/8] change GeometryCache::renderQuad() to use TRIANGLES as lower level render primitive --- libraries/gpu/src/gpu/Format.h | 2 + libraries/model/src/model/Geometry.h | 2 +- libraries/render-utils/src/GeometryCache.cpp | 97 ++++++++++++++++---- libraries/render-utils/src/GeometryCache.h | 2 + 4 files changed, 86 insertions(+), 17 deletions(-) diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index 981a560965..01d3f37ef8 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -213,6 +213,8 @@ enum Primitive { TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN, + + // FIXME - remove these QUADS, QUAD_STRIP, diff --git a/libraries/model/src/model/Geometry.h b/libraries/model/src/model/Geometry.h index 16ebb60b72..5ef414a2d1 100755 --- a/libraries/model/src/model/Geometry.h +++ b/libraries/model/src/model/Geometry.h @@ -71,7 +71,7 @@ public: LINE_STRIP, TRIANGLES, TRIANGLE_STRIP, - QUADS, + QUADS, // NOTE: These must be translated to triangles before rendering QUAD_STRIP, NUM_TOPOLOGIES, diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index def5f38db4..12a6d46be6 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -1012,21 +1012,27 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co } const int FLOATS_PER_VERTEX = 2; // vertices - const int vertices = 4; + const int NUMBER_OF_INDICES = 6; // 1 quad = 2 triangles + const int VERTICES = 4; // 1 quad = 4 vertices if (!details.isCreated) { details.isCreated = true; - details.vertices = vertices; + details.vertices = VERTICES; + details.indices = NUMBER_OF_INDICES; details.vertexSize = FLOATS_PER_VERTEX; auto verticesBuffer = std::make_shared(); auto colorBuffer = std::make_shared(); + auto indicesBuffer = std::make_shared(); + auto streamFormat = std::make_shared(); auto stream = std::make_shared(); details.verticesBuffer = verticesBuffer; details.colorBuffer = colorBuffer; + details.indicesBuffer = indicesBuffer; + details.streamFormat = streamFormat; details.stream = stream; @@ -1037,7 +1043,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride); - float vertexBuffer[vertices * FLOATS_PER_VERTEX] = { + float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = { minCorner.x, minCorner.y, maxCorner.x, minCorner.y, maxCorner.x, maxCorner.y, @@ -1050,14 +1056,24 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co ((int(color.w * 255.0f) & 0xFF) << 24); int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; + // Sam's recommended triangle slices + // Triangle tri1 = { v0, v1, v3 }; + // Triangle tri2 = { v1, v2, v3 }; + // NOTE: Random guy on the internet's recommended triangle slices + // Triangle tri1 = { v0, v1, v2 }; + // Triangle tri2 = { v2, v3, v0 }; + + quint16 indices[NUMBER_OF_INDICES] = { 0, 1, 3, 1, 2, 3 }; details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); + details.indicesBuffer->append(sizeof(indices), (gpu::Byte*) indices); } batch.setInputFormat(details.streamFormat); batch.setInputStream(0, *details.stream); - batch.draw(gpu::QUADS, 4, 0); + batch.setIndexBuffer(gpu::UINT16, details.indicesBuffer, 0); + batch.drawIndexed(gpu::TRIANGLES, NUMBER_OF_INDICES, 0); } void GeometryCache::renderUnitCube(gpu::Batch& batch) { @@ -1102,23 +1118,29 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co } const int FLOATS_PER_VERTEX = 2 * 2; // text coords & vertices - const int vertices = 4; + const int VERTICES = 4; // 1 quad = 4 vertices const int NUM_POS_COORDS = 2; const int VERTEX_TEXCOORD_OFFSET = NUM_POS_COORDS * sizeof(float); + const int NUMBER_OF_INDICES = 6; // 1 quad = 2 triangles if (!details.isCreated) { details.isCreated = true; - details.vertices = vertices; + details.vertices = VERTICES; + details.indices = NUMBER_OF_INDICES; details.vertexSize = FLOATS_PER_VERTEX; auto verticesBuffer = std::make_shared(); auto colorBuffer = std::make_shared(); + auto indicesBuffer = std::make_shared(); + auto streamFormat = std::make_shared(); auto stream = std::make_shared(); details.verticesBuffer = verticesBuffer; details.colorBuffer = colorBuffer; + details.indicesBuffer = indicesBuffer; + details.streamFormat = streamFormat; details.stream = stream; @@ -1130,7 +1152,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride); - float vertexBuffer[vertices * FLOATS_PER_VERTEX] = { + float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = { minCorner.x, minCorner.y, texCoordMinCorner.x, texCoordMinCorner.y, maxCorner.x, minCorner.y, texCoordMaxCorner.x, texCoordMinCorner.y, maxCorner.x, maxCorner.y, texCoordMaxCorner.x, texCoordMaxCorner.y, @@ -1144,14 +1166,24 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co ((int(color.w * 255.0f) & 0xFF) << 24); int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; + // Sam's recommended triangle slices + // Triangle tri1 = { v0, v1, v3 }; + // Triangle tri2 = { v1, v2, v3 }; + // NOTE: Random guy on the internet's recommended triangle slices + // Triangle tri1 = { v0, v1, v2 }; + // Triangle tri2 = { v2, v3, v0 }; + + quint16 indices[NUMBER_OF_INDICES] = { 0, 1, 3, 1, 2, 3 }; details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); + details.indicesBuffer->append(sizeof(indices), (gpu::Byte*) indices); } batch.setInputFormat(details.streamFormat); batch.setInputStream(0, *details.stream); - batch.draw(gpu::QUADS, 4, 0); + batch.setIndexBuffer(gpu::UINT16, details.indicesBuffer, 0); + batch.drawIndexed(gpu::TRIANGLES, NUMBER_OF_INDICES, 0); } void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id) { @@ -1177,21 +1209,27 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co } const int FLOATS_PER_VERTEX = 3; // vertices - const int vertices = 4; + const int NUMBER_OF_INDICES = 6; // 1 quad = 2 triangles + const int VERTICES = 4; // 1 quad = 4 vertices if (!details.isCreated) { details.isCreated = true; - details.vertices = vertices; + details.vertices = VERTICES; + details.indices = NUMBER_OF_INDICES; details.vertexSize = FLOATS_PER_VERTEX; auto verticesBuffer = std::make_shared(); auto colorBuffer = std::make_shared(); + auto indicesBuffer = std::make_shared(); + auto streamFormat = std::make_shared(); auto stream = std::make_shared(); details.verticesBuffer = verticesBuffer; details.colorBuffer = colorBuffer; + details.indicesBuffer = indicesBuffer; + details.streamFormat = streamFormat; details.stream = stream; @@ -1202,7 +1240,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride); - float vertexBuffer[vertices * FLOATS_PER_VERTEX] = { + float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = { minCorner.x, minCorner.y, minCorner.z, maxCorner.x, minCorner.y, minCorner.z, maxCorner.x, maxCorner.y, maxCorner.z, @@ -1215,14 +1253,24 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co ((int(color.w * 255.0f) & 0xFF) << 24); int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; + // Sam's recommended triangle slices + // Triangle tri1 = { v0, v1, v3 }; + // Triangle tri2 = { v1, v2, v3 }; + // NOTE: Random guy on the internet's recommended triangle slices + // Triangle tri1 = { v0, v1, v2 }; + // Triangle tri2 = { v2, v3, v0 }; + + quint16 indices[NUMBER_OF_INDICES] = { 0, 1, 3, 1, 2, 3 }; details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); + details.indicesBuffer->append(sizeof(indices), (gpu::Byte*) indices); } batch.setInputFormat(details.streamFormat); batch.setInputStream(0, *details.stream); - batch.draw(gpu::QUADS, 4, 0); + batch.setIndexBuffer(gpu::UINT16, details.indicesBuffer, 0); + batch.drawIndexed(gpu::TRIANGLES, NUMBER_OF_INDICES, 0); } void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, const glm::vec3& bottomLeft, @@ -1267,23 +1315,29 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons } const int FLOATS_PER_VERTEX = 3 + 2; // 3d vertices + text coords - const int vertices = 4; + const int NUMBER_OF_INDICES = 6; // 1 quad = 2 triangles + const int VERTICES = 4; // 1 quad = 4 vertices const int NUM_POS_COORDS = 3; const int VERTEX_TEXCOORD_OFFSET = NUM_POS_COORDS * sizeof(float); if (!details.isCreated) { details.isCreated = true; - details.vertices = vertices; + details.vertices = VERTICES; + details.indices = NUMBER_OF_INDICES; details.vertexSize = FLOATS_PER_VERTEX; // NOTE: this isn't used for BatchItemDetails maybe we can get rid of it auto verticesBuffer = std::make_shared(); auto colorBuffer = std::make_shared(); + auto indicesBuffer = std::make_shared(); + auto streamFormat = std::make_shared(); auto stream = std::make_shared(); details.verticesBuffer = verticesBuffer; details.colorBuffer = colorBuffer; + details.indicesBuffer = indicesBuffer; + details.streamFormat = streamFormat; details.stream = stream; @@ -1295,7 +1349,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride); - float vertexBuffer[vertices * FLOATS_PER_VERTEX] = { + float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = { topLeft.x, topLeft.y, topLeft.z, texCoordTopLeft.x, texCoordTopLeft.y, bottomLeft.x, bottomLeft.y, bottomLeft.z, texCoordBottomLeft.x, texCoordBottomLeft.y, bottomRight.x, bottomRight.y, bottomRight.z, texCoordBottomRight.x, texCoordBottomRight.y, @@ -1309,13 +1363,24 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons ((int(color.w * 255.0f) & 0xFF) << 24); int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; + // Sam's recommended triangle slices + // Triangle tri1 = { v0, v1, v3 }; + // Triangle tri2 = { v1, v2, v3 }; + // NOTE: Random guy on the internet's recommended triangle slices + // Triangle tri1 = { v0, v1, v2 }; + // Triangle tri2 = { v2, v3, v0 }; + + quint16 indices[NUMBER_OF_INDICES] = { 0, 1, 3, 1, 2, 3 }; + details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); + details.indicesBuffer->append(sizeof(indices), (gpu::Byte*) indices); } batch.setInputFormat(details.streamFormat); batch.setInputStream(0, *details.stream); - batch.draw(gpu::QUADS, 4, 0); + batch.setIndexBuffer(gpu::UINT16, details.indicesBuffer, 0); + batch.drawIndexed(gpu::TRIANGLES, NUMBER_OF_INDICES, 0); } void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color, int id) { diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 812d12b846..19e84e9346 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -235,10 +235,12 @@ private: static int population; gpu::BufferPointer verticesBuffer; gpu::BufferPointer colorBuffer; + gpu::BufferPointer indicesBuffer; gpu::Stream::FormatPointer streamFormat; gpu::BufferStreamPointer stream; int vertices; + int indices; int vertexSize; bool isCreated; From 452225ddaf87ba387f6c06ffc96e863f2dfc95be Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 1 Aug 2015 11:51:07 -0700 Subject: [PATCH 3/8] removed QUADS from Font::drawString() --- libraries/render-utils/src/text/Font.cpp | 30 ++++++++++++++++++++++-- libraries/render-utils/src/text/Font.h | 2 ++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index b341f444e6..3cedcdcbc1 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -18,8 +18,12 @@ struct TextureVertex { TextureVertex(const glm::vec2& pos, const glm::vec2& tex) : pos(pos), tex(tex) {} }; +static const int NUMBER_OF_INDICES_PER_QUAD = 6; // 1 quad = 2 triangles +static const int VERTICES_PER_QUAD = 4; // 1 quad = 4 vertices + struct QuadBuilder { - TextureVertex vertices[4]; + TextureVertex vertices[VERTICES_PER_QUAD]; + QuadBuilder(const glm::vec2& min, const glm::vec2& size, const glm::vec2& texMin, const glm::vec2& texSize) { // min = bottomLeft @@ -249,6 +253,9 @@ void Font::setupGPU() { void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2& bounds) { _verticesBuffer = std::make_shared(); _numVertices = 0; + _indicesBuffer = std::make_shared(); + _numIndices = 0; + _lastStringRendered = str; _lastBounds = bounds; @@ -284,10 +291,28 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2 if (!isNewLine) { for (auto c : token) { auto glyph = _glyphs[c]; + quint16 verticesOffset = _numVertices; QuadBuilder qd(glyph, advance - glm::vec2(0.0f, _ascent)); _verticesBuffer->append(sizeof(QuadBuilder), (const gpu::Byte*)&qd); _numVertices += 4; + + // Sam's recommended triangle slices + // Triangle tri1 = { v0, v1, v3 }; + // Triangle tri2 = { v1, v2, v3 }; + // NOTE: Random guy on the internet's recommended triangle slices + // Triangle tri1 = { v0, v1, v2 }; + // Triangle tri2 = { v2, v3, v0 }; + quint16 indices[NUMBER_OF_INDICES_PER_QUAD]; + indices[0] = verticesOffset + 0; + indices[1] = verticesOffset + 1; + indices[2] = verticesOffset + 3; + indices[3] = verticesOffset + 1; + indices[4] = verticesOffset + 2; + indices[5] = verticesOffset + 3; + _indicesBuffer->append(sizeof(indices), (const gpu::Byte*)indices); + _numIndices += NUMBER_OF_INDICES_PER_QUAD; + // Advance by glyph size advance.x += glyph.d; @@ -318,5 +343,6 @@ void Font::drawString(gpu::Batch& batch, float x, float y, const QString& str, c batch.setInputFormat(_format); batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride); - batch.draw(gpu::QUADS, _numVertices, 0); + batch.setIndexBuffer(gpu::UINT16, _indicesBuffer, 0); + batch.drawIndexed(gpu::TRIANGLES, _numIndices, 0); } diff --git a/libraries/render-utils/src/text/Font.h b/libraries/render-utils/src/text/Font.h index 55801419f9..e10360d45f 100644 --- a/libraries/render-utils/src/text/Font.h +++ b/libraries/render-utils/src/text/Font.h @@ -64,8 +64,10 @@ private: gpu::TexturePointer _texture; gpu::Stream::FormatPointer _format; gpu::BufferPointer _verticesBuffer; + gpu::BufferPointer _indicesBuffer; gpu::BufferStreamPointer _stream; unsigned int _numVertices = 0; + unsigned int _numIndices = 0; int _fontLoc = -1; int _outlineLoc = -1; From 05a4a6aa9bb99c6b55d38d6127d3f18db711d08b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 1 Aug 2015 13:07:56 -0700 Subject: [PATCH 4/8] implement on-the-fly conversion of FBXMeshParts that are quads, into their triangle equivalents --- libraries/fbx/src/FBXReader.cpp | 51 +++++++++++++++++++++++++++- libraries/fbx/src/FBXReader.h | 11 ++++-- libraries/render-utils/src/Model.cpp | 5 ++- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index e18b334264..51f91de71a 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -830,6 +830,56 @@ public: std::vector attributes; }; +gpu::BufferPointer FBXMeshPart::getTrianglesForQuads() const { + // if we've been asked for our triangulation of the original quads, but we don't yet have them + // then create them now. + if (!trianglesForQuadsAvailable) { + trianglesForQuadsAvailable = true; + + quadsAsTrianglesIndicesBuffer = std::make_shared(); + + // QVector quadIndices; // original indices from the FBX mesh + QVector quadsAsTrianglesIndices; // triangle versions of quads converted when first needed + const int INDICES_PER_ORIGINAL_QUAD = 4; + const int INDICES_PER_TRIANGULATED_QUAD = 6; + int numberOfQuads = quadIndices.size() / INDICES_PER_ORIGINAL_QUAD; + + quadsAsTrianglesIndices.resize(numberOfQuads * INDICES_PER_TRIANGULATED_QUAD); + + int originalIndex = 0; + int triangulatedIndex = 0; + for (int fromQuad = 0; fromQuad < numberOfQuads; fromQuad++) { + int i0 = quadIndices[originalIndex + 0]; + int i1 = quadIndices[originalIndex + 1]; + int i2 = quadIndices[originalIndex + 2]; + int i3 = quadIndices[originalIndex + 3]; + + // Sam's recommended triangle slices + // Triangle tri1 = { v0, v1, v3 }; + // Triangle tri2 = { v1, v2, v3 }; + // NOTE: Random guy on the internet's recommended triangle slices + // Triangle tri1 = { v0, v1, v2 }; + // Triangle tri2 = { v2, v3, v0 }; + + quadsAsTrianglesIndices[triangulatedIndex + 0] = i0; + quadsAsTrianglesIndices[triangulatedIndex + 1] = i1; + quadsAsTrianglesIndices[triangulatedIndex + 2] = i3; + + quadsAsTrianglesIndices[triangulatedIndex + 3] = i1; + quadsAsTrianglesIndices[triangulatedIndex + 4] = i2; + quadsAsTrianglesIndices[triangulatedIndex + 5] = i3; + + originalIndex += INDICES_PER_ORIGINAL_QUAD; + triangulatedIndex += INDICES_PER_TRIANGULATED_QUAD; + } + + trianglesForQuadsIndicesCount = INDICES_PER_TRIANGULATED_QUAD * numberOfQuads; + quadsAsTrianglesIndicesBuffer->append(quadsAsTrianglesIndices.size() * sizeof(quint32), (gpu::Byte*)quadsAsTrianglesIndices.data()); + + } + return quadsAsTrianglesIndicesBuffer; +} + void appendIndex(MeshData& data, QVector& indices, int index) { if (index >= data.polygonIndices.size()) { return; @@ -1089,7 +1139,6 @@ ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex) { appendIndex(data, part.quadIndices, beginIndex++); appendIndex(data, part.quadIndices, beginIndex++); appendIndex(data, part.quadIndices, beginIndex++); - } else { for (int nextIndex = beginIndex + 1;; ) { appendIndex(data, part.triangleIndices, beginIndex); diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 198e2d3534..a20dd4a07f 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -109,9 +109,10 @@ public: class FBXMeshPart { public: - QVector quadIndices; - QVector triangleIndices; - + QVector quadIndices; // original indices from the FBX mesh + QVector triangleIndices; // original indices from the FBX mesh + mutable gpu::BufferPointer quadsAsTrianglesIndicesBuffer; + glm::vec3 diffuseColor; glm::vec3 specularColor; glm::vec3 emissiveColor; @@ -126,6 +127,10 @@ public: QString materialID; model::MaterialPointer _material; + mutable bool trianglesForQuadsAvailable = false; + mutable int trianglesForQuadsIndicesCount = 0; + + gpu::BufferPointer getTrianglesForQuads() const; }; /// A single mesh (with optional blendshapes) extracted from an FBX document. diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 1e4f3f7190..b77bafc354 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2096,8 +2096,11 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran } if (part.quadIndices.size() > 0) { - batch.drawIndexed(gpu::QUADS, part.quadIndices.size(), offset); + batch.setIndexBuffer(gpu::UINT32, part.getTrianglesForQuads(), 0); + batch.drawIndexed(gpu::TRIANGLES, part.trianglesForQuadsIndicesCount, 0); + offset += part.quadIndices.size() * sizeof(int); + batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); // restore this in case there are triangles too } if (part.triangleIndices.size() > 0) { From b138c16c7f689e249cdca0436d1bbcd4b52fbf14 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 1 Aug 2015 16:50:36 -0700 Subject: [PATCH 5/8] use Austins QUAD to TRIANGLE_STRIP approach --- libraries/render-utils/src/GeometryCache.cpp | 89 +++----------------- libraries/render-utils/src/GeometryCache.h | 2 - 2 files changed, 14 insertions(+), 77 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 12a6d46be6..3d43cc6934 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -1012,27 +1012,21 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co } const int FLOATS_PER_VERTEX = 2; // vertices - const int NUMBER_OF_INDICES = 6; // 1 quad = 2 triangles const int VERTICES = 4; // 1 quad = 4 vertices if (!details.isCreated) { details.isCreated = true; details.vertices = VERTICES; - details.indices = NUMBER_OF_INDICES; details.vertexSize = FLOATS_PER_VERTEX; auto verticesBuffer = std::make_shared(); auto colorBuffer = std::make_shared(); - auto indicesBuffer = std::make_shared(); - auto streamFormat = std::make_shared(); auto stream = std::make_shared(); details.verticesBuffer = verticesBuffer; details.colorBuffer = colorBuffer; - details.indicesBuffer = indicesBuffer; - details.streamFormat = streamFormat; details.stream = stream; @@ -1046,8 +1040,9 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = { minCorner.x, minCorner.y, maxCorner.x, minCorner.y, - maxCorner.x, maxCorner.y, - minCorner.x, maxCorner.y }; + minCorner.x, maxCorner.y, + maxCorner.x, maxCorner.y + }; const int NUM_COLOR_SCALARS_PER_QUAD = 4; int compactColor = ((int(color.x * 255.0f) & 0xFF)) | @@ -1056,24 +1051,13 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co ((int(color.w * 255.0f) & 0xFF) << 24); int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; - // Sam's recommended triangle slices - // Triangle tri1 = { v0, v1, v3 }; - // Triangle tri2 = { v1, v2, v3 }; - // NOTE: Random guy on the internet's recommended triangle slices - // Triangle tri1 = { v0, v1, v2 }; - // Triangle tri2 = { v2, v3, v0 }; - - quint16 indices[NUMBER_OF_INDICES] = { 0, 1, 3, 1, 2, 3 }; - details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); - details.indicesBuffer->append(sizeof(indices), (gpu::Byte*) indices); } batch.setInputFormat(details.streamFormat); batch.setInputStream(0, *details.stream); - batch.setIndexBuffer(gpu::UINT16, details.indicesBuffer, 0); - batch.drawIndexed(gpu::TRIANGLES, NUMBER_OF_INDICES, 0); + batch.draw(gpu::TRIANGLE_STRIP, 4, 0); } void GeometryCache::renderUnitCube(gpu::Batch& batch) { @@ -1121,25 +1105,21 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co const int VERTICES = 4; // 1 quad = 4 vertices const int NUM_POS_COORDS = 2; const int VERTEX_TEXCOORD_OFFSET = NUM_POS_COORDS * sizeof(float); - const int NUMBER_OF_INDICES = 6; // 1 quad = 2 triangles if (!details.isCreated) { details.isCreated = true; details.vertices = VERTICES; - details.indices = NUMBER_OF_INDICES; details.vertexSize = FLOATS_PER_VERTEX; auto verticesBuffer = std::make_shared(); auto colorBuffer = std::make_shared(); - auto indicesBuffer = std::make_shared(); auto streamFormat = std::make_shared(); auto stream = std::make_shared(); details.verticesBuffer = verticesBuffer; details.colorBuffer = colorBuffer; - details.indicesBuffer = indicesBuffer; details.streamFormat = streamFormat; details.stream = stream; @@ -1155,8 +1135,9 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = { minCorner.x, minCorner.y, texCoordMinCorner.x, texCoordMinCorner.y, maxCorner.x, minCorner.y, texCoordMaxCorner.x, texCoordMinCorner.y, - maxCorner.x, maxCorner.y, texCoordMaxCorner.x, texCoordMaxCorner.y, - minCorner.x, maxCorner.y, texCoordMinCorner.x, texCoordMaxCorner.y }; + minCorner.x, maxCorner.y, texCoordMinCorner.x, texCoordMaxCorner.y, + maxCorner.x, maxCorner.y, texCoordMaxCorner.x, texCoordMaxCorner.y + }; const int NUM_COLOR_SCALARS_PER_QUAD = 4; @@ -1166,24 +1147,13 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co ((int(color.w * 255.0f) & 0xFF) << 24); int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; - // Sam's recommended triangle slices - // Triangle tri1 = { v0, v1, v3 }; - // Triangle tri2 = { v1, v2, v3 }; - // NOTE: Random guy on the internet's recommended triangle slices - // Triangle tri1 = { v0, v1, v2 }; - // Triangle tri2 = { v2, v3, v0 }; - - quint16 indices[NUMBER_OF_INDICES] = { 0, 1, 3, 1, 2, 3 }; - details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); - details.indicesBuffer->append(sizeof(indices), (gpu::Byte*) indices); } batch.setInputFormat(details.streamFormat); batch.setInputStream(0, *details.stream); - batch.setIndexBuffer(gpu::UINT16, details.indicesBuffer, 0); - batch.drawIndexed(gpu::TRIANGLES, NUMBER_OF_INDICES, 0); + batch.draw(gpu::TRIANGLE_STRIP, 4, 0); } void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id) { @@ -1209,26 +1179,22 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co } const int FLOATS_PER_VERTEX = 3; // vertices - const int NUMBER_OF_INDICES = 6; // 1 quad = 2 triangles const int VERTICES = 4; // 1 quad = 4 vertices if (!details.isCreated) { details.isCreated = true; details.vertices = VERTICES; - details.indices = NUMBER_OF_INDICES; details.vertexSize = FLOATS_PER_VERTEX; auto verticesBuffer = std::make_shared(); auto colorBuffer = std::make_shared(); - auto indicesBuffer = std::make_shared(); auto streamFormat = std::make_shared(); auto stream = std::make_shared(); details.verticesBuffer = verticesBuffer; details.colorBuffer = colorBuffer; - details.indicesBuffer = indicesBuffer; details.streamFormat = streamFormat; details.stream = stream; @@ -1243,8 +1209,9 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = { minCorner.x, minCorner.y, minCorner.z, maxCorner.x, minCorner.y, minCorner.z, - maxCorner.x, maxCorner.y, maxCorner.z, - minCorner.x, maxCorner.y, maxCorner.z }; + minCorner.x, maxCorner.y, maxCorner.z, + maxCorner.x, maxCorner.y, maxCorner.z + }; const int NUM_COLOR_SCALARS_PER_QUAD = 4; int compactColor = ((int(color.x * 255.0f) & 0xFF)) | @@ -1253,24 +1220,13 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co ((int(color.w * 255.0f) & 0xFF) << 24); int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; - // Sam's recommended triangle slices - // Triangle tri1 = { v0, v1, v3 }; - // Triangle tri2 = { v1, v2, v3 }; - // NOTE: Random guy on the internet's recommended triangle slices - // Triangle tri1 = { v0, v1, v2 }; - // Triangle tri2 = { v2, v3, v0 }; - - quint16 indices[NUMBER_OF_INDICES] = { 0, 1, 3, 1, 2, 3 }; - details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); - details.indicesBuffer->append(sizeof(indices), (gpu::Byte*) indices); } batch.setInputFormat(details.streamFormat); batch.setInputStream(0, *details.stream); - batch.setIndexBuffer(gpu::UINT16, details.indicesBuffer, 0); - batch.drawIndexed(gpu::TRIANGLES, NUMBER_OF_INDICES, 0); + batch.draw(gpu::TRIANGLE_STRIP, 4, 0); } void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, const glm::vec3& bottomLeft, @@ -1315,7 +1271,6 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons } const int FLOATS_PER_VERTEX = 3 + 2; // 3d vertices + text coords - const int NUMBER_OF_INDICES = 6; // 1 quad = 2 triangles const int VERTICES = 4; // 1 quad = 4 vertices const int NUM_POS_COORDS = 3; const int VERTEX_TEXCOORD_OFFSET = NUM_POS_COORDS * sizeof(float); @@ -1324,20 +1279,15 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons details.isCreated = true; details.vertices = VERTICES; - details.indices = NUMBER_OF_INDICES; details.vertexSize = FLOATS_PER_VERTEX; // NOTE: this isn't used for BatchItemDetails maybe we can get rid of it auto verticesBuffer = std::make_shared(); auto colorBuffer = std::make_shared(); - auto indicesBuffer = std::make_shared(); - auto streamFormat = std::make_shared(); auto stream = std::make_shared(); details.verticesBuffer = verticesBuffer; details.colorBuffer = colorBuffer; - details.indicesBuffer = indicesBuffer; - details.streamFormat = streamFormat; details.stream = stream; @@ -1350,9 +1300,9 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = { - topLeft.x, topLeft.y, topLeft.z, texCoordTopLeft.x, texCoordTopLeft.y, bottomLeft.x, bottomLeft.y, bottomLeft.z, texCoordBottomLeft.x, texCoordBottomLeft.y, bottomRight.x, bottomRight.y, bottomRight.z, texCoordBottomRight.x, texCoordBottomRight.y, + topLeft.x, topLeft.y, topLeft.z, texCoordTopLeft.x, texCoordTopLeft.y, topRight.x, topRight.y, topRight.z, texCoordTopRight.x, texCoordTopRight.y, }; @@ -1363,24 +1313,13 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons ((int(color.w * 255.0f) & 0xFF) << 24); int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor }; - // Sam's recommended triangle slices - // Triangle tri1 = { v0, v1, v3 }; - // Triangle tri2 = { v1, v2, v3 }; - // NOTE: Random guy on the internet's recommended triangle slices - // Triangle tri1 = { v0, v1, v2 }; - // Triangle tri2 = { v2, v3, v0 }; - - quint16 indices[NUMBER_OF_INDICES] = { 0, 1, 3, 1, 2, 3 }; - details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer); details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors); - details.indicesBuffer->append(sizeof(indices), (gpu::Byte*) indices); } batch.setInputFormat(details.streamFormat); batch.setInputStream(0, *details.stream); - batch.setIndexBuffer(gpu::UINT16, details.indicesBuffer, 0); - batch.drawIndexed(gpu::TRIANGLES, NUMBER_OF_INDICES, 0); + batch.draw(gpu::TRIANGLE_STRIP, 4, 0); } void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color, int id) { diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 19e84e9346..812d12b846 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -235,12 +235,10 @@ private: static int population; gpu::BufferPointer verticesBuffer; gpu::BufferPointer colorBuffer; - gpu::BufferPointer indicesBuffer; gpu::Stream::FormatPointer streamFormat; gpu::BufferStreamPointer stream; int vertices; - int indices; int vertexSize; bool isCreated; From b02f751830bdc9cbd526af7c57608ba1dadd7348 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 1 Aug 2015 16:53:35 -0700 Subject: [PATCH 6/8] diff redux --- libraries/render-utils/src/GeometryCache.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 3d43cc6934..ca14e80cd3 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -1041,7 +1041,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co minCorner.x, minCorner.y, maxCorner.x, minCorner.y, minCorner.x, maxCorner.y, - maxCorner.x, maxCorner.y + maxCorner.x, maxCorner.y, }; const int NUM_COLOR_SCALARS_PER_QUAD = 4; @@ -1136,7 +1136,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co minCorner.x, minCorner.y, texCoordMinCorner.x, texCoordMinCorner.y, maxCorner.x, minCorner.y, texCoordMaxCorner.x, texCoordMinCorner.y, minCorner.x, maxCorner.y, texCoordMinCorner.x, texCoordMaxCorner.y, - maxCorner.x, maxCorner.y, texCoordMaxCorner.x, texCoordMaxCorner.y + maxCorner.x, maxCorner.y, texCoordMaxCorner.x, texCoordMaxCorner.y, }; @@ -1210,7 +1210,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co minCorner.x, minCorner.y, minCorner.z, maxCorner.x, minCorner.y, minCorner.z, minCorner.x, maxCorner.y, maxCorner.z, - maxCorner.x, maxCorner.y, maxCorner.z + maxCorner.x, maxCorner.y, maxCorner.z, }; const int NUM_COLOR_SCALARS_PER_QUAD = 4; From 771ce6dca311ef6ec5be54e0075881b7da1c9d7e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 1 Aug 2015 17:20:48 -0700 Subject: [PATCH 7/8] remove QUAD_STRIP from Circle3DOverlay --- interface/src/ui/overlays/Circle3DOverlay.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 53f1b4ce21..fafb759439 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -119,19 +119,21 @@ void Circle3DOverlay::render(RenderArgs* args) { float angle = startAt; float angleInRadians = glm::radians(angle); - glm::vec2 firstInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); - glm::vec2 firstOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); - - points << firstInnerPoint << firstOuterPoint; + glm::vec2 mostRecentInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); + glm::vec2 mostRecentOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); while (angle < endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); glm::vec2 thisOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); - points << thisOuterPoint << thisInnerPoint; + points << mostRecentInnerPoint << mostRecentOuterPoint << thisOuterPoint; // first triangle + points << mostRecentInnerPoint << thisInnerPoint << thisOuterPoint; // second triangle angle += SLICE_ANGLE; + + mostRecentInnerPoint = thisInnerPoint; + mostRecentOuterPoint = thisOuterPoint; } // get the last slice portion.... @@ -139,13 +141,14 @@ void Circle3DOverlay::render(RenderArgs* args) { angleInRadians = glm::radians(angle); glm::vec2 lastInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); glm::vec2 lastOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); - - points << lastOuterPoint << lastInnerPoint; + + points << mostRecentInnerPoint << mostRecentOuterPoint << lastOuterPoint; // first triangle + points << mostRecentInnerPoint << lastInnerPoint << lastOuterPoint; // second triangle geometryCache->updateVertices(_quadVerticesID, points, color); } - geometryCache->renderVertices(batch, gpu::QUAD_STRIP, _quadVerticesID); + geometryCache->renderVertices(batch, gpu::TRIANGLES, _quadVerticesID); } else { if (_lineVerticesID == GeometryCache::UNKNOWN_ID) { From 493836e36312647ab5fa25313e9937ed704000f7 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 1 Aug 2015 17:26:38 -0700 Subject: [PATCH 8/8] remove QUADS from GLBackendShared and Format --- libraries/gpu/src/gpu/Format.h | 5 ----- libraries/gpu/src/gpu/GLBackendShared.h | 2 -- 2 files changed, 7 deletions(-) diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index 01d3f37ef8..b710a44f39 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -213,11 +213,6 @@ enum Primitive { TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN, - - // FIXME - remove these - QUADS, - QUAD_STRIP, - NUM_PRIMITIVES, }; diff --git a/libraries/gpu/src/gpu/GLBackendShared.h b/libraries/gpu/src/gpu/GLBackendShared.h index 888fd1164d..7ce54665be 100644 --- a/libraries/gpu/src/gpu/GLBackendShared.h +++ b/libraries/gpu/src/gpu/GLBackendShared.h @@ -23,8 +23,6 @@ static const GLenum _primitiveToGLmode[gpu::NUM_PRIMITIVES] = { GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, - GL_QUADS, - GL_QUAD_STRIP, }; static const GLenum _elementTypeToGLType[gpu::NUM_TYPES] = {