diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 2896ce711e..22995cbc35 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -17,28 +17,7 @@ QString const Circle3DOverlay::TYPE = "circle3d"; -Circle3DOverlay::Circle3DOverlay() : - _startAt(0.0f), - _endAt(360.0f), - _outerRadius(1.0f), - _innerRadius(0.0f), - _hasTickMarks(false), - _majorTickMarksAngle(0.0f), - _minorTickMarksAngle(0.0f), - _majorTickMarksLength(0.0f), - _minorTickMarksLength(0.0f), - _quadVerticesID(GeometryCache::UNKNOWN_ID), - _lineVerticesID(GeometryCache::UNKNOWN_ID), - _majorTicksVerticesID(GeometryCache::UNKNOWN_ID), - _minorTicksVerticesID(GeometryCache::UNKNOWN_ID), - _lastStartAt(-1.0f), - _lastEndAt(-1.0f), - _lastOuterRadius(-1.0f), - _lastInnerRadius(-1.0f) -{ - _majorTickMarksColor.red = _majorTickMarksColor.green = _majorTickMarksColor.blue = (unsigned char)0; - _minorTickMarksColor.red = _minorTickMarksColor.green = _minorTickMarksColor.blue = (unsigned char)0; -} +Circle3DOverlay::Circle3DOverlay() { } Circle3DOverlay::Circle3DOverlay(const Circle3DOverlay* circle3DOverlay) : Planar3DOverlay(circle3DOverlay), @@ -56,11 +35,7 @@ Circle3DOverlay::Circle3DOverlay(const Circle3DOverlay* circle3DOverlay) : _quadVerticesID(GeometryCache::UNKNOWN_ID), _lineVerticesID(GeometryCache::UNKNOWN_ID), _majorTicksVerticesID(GeometryCache::UNKNOWN_ID), - _minorTicksVerticesID(GeometryCache::UNKNOWN_ID), - _lastStartAt(-1.0f), - _lastEndAt(-1.0f), - _lastOuterRadius(-1.0f), - _lastInnerRadius(-1.0f) + _minorTicksVerticesID(GeometryCache::UNKNOWN_ID) { } @@ -70,36 +45,25 @@ void Circle3DOverlay::render(RenderArgs* args) { } float alpha = getAlpha(); - if (alpha == 0.0f) { return; // do nothing if our alpha is 0, we're not visible } - // Create the circle in the coordinates origin - float outerRadius = getOuterRadius(); - float innerRadius = getInnerRadius(); // only used in solid case - float startAt = getStartAt(); - float endAt = getEndAt(); - - bool geometryChanged = (startAt != _lastStartAt || endAt != _lastEndAt || - innerRadius != _lastInnerRadius || outerRadius != _lastOuterRadius); - + bool geometryChanged = _dirty; + _dirty = false; const float FULL_CIRCLE = 360.0f; const float SLICES = 180.0f; // The amount of segment to create the circle const float SLICE_ANGLE = FULL_CIRCLE / SLICES; - - xColor colorX = getColor(); const float MAX_COLOR = 255.0f; - glm::vec4 color(colorX.red / MAX_COLOR, colorX.green / MAX_COLOR, colorX.blue / MAX_COLOR, alpha); - - bool colorChanged = colorX.red != _lastColor.red || colorX.green != _lastColor.green || colorX.blue != _lastColor.blue; - _lastColor = colorX; auto geometryCache = DependencyManager::get(); Q_ASSERT(args->_batch); auto& batch = *args->_batch; + if (args->_pipeline) { + batch.setPipeline(args->_pipeline->pipeline); + } // FIXME: THe line width of _lineWidth is not supported anymore, we ll need a workaround @@ -110,81 +74,89 @@ void Circle3DOverlay::render(RenderArgs* args) { // for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise // we just draw a line... if (getIsSolid()) { - if (_quadVerticesID == GeometryCache::UNKNOWN_ID) { + if (!_quadVerticesID) { _quadVerticesID = geometryCache->allocateID(); } - if (geometryChanged || colorChanged) { - + if (geometryChanged) { QVector points; - - float angle = startAt; - float angleInRadians = glm::radians(angle); - 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 << mostRecentInnerPoint << mostRecentOuterPoint << thisOuterPoint; // first triangle - points << mostRecentInnerPoint << thisInnerPoint << thisOuterPoint; // second triangle - - angle += SLICE_ANGLE; + QVector colors; - mostRecentInnerPoint = thisInnerPoint; - mostRecentOuterPoint = thisOuterPoint; + float pulseLevel = updatePulse(); + vec4 pulseModifier = vec4(1); + if (_alphaPulse != 0.0) { + pulseModifier.a = (_alphaPulse >= 0.0f) ? pulseLevel : (1.0f - pulseLevel); } - - // get the last slice portion.... - angle = endAt; - angleInRadians = glm::radians(angle); - glm::vec2 lastInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); - glm::vec2 lastOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); + if (_colorPulse != 0.0) { + float pulseValue = (_colorPulse >= 0.0f) ? pulseLevel : (1.0f - pulseLevel); + pulseModifier = vec4(vec3(pulseValue), pulseModifier.a); + } + vec4 innerStartColor = vec4(toGlm(_innerStartColor), _innerStartAlpha) * pulseModifier; + vec4 outerStartColor = vec4(toGlm(_outerStartColor), _outerStartAlpha) * pulseModifier; + vec4 innerEndColor = vec4(toGlm(_innerEndColor), _innerEndAlpha) * pulseModifier; + vec4 outerEndColor = vec4(toGlm(_outerEndColor), _outerEndAlpha) * pulseModifier; - points << mostRecentInnerPoint << mostRecentOuterPoint << lastOuterPoint; // first triangle - points << mostRecentInnerPoint << lastInnerPoint << lastOuterPoint; // second triangle - - geometryCache->updateVertices(_quadVerticesID, points, color); + if (_innerRadius <= 0) { + _solidPrimitive = gpu::TRIANGLE_FAN; + points << vec2(); + colors << innerStartColor; + for (float angle = _startAt; angle <= _endAt; angle += SLICE_ANGLE) { + float range = (angle - _startAt) / (_endAt - _startAt); + float angleRadians = glm::radians(angle); + points << glm::vec2(cos(angleRadians) * _outerRadius, sin(angleRadians) * _outerRadius); + colors << glm::mix(outerStartColor, outerEndColor, range); + } + } else { + _solidPrimitive = gpu::TRIANGLE_STRIP; + for (float angle = _startAt; angle <= _endAt; angle += SLICE_ANGLE) { + float range = (angle - _startAt) / (_endAt - _startAt); + + float angleRadians = glm::radians(angle); + points << glm::vec2(cos(angleRadians) * _innerRadius, sin(angleRadians) * _innerRadius); + colors << glm::mix(innerStartColor, innerEndColor, range); + + points << glm::vec2(cos(angleRadians) * _outerRadius, sin(angleRadians) * _outerRadius); + colors << glm::mix(outerStartColor, outerEndColor, range); + } + } + geometryCache->updateVertices(_quadVerticesID, points, colors); } - geometryCache->renderVertices(batch, gpu::TRIANGLES, _quadVerticesID); + geometryCache->renderVertices(batch, _solidPrimitive, _quadVerticesID); } else { - if (_lineVerticesID == GeometryCache::UNKNOWN_ID) { + if (!_lineVerticesID) { _lineVerticesID = geometryCache->allocateID(); } - if (geometryChanged || colorChanged) { + if (geometryChanged) { QVector points; - float angle = startAt; + float angle = _startAt; float angleInRadians = glm::radians(angle); - glm::vec2 firstPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); + glm::vec2 firstPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius); points << firstPoint; - while (angle < endAt) { + while (angle < _endAt) { angle += SLICE_ANGLE; angleInRadians = glm::radians(angle); - glm::vec2 thisPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); + glm::vec2 thisPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius); points << thisPoint; if (getIsDashedLine()) { angle += SLICE_ANGLE / 2.0f; // short gap angleInRadians = glm::radians(angle); - glm::vec2 dashStartPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); + glm::vec2 dashStartPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius); points << dashStartPoint; } } // get the last slice portion.... - angle = endAt; + angle = _endAt; angleInRadians = glm::radians(angle); - glm::vec2 lastPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); + glm::vec2 lastPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius); points << lastPoint; - - geometryCache->updateVertices(_lineVerticesID, points, color); + geometryCache->updateVertices(_lineVerticesID, points, vec4(toGlm(getColor()), getAlpha())); } if (getIsDashedLine()) { @@ -214,13 +186,13 @@ void Circle3DOverlay::render(RenderArgs* args) { if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) { float tickMarkAngle = getMajorTickMarksAngle(); - float angle = startAt - fmodf(startAt, tickMarkAngle) + tickMarkAngle; + float angle = _startAt - fmodf(_startAt, tickMarkAngle) + tickMarkAngle; float angleInRadians = glm::radians(angle); float tickMarkLength = getMajorTickMarksLength(); - float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; + float startRadius = (tickMarkLength > 0.0f) ? _innerRadius : _outerRadius; float endRadius = startRadius + tickMarkLength; - while (angle <= endAt) { + while (angle <= _endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius); @@ -236,13 +208,13 @@ void Circle3DOverlay::render(RenderArgs* args) { if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) { float tickMarkAngle = getMinorTickMarksAngle(); - float angle = startAt - fmodf(startAt, tickMarkAngle) + tickMarkAngle; + float angle = _startAt - fmodf(_startAt, tickMarkAngle) + tickMarkAngle; float angleInRadians = glm::radians(angle); float tickMarkLength = getMinorTickMarksLength(); - float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; + float startRadius = (tickMarkLength > 0.0f) ? _innerRadius : _outerRadius; float endRadius = startRadius + tickMarkLength; - while (angle <= endAt) { + while (angle <= _endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius); @@ -269,17 +241,10 @@ void Circle3DOverlay::render(RenderArgs* args) { geometryCache->renderVertices(batch, gpu::LINES, _minorTicksVerticesID); } - - if (geometryChanged) { - _lastStartAt = startAt; - _lastEndAt = endAt; - _lastInnerRadius = innerRadius; - _lastOuterRadius = outerRadius; - } } const render::ShapeKey Circle3DOverlay::getShapeKey() { - auto builder = render::ShapeKey::Builder().withoutCullFace(); + auto builder = render::ShapeKey::Builder().withoutCullFace().withUnlit(); if (getAlpha() != 1.0f) { builder.withTranslucent(); } @@ -289,72 +254,102 @@ const render::ShapeKey Circle3DOverlay::getShapeKey() { return builder.build(); } +template T fromVariant(const QVariant& v, bool& valid) { + valid = v.isValid(); + return qvariant_cast(v); +} + +template<> xColor fromVariant(const QVariant& v, bool& valid) { + return xColorFromVariant(v, valid); +} + +template +bool updateIfValid(const QVariantMap& properties, const char* key, T& output) { + bool valid; + T result = fromVariant(properties[key], valid); + if (!valid) { + return false; + } + + // Don't signal updates if the value was already set + if (result == output) { + return false; + } + + output = result; + return true; +} + +// Multicast, many outputs +template +bool updateIfValid(const QVariantMap& properties, const char* key, std::initializer_list> outputs) { + bool valid; + T value = fromVariant(properties[key], valid); + if (!valid) { + return false; + } + bool updated = false; + for (T& output : outputs) { + if (output != value) { + output = value; + updated = true; + } + } + return updated; +} + +// Multicast, multiple possible inputs, in order of preference +template +bool updateIfValid(const QVariantMap& properties, const std::initializer_list keys, T& output) { + for (const char* key : keys) { + if (updateIfValid(properties, key, output)) { + return true; + } + } + return false; +} + + void Circle3DOverlay::setProperties(const QVariantMap& properties) { Planar3DOverlay::setProperties(properties); + _dirty |= updateIfValid(properties, "alpha", { _innerStartAlpha, _innerEndAlpha, _outerStartAlpha, _outerEndAlpha }); + _dirty |= updateIfValid(properties, "Alpha", { _innerStartAlpha, _innerEndAlpha, _outerStartAlpha, _outerEndAlpha }); + _dirty |= updateIfValid(properties, "startAlpha", { _innerStartAlpha, _outerStartAlpha }); + _dirty |= updateIfValid(properties, "endAlpha", { _innerEndAlpha, _outerEndAlpha }); + _dirty |= updateIfValid(properties, "innerAlpha", { _innerStartAlpha, _innerEndAlpha }); + _dirty |= updateIfValid(properties, "outerAlpha", { _outerStartAlpha, _outerEndAlpha }); + _dirty |= updateIfValid(properties, "innerStartAlpha", _innerStartAlpha); + _dirty |= updateIfValid(properties, "innerEndAlpha", _innerEndAlpha); + _dirty |= updateIfValid(properties, "outerStartAlpha", _outerStartAlpha); + _dirty |= updateIfValid(properties, "outerEndAlpha", _outerEndAlpha); - QVariant startAt = properties["startAt"]; - if (startAt.isValid()) { - setStartAt(startAt.toFloat()); - } + _dirty |= updateIfValid(properties, "color", { _innerStartColor, _innerEndColor, _outerStartColor, _outerEndColor }); + _dirty |= updateIfValid(properties, "startColor", { _innerStartColor, _outerStartColor } ); + _dirty |= updateIfValid(properties, "endColor", { _innerEndColor, _outerEndColor } ); + _dirty |= updateIfValid(properties, "innerColor", { _innerStartColor, _innerEndColor } ); + _dirty |= updateIfValid(properties, "outerColor", { _outerStartColor, _outerEndColor } ); + _dirty |= updateIfValid(properties, "innerStartColor", _innerStartColor); + _dirty |= updateIfValid(properties, "innerEndColor", _innerEndColor); + _dirty |= updateIfValid(properties, "outerStartColor", _outerStartColor); + _dirty |= updateIfValid(properties, "outerEndColor", _outerEndColor); - QVariant endAt = properties["endAt"]; - if (endAt.isValid()) { - setEndAt(endAt.toFloat()); - } + _dirty |= updateIfValid(properties, "startAt", _startAt); + _dirty |= updateIfValid(properties, "endAt", _endAt); - QVariant outerRadius = properties["radius"]; - if (!outerRadius.isValid()) { - outerRadius = properties["outerRadius"]; - } - if (outerRadius.isValid()) { - setOuterRadius(outerRadius.toFloat()); - } + _dirty |= updateIfValid(properties, { "radius", "outerRadius" }, _outerRadius); + _dirty |= updateIfValid(properties, "innerRadius", _innerRadius); + _dirty |= updateIfValid(properties, "hasTickMarks", _hasTickMarks); + _dirty |= updateIfValid(properties, "majorTickMarksAngle", _majorTickMarksAngle); + _dirty |= updateIfValid(properties, "minorTickMarksAngle", _minorTickMarksAngle); + _dirty |= updateIfValid(properties, "majorTickMarksLength", _majorTickMarksLength); + _dirty |= updateIfValid(properties, "minorTickMarksLength", _minorTickMarksLength); + _dirty |= updateIfValid(properties, "majorTickMarksColor", _majorTickMarksColor); + _dirty |= updateIfValid(properties, "minorTickMarksColor", _minorTickMarksColor); - QVariant innerRadius = properties["innerRadius"]; - if (innerRadius.isValid()) { - setInnerRadius(innerRadius.toFloat()); - } - - QVariant hasTickMarks = properties["hasTickMarks"]; - if (hasTickMarks.isValid()) { - setHasTickMarks(hasTickMarks.toBool()); - } - - QVariant majorTickMarksAngle = properties["majorTickMarksAngle"]; - if (majorTickMarksAngle.isValid()) { - setMajorTickMarksAngle(majorTickMarksAngle.toFloat()); - } - - QVariant minorTickMarksAngle = properties["minorTickMarksAngle"]; - if (minorTickMarksAngle.isValid()) { - setMinorTickMarksAngle(minorTickMarksAngle.toFloat()); - } - - QVariant majorTickMarksLength = properties["majorTickMarksLength"]; - if (majorTickMarksLength.isValid()) { - setMajorTickMarksLength(majorTickMarksLength.toFloat()); - } - - QVariant minorTickMarksLength = properties["minorTickMarksLength"]; - if (minorTickMarksLength.isValid()) { - setMinorTickMarksLength(minorTickMarksLength.toFloat()); - } - - bool valid; - auto majorTickMarksColor = properties["majorTickMarksColor"]; - if (majorTickMarksColor.isValid()) { - auto color = xColorFromVariant(majorTickMarksColor, valid); - if (valid) { - _majorTickMarksColor = color; - } - } - - auto minorTickMarksColor = properties["minorTickMarksColor"]; - if (minorTickMarksColor.isValid()) { - auto color = xColorFromVariant(majorTickMarksColor, valid); - if (valid) { - _minorTickMarksColor = color; - } + if (_innerStartAlpha < 1.0f || _innerEndAlpha < 1.0f || _outerStartAlpha < 1.0f || _outerEndAlpha < 1.0f) { + // Force the alpha to 0.5, since we'll ignore it in the presence of these other values, but we need + // it to be non-1 in order to get the right pipeline and non-0 in order to render at all. + _alpha = 0.5f; } } diff --git a/interface/src/ui/overlays/Circle3DOverlay.h b/interface/src/ui/overlays/Circle3DOverlay.h index c0e84ef1c6..39f1ade7e9 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.h +++ b/interface/src/ui/overlays/Circle3DOverlay.h @@ -59,28 +59,34 @@ public: virtual Circle3DOverlay* createClone() const override; protected: - float _startAt; - float _endAt; - float _outerRadius; - float _innerRadius; - bool _hasTickMarks; - float _majorTickMarksAngle; - float _minorTickMarksAngle; - float _majorTickMarksLength; - float _minorTickMarksLength; - xColor _majorTickMarksColor; - xColor _minorTickMarksColor; - - int _quadVerticesID; - int _lineVerticesID; - int _majorTicksVerticesID; - int _minorTicksVerticesID; + float _startAt { 0 }; + float _endAt { 360 }; + float _outerRadius { 1 }; + float _innerRadius { 0 }; - xColor _lastColor; - float _lastStartAt; - float _lastEndAt; - float _lastOuterRadius; - float _lastInnerRadius; + xColor _innerStartColor; + xColor _innerEndColor; + xColor _outerStartColor; + xColor _outerEndColor; + float _innerStartAlpha; + float _innerEndAlpha; + float _outerStartAlpha; + float _outerEndAlpha; + + bool _hasTickMarks { false }; + float _majorTickMarksAngle { 0 }; + float _minorTickMarksAngle { 0 }; + float _majorTickMarksLength { 0 }; + float _minorTickMarksLength { 0 }; + xColor _majorTickMarksColor {}; + xColor _minorTickMarksColor {}; + gpu::Primitive _solidPrimitive { gpu::TRIANGLE_FAN }; + int _quadVerticesID { 0 }; + int _lineVerticesID { 0 }; + int _majorTicksVerticesID { 0 }; + int _minorTicksVerticesID { 0 }; + + bool _dirty { true }; }; diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index fd06272fa9..8be1c478be 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -432,7 +432,7 @@ void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, co renderQuad(batch, minCorner, maxCorner, MIN_TEX_COORD, MAX_TEX_COORD, color, id); } -void GeometryCache::updateVertices(int id, const QVector& points, const glm::vec4& color) { +void GeometryCache::updateVertices(int id, const QVector& points, const QVector& colors) { BatchItemDetails& details = _registeredVertices[id]; if (details.isCreated) { @@ -469,11 +469,6 @@ void GeometryCache::updateVertices(int id, const QVector& points, con details.vertices = points.size(); details.vertexSize = FLOATS_PER_VERTEX; - int compactColor = ((int(color.x * 255.0f) & 0xFF)) | - ((int(color.y * 255.0f) & 0xFF) << 8) | - ((int(color.z * 255.0f) & 0xFF) << 16) | - ((int(color.w * 255.0f) & 0xFF) << 24); - float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX]; float* vertex = vertexData; @@ -481,16 +476,25 @@ void GeometryCache::updateVertices(int id, const QVector& points, con int* colorDataAt = colorData; const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f); - foreach(const glm::vec2& point, points) { + auto pointCount = points.size(); + auto colorCount = colors.size(); + int compactColor; + for (auto i = 0; i < pointCount; ++i) { + const auto& point = points[i]; *(vertex++) = point.x; *(vertex++) = point.y; *(vertex++) = NORMAL.x; *(vertex++) = NORMAL.y; *(vertex++) = NORMAL.z; - + if (i < colorCount) { + const auto& color = colors[i]; + compactColor = ((int(color.x * 255.0f) & 0xFF)) | + ((int(color.y * 255.0f) & 0xFF) << 8) | + ((int(color.z * 255.0f) & 0xFF) << 16) | + ((int(color.w * 255.0f) & 0xFF) << 24); + } *(colorDataAt++) = compactColor; } - details.verticesBuffer->append(sizeof(float) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData); details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData); delete[] vertexData; @@ -501,7 +505,11 @@ void GeometryCache::updateVertices(int id, const QVector& points, con #endif } -void GeometryCache::updateVertices(int id, const QVector& points, const glm::vec4& color) { +void GeometryCache::updateVertices(int id, const QVector& points, const glm::vec4& color) { + updateVertices(id, points, QVector({ color })); +} + +void GeometryCache::updateVertices(int id, const QVector& points, const QVector& colors) { BatchItemDetails& details = _registeredVertices[id]; if (details.isCreated) { details.clear(); @@ -537,11 +545,8 @@ void GeometryCache::updateVertices(int id, const QVector& points, con details.vertices = points.size(); details.vertexSize = FLOATS_PER_VERTEX; - int compactColor = ((int(color.x * 255.0f) & 0xFF)) | - ((int(color.y * 255.0f) & 0xFF) << 8) | - ((int(color.z * 255.0f) & 0xFF) << 16) | - ((int(color.w * 255.0f) & 0xFF) << 24); - + // Default to white + int compactColor = 0xFFFFFFFF; float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX]; float* vertex = vertexData; @@ -549,14 +554,23 @@ void GeometryCache::updateVertices(int id, const QVector& points, con int* colorDataAt = colorData; const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f); - foreach(const glm::vec3& point, points) { + auto pointCount = points.size(); + auto colorCount = colors.size(); + for (auto i = 0; i < pointCount; ++i) { + const glm::vec3& point = points[i]; + if (i < colorCount) { + const glm::vec4& color = colors[i]; + compactColor = ((int(color.x * 255.0f) & 0xFF)) | + ((int(color.y * 255.0f) & 0xFF) << 8) | + ((int(color.z * 255.0f) & 0xFF) << 16) | + ((int(color.w * 255.0f) & 0xFF) << 24); + } *(vertex++) = point.x; *(vertex++) = point.y; *(vertex++) = point.z; *(vertex++) = NORMAL.x; *(vertex++) = NORMAL.y; *(vertex++) = NORMAL.z; - *(colorDataAt++) = compactColor; } @@ -570,6 +584,10 @@ void GeometryCache::updateVertices(int id, const QVector& points, con #endif } +void GeometryCache::updateVertices(int id, const QVector& points, const glm::vec4& color) { + updateVertices(id, points, QVector({ color })); +} + void GeometryCache::updateVertices(int id, const QVector& points, const QVector& texCoords, const glm::vec4& color) { BatchItemDetails& details = _registeredVertices[id]; diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 647fa9889c..1bfdc1798e 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -283,7 +283,9 @@ public: const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID); void updateVertices(int id, const QVector& points, const glm::vec4& color); + void updateVertices(int id, const QVector& points, const QVector& colors); void updateVertices(int id, const QVector& points, const glm::vec4& color); + void updateVertices(int id, const QVector& points, const QVector& colors); void updateVertices(int id, const QVector& points, const QVector& texCoords, const glm::vec4& color); void renderVertices(gpu::Batch& batch, gpu::Primitive primitiveType, int id); @@ -360,7 +362,7 @@ private: QHash _coneVBOs; - int _nextID{ 0 }; + int _nextID{ 1 }; QHash _lastRegisteredQuad3DTexture; QHash _quad3DTextures;