From 67473ac2541bc4a088ef4acce098a07efac569e3 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 19 Jun 2015 15:37:05 +0200 Subject: [PATCH 1/2] Fix rotation handle crash --- interface/src/ui/overlays/Circle3DOverlay.cpp | 356 +++++++++--------- 1 file changed, 168 insertions(+), 188 deletions(-) diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 77debf304f..d8b481d75f 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -11,6 +11,7 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" +#include #include #include #include @@ -101,206 +102,185 @@ void Circle3DOverlay::render(RenderArgs* args) { bool colorChanged = colorX.red != _lastColor.red || colorX.green != _lastColor.green || colorX.blue != _lastColor.blue; _lastColor = colorX; - 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 / 2.0f, dimensions.y / 2.0f, 1.0f); - - glLineWidth(_lineWidth); - - auto geometryCache = DependencyManager::get(); - - // 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 points; - - float angle = startAt; - float angleInRadians = glm::radians(angle); - glm::vec2 firstInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); - glm::vec2 firstOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); - - points << firstInnerPoint << firstOuterPoint; - - while (angle < endAt) { - angleInRadians = glm::radians(angle); - glm::vec2 thisInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); - glm::vec2 thisOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); - - points << thisOuterPoint << thisInnerPoint; - - angle += SLICE_ANGLE; - } - - // 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 << lastOuterPoint << lastInnerPoint; - - geometryCache->updateVertices(_quadVerticesID, points, color); - } - - geometryCache->renderVertices(gpu::QUAD_STRIP, _quadVerticesID); - - } else { - if (_lineVerticesID == GeometryCache::UNKNOWN_ID) { - _lineVerticesID = geometryCache->allocateID(); - } - - if (geometryChanged || colorChanged) { - QVector 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); - } + auto geometryCache = DependencyManager::get(); + Transform transform; + transform.setTranslation(getCenter()); + transform.setRotation(getRotation()); + transform.setScale(glm::vec3(getDimensions(), 0.01f)); + + + auto& batch = *args->_batch; + batch._glLineWidth(_lineWidth); + batch.setModelTransform(transform); + DependencyManager::get()->bindSimpleProgram(batch); + + // 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 points; + + float angle = startAt; + float angleInRadians = glm::radians(angle); + glm::vec2 firstInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); + glm::vec2 firstOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); + + points << firstInnerPoint << firstOuterPoint; + + while (angle < endAt) { + angleInRadians = glm::radians(angle); + glm::vec2 thisInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius); + glm::vec2 thisOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); + + points << thisOuterPoint << thisInnerPoint; + + angle += SLICE_ANGLE; + } + + // 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 << lastOuterPoint << lastInnerPoint; + + geometryCache->updateVertices(_quadVerticesID, points, color); + } + + geometryCache->renderVertices(batch, gpu::QUAD_STRIP, _quadVerticesID); + + } else { + if (_lineVerticesID == GeometryCache::UNKNOWN_ID) { + _lineVerticesID = geometryCache->allocateID(); + } + + if (geometryChanged || colorChanged) { + QVector 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()) { - geometryCache->renderVertices(gpu::LINES, _lineVerticesID); - } else { - geometryCache->renderVertices(gpu::LINE_STRIP, _lineVerticesID); + angle += SLICE_ANGLE / 2.0f; // short gap + angleInRadians = glm::radians(angle); + glm::vec2 dashStartPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius); + points << dashStartPoint; } } - - // 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(); + + // 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 majorPoints; + QVector 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; } - if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) { - _minorTicksVerticesID = geometryCache->allocateID(); - } - - if (geometryChanged) { - QVector majorPoints; - QVector 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(gpu::LINES, _majorTicksVerticesID); - - geometryCache->renderVertices(gpu::LINES, _minorTicksVerticesID); } - - - glPopMatrix(); - glPopMatrix(); - + + // 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; } - - if (glower) { - delete glower; - } } void Circle3DOverlay::setProperties(const QScriptValue &properties) { From 9c7f24eeb6385e8c34cf6f2877a519d4883d29bc Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 19 Jun 2015 16:50:38 +0200 Subject: [PATCH 2/2] Add culled option for simple programs --- interface/src/ui/overlays/Circle3DOverlay.cpp | 2 +- .../src/DeferredLightingEffect.cpp | 27 ++++++++++++++++--- .../render-utils/src/DeferredLightingEffect.h | 4 ++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index d8b481d75f..034095291f 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -113,7 +113,7 @@ void Circle3DOverlay::render(RenderArgs* args) { auto& batch = *args->_batch; batch._glLineWidth(_lineWidth); batch.setModelTransform(transform); - DependencyManager::get()->bindSimpleProgram(batch); + DependencyManager::get()->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... diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index f0a52af086..5ebd798c19 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -61,15 +61,26 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { gpu::Shader::BindingSet slotBindings; gpu::Shader::makeProgram(*program, slotBindings); gpu::Shader::makeProgram(*programTextured, slotBindings); - + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setCullMode(gpu::State::CULL_BACK); state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + + + gpu::StatePointer stateCullNone = gpu::StatePointer(new gpu::State()); + stateCullNone->setCullMode(gpu::State::CULL_NONE); + stateCullNone->setDepthTest(true, true, gpu::LESS_EQUAL); + stateCullNone->setBlendFunction(false, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + _simpleProgram = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); + _simpleProgramCullNone = gpu::PipelinePointer(gpu::Pipeline::create(program, stateCullNone)); _simpleProgramTextured = gpu::PipelinePointer(gpu::Pipeline::create(programTextured, state)); + _simpleProgramTexturedCullNone = gpu::PipelinePointer(gpu::Pipeline::create(programTextured, stateCullNone)); _viewState = viewState; loadLightProgram(directional_light_frag, false, _directionalLight, _directionalLightLocations); @@ -106,13 +117,21 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET)); } -void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured) { +void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled) { // DependencyManager::get()->setPrimaryDrawBuffers(batch, true, true, true); if (textured) { - batch.setPipeline(_simpleProgramTextured); + if (culled) { + batch.setPipeline(_simpleProgramTextured); + } else { + batch.setPipeline(_simpleProgramTexturedCullNone); + } } else { - batch.setPipeline(_simpleProgram); + if (culled) { + batch.setPipeline(_simpleProgram); + } else { + batch.setPipeline(_simpleProgramCullNone); + } } } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index bd7fcb286b..e841fed321 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -34,7 +34,7 @@ public: void init(AbstractViewStateInterface* viewState); /// Sets up the state necessary to render static untextured geometry with the simple program. - void bindSimpleProgram(gpu::Batch& batch, bool textured = false); + void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true); /// Tears down the state necessary to render static untextured geometry with the simple program. void releaseSimpleProgram(gpu::Batch& batch); @@ -100,7 +100,9 @@ private: static void loadLightProgram(const char* fragSource, bool limited, ProgramObject& program, LightLocations& locations); gpu::PipelinePointer _simpleProgram; + gpu::PipelinePointer _simpleProgramCullNone; gpu::PipelinePointer _simpleProgramTextured; + gpu::PipelinePointer _simpleProgramTexturedCullNone; ProgramObject _directionalSkyboxLight; LightLocations _directionalSkyboxLightLocations;