mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 15:14:19 +02:00
Support alpha and color gradients in circle overlays
This commit is contained in:
parent
e893b17047
commit
31948bce2d
4 changed files with 219 additions and 198 deletions
|
@ -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<GeometryCache>();
|
||||
|
||||
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<glm::vec2> 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<glm::vec4> 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<glm::vec2> 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<typename T> T fromVariant(const QVariant& v, bool& valid) {
|
||||
valid = v.isValid();
|
||||
return qvariant_cast<T>(v);
|
||||
}
|
||||
|
||||
template<> xColor fromVariant(const QVariant& v, bool& valid) {
|
||||
return xColorFromVariant(v, valid);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool updateIfValid(const QVariantMap& properties, const char* key, T& output) {
|
||||
bool valid;
|
||||
T result = fromVariant<T>(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<typename T>
|
||||
bool updateIfValid(const QVariantMap& properties, const char* key, std::initializer_list<std::reference_wrapper<T>> outputs) {
|
||||
bool valid;
|
||||
T value = fromVariant<T>(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<typename T>
|
||||
bool updateIfValid(const QVariantMap& properties, const std::initializer_list<const char*> keys, T& output) {
|
||||
for (const char* key : keys) {
|
||||
if (updateIfValid<T>(properties, key, output)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Circle3DOverlay::setProperties(const QVariantMap& properties) {
|
||||
Planar3DOverlay::setProperties(properties);
|
||||
_dirty |= updateIfValid<float>(properties, "alpha", { _innerStartAlpha, _innerEndAlpha, _outerStartAlpha, _outerEndAlpha });
|
||||
_dirty |= updateIfValid<float>(properties, "Alpha", { _innerStartAlpha, _innerEndAlpha, _outerStartAlpha, _outerEndAlpha });
|
||||
_dirty |= updateIfValid<float>(properties, "startAlpha", { _innerStartAlpha, _outerStartAlpha });
|
||||
_dirty |= updateIfValid<float>(properties, "endAlpha", { _innerEndAlpha, _outerEndAlpha });
|
||||
_dirty |= updateIfValid<float>(properties, "innerAlpha", { _innerStartAlpha, _innerEndAlpha });
|
||||
_dirty |= updateIfValid<float>(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<xColor>(properties, "color", { _innerStartColor, _innerEndColor, _outerStartColor, _outerEndColor });
|
||||
_dirty |= updateIfValid<xColor>(properties, "startColor", { _innerStartColor, _outerStartColor } );
|
||||
_dirty |= updateIfValid<xColor>(properties, "endColor", { _innerEndColor, _outerEndColor } );
|
||||
_dirty |= updateIfValid<xColor>(properties, "innerColor", { _innerStartColor, _innerEndColor } );
|
||||
_dirty |= updateIfValid<xColor>(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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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<glm::vec2>& points, const glm::vec4& color) {
|
||||
void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& points, const QVector<glm::vec4>& colors) {
|
||||
BatchItemDetails& details = _registeredVertices[id];
|
||||
|
||||
if (details.isCreated) {
|
||||
|
@ -469,11 +469,6 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& 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<glm::vec2>& 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<glm::vec2>& points, con
|
|||
#endif
|
||||
}
|
||||
|
||||
void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, const glm::vec4& color) {
|
||||
void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& points, const glm::vec4& color) {
|
||||
updateVertices(id, points, QVector<glm::vec4>({ color }));
|
||||
}
|
||||
|
||||
void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, const QVector<glm::vec4>& colors) {
|
||||
BatchItemDetails& details = _registeredVertices[id];
|
||||
if (details.isCreated) {
|
||||
details.clear();
|
||||
|
@ -537,11 +545,8 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& 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<glm::vec3>& 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<glm::vec3>& points, con
|
|||
#endif
|
||||
}
|
||||
|
||||
void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, const glm::vec4& color) {
|
||||
updateVertices(id, points, QVector<glm::vec4>({ color }));
|
||||
}
|
||||
|
||||
void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, const QVector<glm::vec2>& texCoords, const glm::vec4& color) {
|
||||
BatchItemDetails& details = _registeredVertices[id];
|
||||
|
||||
|
|
|
@ -283,7 +283,9 @@ public:
|
|||
const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID);
|
||||
|
||||
void updateVertices(int id, const QVector<glm::vec2>& points, const glm::vec4& color);
|
||||
void updateVertices(int id, const QVector<glm::vec2>& points, const QVector<glm::vec4>& colors);
|
||||
void updateVertices(int id, const QVector<glm::vec3>& points, const glm::vec4& color);
|
||||
void updateVertices(int id, const QVector<glm::vec3>& points, const QVector<glm::vec4>& colors);
|
||||
void updateVertices(int id, const QVector<glm::vec3>& points, const QVector<glm::vec2>& texCoords, const glm::vec4& color);
|
||||
void renderVertices(gpu::Batch& batch, gpu::Primitive primitiveType, int id);
|
||||
|
||||
|
@ -360,7 +362,7 @@ private:
|
|||
|
||||
QHash<IntPair, VerticesIndices> _coneVBOs;
|
||||
|
||||
int _nextID{ 0 };
|
||||
int _nextID{ 1 };
|
||||
|
||||
QHash<int, Vec3PairVec4Pair> _lastRegisteredQuad3DTexture;
|
||||
QHash<Vec3PairVec4Pair, BatchItemDetails> _quad3DTextures;
|
||||
|
|
Loading…
Reference in a new issue