Skip to content

Commit

Permalink
Fixed Ribbon Count
Browse files Browse the repository at this point in the history
Separate different vertexbuffers and indexbuffers into different Components.
  • Loading branch information
OVOAOVO committed Apr 1, 2024
1 parent 3619462 commit 5ab835d
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 134 deletions.
2 changes: 1 addition & 1 deletion Engine/BuiltInShaders/shaders/cs_particleRibbon.sc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ uniform vec4 u_ribbonCount;
// x : allRibbonVertexCount
// y : particleActiveCount

uniform vec4 u_ribbonMaxPos[75];
uniform vec4 u_ribbonMaxPos[300];
//here have max particle count (max limit of inspector)

NUM_THREADS(1u, 1u, 1u)
Expand Down
2 changes: 2 additions & 0 deletions Engine/Source/Editor/UILayers/EntityList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ void EntityList::AddEntity(engine::SceneWorld* pSceneWorld)
{
engine::Entity entity = AddNamedEntity("ParticleEmitter");
auto& particleEmitterComponent = pWorld->CreateComponent<engine::ParticleEmitterComponent>(entity);
auto& particleRibbonComponent = pWorld->CreateComponent<engine::ParticleRibbonComponent>(entity);
auto& particleMaterialComponent = pWorld->CreateComponent<engine::MaterialComponent>(entity);
// TODO : Some initialization here.
auto& transformComponent = pWorld->CreateComponent<engine::TransformComponent>(entity);
Expand All @@ -271,6 +272,7 @@ void EntityList::AddEntity(engine::SceneWorld* pSceneWorld)
particleMaterialComponent.SetMaterialType(pParticleMaterialType);
//particleMaterialComponent.ActivateShaderFeature(engine::ShaderFeature::PARTICLE_INSTANCE);
particleEmitterComponent.Build();
particleRibbonComponent.Build();
}
else if (ImGui::MenuItem("Add Particle ForceField"))
{
Expand Down
1 change: 1 addition & 0 deletions Engine/Source/Runtime/ECWorld/AllComponentsHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
#include "ECWorld/TerrainComponent.h"
#include "ECWorld/TransformComponent.h"
#include "ECWorld/ParticleEmitterComponent.h"
#include "ECWorld/ParticleRibbonComponent.h"
#include "ECWorld/ParticleForceFieldComponent.h"
102 changes: 0 additions & 102 deletions Engine/Source/Runtime/ECWorld/ParticleEmitterComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ void ParticleEmitterComponent::Build()
PaddingSpriteVertexBuffer();
PaddingSpriteIndexBuffer();

PaddingRibbonVertexBuffer();
PaddingRibbonIndexBuffer();

m_spriteParticleVertexBufferHandle = bgfx::createVertexBuffer(bgfx::makeRef(m_spriteParticleVertexBuffer.data(), static_cast<uint32_t>(m_spriteParticleVertexBuffer.size())), vertexLayout).idx;
m_spriteParticleIndexBufferHandle = bgfx::createIndexBuffer(bgfx::makeRef(m_spriteParticleIndexBuffer.data(), static_cast<uint32_t>(m_spriteParticleIndexBuffer.size())), 0U).idx;
}
Expand Down Expand Up @@ -127,105 +124,6 @@ void ParticleEmitterComponent::PaddingSpriteIndexBuffer()
}
}

