Skip to content

Commit

Permalink
#149 Update material & save/load CPrimitive
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Jun 11, 2022
1 parent cf6e6dc commit 96a3b33
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 55 deletions.
55 changes: 52 additions & 3 deletions Projects/Skylicht/Components/Source/Primitive/CPrimitive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,26 @@ namespace Skylicht
CPrimitive::CPrimitive() :
m_type(CPrimiviteData::Unknown),
m_instancing(false),
m_color(255, 180, 180, 180)
m_color(255, 180, 180, 180),
m_material(NULL)
{

}

CPrimitive::~CPrimitive()
{

if (m_material)
delete m_material;
}

void CPrimitive::initComponent()
{
m_gameObject->getEntityManager()->addRenderSystem<CPrimitiveRenderer>();

// init material
m_material = new CMaterial("Primitive", "BuiltIn/Shader/SpecularGlossiness/Deferred/Color.xml");
m_material->setUniform4("uColor", m_color);

// add default primitive
if (m_type != CPrimiviteData::Unknown)
{
Expand All @@ -72,6 +78,21 @@ namespace Skylicht
object->autoRelease(new CBoolProperty(object, "instancing", m_instancing));
object->autoRelease(new CColorProperty(object, "color", m_color));

CArraySerializable* primitives = new CArraySerializable("Primitives");
object->addProperty(primitives);
object->autoRelease(primitives);

int numPrimities = (int)m_entities.size();
for (int i = 0; i < numPrimities; i++)
{
CMatrixProperty* transformData = new CMatrixProperty(primitives, "transform");
primitives->autoRelease(transformData);

// get world transform data
CWorldTransformData* world = (CWorldTransformData*)m_entities[i]->getDataByIndex(CWorldTransformData::DataTypeIndex);
transformData->set(world->Relative);
}

return object;
}

Expand All @@ -80,7 +101,34 @@ namespace Skylicht
CComponentSystem::loadSerializable(object);

m_instancing = object->get<bool>("instancing", false);
m_color = object->get<SColor>("instancing", SColor(255, 180, 180, 180));
m_color = object->get<SColor>("color", SColor(255, 180, 180, 180));

m_material->setUniform4("uColor", m_color);

CArraySerializable* primitives = (CArraySerializable*)object->getProperty("Primitives");
if (primitives == NULL)
return;

int numPrimities = primitives->getElementCount();

removeAllEntities();

for (int i = 0; i < numPrimities; i++)
{
CMatrixProperty* transformData = (CMatrixProperty*)primitives->getElement(i);
if (transformData == NULL)
return;

CEntity* entity = addPrimitive(
core::vector3df(),
core::vector3df(),
core::vector3df(1.0f, 1.0f, 1.0f)
);

// set transform
CWorldTransformData* world = (CWorldTransformData*)entity->getDataByIndex(CWorldTransformData::DataTypeIndex);
world->Relative = transformData->get();
}
}

CEntity* CPrimitive::spawn()
Expand All @@ -94,6 +142,7 @@ namespace Skylicht

CPrimiviteData* primitiveData = entity->addData<CPrimiviteData>();
primitiveData->Type = m_type;
primitiveData->Material = m_material;

// Culling
entity->addData<CWorldInverseTransformData>();
Expand Down
2 changes: 2 additions & 0 deletions Projects/Skylicht/Components/Source/Primitive/CPrimitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ namespace Skylicht

bool m_instancing;

CMaterial* m_material;

protected:

