History

Merge pull request #1354 from HifiExperiments/torus

add torus rendering

ksuprynowicz committed 1 year ago

Commit 3a5fd2e2 parents 95c24e7 412988a12 files · +207 −36Browse files

Showing the changes to libraries/render-utils/src/GeometryCache.cpp (1 of 12 files). Show all

Unified · Split

libraries/render-utils/src/GeometryCache.cpp+135−20
@@ -19,6 +19,7 @@ · 18 unmodified lines
19#include <QtCore/QFileInfo>19#include <QtCore/QFileInfo>
20#include <QtNetwork/QNetworkReply>20#include <QtNetwork/QNetworkReply>
21 21
22#include <glm/gtx/transform.hpp>
22#include <shared/Shapes.h>23#include <shared/Shapes.h>
23#include <shared/PlatformHacks.h>24#include <shared/PlatformHacks.h>
24 25
@@ -590,8 +591,7 @@ void GeometryCache::buildShapes() { · 565 unmodified lines
590 extrudePolygon<64>(_shapes[Cone], _shapeVertices, _shapeIndices, true);591 extrudePolygon<64>(_shapes[Cone], _shapeVertices, _shapeIndices, true);
591 // Circle renders as flat Cylinder592 // Circle renders as flat Cylinder
592 extrudePolygon<64>(_shapes[Circle], _shapeVertices, _shapeIndices);593 extrudePolygon<64>(_shapes[Circle], _shapeVertices, _shapeIndices);
593 // Not implemented yet:594 //Torus is implemented in renderTorus, not with ShapeData, because the inner radius can change
594 //Torus,
595}595}
596 596
597const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) const {597const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) const {
@@ -696,6 +696,9 @@ void GeometryCache::releaseID(int id) { · 98 unmodified lines
696 696
697 _lastRegisteredGridBuffer.remove(id);697 _lastRegisteredGridBuffer.remove(id);
698 _registeredGridBuffers.remove(id);698 _registeredGridBuffers.remove(id);
699
700 _lastRegisteredTorusBuffer.remove(id);
701 _registeredTorusBuffers.remove(id);
699}702}
700 703
701void GeometryCache::initializeShapePipelines() {704void GeometryCache::initializeShapePipelines() {
@@ -1618,18 +1621,132 @@ void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start, · 916 unmodified lines
1618 batch.draw(gpu::LINES, details.vertices, 0);1621 batch.draw(gpu::LINES, details.vertices, 0);
1619}1622}
1620 1623
1624void GeometryCache::renderTorus(gpu::Batch& batch, float innerRadius, gpu::BufferPointer& colorBuffer, int id) {
1625 bool registered = (id != UNKNOWN_ID);
1626 BatchItemDetails& details = _registeredTorusBuffers[id];
1627
1628 // if this is a registered, and we have buffers, then check to see if the geometry changed and rebuild if needed
1629 if (registered && details.isCreated) {
1630 if (_lastRegisteredTorusBuffer[id] != innerRadius) {
1631 details.clear();
1632 _lastRegisteredTorusBuffer[id] = innerRadius;
1633#ifdef WANT_DEBUG
1634 qCDebug(renderutils) << "renderTorus()... RELEASING REGISTERED";
1635#endif // def WANT_DEBUG
1636 }
1637 }
1638
1639 if (!details.isCreated) {
1640 const int NUM_DIVISIONS = 64;
1641 const float ANGLE_STEP = 2.0f * ((float)M_PI) / NUM_DIVISIONS;
1642 const int FLOATS_PER_VERTEX = 3 + 3 + 2 + 3; // vertices + normals + tex coords + tangents
1643 details.isCreated = true;
1644 details.vertices = 6 * (NUM_DIVISIONS + 1) * (NUM_DIVISIONS + 1);
1645 details.vertexSize = FLOATS_PER_VERTEX;
1646
1647 auto verticesBuffer = std::make_shared<gpu::Buffer>();
1648 auto indicesBuffer = std::make_shared<gpu::Buffer>();
1649 auto streamFormat = std::make_shared<gpu::Stream::Format>();
1650 auto stream = std::make_shared<gpu::BufferStream>();
1651
1652 details.verticesBuffer = verticesBuffer;
1653 details.uniformBuffer = indicesBuffer; // we use the uniformBuffer to store the incides
1654 details.streamFormat = streamFormat;
1655 details.stream = stream;
1656
1657 details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, POSITION_ELEMENT);
1658 details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, NORMAL_ELEMENT, 3 * sizeof(float));
1659 details.streamFormat->setAttribute(gpu::Stream::TEXCOORD0, 0, TEXCOORD0_ELEMENT, 6 * sizeof(float));
1660 details.streamFormat->setAttribute(gpu::Stream::TANGENT, 0, TANGENT_ELEMENT, 8 * sizeof(float));
1661 details.streamFormat->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
1662
1663 details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride);
1664
1665 // Build our initial circle. Keep track of the center point for normal calculations.
1666 glm::vec3 center = glm::vec3(0.5f - innerRadius, 0.0f, 0.0f);
1667 std::array<glm::vec3, NUM_DIVISIONS + 1> points;
1668 for (int i = 0; i <= NUM_DIVISIONS; i++) {
1669 // Inner radius only affects X. Y still needs to be -0.5 -> 0.5.
1670 points[i] = center + glm::vec3(innerRadius * glm::cos(i * ANGLE_STEP), 0.5f * glm::sin(i * ANGLE_STEP), 0.0f);
1671 }
1672 glm::mat3 normalMatrix = glm::transpose(glm::inverse(glm::scale(glm::vec3(1.0f, 0.5f / innerRadius, 1.0f))));
1673
1674 // Build all of our vertex data
1675 float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX];
1676 float* vertex = vertexData;
1677 for (int y = 0; y <= NUM_DIVISIONS; y++) {
1678 const float ANGLE = y * ANGLE_STEP;
1679 for (int i = 0; i <= NUM_DIVISIONS; i++) {
1680 glm::vec3 currentCenter = fabs(center.x) * glm::vec3(glm::cos(ANGLE), 0.0f, glm::sin(ANGLE));
1681 // Position
1682 glm::vec3 currentPoint = glm::vec3(0.0f, points[i].y, 0.0f) + fabs(points[i].x) * glm::vec3(glm::cos(ANGLE), 0.0f, glm::sin(ANGLE));
1683 *(vertex++) = currentPoint.x;
1684 *(vertex++) = currentPoint.y;
1685 *(vertex++) = currentPoint.z;
1686 // Normal
1687 glm::vec3 currentNormal = glm::normalize(normalMatrix * glm::normalize(currentPoint - currentCenter));
1688 *(vertex++) = currentNormal.x;
1689 *(vertex++) = currentNormal.y;
1690 *(vertex++) = currentNormal.z;
1691 // UV
1692 glm::vec2 currentUV = glm::vec2((float)i / NUM_DIVISIONS, (float)y / NUM_DIVISIONS);
1693 *(vertex++) = currentUV.x;
1694 *(vertex++) = currentUV.y;
1695 // Tangent
1696 int nextIndex = (i + 1) % (NUM_DIVISIONS + 1) + (i / (NUM_DIVISIONS + 1));
1697 glm::vec3 currentTangent = glm::normalize(glm::cross(currentNormal, points[nextIndex] - points[i]));
1698 *(vertex++) = currentTangent.x;
1699 *(vertex++) = currentTangent.y;
1700 *(vertex++) = currentTangent.z;
1701 }
1702 }
1703
1704 details.verticesBuffer->append(sizeof(float) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*)vertexData);
1705 delete[] vertexData;
1706
1707 // Build our indices
1708 for (int y = 0; y < NUM_DIVISIONS; y++) {
1709 for (int i = 0; i < NUM_DIVISIONS; i++) {
1710 const int baseIndex = i + (NUM_DIVISIONS + 1) * y;
1711 details.uniformBuffer->append((uint16_t)baseIndex);
1712 details.uniformBuffer->append((uint16_t)(baseIndex + 1));
1713 details.uniformBuffer->append((uint16_t)(baseIndex + NUM_DIVISIONS + 1));
1714 details.uniformBuffer->append((uint16_t)(baseIndex + 1));
1715 details.uniformBuffer->append((uint16_t)(baseIndex + NUM_DIVISIONS + 2));
1716 details.uniformBuffer->append((uint16_t)(baseIndex + NUM_DIVISIONS + 1));
1717 }
1718 }
1719
1720#ifdef WANT_DEBUG
1721 if (registered) {
1722 qCDebug(renderutils) << "new registered torus buffer made -- _registeredTorusBuffers:"
1723 << _registeredTorusBuffers.size();
1724 } else {
1725 qCDebug(renderutils) << "new torus buffer made -- _registeredTorusBuffers:" << _registeredTorusBuffers.size();
1726 }
1727#endif
1728 }
1729
1730 // TODO: instanced rendering
1731 gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
1732 batch.setInputBuffer(gpu::Stream::COLOR, colorView);
1733 batch.setInputStream(0, *details.stream);
1734 batch.setInputFormat(details.streamFormat);
1735 batch.setIndexBuffer(gpu::Type::UINT16, details.uniformBuffer, 0); // indices are stored in uniformBuffer
1736 batch.drawIndexed(gpu::TRIANGLES, details.vertices, 0);
1737}
1621 1738
1622int GeometryCache::BatchItemDetails::population = 0;1739int GeometryCache::BatchItemDetails::population = 0;
1623 1740
1624GeometryCache::BatchItemDetails::BatchItemDetails() :1741GeometryCache::BatchItemDetails::BatchItemDetails() :
1625verticesBuffer(NULL),1742 verticesBuffer(NULL),
1626normalBuffer(NULL),1743 normalBuffer(NULL),
1627colorBuffer(NULL),1744 colorBuffer(NULL),
1628streamFormat(NULL),1745 streamFormat(NULL),
1629stream(NULL),1746 stream(NULL),
1630vertices(0),1747 vertices(0),
1631vertexSize(0),1748 vertexSize(0),
1632isCreated(false) {1749 isCreated(false) {
1633 population++;1750 population++;
1634#ifdef WANT_DEBUG1751#ifdef WANT_DEBUG
1635 qCDebug(renderutils) << "BatchItemDetails()... population:" << population << "**********************************";1752 qCDebug(renderutils) << "BatchItemDetails()... population:" << population << "**********************************";
@@ -1637,14 +1754,14 @@ isCreated(false) { · 1 unmodified line
1637}1754}
1638 1755
1639GeometryCache::BatchItemDetails::BatchItemDetails(const GeometryCache::BatchItemDetails& other) :1756GeometryCache::BatchItemDetails::BatchItemDetails(const GeometryCache::BatchItemDetails& other) :
1640verticesBuffer(other.verticesBuffer),1757 verticesBuffer(other.verticesBuffer),
1641normalBuffer(other.normalBuffer),1758 normalBuffer(other.normalBuffer),
1642colorBuffer(other.colorBuffer),1759 colorBuffer(other.colorBuffer),
1643streamFormat(other.streamFormat),1760 streamFormat(other.streamFormat),
1644stream(other.stream),1761 stream(other.stream),
1645vertices(other.vertices),1762 vertices(other.vertices),
1646vertexSize(other.vertexSize),1763 vertexSize(other.vertexSize),
1647isCreated(other.isCreated) {1764 isCreated(other.isCreated) {
1648 population++;1765 population++;
1649#ifdef WANT_DEBUG1766#ifdef WANT_DEBUG
1650 qCDebug(renderutils) << "BatchItemDetails()... population:" << population << "**********************************";1767 qCDebug(renderutils) << "BatchItemDetails()... population:" << population << "**********************************";
@@ -1728,8 +1845,6 @@ void GeometryCache::useGridPipeline(gpu::Batch& batch, GridBuffer gridBuffer, bo · 77 unmodified lines
1728 batch.setUniformBuffer(0, gridBuffer);1845 batch.setUniformBuffer(0, gridBuffer);
1729}1846}
1730 1847
1731
1732
1733class SimpleProgramKey {1848class SimpleProgramKey {
1734public:1849public:
1735 enum FlagBit {1850 enum FlagBit {