void ParticleEmitterComponent::PaddingRibbonVertexBuffer()
{
//vertexbuffer
constexpr int meshVertexCount = Particle::GetMeshVertexCount<ParticleType::Ribbon>();
const int MAX_VERTEX_COUNT = m_particlePool.GetParticleMaxCount() * meshVertexCount;
size_t vertexCount = MAX_VERTEX_COUNT;
uint32_t csVertexCount = MAX_VERTEX_COUNT;
//prePos Vertex format/layout
cd::VertexFormat m_pRibbonPrePosVertexFormat;
m_pRibbonPrePosVertexFormat.AddVertexAttributeLayout(cd::VertexAttributeType::Position, cd::GetAttributeValueType<cd::Point::ValueType>(), cd::Point::Size);
m_pRibbonPrePosVertexFormat.AddVertexAttributeLayout(cd::VertexAttributeType::BoneWeight, cd::AttributeValueType::Float, 1U);
bgfx::VertexLayout prePosLayout;
VertexLayoutUtility::CreateVertexLayout(prePosLayout, m_pRibbonPrePosVertexFormat.GetVertexAttributeLayouts());
//remain Vertex format/layout
cd::VertexFormat m_pRibbonRemainVertexFormat;
m_pRibbonRemainVertexFormat.AddVertexAttributeLayout(cd::VertexAttributeType::Color, cd::GetAttributeValueType<cd::Color::ValueType>(), cd::Color::Size);
m_pRibbonRemainVertexFormat.AddVertexAttributeLayout(cd::VertexAttributeType::UV, cd::GetAttributeValueType<cd::UV::ValueType>(), cd::UV::Size);
bgfx::VertexLayout color_UV_Layout;
VertexLayoutUtility::CreateVertexLayout(color_UV_Layout, m_pRibbonRemainVertexFormat.GetVertexAttributeLayouts());

//const uint32_t posVertexFormatStride = m_pRibbonPrePosVertexFormat.GetStride();
const uint32_t remainVertexFormatStride = m_pRibbonRemainVertexFormat.GetStride();

//m_ribbonParticlePrePosVertexBuffer.resize(vertexCount * posVertexFormatStride);
m_ribbonParticleRemainVertexBuffer.resize(vertexCount * remainVertexFormatStride);

//uint32_t currentPosDataSize = 0U;
//auto currentPosDataPtr = m_ribbonParticlePrePosVertexBuffer.data();
uint32_t currentRemainDataSize = 0U;
auto currentRemainDataPtr = m_ribbonParticleRemainVertexBuffer.data();
//float placeholder = 0.0f;
//uint32_t placeholderSize = sizeof(placeholder);

std::vector<VertexData> vertexDataBuffer;
vertexDataBuffer.resize(MAX_VERTEX_COUNT);
// pos color uv
// only a picture now
for (int i = 0; i < MAX_VERTEX_COUNT; i += meshVertexCount)
{
vertexDataBuffer[i] = { cd::Vec3f(0.0f,1.0f,0.0f),cd::Vec4f(1.0f,1.0f,1.0f,1.0f),cd::Vec2f(0.5f,0.5f)};
vertexDataBuffer[i+1] = { cd::Vec3f(0.0f,-1.0f,0.0f),cd::Vec4f(1.0f,1.0f,1.0f,1.0f),cd::Vec2f(0.5f,0.5f)};
}

for (int i = 0; i < MAX_VERTEX_COUNT; ++i)
{
//std::memcpy(&currentPosDataPtr[currentPosDataSize], &vertexDataBuffer[i].pos, sizeof(cd::Point));
//currentPosDataSize += sizeof(cd::Point);
////vec3 filled to vec4
//std::memcpy(&currentPosDataPtr[currentPosDataSize], &placeholder, placeholderSize);
//currentPosDataSize += placeholderSize;

std::memcpy(&currentRemainDataPtr[currentRemainDataSize], &vertexDataBuffer[i].color, sizeof(cd::Color));
currentRemainDataSize += sizeof(cd::Color);
std::memcpy(&currentRemainDataPtr[currentRemainDataSize], &vertexDataBuffer[i].uv, sizeof(cd::UV));
currentRemainDataSize += sizeof(cd::UV);
}
m_ribbonParticlePrePosVertexBufferHandle = bgfx::createDynamicVertexBuffer(csVertexCount, prePosLayout, BGFX_BUFFER_COMPUTE_READ_WRITE).idx;
const bgfx::Memory* pRibbonParticleRemainVBRef = bgfx::makeRef(m_ribbonParticleRemainVertexBuffer.data(), static_cast<uint32_t>(m_ribbonParticleRemainVertexBuffer.size()));
m_ribbonParticleRemainVertexBufferHandle = bgfx::createVertexBuffer(pRibbonParticleRemainVBRef, color_UV_Layout).idx;
}

