From 11dc3cd2611824001ed8caf519467b931ab52164 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 8 Jan 2016 16:41:19 -0800 Subject: [PATCH] Move primitive rendering out of DeferredLightingEffect --- interface/src/Application.cpp | 2 +- interface/src/Util.cpp | 16 +- interface/src/avatar/Avatar.cpp | 15 +- interface/src/avatar/Hand.cpp | 5 +- interface/src/avatar/Head.cpp | 13 +- interface/src/avatar/SkeletonModel.cpp | 8 +- interface/src/ui/ApplicationOverlay.cpp | 1 - interface/src/ui/overlays/Circle3DOverlay.cpp | 3 +- interface/src/ui/overlays/Cube3DOverlay.cpp | 5 +- interface/src/ui/overlays/Image3DOverlay.cpp | 3 +- interface/src/ui/overlays/Line3DOverlay.cpp | 3 +- interface/src/ui/overlays/Sphere3DOverlay.cpp | 6 +- interface/src/ui/overlays/Text3DOverlay.cpp | 3 +- interface/src/ui/overlays/Web3DOverlay.cpp | 4 +- .../src/EntityTreeRenderer.cpp | 1 - .../src/RenderableBoxEntityItem.cpp | 3 +- .../src/RenderableLightEntityItem.cpp | 2 +- .../src/RenderableLineEntityItem.cpp | 3 +- .../src/RenderableModelEntityItem.cpp | 3 +- .../RenderableParticleEffectEntityItem.cpp | 1 - .../src/RenderablePolyLineEntityItem.cpp | 1 - .../src/RenderablePolyVoxEntityItem.cpp | 1 - .../src/RenderableSphereEntityItem.cpp | 3 +- .../src/RenderableTextEntityItem.cpp | 3 +- .../src/RenderableWebEntityItem.cpp | 5 +- .../src/RenderableZoneEntityItem.cpp | 7 +- .../src/DeferredLightingEffect.cpp | 191 +----------------- .../render-utils/src/DeferredLightingEffect.h | 96 +-------- libraries/render-utils/src/GeometryCache.cpp | 184 +++++++++++++++++ libraries/render-utils/src/GeometryCache.h | 99 ++++++++- .../render-utils/src/MeshPartPayload.cpp | 2 +- libraries/render-utils/src/TextRenderer3D.cpp | 1 - 32 files changed, 333 insertions(+), 360 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2d57d5bd29..7134860df0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3611,7 +3611,7 @@ namespace render { PerformanceTimer perfTimer("worldBox"); auto& batch = *args->_batch; - DependencyManager::get()->bindSimpleProgram(batch); + DependencyManager::get()->bindSimpleProgram(batch); renderWorldBox(batch); } } diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 3d97d48f90..4983983c02 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -96,28 +95,27 @@ void renderWorldBox(gpu::Batch& batch) { geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY); - auto deferredLighting = DependencyManager::get(); - - deferredLighting->renderWireCubeInstance(batch, Transform(), GREY4); + + geometryCache->renderWireCubeInstance(batch, Transform(), GREY4); // Draw meter markers along the 3 axis to help with measuring things const float MARKER_DISTANCE = 1.0f; const float MARKER_RADIUS = 0.05f; transform = Transform().setScale(MARKER_RADIUS); - deferredLighting->renderSolidSphereInstance(batch, transform, RED); + geometryCache->renderSolidSphereInstance(batch, transform, RED); transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, 0.0f)).setScale(MARKER_RADIUS); - deferredLighting->renderSolidSphereInstance(batch, transform, RED); + geometryCache->renderSolidSphereInstance(batch, transform, RED); transform = Transform().setTranslation(glm::vec3(0.0f, MARKER_DISTANCE, 0.0f)).setScale(MARKER_RADIUS); - deferredLighting->renderSolidSphereInstance(batch, transform, GREEN); + geometryCache->renderSolidSphereInstance(batch, transform, GREEN); transform = Transform().setTranslation(glm::vec3(0.0f, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); - deferredLighting->renderSolidSphereInstance(batch, transform, BLUE); + geometryCache->renderSolidSphereInstance(batch, transform, BLUE); transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); - deferredLighting->renderSolidSphereInstance(batch, transform, GREY); + geometryCache->renderSolidSphereInstance(batch, transform, GREY); } // Return a random vector of average length 1 diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 4f19b33abf..7cde674e52 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -331,7 +331,6 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { if (glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), getPosition()) < 10.0f) { auto geometryCache = DependencyManager::get(); - auto deferredLighting = DependencyManager::get(); // render pointing lasers glm::vec3 laserColor = glm::vec3(1.0f, 0.0f, 1.0f); @@ -359,7 +358,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { pointerTransform.setTranslation(position); pointerTransform.setRotation(rotation); batch.setModelTransform(pointerTransform); - deferredLighting->bindSimpleProgram(batch); + geometryCache->bindSimpleProgram(batch); geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor); } } @@ -383,7 +382,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { pointerTransform.setTranslation(position); pointerTransform.setRotation(rotation); batch.setModelTransform(pointerTransform); - deferredLighting->bindSimpleProgram(batch); + geometryCache->bindSimpleProgram(batch); geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor); } } @@ -457,7 +456,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { Transform transform; transform.setTranslation(position); transform.postScale(INDICATOR_RADIUS); - DependencyManager::get()->renderSolidSphereInstance(batch, transform, LOOK_AT_INDICATOR_COLOR); + DependencyManager::get()->renderSolidSphereInstance(batch, transform, LOOK_AT_INDICATOR_COLOR); } // If the avatar is looking at me, indicate that they are @@ -485,7 +484,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { eyeDiameter = DEFAULT_EYE_DIAMETER; } - DependencyManager::get()->renderSolidSphereInstance(batch, + DependencyManager::get()->renderSolidSphereInstance(batch, Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT), glm::vec4(LOOKING_AT_ME_COLOR, alpha)); @@ -495,7 +494,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { if (eyeDiameter == 0.0f) { eyeDiameter = DEFAULT_EYE_DIAMETER; } - DependencyManager::get()->renderSolidSphereInstance(batch, + DependencyManager::get()->renderSolidSphereInstance(batch, Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT), glm::vec4(LOOKING_AT_ME_COLOR, alpha)); @@ -655,7 +654,7 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) { gpu::Batch& batch = *renderArgs->_batch; PROFILE_RANGE_BATCH(batch, __FUNCTION__); batch.setResourceTexture(0, _billboardTexture->getGPUTexture()); - DependencyManager::get()->bindSimpleProgram(batch, true); + DependencyManager::get()->bindSimpleProgram(batch, true); DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); } @@ -791,7 +790,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co { PROFILE_RANGE_BATCH(batch, __FUNCTION__":renderBevelCornersRect"); - DependencyManager::get()->bindSimpleProgram(batch, false, true, true, true); + DependencyManager::get()->bindSimpleProgram(batch, false, true, true, true); DependencyManager::get()->renderBevelCornersRect(batch, left, bottom, width, height, bevelDistance, backgroundColor); } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index fe03d22f0b..fba5e1ab13 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -14,7 +14,6 @@ #include #include -#include #include "Avatar.h" #include "AvatarManager.h" @@ -61,7 +60,7 @@ void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) { transform.setTranslation(position); transform.setRotation(palm.getRotation()); transform.postScale(SPHERE_RADIUS); - DependencyManager::get()->renderSolidSphereInstance(batch, transform, grayColor); + DependencyManager::get()->renderSolidSphereInstance(batch, transform, grayColor); // draw a green sphere at the old "finger tip" transform = Transform(); @@ -69,7 +68,7 @@ void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) { transform.setTranslation(position); transform.setRotation(palm.getRotation()); transform.postScale(SPHERE_RADIUS); - DependencyManager::get()->renderSolidSphereInstance(batch, transform, greenColor); + DependencyManager::get()->renderSolidSphereInstance(batch, transform, greenColor); } } diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index aa2d268f3d..61bc5c861e 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -11,8 +11,6 @@ #include #include -#include -#include #include #include @@ -451,12 +449,11 @@ void Head::renderLookatVectors(RenderArgs* renderArgs, glm::vec3 leftEyePosition batch.setModelTransform(transform); // FIXME: THe line width of 2.0f is not supported anymore, we ll need a workaround - auto deferredLighting = DependencyManager::get(); - deferredLighting->bindSimpleProgram(batch); - - auto geometryCache = DependencyManager::get(); glm::vec4 startColor(0.2f, 0.2f, 0.2f, 1.0f); glm::vec4 endColor(1.0f, 1.0f, 1.0f, 0.0f); + + auto geometryCache = DependencyManager::get(); + geometryCache->bindSimpleProgram(batch); geometryCache->renderLine(batch, leftEyePosition, lookatPosition, startColor, endColor, _leftEyeLookAtID); geometryCache->renderLine(batch, rightEyePosition, lookatPosition, startColor, endColor, _rightEyeLookAtID); } @@ -466,9 +463,9 @@ void Head::renderLookatTarget(RenderArgs* renderArgs, glm::vec3 lookatPosition) auto transform = Transform{}; transform.setTranslation(lookatPosition); - auto deferredLighting = DependencyManager::get(); + auto geometryCache = DependencyManager::get(); const float LOOK_AT_TARGET_RADIUS = 0.075f; transform.postScale(LOOK_AT_TARGET_RADIUS); const glm::vec4 LOOK_AT_TARGET_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f }; - deferredLighting->renderSolidSphereInstance(batch, transform, LOOK_AT_TARGET_COLOR); + geometryCache->renderSolidSphereInstance(batch, transform, LOOK_AT_TARGET_COLOR); } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 3cd74afb81..b7a154851f 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include "Application.h" @@ -347,11 +346,10 @@ void SkeletonModel::computeBoundingShape() { void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float scale, float alpha) { auto geometryCache = DependencyManager::get(); - auto deferredLighting = DependencyManager::get(); // draw a blue sphere at the capsule top point glm::vec3 topPoint = _translation + getRotation() * (scale * (_boundingCapsuleLocalOffset + (0.5f * _boundingCapsuleHeight) * Vectors::UNIT_Y)); - deferredLighting->renderSolidSphereInstance(batch, + geometryCache->renderSolidSphereInstance(batch, Transform().setTranslation(topPoint).postScale(scale * _boundingCapsuleRadius), glm::vec4(0.6f, 0.6f, 0.8f, alpha)); @@ -359,14 +357,14 @@ void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float scale glm::vec3 bottomPoint = topPoint - glm::vec3(0.0f, scale * _boundingCapsuleHeight, 0.0f); glm::vec3 axis = topPoint - bottomPoint; - deferredLighting->renderSolidSphereInstance(batch, + geometryCache->renderSolidSphereInstance(batch, Transform().setTranslation(bottomPoint).postScale(scale * _boundingCapsuleRadius), glm::vec4(0.8f, 0.8f, 0.6f, alpha)); // draw a green cylinder between the two points glm::vec3 origin(0.0f); batch.setModelTransform(Transform().setTranslation(bottomPoint)); - deferredLighting->bindSimpleProgram(batch); + geometryCache->bindSimpleProgram(batch); Avatar::renderJointConnectingCone(batch, origin, axis, scale * _boundingCapsuleRadius, scale * _boundingCapsuleRadius, glm::vec4(0.6f, 0.8f, 0.6f, alpha)); } diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index d16431e9fb..43966553de 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include #include diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 0b7da72d58..bbb9addc3d 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -10,7 +10,6 @@ #include "Circle3DOverlay.h" -#include #include #include @@ -106,7 +105,7 @@ void Circle3DOverlay::render(RenderArgs* args) { auto transform = _transform; transform.postScale(glm::vec3(getDimensions(), 1.0f)); batch.setModelTransform(transform); - DependencyManager::get()->bindSimpleProgram(batch, false, false); + 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/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 3ad887ca65..7688bce985 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -13,7 +13,6 @@ #include -#include #include #include #include @@ -61,7 +60,7 @@ void Cube3DOverlay::render(RenderArgs* args) { // } transform.setScale(dimensions); - DependencyManager::get()->renderSolidCubeInstance(*batch, transform, cubeColor); + DependencyManager::get()->renderSolidCubeInstance(*batch, transform, cubeColor); } else { if (getIsDashedLine()) { @@ -99,7 +98,7 @@ void Cube3DOverlay::render(RenderArgs* args) { } else { batch->setModelTransform(Transform()); transform.setScale(dimensions); - DependencyManager::get()->renderWireCubeInstance(*batch, transform, cubeColor); + DependencyManager::get()->renderWireCubeInstance(*batch, transform, cubeColor); } } } diff --git a/interface/src/ui/overlays/Image3DOverlay.cpp b/interface/src/ui/overlays/Image3DOverlay.cpp index f1e0f08a3a..8ce8bf7a5f 100644 --- a/interface/src/ui/overlays/Image3DOverlay.cpp +++ b/interface/src/ui/overlays/Image3DOverlay.cpp @@ -14,7 +14,6 @@ #include -#include #include #include #include @@ -96,7 +95,7 @@ void Image3DOverlay::render(RenderArgs* args) { batch->setModelTransform(transform); batch->setResourceTexture(0, _texture->getGPUTexture()); - DependencyManager::get()->bindSimpleProgram(*batch, true, false, _emissive, true); + DependencyManager::get()->bindSimpleProgram(*batch, true, false, _emissive, true); DependencyManager::get()->renderQuad( *batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha) diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index 9dc609af31..ed97b95de0 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -12,7 +12,6 @@ #include #include -#include QString const Line3DOverlay::TYPE = "line3d"; @@ -54,7 +53,7 @@ void Line3DOverlay::render(RenderArgs* args) { auto batch = args->_batch; if (batch) { batch->setModelTransform(_transform); - DependencyManager::get()->bindSimpleProgram(*batch); + DependencyManager::get()->bindSimpleProgram(*batch); if (getIsDashedLine()) { // TODO: add support for color to renderDashedLine() diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index 7caff3ea04..63ed7fe31d 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -45,12 +44,11 @@ void Sphere3DOverlay::render(RenderArgs* args) { Transform transform = _transform; transform.postScale(getDimensions() * SPHERE_OVERLAY_SCALE); if (_isSolid) { - DependencyManager::get()->renderSolidSphereInstance(*batch, transform, sphereColor); + DependencyManager::get()->renderSolidSphereInstance(*batch, transform, sphereColor); } else { - DependencyManager::get()->renderWireSphereInstance(*batch, transform, sphereColor); + DependencyManager::get()->renderWireSphereInstance(*batch, transform, sphereColor); } } - } Sphere3DOverlay* Sphere3DOverlay::createClone() const { diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 8c448234ad..2e5110951d 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -10,7 +10,6 @@ #include "Text3DOverlay.h" -#include #include #include #include @@ -101,7 +100,7 @@ void Text3DOverlay::render(RenderArgs* args) { glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND); glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND); - DependencyManager::get()->bindSimpleProgram(batch, false, true, false, true); + DependencyManager::get()->bindSimpleProgram(batch, false, true, false, true); DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, quadColor); // Same font properties as textSize() diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 1088473a25..1ec502139b 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -16,8 +16,6 @@ #include #include - -#include #include #include #include @@ -103,7 +101,7 @@ void Web3DOverlay::render(RenderArgs* args) { } batch.setModelTransform(transform); - DependencyManager::get()->bindSimpleProgram(batch, true, false, false, true); + DependencyManager::get()->bindSimpleProgram(batch, true, false, false, true); DependencyManager::get()->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color); batch.setResourceTexture(0, args->_whiteTexture); // restore default white color after me } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 07d9031f41..6beba4eefa 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp b/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp index 4de363016b..1b1437a7d9 100644 --- a/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp @@ -15,7 +15,6 @@ #include -#include #include #include #include @@ -69,7 +68,7 @@ void RenderableBoxEntityItem::render(RenderArgs* args) { batch._glColor4f(color.r, color.g, color.b, color.a); DependencyManager::get()->renderCube(batch); } else { - DependencyManager::get()->renderSolidCubeInstance(batch, transToCenter, cubeColor); + DependencyManager::get()->renderSolidCubeInstance(batch, transToCenter, cubeColor); } static const auto triCount = DependencyManager::get()->getCubeTriangleCount(); args->_details._trianglesRendered += (int)triCount; diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp index 5b8891d1f2..39182f322c 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp @@ -51,7 +51,7 @@ void RenderableLightEntityItem::render(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; batch.setModelTransform(getTransformToCenter()); - DependencyManager::get()->renderWireSphere(batch, 0.5f, 15, 15, glm::vec4(color, 1.0f)); + DependencyManager::get()->renderWireSphere(batch, 0.5f, 15, 15, glm::vec4(color, 1.0f)); #endif }; diff --git a/libraries/entities-renderer/src/RenderableLineEntityItem.cpp b/libraries/entities-renderer/src/RenderableLineEntityItem.cpp index 8eb3ea8754..b8815aab7c 100644 --- a/libraries/entities-renderer/src/RenderableLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableLineEntityItem.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include "RenderableLineEntityItem.h" @@ -53,7 +52,7 @@ void RenderableLineEntityItem::render(RenderArgs* args) { batch.setModelTransform(transform); if (getLinePoints().size() > 1) { - DependencyManager::get()->bindSimpleProgram(batch); + DependencyManager::get()->bindSimpleProgram(batch); DependencyManager::get()->renderVertices(batch, gpu::LINE_STRIP, _lineVerticesID); } }; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index f5090cc20c..7424180437 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -432,7 +431,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { auto shapeTransform = getTransformToCenter(success); if (success) { batch.setModelTransform(Transform()); // we want to include the scale as well - DependencyManager::get()->renderWireCubeInstance(batch, shapeTransform, greenColor); + DependencyManager::get()->renderWireCubeInstance(batch, shapeTransform, greenColor); } } } diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 115eba0a05..e757f5c68a 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include #include diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index fd28bc043d..600b876d39 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include "RenderablePolyLineEntityItem.h" diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 1048f594f4..1029f3b3af 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -27,7 +27,6 @@ #pragma GCC diagnostic pop #endif -#include #include #include #include diff --git a/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp b/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp index 9bed5b3bb0..9f16de0db1 100644 --- a/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -73,7 +72,7 @@ void RenderableSphereEntityItem::render(RenderArgs* args) { DependencyManager::get()->renderSphere(batch); } else { batch.setModelTransform(Transform()); - DependencyManager::get()->renderSolidSphereInstance(batch, modelTransform, sphereColor); + DependencyManager::get()->renderSolidSphereInstance(batch, modelTransform, sphereColor); } static const auto triCount = DependencyManager::get()->getSphereTriangleCount(); args->_details._trianglesRendered += (int)triCount; diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index d88b4d5f0a..5cf31c15e0 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -11,7 +11,6 @@ #include -#include #include #include #include @@ -63,7 +62,7 @@ void RenderableTextEntityItem::render(RenderArgs* args) { batch.setModelTransform(transformToTopLeft); - DependencyManager::get()->bindSimpleProgram(batch, false, false, false, true); + DependencyManager::get()->bindSimpleProgram(batch, false, false, false, true); DependencyManager::get()->renderQuad(batch, minCorner, maxCorner, backgroundColor); float scale = _lineHeight / _textRenderer->getFontSize(); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 979ec32878..ce89197069 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -15,7 +15,6 @@ #include -#include #include #include #include @@ -69,7 +68,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) { gpu::Batch& batch = *args->_batch; batch.setModelTransform(getTransformToCenter()); // we want to include the scale as well glm::vec4 cubeColor{ 1.0f, 0.0f, 0.0f, 1.0f}; - DependencyManager::get()->renderWireCube(batch, 1.0f, cubeColor); + DependencyManager::get()->renderWireCube(batch, 1.0f, cubeColor); } #endif @@ -201,7 +200,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) { textured = emissive = true; } - DependencyManager::get()->bindSimpleProgram(batch, textured, culled, emissive); + DependencyManager::get()->bindSimpleProgram(batch, textured, culled, emissive); DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f)); } diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index eb01bd551e..9396933fc6 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -140,12 +139,12 @@ void RenderableZoneEntityItem::render(RenderArgs* args) { if (!success) { break; } - auto deferredLightingEffect = DependencyManager::get(); + auto geometryCache = DependencyManager::get(); if (getShapeType() == SHAPE_TYPE_SPHERE) { shapeTransform.postScale(SPHERE_ENTITY_SCALE); - deferredLightingEffect->renderWireSphereInstance(batch, shapeTransform, DEFAULT_COLOR); + geometryCache->renderWireSphereInstance(batch, shapeTransform, DEFAULT_COLOR); } else { - deferredLightingEffect->renderWireCubeInstance(batch, shapeTransform, DEFAULT_COLOR); + geometryCache->renderWireCubeInstance(batch, shapeTransform, DEFAULT_COLOR); } break; } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 5e6d9c2a10..d5dd53c252 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -24,11 +24,6 @@ #include "TextureCache.h" #include "FramebufferCache.h" - -#include "simple_vert.h" -#include "simple_textured_frag.h" -#include "simple_textured_emisive_frag.h" - #include "deferred_light_vert.h" #include "deferred_light_limited_vert.h" #include "deferred_light_spot_vert.h" @@ -53,47 +48,7 @@ struct LightLocations { static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations); -gpu::PipelinePointer DeferredLightingEffect::getPipeline(SimpleProgramKey config) { - auto it = _simplePrograms.find(config); - if (it != _simplePrograms.end()) { - return it.value(); - } - - auto state = std::make_shared(); - if (config.isCulled()) { - state->setCullMode(gpu::State::CULL_BACK); - } else { - state->setCullMode(gpu::State::CULL_NONE); - } - state->setDepthTest(true, true, gpu::LESS_EQUAL); - if (config.hasDepthBias()) { - state->setDepthBias(1.0f); - state->setDepthBiasSlopeScale(1.0f); - } - 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::ShaderPointer program = (config.isEmissive()) ? _emissiveShader : _simpleShader; - gpu::PipelinePointer pipeline = gpu::Pipeline::create(program, state); - _simplePrograms.insert(config, pipeline); - return pipeline; -} - void DeferredLightingEffect::init() { - auto VS = gpu::Shader::createVertex(std::string(simple_vert)); - auto PS = gpu::Shader::createPixel(std::string(simple_textured_frag)); - auto PSEmissive = gpu::Shader::createPixel(std::string(simple_textured_emisive_frag)); - - _simpleShader = gpu::Shader::createProgram(VS, PS); - _emissiveShader = gpu::Shader::createProgram(VS, PSEmissive); - - gpu::Shader::BindingSet slotBindings; - slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT)); - gpu::Shader::makeProgram(*_simpleShader, slotBindings); - gpu::Shader::makeProgram(*_emissiveShader, slotBindings); - - _directionalLightLocations = std::make_shared(); _directionalAmbientSphereLightLocations = std::make_shared(); _directionalSkyboxLightLocations = std::make_shared(); @@ -123,144 +78,6 @@ void DeferredLightingEffect::init() { lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET)); } - - -gpu::PipelinePointer DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled, - bool emissive, bool depthBias) { - SimpleProgramKey config{textured, culled, emissive, depthBias}; - gpu::PipelinePointer pipeline = getPipeline(config); - batch.setPipeline(pipeline); - - gpu::ShaderPointer program = (config.isEmissive()) ? _emissiveShader : _simpleShader; - - if (!config.isTextured()) { - // If it is not textured, bind white texture and keep using textured pipeline - batch.setResourceTexture(0, DependencyManager::get()->getWhiteTexture()); - } - - batch.setResourceTexture(NORMAL_FITTING_MAP_SLOT, DependencyManager::get()->getNormalFittingTexture()); - return pipeline; -} - -uint32_t toCompactColor(const glm::vec4& color) { - uint32_t 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); - return compactColor; -} - -static const size_t INSTANCE_TRANSFORM_BUFFER = 0; -static const size_t INSTANCE_COLOR_BUFFER = 1; - -template -void renderInstances(const std::string& name, gpu::Batch& batch, const Transform& transform, const glm::vec4& color, F f) { - { - gpu::BufferPointer instanceTransformBuffer = batch.getNamedBuffer(name, INSTANCE_TRANSFORM_BUFFER); - glm::mat4 glmTransform; - instanceTransformBuffer->append(transform.getMatrix(glmTransform)); - - gpu::BufferPointer instanceColorBuffer = batch.getNamedBuffer(name, INSTANCE_COLOR_BUFFER); - auto compactColor = toCompactColor(color); - instanceColorBuffer->append(compactColor); - } - - auto that = DependencyManager::get(); - batch.setupNamedCalls(name, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - auto pipeline = that->bindSimpleProgram(batch); - auto location = pipeline->getProgram()->getUniforms().findLocation("Instanced"); - - batch._glUniform1i(location, 1); - f(batch, data); - batch._glUniform1i(location, 0); - }); -} - -void DeferredLightingEffect::renderSolidSphereInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { - static const std::string INSTANCE_NAME = __FUNCTION__; - renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - DependencyManager::get()->renderShapeInstances(batch, GeometryCache::Sphere, data._count, - data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); - }); -} - -void DeferredLightingEffect::renderWireSphereInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { - static const std::string INSTANCE_NAME = __FUNCTION__; - renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - DependencyManager::get()->renderWireShapeInstances(batch, GeometryCache::Sphere, data._count, - data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); - }); -} - -// Enable this in a debug build to cause 'box' entities to iterate through all the -// available shape types, both solid and wireframes -//#define DEBUG_SHAPES - -void DeferredLightingEffect::renderSolidCubeInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { - static const std::string INSTANCE_NAME = __FUNCTION__; - -#ifdef DEBUG_SHAPES - static auto startTime = usecTimestampNow(); - renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - - auto usecs = usecTimestampNow(); - usecs -= startTime; - auto msecs = usecs / USECS_PER_MSEC; - float seconds = msecs; - seconds /= MSECS_PER_SECOND; - float fractionalSeconds = seconds - floor(seconds); - int shapeIndex = (int)seconds; - - // Every second we flip to the next shape. - static const int SHAPE_COUNT = 5; - GeometryCache::Shape shapes[SHAPE_COUNT] = { - GeometryCache::Cube, - GeometryCache::Tetrahedron, - GeometryCache::Sphere, - GeometryCache::Icosahedron, - GeometryCache::Line, - }; - - shapeIndex %= SHAPE_COUNT; - GeometryCache::Shape shape = shapes[shapeIndex]; - - // For the first half second for a given shape, show the wireframe, for the second half, show the solid. - if (fractionalSeconds > 0.5f) { - DependencyManager::get()->renderShapeInstances(batch, shape, data._count, - data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); - } else { - DependencyManager::get()->renderWireShapeInstances(batch, shape, data._count, - data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); - } - }); -#else - renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - DependencyManager::get()->renderCubeInstances(batch, data._count, - data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); - }); -#endif -} - -void DeferredLightingEffect::renderWireCubeInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { - static const std::string INSTANCE_NAME = __FUNCTION__; - renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - DependencyManager::get()->renderWireCubeInstances(batch, data._count, - data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); - }); -} - -void DeferredLightingEffect::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, const glm::vec3& maxCorner, - const glm::vec4& color) { - bindSimpleProgram(batch); - DependencyManager::get()->renderQuad(batch, minCorner, maxCorner, color); -} - -void DeferredLightingEffect::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, - const glm::vec4& color1, const glm::vec4& color2) { - bindSimpleProgram(batch); - DependencyManager::get()->renderLine(batch, p1, p2, color1, color2); -} - void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& color, float intensity) { addSpotLight(position, radius, color, intensity); @@ -663,12 +480,12 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2)); slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), 3)); slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), 5)); - const int LIGHT_GPU_SLOT = 3; + static const int LIGHT_GPU_SLOT = 3; slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT)); - const int ATMOSPHERE_GPU_SLOT = 4; + static const int ATMOSPHERE_GPU_SLOT = 4; slotBindings.insert(gpu::Shader::Binding(std::string("atmosphereBufferUnit"), ATMOSPHERE_GPU_SLOT)); - - slotBindings.insert(gpu::Shader::Binding(std::string("deferredTransformBuffer"), DeferredLightingEffect::DEFERRED_TRANSFORM_BUFFER_SLOT)); + static const int DEFERRED_TRANSFORM_BUFFER_SLOT = 2; + slotBindings.insert(gpu::Shader::Binding(std::string("deferredTransformBuffer"), DEFERRED_TRANSFORM_BUFFER_SLOT)); gpu::Shader::makeProgram(*program, slotBindings); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index f00f558122..cb746153a1 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -21,10 +21,7 @@ #include "model/Stage.h" #include "model/Geometry.h" -#include "render/ShapePipeline.h" - class RenderArgs; -class SimpleProgramKey; struct LightLocations; using LightLocationsPtr = std::shared_ptr; /// Handles deferred lighting for the bits that require it (voxels...) @@ -32,42 +29,7 @@ class DeferredLightingEffect : public Dependency { SINGLETON_DEPENDENCY public: - static const int NORMAL_FITTING_MAP_SLOT = render::ShapePipeline::Slot::NORMAL_FITTING_MAP; - static const int DEFERRED_TRANSFORM_BUFFER_SLOT = 2; - void init(); - - /// Sets up the state necessary to render static untextured geometry with the simple program. - gpu::PipelinePointer bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true, - bool emissive = false, bool depthBias = false); - - void renderSolidSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); - void renderSolidSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { - renderSolidSphereInstance(batch, xfm, glm::vec4(color, 1.0)); - } - - void renderWireSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); - void renderWireSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { - renderWireSphereInstance(batch, xfm, glm::vec4(color, 1.0)); - } - - void renderSolidCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); - void renderSolidCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { - renderSolidCubeInstance(batch, xfm, glm::vec4(color, 1.0)); - } - - void renderWireCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); - void renderWireCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { - renderWireCubeInstance(batch, xfm, glm::vec4(color, 1.0)); - } - - - //// Renders a quad with the simple program. - void renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color); - - //// Renders a line with the simple program. - void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, - const glm::vec4& color1, const glm::vec4& color2); /// Adds a point light to render for the current frame. void addPointLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(0.0f, 0.0f, 0.0f), @@ -90,17 +52,10 @@ public: void setGlobalSkybox(const model::SkyboxPointer& skybox); private: - DeferredLightingEffect() {} - virtual ~DeferredLightingEffect() { } + DeferredLightingEffect() = default; model::MeshPointer _spotLightMesh; model::MeshPointer getSpotLightMesh(); - - gpu::PipelinePointer getPipeline(SimpleProgramKey config); - - gpu::ShaderPointer _simpleShader; - gpu::ShaderPointer _emissiveShader; - QHash _simplePrograms; gpu::PipelinePointer _directionalSkyboxLight; LightLocationsPtr _directionalSkyboxLightLocations; @@ -160,53 +115,4 @@ private: UniformBufferView _deferredTransformBuffer[2]; }; -class SimpleProgramKey { -public: - enum FlagBit { - IS_TEXTURED_FLAG = 0, - IS_CULLED_FLAG, - IS_EMISSIVE_FLAG, - HAS_DEPTH_BIAS_FLAG, - - NUM_FLAGS, - }; - - enum Flag { - IS_TEXTURED = (1 << IS_TEXTURED_FLAG), - IS_CULLED = (1 << IS_CULLED_FLAG), - IS_EMISSIVE = (1 << IS_EMISSIVE_FLAG), - HAS_DEPTH_BIAS = (1 << HAS_DEPTH_BIAS_FLAG), - }; - typedef unsigned short Flags; - - bool isFlag(short flagNum) const { return bool((_flags & flagNum) != 0); } - - bool isTextured() const { return isFlag(IS_TEXTURED); } - bool isCulled() const { return isFlag(IS_CULLED); } - bool isEmissive() const { return isFlag(IS_EMISSIVE); } - bool hasDepthBias() const { return isFlag(HAS_DEPTH_BIAS); } - - Flags _flags = 0; - short _spare = 0; - - int getRaw() const { return *reinterpret_cast(this); } - - - SimpleProgramKey(bool textured = false, bool culled = true, - bool emissive = false, bool depthBias = false) { - _flags = (textured ? IS_TEXTURED : 0) | (culled ? IS_CULLED : 0) | - (emissive ? IS_EMISSIVE : 0) | (depthBias ? HAS_DEPTH_BIAS : 0); - } - - SimpleProgramKey(int bitmask) : _flags(bitmask) {} -}; - -inline uint qHash(const SimpleProgramKey& key, uint seed) { - return qHash(key.getRaw(), seed); -} - -inline bool operator==(const SimpleProgramKey& a, const SimpleProgramKey& b) { - return a.getRaw() == b.getRaw(); -} - #endif // hifi_DeferredLightingEffect_h diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 5ae90e2124..141d4f917d 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -29,6 +29,10 @@ #include "model/TextureMap.h" +#include "simple_vert.h" +#include "simple_textured_frag.h" +#include "simple_textured_emisive_frag.h" + //#define WANT_DEBUG const int GeometryCache::UNKNOWN_ID = -1; @@ -1741,3 +1745,183 @@ void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) { } } + + + + + + + + + + + + +gpu::PipelinePointer GeometryCache::getPipeline(SimpleProgramKey config) { + static std::once_flag once; + std::call_once(once, [&]() { + auto VS = gpu::Shader::createVertex(std::string(simple_vert)); + auto PS = gpu::Shader::createPixel(std::string(simple_textured_frag)); + auto PSEmissive = gpu::Shader::createPixel(std::string(simple_textured_emisive_frag)); + + _simpleShader = gpu::Shader::createProgram(VS, PS); + _emissiveShader = gpu::Shader::createProgram(VS, PSEmissive); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), render::ShapePipeline::Slot::NORMAL_FITTING_MAP)); + gpu::Shader::makeProgram(*_simpleShader, slotBindings); + gpu::Shader::makeProgram(*_emissiveShader, slotBindings); + }); + + + auto it = _simplePrograms.find(config); + if (it != _simplePrograms.end()) { + return it.value(); + } + + auto state = std::make_shared(); + if (config.isCulled()) { + state->setCullMode(gpu::State::CULL_BACK); + } else { + state->setCullMode(gpu::State::CULL_NONE); + } + state->setDepthTest(true, true, gpu::LESS_EQUAL); + if (config.hasDepthBias()) { + state->setDepthBias(1.0f); + state->setDepthBiasSlopeScale(1.0f); + } + 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::ShaderPointer program = (config.isEmissive()) ? _emissiveShader : _simpleShader; + gpu::PipelinePointer pipeline = gpu::Pipeline::create(program, state); + _simplePrograms.insert(config, pipeline); + return pipeline; +} + +gpu::PipelinePointer GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled, + bool emissive, bool depthBias) { + SimpleProgramKey config{textured, culled, emissive, depthBias}; + gpu::PipelinePointer pipeline = getPipeline(config); + batch.setPipeline(pipeline); + + gpu::ShaderPointer program = (config.isEmissive()) ? _emissiveShader : _simpleShader; + + if (!config.isTextured()) { + // If it is not textured, bind white texture and keep using textured pipeline + batch.setResourceTexture(0, DependencyManager::get()->getWhiteTexture()); + } + + batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP, + DependencyManager::get()->getNormalFittingTexture()); + return pipeline; +} + +uint32_t toCompactColor(const glm::vec4& color) { + uint32_t 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); + return compactColor; +} + +static const size_t INSTANCE_TRANSFORM_BUFFER = 0; +static const size_t INSTANCE_COLOR_BUFFER = 1; + +template +void renderInstances(const std::string& name, gpu::Batch& batch, const Transform& transform, const glm::vec4& color, F f) { + { + gpu::BufferPointer instanceTransformBuffer = batch.getNamedBuffer(name, INSTANCE_TRANSFORM_BUFFER); + glm::mat4 glmTransform; + instanceTransformBuffer->append(transform.getMatrix(glmTransform)); + + gpu::BufferPointer instanceColorBuffer = batch.getNamedBuffer(name, INSTANCE_COLOR_BUFFER); + auto compactColor = toCompactColor(color); + instanceColorBuffer->append(compactColor); + } + + auto that = DependencyManager::get(); + batch.setupNamedCalls(name, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + auto pipeline = that->bindSimpleProgram(batch); + auto location = pipeline->getProgram()->getUniforms().findLocation("Instanced"); + + batch._glUniform1i(location, 1); + f(batch, data); + batch._glUniform1i(location, 0); + }); +} + +void GeometryCache::renderSolidSphereInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { + static const std::string INSTANCE_NAME = __FUNCTION__; + renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + DependencyManager::get()->renderShapeInstances(batch, GeometryCache::Sphere, data._count, + data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); + }); +} + +void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { + static const std::string INSTANCE_NAME = __FUNCTION__; + renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + DependencyManager::get()->renderWireShapeInstances(batch, GeometryCache::Sphere, data._count, + data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); + }); +} + +// Enable this in a debug build to cause 'box' entities to iterate through all the +// available shape types, both solid and wireframes +//#define DEBUG_SHAPES + +void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { + static const std::string INSTANCE_NAME = __FUNCTION__; + +#ifdef DEBUG_SHAPES + static auto startTime = usecTimestampNow(); + renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + + auto usecs = usecTimestampNow(); + usecs -= startTime; + auto msecs = usecs / USECS_PER_MSEC; + float seconds = msecs; + seconds /= MSECS_PER_SECOND; + float fractionalSeconds = seconds - floor(seconds); + int shapeIndex = (int)seconds; + + // Every second we flip to the next shape. + static const int SHAPE_COUNT = 5; + GeometryCache::Shape shapes[SHAPE_COUNT] = { + GeometryCache::Cube, + GeometryCache::Tetrahedron, + GeometryCache::Sphere, + GeometryCache::Icosahedron, + GeometryCache::Line, + }; + + shapeIndex %= SHAPE_COUNT; + GeometryCache::Shape shape = shapes[shapeIndex]; + + // For the first half second for a given shape, show the wireframe, for the second half, show the solid. + if (fractionalSeconds > 0.5f) { + DependencyManager::get()->renderShapeInstances(batch, shape, data._count, + data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); + } else { + DependencyManager::get()->renderWireShapeInstances(batch, shape, data._count, + data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); + } + }); +#else + renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + DependencyManager::get()->renderCubeInstances(batch, data._count, + data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); + }); +#endif +} + +void GeometryCache::renderWireCubeInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { + static const std::string INSTANCE_NAME = __FUNCTION__; + renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + DependencyManager::get()->renderWireCubeInstances(batch, data._count, + data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]); + }); +} + diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index c408115011..4c16680622 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -16,7 +16,6 @@ #include - #include #include @@ -25,10 +24,13 @@ #include #include +#include #include #include +class SimpleProgramKey; + typedef glm::vec3 Vec3Key; typedef QPair Vec2Pair; @@ -146,6 +148,32 @@ public: int allocateID() { return _nextID++; } static const int UNKNOWN_ID; + + + /// Sets up the state necessary to render static untextured geometry with the simple program. + gpu::PipelinePointer bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true, + bool emissive = false, bool depthBias = false); + + void renderSolidSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); + void renderSolidSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { + renderSolidSphereInstance(batch, xfm, glm::vec4(color, 1.0)); + } + + void renderWireSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); + void renderWireSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { + renderWireSphereInstance(batch, xfm, glm::vec4(color, 1.0)); + } + + void renderSolidCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); + void renderSolidCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { + renderSolidCubeInstance(batch, xfm, glm::vec4(color, 1.0)); + } + + void renderWireCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); + void renderWireCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { + renderWireCubeInstance(batch, xfm, glm::vec4(color, 1.0)); + } + void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer); void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer); @@ -335,6 +363,75 @@ private: QHash _gridColors; QHash > _networkGeometry; + + + + + + + + + + + + + + + + gpu::PipelinePointer getPipeline(SimpleProgramKey config); + + gpu::ShaderPointer _simpleShader; + gpu::ShaderPointer _emissiveShader; + QHash _simplePrograms; }; +class SimpleProgramKey { +public: + enum FlagBit { + IS_TEXTURED_FLAG = 0, + IS_CULLED_FLAG, + IS_EMISSIVE_FLAG, + HAS_DEPTH_BIAS_FLAG, + + NUM_FLAGS, + }; + + enum Flag { + IS_TEXTURED = (1 << IS_TEXTURED_FLAG), + IS_CULLED = (1 << IS_CULLED_FLAG), + IS_EMISSIVE = (1 << IS_EMISSIVE_FLAG), + HAS_DEPTH_BIAS = (1 << HAS_DEPTH_BIAS_FLAG), + }; + typedef unsigned short Flags; + + bool isFlag(short flagNum) const { return bool((_flags & flagNum) != 0); } + + bool isTextured() const { return isFlag(IS_TEXTURED); } + bool isCulled() const { return isFlag(IS_CULLED); } + bool isEmissive() const { return isFlag(IS_EMISSIVE); } + bool hasDepthBias() const { return isFlag(HAS_DEPTH_BIAS); } + + Flags _flags = 0; + short _spare = 0; + + int getRaw() const { return *reinterpret_cast(this); } + + + SimpleProgramKey(bool textured = false, bool culled = true, + bool emissive = false, bool depthBias = false) { + _flags = (textured ? IS_TEXTURED : 0) | (culled ? IS_CULLED : 0) | + (emissive ? IS_EMISSIVE : 0) | (depthBias ? HAS_DEPTH_BIAS : 0); + } + + SimpleProgramKey(int bitmask) : _flags(bitmask) {} +}; + +inline uint qHash(const SimpleProgramKey& key, uint seed) { + return qHash(key.getRaw(), seed); +} + +inline bool operator==(const SimpleProgramKey& a, const SimpleProgramKey& b) { + return a.getRaw() == b.getRaw(); +} + #endif // hifi_GeometryCache_h diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 492021c1a9..3fe639b47f 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -499,7 +499,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) const { transform.setTranslation(partBounds.calcCenter()); transform.setScale(partBounds.getDimensions()); batch.setModelTransform(transform); - DependencyManager::get()->renderWireCube(batch, 1.0f, cubeColor); + DependencyManager::get()->renderWireCube(batch, 1.0f, cubeColor); } #endif //def DEBUG_BOUNDING_PARTS diff --git a/libraries/render-utils/src/TextRenderer3D.cpp b/libraries/render-utils/src/TextRenderer3D.cpp index c3056be00b..6d10ed7069 100644 --- a/libraries/render-utils/src/TextRenderer3D.cpp +++ b/libraries/render-utils/src/TextRenderer3D.cpp @@ -29,7 +29,6 @@ #include "sdf_text3D_frag.h" #include "GeometryCache.h" -#include "DeferredLightingEffect.h" const float TextRenderer3D::DEFAULT_POINT_SIZE = 12;