CPrimitive();
Expand Down
12 changes: 12 additions & 0 deletions Projects/Skylicht/Components/Source/Primitive/CPrimitiveData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,16 @@ This file is part of the "Skylicht Engine".
namespace Skylicht
{
IMPLEMENT_DATA_TYPE_INDEX(CPrimiviteData);

CPrimiviteData::CPrimiviteData() :
Type(CPrimiviteData::Unknown),
Material(NULL)
{

}

CPrimiviteData::~CPrimiviteData()
{

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ namespace Skylicht
m_pipelineType = IRenderPipeline::Mix;

for (int i = 0; i < (int)CPrimiviteData::Count; i++)
{
m_mesh[i] = NULL;
m_materials[i] = NULL;
}

const IGeometryCreator* geometry = getIrrlichtDevice()->getSceneManager()->getGeometryCreator();

Expand All @@ -62,9 +59,6 @@ namespace Skylicht
{
if (m_mesh[i])
m_mesh[i]->drop();

if (m_materials[i])
m_materials[i]->drop();
}
}

Expand Down Expand Up @@ -160,50 +154,37 @@ namespace Skylicht
ib->setIndex(i, u[i]);

CMesh* mesh = new CMesh();
CMaterial* mat = new CMaterial("Primitive", "BuiltIn/Shader/SpecularGlossiness/Deferred/Color.xml");

mesh->addMeshBuffer(meshBuffer, "", mat);

mat->setUniform4("uColor", SColor(255, 180, 180, 180));
mat->addAffectMesh(meshBuffer);
mat->applyMaterial();
mesh->addMeshBuffer(meshBuffer);

meshBuffer->recalculateBoundingBox();
mesh->recalculateBoundingBox();
mesh->setHardwareMappingHint(EHM_STATIC);

m_mesh[CPrimiviteData::Cube] = mesh;
m_materials[CPrimiviteData::Cube] = mat;

meshBuffer->drop();
}

void CPrimitiveRenderer::initMesh(IMesh* primitiveMesh, CPrimiviteData::EPrimitive primitive)
{
CMesh* mesh = new CMesh();
CMaterial* mat = new CMaterial("Primitive", "BuiltIn/Shader/SpecularGlossiness/Deferred/Color.xml");

IMeshBuffer* mb = primitiveMesh->getMeshBuffer(0);
mesh->addMeshBuffer(mb, "", mat);

mat->setUniform4("uColor", SColor(255, 180, 180, 180));
mat->addAffectMesh(mb);
mat->applyMaterial();
mesh->addMeshBuffer(mb);

mb->recalculateBoundingBox();
mesh->recalculateBoundingBox();
mesh->setHardwareMappingHint(EHM_STATIC);

m_mesh[primitive] = mesh;
m_materials[primitive] = mat;
}

void CPrimitiveRenderer::beginQuery(CEntityManager* entityManager)
{
for (int i = 0; i < CPrimiviteData::Count; i++)
{
m_transforms[i].set_used(0);
m_primitives[i].set_used(0);
m_transforms[i].set_used(0);
}
}

Expand All @@ -213,11 +194,8 @@ namespace Skylicht
if (p != NULL)
{
CVisibleData* visible = (CVisibleData*)entity->getDataByIndex(CVisibleData::DataTypeIndex);
CWorldTransformData* transformData = (CWorldTransformData*)entity->getDataByIndex(CWorldTransformData::DataTypeIndex);

if (visible->Visible)
{
m_transforms[p->Type].push_back(transformData->World);
m_primitives[p->Type].push_back(p);
}
}
Expand All @@ -228,24 +206,50 @@ namespace Skylicht

}

int cmpfunc(const void* a, const void* b)
{
CPrimiviteData* pa = *((CPrimiviteData**)a);
CPrimiviteData* pb = *((CPrimiviteData**)b);

return pa->Material > pb->Material;
}

void CPrimitiveRenderer::update(CEntityManager* entityManager)
{
for (int type = 0; type < CPrimiviteData::Count; type++)
{
if (m_mesh[type] == NULL)
continue;

core::array<CPrimiviteData*>& primitives = m_primitives[type];
u32 count = primitives.size();

// need sort by material
qsort(primitives.pointer(), count, sizeof(CPrimiviteData*), cmpfunc);

// get world transform
for (u32 i = 0; i < count; i++)
{
CEntity* entity = entityManager->getEntity(primitives[i]->EntityIndex);

CWorldTransformData* transform = (CWorldTransformData*)entity->getDataByIndex(CWorldTransformData::DataTypeIndex);
m_transforms[type].push_back(transform->World);
}
}
}