void ParticleEmitterComponent::PaddingRibbonIndexBuffer()
{
constexpr int meshVertexCount = Particle::GetMeshVertexCount<ParticleType::Ribbon>();;
const bool useU16Index = meshVertexCount <= static_cast<uint32_t>(std::numeric_limits<uint16_t>::max()) + 1U;
const uint32_t indexTypeSize = useU16Index ? sizeof(uint16_t) : sizeof(uint32_t);
const int MAX_VERTEX_COUNT = (m_particlePool.GetParticleMaxCount() - 1)* meshVertexCount;
int indexCountForOneRibbon = 6;
const uint32_t indicesCount = MAX_VERTEX_COUNT / meshVertexCount * indexCountForOneRibbon;
m_ribbonParticleIndexBuffer.resize(indicesCount * indexTypeSize);
///
/* size_t indexTypeSize = sizeof(uint16_t);
m_particleIndexBuffer.resize(m_particleSystem.GetMaxCount() / 4 * 6 * indexTyp
eSize);*/
uint32_t currentDataSize = 0U;
auto currentDataPtr = m_ribbonParticleIndexBuffer.data();

std::vector<uint16_t> indexes;

for (uint16_t i = 0; i < MAX_VERTEX_COUNT; i += meshVertexCount)
{
uint16_t vertexIndex = static_cast<uint16_t>(i);
indexes.push_back(vertexIndex);
indexes.push_back(vertexIndex+1);
indexes.push_back(vertexIndex+2);

indexes.push_back(vertexIndex + 2);
indexes.push_back(vertexIndex + 1);
indexes.push_back(vertexIndex + 3);
}

for (const auto& index : indexes)
{
std::memcpy(&currentDataPtr[currentDataSize], &index, indexTypeSize);
currentDataSize += static_cast<uint32_t>(indexTypeSize);
}
m_ribbonParticleIndexBufferHandle = bgfx::createIndexBuffer(bgfx::makeRef(m_ribbonParticleIndexBuffer.data(), static_cast<uint32_t>(m_ribbonParticleIndexBuffer.size())), 0U).idx;
}

