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 | |