| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
| 3 | #include "BsRendererDecal.h" |
| 4 | #include "BsRendererRenderable.h" |
| 5 | #include "Renderer/BsDecal.h" |
| 6 | #include "Mesh/BsMesh.h" |
| 7 | #include "Renderer/BsRendererUtility.h" |
| 8 | |
| 9 | namespace bs { namespace ct |
| 10 | { |
| 11 | DecalParamDef gDecalParamDef; |
| 12 | |
| 13 | void DecalRenderElement::draw() const |
| 14 | { |
| 15 | gRendererUtility().draw(mesh, subMesh); |
| 16 | } |
| 17 | |
| 18 | RendererDecal::RendererDecal() |
| 19 | { |
| 20 | decalParamBuffer = gDecalParamDef.createBuffer(); |
| 21 | perObjectParamBuffer = gPerObjectParamDef.createBuffer(); |
| 22 | perCallParamBuffer = gPerCallParamDef.createBuffer(); |
| 23 | } |
| 24 | |
| 25 | void RendererDecal::updatePerObjectBuffer() |
| 26 | { |
| 27 | const Vector2 size = decal->getSize(); |
| 28 | const Vector2 extent = size * 0.5f; |
| 29 | const float maxDistance = decal->getMaxDistance(); |
| 30 | |
| 31 | const Vector3 scale(extent.x, extent.y, maxDistance * 0.5f); |
| 32 | const Vector3 offset(0.0f, 0.0f, -maxDistance * 0.5f); |
| 33 | |
| 34 | const Matrix4 scaleAndOffset = Matrix4::TRS(offset, Quaternion::IDENTITY, scale); |
| 35 | |
| 36 | const Matrix4 worldTransform = decal->getMatrix() * scaleAndOffset; |
| 37 | const Matrix4 worldNoScaleTransform = decal->getMatrixNoScale() * scaleAndOffset; |
| 38 | |
| 39 | PerObjectBuffer::update(perObjectParamBuffer, worldTransform, worldNoScaleTransform, 0); |
| 40 | |
| 41 | const Transform& tfrm = decal->getTransform(); |
| 42 | |
| 43 | const Matrix4 view = Matrix4::view(tfrm.getPosition(), tfrm.getRotation()); |
| 44 | const Matrix4 proj = Matrix4::projectionOrthographic(-extent.x, extent.x, -extent.y, extent.y, 0.0f, |
| 45 | decal->getMaxDistance()); |
| 46 | |
| 47 | const Matrix4 worldToDecal = proj * view; |
| 48 | const Vector3 decalNormal = -decal->getTransform().getRotation().zAxis(); |
| 49 | const float normalTolerance = -0.05f; |
| 50 | |
| 51 | float flipDerivatives = 1.0f; |
| 52 | |
| 53 | const Conventions& rapiConventions = gCaps().conventions; |
| 54 | if(rapiConventions.uvYAxis == Conventions::Axis::Up) |
| 55 | flipDerivatives = -1.0f; |
| 56 | |
| 57 | gDecalParamDef.gWorldToDecal.set(decalParamBuffer, worldToDecal); |
| 58 | gDecalParamDef.gDecalNormal.set(decalParamBuffer, decalNormal); |
| 59 | gDecalParamDef.gNormalTolerance.set(decalParamBuffer, normalTolerance); |
| 60 | gDecalParamDef.gFlipDerivatives.set(decalParamBuffer, flipDerivatives); |
| 61 | gDecalParamDef.gLayerMask.set(decalParamBuffer, (INT32)decal->getLayerMask()); |
| 62 | } |
| 63 | |
| 64 | void RendererDecal::updatePerCallBuffer(const Matrix4& viewProj, bool flush) const |
| 65 | { |
| 66 | const Matrix4 worldViewProjMatrix = viewProj * decal->getMatrix(); |
| 67 | |
| 68 | gPerCallParamDef.gMatWorldViewProj.set(perCallParamBuffer, worldViewProjMatrix); |
| 69 | |
| 70 | if(flush) |
| 71 | perCallParamBuffer->flushToGPU(); |
| 72 | } |
| 73 | }} |
| 74 | |