**Refactor meshes format to support custom vertex layouts and new flexible api to access mesh data**
#3044 #2667
This commit is contained in:
@@ -18,18 +18,37 @@
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Core/Types/Variant.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
#include "Engine/Localization/Localization.h"
|
||||
#if USE_EDITOR
|
||||
#include "Editor/Editor.h"
|
||||
#endif
|
||||
|
||||
PACK_STRUCT(struct TextRenderVertex
|
||||
{
|
||||
Float3 Position;
|
||||
Color32 Color;
|
||||
Float1010102 Normal;
|
||||
Float1010102 Tangent;
|
||||
Half2 TexCoord;
|
||||
|
||||
static GPUVertexLayout* GetLayout()
|
||||
{
|
||||
return GPUVertexLayout::Get({
|
||||
{ VertexElement::Types::Position, 0, 0, 0, PixelFormat::R32G32B32_Float },
|
||||
{ VertexElement::Types::Color, 0, 0, 0, PixelFormat::R8G8B8A8_UNorm },
|
||||
{ VertexElement::Types::Normal, 0, 0, 0, PixelFormat::R10G10B10A2_UNorm },
|
||||
{ VertexElement::Types::Tangent, 0, 0, 0, PixelFormat::R10G10B10A2_UNorm },
|
||||
{ VertexElement::Types::TexCoord, 0, 0, 0, PixelFormat::R16G16_Float },
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
TextRender::TextRender(const SpawnParams& params)
|
||||
: Actor(params)
|
||||
, _size(32)
|
||||
, _ib(0, sizeof(uint16))
|
||||
, _vb0(0, sizeof(VB0ElementType), String::Empty, VB0ElementType::GetLayout())
|
||||
, _vb1(0, sizeof(VB1ElementType), String::Empty, VB1ElementType::GetLayout())
|
||||
, _vb2(0, sizeof(VB2ElementType), String::Empty, VB2ElementType::GetLayout())
|
||||
, _vb(0, sizeof(TextRenderVertex), String::Empty, TextRenderVertex::GetLayout())
|
||||
{
|
||||
_color = Color::White;
|
||||
_localBox = BoundingBox(Vector3::Zero);
|
||||
@@ -102,9 +121,7 @@ void TextRender::UpdateLayout()
|
||||
{
|
||||
// Clear
|
||||
_ib.Clear();
|
||||
_vb0.Clear();
|
||||
_vb1.Clear();
|
||||
_vb2.Clear();
|
||||
_vb.Clear();
|
||||
_localBox = BoundingBox(Vector3::Zero);
|
||||
BoundingBox::Transform(_localBox, _transform, _box);
|
||||
BoundingSphere::FromBox(_box, _sphere);
|
||||
@@ -163,9 +180,7 @@ void TextRender::UpdateLayout()
|
||||
|
||||
// Prepare buffers capacity
|
||||
_ib.Data.EnsureCapacity(text.Length() * 6 * sizeof(uint16));
|
||||
_vb0.Data.EnsureCapacity(text.Length() * 4 * sizeof(VB0ElementType));
|
||||
_vb1.Data.EnsureCapacity(text.Length() * 4 * sizeof(VB1ElementType));
|
||||
_vb2.Data.EnsureCapacity(text.Length() * 4 * sizeof(VB2ElementType));
|
||||
_vb.Data.EnsureCapacity(text.Length() * 4 * sizeof(TextRenderVertex));
|
||||
_buffersDirty = true;
|
||||
|
||||
// Init draw chunks data
|
||||
@@ -268,20 +283,15 @@ void TextRender::UpdateLayout()
|
||||
byte sign = 0;
|
||||
|
||||
// Write vertices
|
||||
VB0ElementType vb0;
|
||||
VB1ElementType vb1;
|
||||
VB2ElementType vb2;
|
||||
TextRenderVertex v;
|
||||
#define WRITE_VB(pos, uv) \
|
||||
vb0.Position = Float3(-pos, 0.0f); \
|
||||
box.Merge(vb0.Position); \
|
||||
_vb0.Write(vb0); \
|
||||
vb1.TexCoord = Half2(uv); \
|
||||
vb1.Normal = Float1010102(normal * 0.5f + 0.5f, 0); \
|
||||
vb1.Tangent = Float1010102(tangent * 0.5f + 0.5f, sign); \
|
||||
vb1.LightmapUVs = Half2::Zero; \
|
||||
_vb1.Write(vb1); \
|
||||
vb2.Color = color; \
|
||||
_vb2.Write(vb2)
|
||||
v.Position = Float3(-pos, 0.0f); \
|
||||
box.Merge(v.Position); \
|
||||
v.TexCoord = Half2(uv); \
|
||||
v.Normal = Float1010102(normal * 0.5f + 0.5f, 0); \
|
||||
v.Tangent = Float1010102(tangent * 0.5f + 0.5f, sign); \
|
||||
v.Color = color; \
|
||||
_vb.Write(v)
|
||||
//
|
||||
WRITE_VB(charRect.GetBottomRight(), rightBottomUV);
|
||||
WRITE_VB(charRect.GetBottomLeft(), Float2(upperLeftUV.X, rightBottomUV.Y));
|
||||
@@ -317,7 +327,7 @@ void TextRender::UpdateLayout()
|
||||
#if MODEL_USE_PRECISE_MESH_INTERSECTS
|
||||
// Setup collision proxy for detailed collision detection for triangles
|
||||
const int32 totalIndicesCount = _ib.Data.Count() / sizeof(uint16);
|
||||
_collisionProxy.Init(_vb0.Data.Count() / sizeof(Float3), totalIndicesCount / 3, (Float3*)_vb0.Data.Get(), (uint16*)_ib.Data.Get());
|
||||
_collisionProxy.Init(_vb.Data.Count() / sizeof(TextRenderVertex), totalIndicesCount / 3, (const Float3*)_vb.Data.Get(), (const uint16*)_ib.Data.Get(), sizeof(TextRenderVertex));
|
||||
#endif
|
||||
|
||||
// Update text bounds (from build vertex positions)
|
||||
@@ -351,16 +361,14 @@ void TextRender::Draw(RenderContext& renderContext)
|
||||
GEOMETRY_DRAW_STATE_EVENT_BEGIN(_drawState, world);
|
||||
|
||||
const DrawPass drawModes = DrawModes & renderContext.View.Pass & renderContext.View.GetShadowsDrawPassMask(ShadowsMode);
|
||||
if (_vb0.Data.Count() > 0 && drawModes != DrawPass::None)
|
||||
if (_vb.Data.Count() > 0 && drawModes != DrawPass::None)
|
||||
{
|
||||
// Flush buffers
|
||||
if (_buffersDirty)
|
||||
{
|
||||
_buffersDirty = false;
|
||||
_ib.Flush();
|
||||
_vb0.Flush();
|
||||
_vb1.Flush();
|
||||
_vb2.Flush();
|
||||
_vb.Flush();
|
||||
}
|
||||
|
||||
// Setup draw call
|
||||
@@ -373,9 +381,7 @@ void TextRender::Draw(RenderContext& renderContext)
|
||||
drawCall.WorldDeterminantSign = RenderTools::GetWorldDeterminantSign(drawCall.World);
|
||||
drawCall.PerInstanceRandom = GetPerInstanceRandom();
|
||||
drawCall.Geometry.IndexBuffer = _ib.GetBuffer();
|
||||
drawCall.Geometry.VertexBuffers[0] = _vb0.GetBuffer();
|
||||
drawCall.Geometry.VertexBuffers[1] = _vb1.GetBuffer();
|
||||
drawCall.Geometry.VertexBuffers[2] = _vb2.GetBuffer();
|
||||
drawCall.Geometry.VertexBuffers[0] = _vb.GetBuffer();
|
||||
drawCall.InstanceCount = 1;
|
||||
|
||||
// Submit draw calls
|
||||
|
||||
Reference in New Issue
Block a user