void Line3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } float alpha = getAlpha(); xColor color = getColor(); const float MAX_COLOR = 255.0f; glm::vec4 colorv4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); auto batch = args->_batch; if (batch) { batch->setModelTransform(_transform); if (getIsDashedLine()) { // TODO: add support for color to renderDashedLine() DependencyManager::get<GeometryCache>()->renderDashedLine(*batch, _start, _end, colorv4, _geometryCacheID); } else { DependencyManager::get<GeometryCache>()->renderLine(*batch, _start, _end, colorv4, _geometryCacheID); } } else { float glowLevel = getGlowLevel(); Glower* glower = NULL; if (glowLevel > 0.0f) { glower = new Glower(glowLevel); } glPushMatrix(); glDisable(GL_LIGHTING); glLineWidth(_lineWidth); glm::vec3 position = getPosition(); glm::quat rotation = getRotation(); glTranslatef(position.x, position.y, position.z); glm::vec3 axis = glm::axis(rotation); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); if (getIsDashedLine()) { // TODO: add support for color to renderDashedLine() DependencyManager::get<GeometryCache>()->renderDashedLine(_start, _end, colorv4, _geometryCacheID); } else { DependencyManager::get<GeometryCache>()->renderLine(_start, _end, colorv4, _geometryCacheID); } glEnable(GL_LIGHTING); glPopMatrix(); if (glower) { delete glower; } } }
void Line3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } float alpha = getAlpha(); xColor color = getColor(); const float MAX_COLOR = 255.0f; glm::vec4 colorv4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); auto batch = args->_batch; if (batch) { batch->setModelTransform(_transform); auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->bindSimpleProgram(*batch, false, false, true, true); if (getIsDashedLine()) { // TODO: add support for color to renderDashedLine() geometryCache->renderDashedLine(*batch, _start, _end, colorv4, _geometryCacheID); } else { geometryCache->renderLine(*batch, _start, _end, colorv4, _geometryCacheID); } } }
void Rectangle3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } float alpha = getAlpha(); xColor color = getColor(); const float MAX_COLOR = 255.0f; glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); glm::vec3 position = getPosition(); glm::vec2 dimensions = getDimensions(); glm::vec2 halfDimensions = dimensions * 0.5f; glm::quat rotation = getRotation(); auto batch = args->_batch; if (batch) { Transform transform; transform.setTranslation(position); transform.setRotation(rotation); batch->setModelTransform(transform); auto geometryCache = DependencyManager::get<GeometryCache>(); if (getIsSolid()) { glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f); geometryCache->bindSimpleProgram(*batch); geometryCache->renderQuad(*batch, topLeft, bottomRight, rectangleColor); } else { geometryCache->bindSimpleProgram(*batch, false, false, false, true, true); if (getIsDashedLine()) { glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f); glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f); geometryCache->renderDashedLine(*batch, point1, point2, rectangleColor); geometryCache->renderDashedLine(*batch, point2, point3, rectangleColor); geometryCache->renderDashedLine(*batch, point3, point4, rectangleColor); geometryCache->renderDashedLine(*batch, point4, point1, rectangleColor); } else { if (halfDimensions != _previousHalfDimensions) { QVector<glm::vec3> border; border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f); border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f); border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f); border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); geometryCache->updateVertices(_geometryCacheID, border, rectangleColor); _previousHalfDimensions = halfDimensions; } geometryCache->renderVertices(*batch, gpu::LINE_STRIP, _geometryCacheID); } } } }
void Circle3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } 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); 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; //const int slices = 15; 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; batch._glLineWidth(_lineWidth); auto transform = _transform; transform.postScale(glm::vec3(getDimensions(), 1.0f)); batch.setModelTransform(transform); DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, false, false); // 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) { _quadVerticesID = geometryCache->allocateID(); } if (geometryChanged || colorChanged) { 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; mostRecentInnerPoint = thisInnerPoint; mostRecentOuterPoint = thisOuterPoint; } // 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); points << mostRecentInnerPoint << mostRecentOuterPoint << lastOuterPoint; // first triangle points << mostRecentInnerPoint << lastInnerPoint << lastOuterPoint; // second triangle geometryCache->updateVertices(_quadVerticesID, points, color); } geometryCache->renderVertices(batch, gpu::TRIANGLES, _quadVerticesID); } else { if (_lineVerticesID == GeometryCache::UNKNOWN_ID) { _lineVerticesID = geometryCache->allocateID(); } if (geometryChanged || colorChanged) { QVector<glm::vec2> points; float angle = startAt; float angleInRadians = glm::radians(angle); glm::vec2 firstPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); points << firstPoint; while (angle < endAt) { angle += SLICE_ANGLE; angleInRadians = glm::radians(angle); 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); points << dashStartPoint; } } // get the last slice portion.... angle = endAt; angleInRadians = glm::radians(angle); glm::vec2 lastPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); points << lastPoint; geometryCache->updateVertices(_lineVerticesID, points, color); } if (getIsDashedLine()) { geometryCache->renderVertices(batch, gpu::LINES, _lineVerticesID); } else { geometryCache->renderVertices(batch, gpu::LINE_STRIP, _lineVerticesID); } } // draw our tick marks // 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 (getHasTickMarks()) { if (_majorTicksVerticesID == GeometryCache::UNKNOWN_ID) { _majorTicksVerticesID = geometryCache->allocateID(); } if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) { _minorTicksVerticesID = geometryCache->allocateID(); } if (geometryChanged) { QVector<glm::vec2> majorPoints; QVector<glm::vec2> minorPoints; // draw our major tick marks if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) { float tickMarkAngle = getMajorTickMarksAngle(); float angle = startAt - fmodf(startAt, tickMarkAngle) + tickMarkAngle; float angleInRadians = glm::radians(angle); float tickMarkLength = getMajorTickMarksLength(); float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; float endRadius = startRadius + tickMarkLength; while (angle <= endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius); glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius); majorPoints << thisPointA << thisPointB; angle += tickMarkAngle; } } // draw our minor tick marks if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) { float tickMarkAngle = getMinorTickMarksAngle(); float angle = startAt - fmodf(startAt, tickMarkAngle) + tickMarkAngle; float angleInRadians = glm::radians(angle); float tickMarkLength = getMinorTickMarksLength(); float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; float endRadius = startRadius + tickMarkLength; while (angle <= endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius); glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius); minorPoints << thisPointA << thisPointB; angle += tickMarkAngle; } } xColor majorColorX = getMajorTickMarksColor(); glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha); geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor); xColor minorColorX = getMinorTickMarksColor(); glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha); geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor); } geometryCache->renderVertices(batch, gpu::LINES, _majorTicksVerticesID); geometryCache->renderVertices(batch, gpu::LINES, _minorTicksVerticesID); } if (geometryChanged) { _lastStartAt = startAt; _lastEndAt = endAt; _lastInnerRadius = innerRadius; _lastOuterRadius = outerRadius; } }
void Cube3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } float alpha = getAlpha(); xColor color = getColor(); const float MAX_COLOR = 255.0f; glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); // TODO: handle registration point?? glm::vec3 position = getPosition(); glm::vec3 center = getCenter(); glm::vec3 dimensions = getDimensions(); glm::quat rotation = getRotation(); auto batch = args->_batch; if (batch) { Transform transform; transform.setTranslation(position); transform.setRotation(rotation); if (_isSolid) { // if (_borderSize > 0) { // // Draw a cube at a larger size behind the main cube, creating // // a border effect. // // Disable writing to the depth mask so that the "border" cube will not // // occlude the main cube. This means the border could be covered by // // overlays that are further back and drawn later, but this is good // // enough for the use-case. // transform.setScale(dimensions * _borderSize); // batch->setModelTransform(transform); // DependencyManager::get<GeometryCache>()->renderSolidCube(*batch, 1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha)); // } transform.setScale(dimensions); batch->setModelTransform(transform); DependencyManager::get<GeometryCache>()->renderSolidCube(*batch, 1.0f, cubeColor); } else { if (getIsDashedLine()) { transform.setScale(1.0f); batch->setModelTransform(transform); glm::vec3 halfDimensions = dimensions / 2.0f; glm::vec3 bottomLeftNear(-halfDimensions.x, -halfDimensions.y, -halfDimensions.z); glm::vec3 bottomRightNear(halfDimensions.x, -halfDimensions.y, -halfDimensions.z); glm::vec3 topLeftNear(-halfDimensions.x, halfDimensions.y, -halfDimensions.z); glm::vec3 topRightNear(halfDimensions.x, halfDimensions.y, -halfDimensions.z); glm::vec3 bottomLeftFar(-halfDimensions.x, -halfDimensions.y, halfDimensions.z); glm::vec3 bottomRightFar(halfDimensions.x, -halfDimensions.y, halfDimensions.z); glm::vec3 topLeftFar(-halfDimensions.x, halfDimensions.y, halfDimensions.z); glm::vec3 topRightFar(halfDimensions.x, halfDimensions.y, halfDimensions.z); auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->renderDashedLine(*batch, bottomLeftNear, bottomRightNear, cubeColor); geometryCache->renderDashedLine(*batch, bottomRightNear, bottomRightFar, cubeColor); geometryCache->renderDashedLine(*batch, bottomRightFar, bottomLeftFar, cubeColor); geometryCache->renderDashedLine(*batch, bottomLeftFar, bottomLeftNear, cubeColor); geometryCache->renderDashedLine(*batch, topLeftNear, topRightNear, cubeColor); geometryCache->renderDashedLine(*batch, topRightNear, topRightFar, cubeColor); geometryCache->renderDashedLine(*batch, topRightFar, topLeftFar, cubeColor); geometryCache->renderDashedLine(*batch, topLeftFar, topLeftNear, cubeColor); geometryCache->renderDashedLine(*batch, bottomLeftNear, topLeftNear, cubeColor); geometryCache->renderDashedLine(*batch, bottomRightNear, topRightNear, cubeColor); geometryCache->renderDashedLine(*batch, bottomLeftFar, topLeftFar, cubeColor); geometryCache->renderDashedLine(*batch, bottomRightFar, topRightFar, cubeColor); } else { transform.setScale(dimensions); batch->setModelTransform(transform); DependencyManager::get<DeferredLightingEffect>()->renderWireCube(*batch, 1.0f, cubeColor); } } } }
void Circle3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } float alpha = getAlpha(); if (alpha == 0.0f) { return; // do nothing if our alpha is 0, we're not visible } 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; const float MAX_COLOR = 255.0f; 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 auto transform = getTransform(); transform.postScale(glm::vec3(getDimensions(), 1.0f)); batch.setModelTransform(transform); // 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) { _quadVerticesID = geometryCache->allocateID(); } if (geometryChanged) { QVector<glm::vec2> points; QVector<glm::vec4> colors; float pulseLevel = updatePulse(); vec4 pulseModifier = vec4(1); if (_alphaPulse != 0.0f) { pulseModifier.a = (_alphaPulse >= 0.0f) ? pulseLevel : (1.0f - pulseLevel); } if (_colorPulse != 0.0f) { 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; 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(cosf(angleRadians) * _outerRadius, sinf(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(cosf(angleRadians) * _innerRadius, sinf(angleRadians) * _innerRadius); colors << glm::mix(innerStartColor, innerEndColor, range); points << glm::vec2(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius); colors << glm::mix(outerStartColor, outerEndColor, range); } } geometryCache->updateVertices(_quadVerticesID, points, colors); } geometryCache->renderVertices(batch, _solidPrimitive, _quadVerticesID); } else { if (!_lineVerticesID) { _lineVerticesID = geometryCache->allocateID(); } if (geometryChanged) { QVector<glm::vec2> points; float angle = _startAt; float angleInRadians = glm::radians(angle); glm::vec2 firstPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius); points << firstPoint; while (angle < _endAt) { angle += SLICE_ANGLE; angleInRadians = glm::radians(angle); 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); points << dashStartPoint; } } // get the last slice portion.... angle = _endAt; angleInRadians = glm::radians(angle); glm::vec2 lastPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius); points << lastPoint; geometryCache->updateVertices(_lineVerticesID, points, vec4(toGlm(getColor()), getAlpha())); } if (getIsDashedLine()) { geometryCache->renderVertices(batch, gpu::LINES, _lineVerticesID); } else { geometryCache->renderVertices(batch, gpu::LINE_STRIP, _lineVerticesID); } } // draw our tick marks // 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 (getHasTickMarks()) { if (_majorTicksVerticesID == GeometryCache::UNKNOWN_ID) { _majorTicksVerticesID = geometryCache->allocateID(); } if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) { _minorTicksVerticesID = geometryCache->allocateID(); } if (geometryChanged) { QVector<glm::vec2> majorPoints; QVector<glm::vec2> minorPoints; // draw our major tick marks if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) { float tickMarkAngle = getMajorTickMarksAngle(); float angle = _startAt - fmodf(_startAt, tickMarkAngle) + tickMarkAngle; float angleInRadians = glm::radians(angle); float tickMarkLength = getMajorTickMarksLength(); float startRadius = (tickMarkLength > 0.0f) ? _innerRadius : _outerRadius; float endRadius = startRadius + tickMarkLength; while (angle <= _endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius); glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius); majorPoints << thisPointA << thisPointB; angle += tickMarkAngle; } } // draw our minor tick marks if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) { float tickMarkAngle = getMinorTickMarksAngle(); float angle = _startAt - fmodf(_startAt, tickMarkAngle) + tickMarkAngle; float angleInRadians = glm::radians(angle); float tickMarkLength = getMinorTickMarksLength(); float startRadius = (tickMarkLength > 0.0f) ? _innerRadius : _outerRadius; float endRadius = startRadius + tickMarkLength; while (angle <= _endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius); glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius); minorPoints << thisPointA << thisPointB; angle += tickMarkAngle; } } xColor majorColorX = getMajorTickMarksColor(); glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha); geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor); xColor minorColorX = getMinorTickMarksColor(); glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha); geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor); } geometryCache->renderVertices(batch, gpu::LINES, _majorTicksVerticesID); geometryCache->renderVertices(batch, gpu::LINES, _minorTicksVerticesID); } }
void Cube3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } float glowLevel = getGlowLevel(); Glower* glower = NULL; if (glowLevel > 0.0f) { glower = new Glower(glowLevel); } float alpha = getAlpha(); xColor color = getColor(); const float MAX_COLOR = 255.0f; glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); //glDisable(GL_LIGHTING); // TODO: handle registration point?? glm::vec3 position = getPosition(); glm::vec3 center = getCenter(); glm::vec3 dimensions = getDimensions(); glm::quat rotation = getRotation(); glPushMatrix(); glTranslatef(position.x, position.y, position.z); glm::vec3 axis = glm::axis(rotation); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); glPushMatrix(); glm::vec3 positionToCenter = center - position; glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); if (_isSolid) { if (_borderSize > 0) { // Draw a cube at a larger size behind the main cube, creating // a border effect. // Disable writing to the depth mask so that the "border" cube will not // occlude the main cube. This means the border could be covered by // overlays that are further back and drawn later, but this is good // enough for the use-case. glDepthMask(GL_FALSE); glPushMatrix(); glScalef(dimensions.x * _borderSize, dimensions.y * _borderSize, dimensions.z * _borderSize); if (_drawOnHUD) { DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha)); } else { DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha)); } glPopMatrix(); glDepthMask(GL_TRUE); } glPushMatrix(); glScalef(dimensions.x, dimensions.y, dimensions.z); if (_drawOnHUD) { DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, cubeColor); } else { DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, cubeColor); } glPopMatrix(); } else { glLineWidth(_lineWidth); if (getIsDashedLine()) { glm::vec3 halfDimensions = dimensions / 2.0f; glm::vec3 bottomLeftNear(-halfDimensions.x, -halfDimensions.y, -halfDimensions.z); glm::vec3 bottomRightNear(halfDimensions.x, -halfDimensions.y, -halfDimensions.z); glm::vec3 topLeftNear(-halfDimensions.x, halfDimensions.y, -halfDimensions.z); glm::vec3 topRightNear(halfDimensions.x, halfDimensions.y, -halfDimensions.z); glm::vec3 bottomLeftFar(-halfDimensions.x, -halfDimensions.y, halfDimensions.z); glm::vec3 bottomRightFar(halfDimensions.x, -halfDimensions.y, halfDimensions.z); glm::vec3 topLeftFar(-halfDimensions.x, halfDimensions.y, halfDimensions.z); glm::vec3 topRightFar(halfDimensions.x, halfDimensions.y, halfDimensions.z); auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->renderDashedLine(bottomLeftNear, bottomRightNear, cubeColor); geometryCache->renderDashedLine(bottomRightNear, bottomRightFar, cubeColor); geometryCache->renderDashedLine(bottomRightFar, bottomLeftFar, cubeColor); geometryCache->renderDashedLine(bottomLeftFar, bottomLeftNear, cubeColor); geometryCache->renderDashedLine(topLeftNear, topRightNear, cubeColor); geometryCache->renderDashedLine(topRightNear, topRightFar, cubeColor); geometryCache->renderDashedLine(topRightFar, topLeftFar, cubeColor); geometryCache->renderDashedLine(topLeftFar, topLeftNear, cubeColor); geometryCache->renderDashedLine(bottomLeftNear, topLeftNear, cubeColor); geometryCache->renderDashedLine(bottomRightNear, topRightNear, cubeColor); geometryCache->renderDashedLine(bottomLeftFar, topLeftFar, cubeColor); geometryCache->renderDashedLine(bottomRightFar, topRightFar, cubeColor); } else { glScalef(dimensions.x, dimensions.y, dimensions.z); DependencyManager::get<DeferredLightingEffect>()->renderWireCube(1.0f, cubeColor); } } glPopMatrix(); glPopMatrix(); if (glower) { delete glower; } }
void Rectangle3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } float alpha = getAlpha(); xColor color = getColor(); const float MAX_COLOR = 255.0f; glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); glm::vec3 position = getPosition(); glm::vec3 center = getCenter(); glm::vec2 dimensions = getDimensions(); glm::vec2 halfDimensions = dimensions * 0.5f; glm::quat rotation = getRotation(); auto batch = args->_batch; if (batch) { Transform transform; transform.setTranslation(position); transform.setRotation(rotation); batch->setModelTransform(transform); if (getIsSolid()) { glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f); DependencyManager::get<GeometryCache>()->renderQuad(*batch, topLeft, bottomRight, rectangleColor); } else { auto geometryCache = DependencyManager::get<GeometryCache>(); if (getIsDashedLine()) { glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f); glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f); geometryCache->renderDashedLine(*batch, point1, point2, rectangleColor); geometryCache->renderDashedLine(*batch, point2, point3, rectangleColor); geometryCache->renderDashedLine(*batch, point3, point4, rectangleColor); geometryCache->renderDashedLine(*batch, point4, point1, rectangleColor); } else { if (halfDimensions != _previousHalfDimensions) { QVector<glm::vec3> border; border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f); border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f); border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f); border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); geometryCache->updateVertices(_geometryCacheID, border, rectangleColor); _previousHalfDimensions = halfDimensions; } geometryCache->renderVertices(*batch, gpu::LINE_STRIP, _geometryCacheID); } } } else { glDisable(GL_LIGHTING); float glowLevel = getGlowLevel(); Glower* glower = NULL; if (glowLevel > 0.0f) { glower = new Glower(glowLevel); } glPushMatrix(); glTranslatef(position.x, position.y, position.z); glm::vec3 axis = glm::axis(rotation); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); glPushMatrix(); glm::vec3 positionToCenter = center - position; glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); //glScalef(dimensions.x, dimensions.y, 1.0f); glLineWidth(_lineWidth); auto geometryCache = DependencyManager::get<GeometryCache>(); // for our overlay, is solid means we draw a solid "filled" rectangle otherwise we just draw a border line... if (getIsSolid()) { glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f); DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, rectangleColor); } else { if (getIsDashedLine()) { glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f); glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f); geometryCache->renderDashedLine(point1, point2, rectangleColor); geometryCache->renderDashedLine(point2, point3, rectangleColor); geometryCache->renderDashedLine(point3, point4, rectangleColor); geometryCache->renderDashedLine(point4, point1, rectangleColor); } else { if (halfDimensions != _previousHalfDimensions) { QVector<glm::vec3> border; border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f); border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f); border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f); border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); geometryCache->updateVertices(_geometryCacheID, border, rectangleColor); _previousHalfDimensions = halfDimensions; } geometryCache->renderVertices(gpu::LINE_STRIP, _geometryCacheID); } } glPopMatrix(); glPopMatrix(); if (glower) { delete glower; } } }
void Circle3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } float alpha = getAlpha(); if (alpha == 0.0) { return; // do nothing if our alpha is 0, we're not visible } 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; //const int slices = 15; xColor color = getColor(); const float MAX_COLOR = 255.0f; glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); glDisable(GL_LIGHTING); glm::vec3 position = getPosition(); glm::vec3 center = getCenter(); glm::vec2 dimensions = getDimensions(); glm::quat rotation = getRotation(); float glowLevel = getGlowLevel(); Glower* glower = NULL; if (glowLevel > 0.0f) { glower = new Glower(glowLevel); } glPushMatrix(); glTranslatef(position.x, position.y, position.z); glm::vec3 axis = glm::axis(rotation); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); glPushMatrix(); glm::vec3 positionToCenter = center - position; glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); glScalef(dimensions.x, dimensions.y, 1.0f); // Create the circle in the coordinates origin float outerRadius = getOuterRadius(); float innerRadius = getInnerRadius(); // only used in solid case float startAt = getStartAt(); float endAt = getEndAt(); glLineWidth(_lineWidth); // 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()) { glBegin(GL_QUAD_STRIP); float angle = startAt; float angleInRadians = glm::radians(angle); glm::vec2 firstInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 firstOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(firstInnerPoint.x, firstInnerPoint.y); glVertex2f(firstOuterPoint.x, firstOuterPoint.y); while (angle < endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 thisOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(thisOuterPoint.x, thisOuterPoint.y); glVertex2f(thisInnerPoint.x, thisInnerPoint.y); angle += SLICE_ANGLE; } // get the last slice portion.... angle = endAt; angleInRadians = glm::radians(angle); glm::vec2 lastInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 lastOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(lastOuterPoint.x, lastOuterPoint.y); glVertex2f(lastInnerPoint.x, lastInnerPoint.y); glEnd(); } else { if (getIsDashedLine()) { glBegin(GL_LINES); } else { glBegin(GL_LINE_STRIP); } float angle = startAt; float angleInRadians = glm::radians(angle); glm::vec2 firstPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(firstPoint.x, firstPoint.y); while (angle < endAt) { angle += SLICE_ANGLE; angleInRadians = glm::radians(angle); glm::vec2 thisPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(thisPoint.x, thisPoint.y); if (getIsDashedLine()) { angle += SLICE_ANGLE / 2.0f; // short gap angleInRadians = glm::radians(angle); glm::vec2 dashStartPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(dashStartPoint.x, dashStartPoint.y); } } // get the last slice portion.... angle = endAt; angleInRadians = glm::radians(angle); glm::vec2 lastOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(lastOuterPoint.x, lastOuterPoint.y); glEnd(); } // draw our tick marks // 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 (getHasTickMarks()) { glBegin(GL_LINES); // draw our major tick marks if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) { xColor color = getMajorTickMarksColor(); glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); float tickMarkAngle = getMajorTickMarksAngle(); float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle; float angleInRadians = glm::radians(angle); float tickMarkLength = getMajorTickMarksLength(); float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; float endRadius = startRadius + tickMarkLength; while (angle <= endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius); glVertex2f(thisPointA.x, thisPointA.y); glVertex2f(thisPointB.x, thisPointB.y); angle += tickMarkAngle; } } // draw our minor tick marks if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) { xColor color = getMinorTickMarksColor(); glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); float tickMarkAngle = getMinorTickMarksAngle(); float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle; float angleInRadians = glm::radians(angle); float tickMarkLength = getMinorTickMarksLength(); float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; float endRadius = startRadius + tickMarkLength; while (angle <= endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius); glVertex2f(thisPointA.x, thisPointA.y); glVertex2f(thisPointB.x, thisPointB.y); angle += tickMarkAngle; } } glEnd(); } glPopMatrix(); glPopMatrix(); if (glower) { delete glower; } }
void Circle3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } float alpha = getAlpha(); if (alpha == 0.0) { 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); 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; //const int slices = 15; xColor color = getColor(); const float MAX_COLOR = 255.0f; glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); glDisable(GL_LIGHTING); glm::vec3 position = getPosition(); glm::vec3 center = getCenter(); glm::vec2 dimensions = getDimensions(); glm::quat rotation = getRotation(); float glowLevel = getGlowLevel(); Glower* glower = NULL; if (glowLevel > 0.0f) { glower = new Glower(glowLevel); } glPushMatrix(); glTranslatef(position.x, position.y, position.z); glm::vec3 axis = glm::axis(rotation); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); glPushMatrix(); glm::vec3 positionToCenter = center - position; glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); glScalef(dimensions.x, dimensions.y, 1.0f); glLineWidth(_lineWidth); auto geometryCache = DependencyManager::get<GeometryCache>(); // 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) { _quadVerticesID = geometryCache->allocateID(); } if (geometryChanged) { QVector<glm::vec2> points; float angle = startAt; float angleInRadians = glm::radians(angle); glm::vec2 firstInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 firstOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << firstInnerPoint << firstOuterPoint; while (angle < endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 thisOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << thisOuterPoint << thisInnerPoint; angle += SLICE_ANGLE; } // get the last slice portion.... angle = endAt; angleInRadians = glm::radians(angle); glm::vec2 lastInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 lastOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << lastOuterPoint << lastInnerPoint; geometryCache->updateVertices(_quadVerticesID, points); } geometryCache->renderVertices(GL_QUAD_STRIP, _quadVerticesID); } else { if (_lineVerticesID == GeometryCache::UNKNOWN_ID) { _lineVerticesID = geometryCache->allocateID(); } if (geometryChanged) { QVector<glm::vec2> points; float angle = startAt; float angleInRadians = glm::radians(angle); glm::vec2 firstPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << firstPoint; while (angle < endAt) { angle += SLICE_ANGLE; angleInRadians = glm::radians(angle); glm::vec2 thisPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << thisPoint; if (getIsDashedLine()) { angle += SLICE_ANGLE / 2.0f; // short gap angleInRadians = glm::radians(angle); glm::vec2 dashStartPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << dashStartPoint; } } // get the last slice portion.... angle = endAt; angleInRadians = glm::radians(angle); glm::vec2 lastPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << lastPoint; geometryCache->updateVertices(_lineVerticesID, points); } if (getIsDashedLine()) { geometryCache->renderVertices(GL_LINES, _lineVerticesID); } else { geometryCache->renderVertices(GL_LINE_STRIP, _lineVerticesID); } } // draw our tick marks // 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 (getHasTickMarks()) { if (_majorTicksVerticesID == GeometryCache::UNKNOWN_ID) { _majorTicksVerticesID = geometryCache->allocateID(); } if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) { _minorTicksVerticesID = geometryCache->allocateID(); } if (geometryChanged) { QVector<glm::vec2> majorPoints; QVector<glm::vec2> minorPoints; // draw our major tick marks if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) { float tickMarkAngle = getMajorTickMarksAngle(); float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle; float angleInRadians = glm::radians(angle); float tickMarkLength = getMajorTickMarksLength(); float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; float endRadius = startRadius + tickMarkLength; while (angle <= endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius); majorPoints << thisPointA << thisPointB; angle += tickMarkAngle; } } // draw our minor tick marks if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) { float tickMarkAngle = getMinorTickMarksAngle(); float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle; float angleInRadians = glm::radians(angle); float tickMarkLength = getMinorTickMarksLength(); float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; float endRadius = startRadius + tickMarkLength; while (angle <= endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius); minorPoints << thisPointA << thisPointB; angle += tickMarkAngle; } } geometryCache->updateVertices(_majorTicksVerticesID, majorPoints); geometryCache->updateVertices(_minorTicksVerticesID, minorPoints); } xColor majorColor = getMajorTickMarksColor(); glColor4f(majorColor.red / MAX_COLOR, majorColor.green / MAX_COLOR, majorColor.blue / MAX_COLOR, alpha); geometryCache->renderVertices(GL_LINES, _majorTicksVerticesID); xColor minorColor = getMinorTickMarksColor(); glColor4f(minorColor.red / MAX_COLOR, minorColor.green / MAX_COLOR, minorColor.blue / MAX_COLOR, alpha); geometryCache->renderVertices(GL_LINES, _minorTicksVerticesID); } glPopMatrix(); glPopMatrix(); if (geometryChanged) { _lastStartAt = startAt; _lastEndAt = endAt; _lastInnerRadius = innerRadius; _lastOuterRadius = outerRadius; } if (glower) { delete glower; } }