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