void CPrimitiveRenderer::render(CEntityManager* entityManager)
{
for (int type = 0; type < CPrimiviteData::Count; type++)
{
if (m_mesh[type] == NULL || m_materials[type] == NULL)
if (m_mesh[type] == NULL)
continue;

renderPrimitive(
entityManager,
m_primitives[type],
m_transforms[type],
m_mesh[type],
m_materials[type]
m_mesh[type]
);
}
}
Expand All @@ -254,20 +258,34 @@ namespace Skylicht
CEntityManager* entityManager,
core::array<CPrimiviteData*>& primitives,
core::array<core::matrix4>& transforms,
CMesh* mesh,
CMaterial* material)
CMesh* mesh)
{
IVideoDriver* driver = getVideoDriver();
IRenderPipeline* rp = entityManager->getRenderPipeline();

if (!rp->canRenderMaterial(material))
return;
CMaterial* mat = NULL;

u32 count = transforms.size();
for (u32 i = 0; i < count; i++)
{
core::matrix4& world = transforms[i];
CPrimiviteData* data = primitives[i];

if (data->Material == NULL || !rp->canRenderMaterial(data->Material))
continue;

if (mat != data->Material)
{
mat = data->Material;
CShaderMaterial::setMaterial(data->Material);

for (u32 i = 0, n = mesh->MeshBuffers.size(); i < n; i++)
{
IMeshBuffer* mb = mesh->MeshBuffers[i];
mat->applyMaterial(mb->getMaterial());
}
}

core::matrix4& world = transforms[i];
driver->setTransform(video::ETS_WORLD, world);

for (u32 i = 0, n = mesh->MeshBuffers.size(); i < n; i++)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ namespace Skylicht
{
protected:
CMesh* m_mesh[CPrimiviteData::Count];
CMaterial* m_materials[CPrimiviteData::Count];

core::array<CPrimiviteData*> m_primitives[CPrimiviteData::Count];
core::array<core::matrix4> m_transforms[CPrimiviteData::Count];
Expand All @@ -62,8 +61,7 @@ namespace Skylicht
void renderPrimitive(CEntityManager* entityManager,
core::array<CPrimiviteData*>& primitives,
core::array<core::matrix4>& transforms,
CMesh* mesh,
CMaterial* material
CMesh* mesh
);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ This file is part of the "Skylicht Engine".
#pragma once

#include "Entity/IEntityData.h"
#include "Material/CMaterial.h"

namespace Skylicht
{
Expand All @@ -39,8 +40,14 @@ namespace Skylicht
Count
};

CPrimiviteData();

virtual ~CPrimiviteData();

DECLARE_DATA_TYPE_INDEX;

EPrimitive Type;

CMaterial* Material;
};
}
2 changes: 1 addition & 1 deletion Projects/Skylicht/Engine/Source/Culling/CCullingData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace Skylicht
IMPLEMENT_DATA_TYPE_INDEX(CCullingData);

CCullingData::CCullingData() :
Type(CCullingData::FrustumBox),
Type(CCullingData::BoundingBox),
Visible(true)
{

Expand Down
15 changes: 3 additions & 12 deletions Projects/Skylicht/Engine/Source/LightProbes/CLightProbes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,6 @@ namespace Skylicht
CWorldTransformData* world = (CWorldTransformData*)m_entities[i]->getDataByIndex(CWorldTransformData::DataTypeIndex);
CLightProbeData* light = (CLightProbeData*)m_entities[i]->getDataByIndex(CLightProbeData::DataTypeIndex);

// save id
probeData->EntityID.set(m_entities[i]->getID());

// save transform
probeData->Transform.set(world->Relative);

Expand All @@ -107,15 +104,12 @@ namespace Skylicht
CComponentSystem::loadSerializable(object);

CArraySerializable* probes = (CArraySerializable*)object->getProperty("Probes");
int numProbes = probes->getElementCount();

removeAllEntities();

if (probes == NULL)
return;

if (probes->getElementCount() < numProbes)
return;
int numProbes = probes->getElementCount();

removeAllEntities();

for (int i = 0; i < numProbes; i++)
{
Expand All @@ -127,9 +121,6 @@ namespace Skylicht
CWorldTransformData* world = (CWorldTransformData*)entity->getDataByIndex(CWorldTransformData::DataTypeIndex);
CLightProbeData* light = (CLightProbeData*)entity->getDataByIndex(CLightProbeData::DataTypeIndex);

// set id
entity->setID(shData->EntityID.getString());

// set transform
world->Relative = shData->Transform.get();

Expand Down
Loading

0 comments on commit 96a3b33

Please sign in to comment.