void ParticleEmitterComponent::BuildParticleShape()
{
if (m_emitterShape == ParticleEmitterShape::Box)
Expand Down
20 changes: 0 additions & 20 deletions Engine/Source/Runtime/ECWorld/ParticleEmitterComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,6 @@ class ParticleEmitterComponent final
std::vector<std::byte>& GetSpriteVertexBuffer() { return m_spriteParticleVertexBuffer; }
std::vector<std::byte>& GetSpriteIndexBuffer() { return m_spriteParticleIndexBuffer; }

uint16_t& GetRibbonParticlePrePosVertexBufferHandle() { return m_ribbonParticlePrePosVertexBufferHandle; }
uint16_t& GetRibbonParticleRemainVertexBufferHandle() { return m_ribbonParticleRemainVertexBufferHandle; }
uint16_t& GetRibbonParticleIndexBufferHandle() { return m_ribbonParticleIndexBufferHandle; }

std::vector<std::byte>& GetRibbonPrePosVertexBuffer() { return m_ribbonParticlePrePosVertexBuffer; }
std::vector<std::byte>& GetRibbonRemainVertexBuffer() { return m_ribbonParticleRemainVertexBuffer; }
std::vector<std::byte>& GetRibbonIndexBuffer() { return m_ribbonParticleIndexBuffer; }

uint16_t& GetEmitterShapeVertexBufferHandle() { return m_emitterShapeVertexBufferHandle; }
uint16_t& GetEmitterShapeIndexBufferHandle() { return m_emitterShapeIndexBufferHandle; }

Expand All @@ -115,9 +107,6 @@ class ParticleEmitterComponent final
void PaddingSpriteVertexBuffer();
void PaddingSpriteIndexBuffer();

void PaddingRibbonVertexBuffer();
void PaddingRibbonIndexBuffer();

void BuildParticleShape();
void RePaddingShapeBuffer();

Expand Down Expand Up @@ -162,15 +151,6 @@ class ParticleEmitterComponent final
uint16_t m_spriteParticleVertexBufferHandle = UINT16_MAX;
uint16_t m_spriteParticleIndexBufferHandle = UINT16_MAX;

//Ribbon
std::vector<std::byte> m_ribbonParticlePrePosVertexBuffer;
std::vector<std::byte> m_ribbonParticleRemainVertexBuffer;
std::vector<std::byte> m_ribbonParticleIndexBuffer;
uint16_t m_ribbonParticlePrePosVertexBufferHandle = UINT16_MAX;
uint16_t m_ribbonParticleRemainVertexBufferHandle = UINT16_MAX;
uint16_t m_ribbonParticleIndexBufferHandle = UINT16_MAX;


//emitter shape vertex/index
ParticleEmitterShape m_emitterShape = ParticleEmitterShape::Box;
cd::Vec3f m_emitterShapeRange {10.0f ,5.0f ,10.0f};
Expand Down
105 changes: 105 additions & 0 deletions Engine/Source/Runtime/ECWorld/ParticleRibbonComponent.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include "Log/Log.h"
#include "ParticleRibbonComponent.h"
#include "Rendering/Utility/VertexLayoutUtility.h"
#include "Utilities/MeshUtils.hpp"

#include <limits>

namespace engine
{
void ParticleRibbonComponent::Build()
{
PaddingRibbonVertexBuffer();
PaddingRibbonIndexBuffer();
}

void ParticleRibbonComponent::PaddingRibbonVertexBuffer()
{
//vertexbuffer
constexpr int meshVertexCount = Particle::GetMeshVertexCount<ParticleType::Ribbon>();
//75 is from particle's MaxCount,There only padding once.
const int MAX_VERTEX_COUNT = 75 * meshVertexCount;
size_t vertexCount = MAX_VERTEX_COUNT;
uint32_t csVertexCount = MAX_VERTEX_COUNT;
//prePos Vertex format/layout
cd::VertexFormat m_pRibbonPrePosVertexFormat;
m_pRibbonPrePosVertexFormat.AddVertexAttributeLayout(cd::VertexAttributeType::Position, cd::GetAttributeValueType<cd::Point::ValueType>(), cd::Point::Size);
m_pRibbonPrePosVertexFormat.AddVertexAttributeLayout(cd::VertexAttributeType::BoneWeight, cd::AttributeValueType::Float, 1U);
bgfx::VertexLayout prePosLayout;
VertexLayoutUtility::CreateVertexLayout(prePosLayout, m_pRibbonPrePosVertexFormat.GetVertexAttributeLayouts());
//remain Vertex format/layout
cd::VertexFormat m_pRibbonRemainVertexFormat;
m_pRibbonRemainVertexFormat.AddVertexAttributeLayout(cd::VertexAttributeType::Color, cd::GetAttributeValueType<cd::Color::ValueType>(), cd::Color::Size);
m_pRibbonRemainVertexFormat.AddVertexAttributeLayout(cd::VertexAttributeType::UV, cd::GetAttributeValueType<cd::UV::ValueType>(), cd::UV::Size);
bgfx::VertexLayout color_UV_Layout;
VertexLayoutUtility::CreateVertexLayout(color_UV_Layout, m_pRibbonRemainVertexFormat.GetVertexAttributeLayouts());

const uint32_t remainVertexFormatStride = m_pRibbonRemainVertexFormat.GetStride();

m_ribbonParticleRemainVertexBuffer.resize(vertexCount * remainVertexFormatStride);

uint32_t currentRemainDataSize = 0U;
auto currentRemainDataPtr = m_ribbonParticleRemainVertexBuffer.data();

std::vector<VertexData> vertexDataBuffer;
vertexDataBuffer.resize(MAX_VERTEX_COUNT);
// pos color uv
// only a picture now
for (int i = 0; i < MAX_VERTEX_COUNT; i += meshVertexCount)
{
vertexDataBuffer[i] = { cd::Vec3f(0.0f,1.0f,0.0f),cd::Vec4f(1.0f,1.0f,1.0f,1.0f),cd::Vec2f(0.5f,0.5f) };
vertexDataBuffer[i + 1] = { cd::Vec3f(0.0f,-1.0f,0.0f),cd::Vec4f(1.0f,1.0f,1.0f,1.0f),cd::Vec2f(0.5f,0.5f) };
}

for (int i = 0; i < MAX_VERTEX_COUNT; ++i)
{
std::memcpy(&currentRemainDataPtr[currentRemainDataSize], &vertexDataBuffer[i].color, sizeof(cd::Color));
currentRemainDataSize += sizeof(cd::Color);
std::memcpy(&currentRemainDataPtr[currentRemainDataSize], &vertexDataBuffer[i].uv, sizeof(cd::UV));
currentRemainDataSize += sizeof(cd::UV);
}
m_ribbonParticlePrePosVertexBufferHandle = bgfx::createDynamicVertexBuffer(csVertexCount, prePosLayout, BGFX_BUFFER_COMPUTE_READ_WRITE).idx;
const bgfx::Memory* pRibbonParticleRemainVBRef = bgfx::makeRef(m_ribbonParticleRemainVertexBuffer.data(), static_cast<uint32_t>(m_ribbonParticleRemainVertexBuffer.size()));
m_ribbonParticleRemainVertexBufferHandle = bgfx::createVertexBuffer(pRibbonParticleRemainVBRef, color_UV_Layout).idx;
}

void ParticleRibbonComponent::PaddingRibbonIndexBuffer()
{
constexpr int meshVertexCount = Particle::GetMeshVertexCount<ParticleType::Ribbon>();;
const bool useU16Index = meshVertexCount <= static_cast<uint32_t>(std::numeric_limits<uint16_t>::max()) + 1U;
const uint32_t indexTypeSize = useU16Index ? sizeof(uint16_t) : sizeof(uint32_t);
//TODO: 75 is from particle's MaxCount There only padding once.
const int MAX_VERTEX_COUNT = (75 - 1) * meshVertexCount;
int indexCountForOneRibbon = 6;
const uint32_t indicesCount = MAX_VERTEX_COUNT / meshVertexCount * indexCountForOneRibbon;
m_ribbonParticleIndexBuffer.resize(indicesCount * indexTypeSize);
///
/* size_t indexTypeSize = sizeof(uint16_t);
m_particleIndexBuffer.resize(m_particleSystem.GetMaxCount() / 4 * 6 * indexTyp
eSize);*/
uint32_t currentDataSize = 0U;
auto currentDataPtr = m_ribbonParticleIndexBuffer.data();

std::vector<uint16_t> indexes;

for (uint16_t i = 0; i < MAX_VERTEX_COUNT; i += meshVertexCount)
{
uint16_t vertexIndex = static_cast<uint16_t>(i);
indexes.push_back(vertexIndex);
indexes.push_back(vertexIndex + 1);
indexes.push_back(vertexIndex + 2);

indexes.push_back(vertexIndex + 2);
indexes.push_back(vertexIndex + 1);
indexes.push_back(vertexIndex + 3);
}

for (const auto& index : indexes)
{
std::memcpy(&currentDataPtr[currentDataSize], &index, indexTypeSize);
currentDataSize += static_cast<uint32_t>(indexTypeSize);
}
m_ribbonParticleIndexBufferHandle = bgfx::createIndexBuffer(bgfx::makeRef(m_ribbonParticleIndexBuffer.data(), static_cast<uint32_t>(m_ribbonParticleIndexBuffer.size())), 0U).idx;
}

}
61 changes: 61 additions & 0 deletions Engine/Source/Runtime/ECWorld/ParticleRibbonComponent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "Base/Template.h"
#include "Core/StringCrc.h"
#include "Math/Vector.hpp"
#include "Math/Transform.hpp"
#include "Material/ShaderSchema.h"
#include "Material/MaterialType.h"
#include "ParticleSystem/ParticlePool.h"
#include "Scene/Mesh.h"
#include "Scene/Types.h"
#include "Scene/VertexFormat.h"

namespace engine
{

class ParticleRibbonComponent final
{
public:
static constexpr StringCrc GetClassName()
{
constexpr StringCrc className("ParticleRibbonComponent");
return className;
}

ParticleRibbonComponent() = default;
ParticleRibbonComponent(const ParticleRibbonComponent&) = default;
ParticleRibbonComponent& operator=(const ParticleRibbonComponent&) = default;
ParticleRibbonComponent(ParticleRibbonComponent&&) = default;
ParticleRibbonComponent& operator=(ParticleRibbonComponent&&) = default;
~ParticleRibbonComponent() = default;

void PaddingRibbonVertexBuffer();
void PaddingRibbonIndexBuffer();

void Build();

uint16_t& GetRibbonParticlePrePosVertexBufferHandle() { return m_ribbonParticlePrePosVertexBufferHandle; }
uint16_t& GetRibbonParticleRemainVertexBufferHandle() { return m_ribbonParticleRemainVertexBufferHandle; }
uint16_t& GetRibbonParticleIndexBufferHandle() { return m_ribbonParticleIndexBufferHandle; }

std::vector<std::byte>& GetRibbonPrePosVertexBuffer() { return m_ribbonParticlePrePosVertexBuffer; }
std::vector<std::byte>& GetRibbonRemainVertexBuffer() { return m_ribbonParticleRemainVertexBuffer; }
std::vector<std::byte>& GetRibbonIndexBuffer() { return m_ribbonParticleIndexBuffer; }

private:
//particle vertex/index
struct VertexData
{
cd::Vec3f pos;
cd::Vec4f color;
cd::UV uv;
};

std::vector<std::byte> m_ribbonParticlePrePosVertexBuffer;
std::vector<std::byte> m_ribbonParticleRemainVertexBuffer;
std::vector<std::byte> m_ribbonParticleIndexBuffer;
uint16_t m_ribbonParticlePrePosVertexBufferHandle = UINT16_MAX;
uint16_t m_ribbonParticleRemainVertexBufferHandle = UINT16_MAX;
uint16_t m_ribbonParticleIndexBufferHandle = UINT16_MAX;
};

}
1 change: 1 addition & 0 deletions Engine/Source/Runtime/ECWorld/SceneWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ SceneWorld::SceneWorld()
m_pSkyComponentStorage = m_pWorld->Register<engine::SkyComponent>();
m_pStaticMeshComponentStorage = m_pWorld->Register<engine::StaticMeshComponent>();
m_pParticleEmitterComponentStorage = m_pWorld->Register<engine::ParticleEmitterComponent>();
m_pParticleRibbonComponentStorage = m_pWorld->Register<engine::ParticleRibbonComponent>();
m_pParticleForceFieldComponentStorage = m_pWorld->Register<engine::ParticleForceFieldComponent>();
m_pTerrainComponentStorage = m_pWorld->Register<engine::TerrainComponent>();
m_pTransformComponentStorage = m_pWorld->Register<engine::TransformComponent>();
Expand Down
2 changes: 2 additions & 0 deletions Engine/Source/Runtime/ECWorld/SceneWorld.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class SceneWorld
DEFINE_COMPONENT_STORAGE_WITH_APIS(Sky);
DEFINE_COMPONENT_STORAGE_WITH_APIS(StaticMesh);
DEFINE_COMPONENT_STORAGE_WITH_APIS(ParticleEmitter);
DEFINE_COMPONENT_STORAGE_WITH_APIS(ParticleRibbon);
DEFINE_COMPONENT_STORAGE_WITH_APIS(ParticleForceField);
DEFINE_COMPONENT_STORAGE_WITH_APIS(Terrain);
DEFINE_COMPONENT_STORAGE_WITH_APIS(Transform);
Expand Down Expand Up @@ -99,6 +100,7 @@ class SceneWorld
DeleteSkyComponent(entity);
DeleteStaticMeshComponent(entity);
DeleteParticleEmitterComponent(entity);
DeleteParticleRibbonComponent(entity);
DeleteParticleForceFieldComponent(entity);
DeleteTerrainComponent(entity);
DeleteTransformComponent(entity);
Expand Down
Loading

0 comments on commit 5ab835d

Please sign in to comment.