From f34f898a4b97b8d3380cff2d1240db67fd4c2706 Mon Sep 17 00:00:00 2001 From: Pham Hong Duc Date: Fri, 27 May 2022 21:54:00 +0700 Subject: [PATCH] #149 Add culling for primitive & fix normal cube mesh --- .../Source/Primitive/CPrimitive.cpp | 13 ++ .../Source/Primitive/CPrimitiveRenderer.cpp | 121 +++++++++++++++++- .../Source/Primitive/CPrimitiveRenderer.h | 2 + .../Engine/Source/Culling/CCullingSystem.cpp | 2 +- .../Engine/Source/Culling/CCullingSystem.h | 13 +- .../Source/Lighting/CDirectionalLight.cpp | 1 + .../Source/RenderPipeline/CShadowMapRP.cpp | 6 +- 7 files changed, 148 insertions(+), 10 deletions(-) diff --git a/Projects/Skylicht/Components/Source/Primitive/CPrimitive.cpp b/Projects/Skylicht/Components/Source/Primitive/CPrimitive.cpp index 763c91f5f..526144155 100644 --- a/Projects/Skylicht/Components/Source/Primitive/CPrimitive.cpp +++ b/Projects/Skylicht/Components/Source/Primitive/CPrimitive.cpp @@ -28,6 +28,10 @@ This file is part of the "Skylicht Engine". #include "GameObject/CGameObject.h" #include "Entity/CEntityManager.h" #include "Transform/CWorldTransformData.h" +#include "Transform/CWorldInverseTransformData.h" +#include "Culling/CCullingData.h" +#include "Culling/CCullingBBoxData.h" + namespace Skylicht { @@ -64,6 +68,15 @@ namespace Skylicht CPrimiviteData* primitiveData = entity->addData(); primitiveData->Type = m_type; + // Culling + entity->addData(); + entity->addData(); + + CCullingBBoxData* cullingBBox = entity->addData(); + cullingBBox->BBox.MinEdge.set(-1.0f, -1.0f, -1.0f); + cullingBBox->BBox.MaxEdge.set(1.0f, 1.0f, 1.0f); + + // Position CWorldTransformData* transform = (CWorldTransformData*)entity->getDataByIndex(CWorldTransformData::DataTypeIndex); transform->Relative.setTranslation(pos); transform->Relative.setRotationDegrees(rotDeg); diff --git a/Projects/Skylicht/Components/Source/Primitive/CPrimitiveRenderer.cpp b/Projects/Skylicht/Components/Source/Primitive/CPrimitiveRenderer.cpp index 3d7d448ba..ae4bb6b84 100644 --- a/Projects/Skylicht/Components/Source/Primitive/CPrimitiveRenderer.cpp +++ b/Projects/Skylicht/Components/Source/Primitive/CPrimitiveRenderer.cpp @@ -45,9 +45,7 @@ namespace Skylicht // cube mesh { - IMesh* m = geometry->createCubeMesh(core::vector3df(1.0f, 1.0f, 1.0f)); - initMesh(m, CPrimiviteData::Cube); - m->drop(); + initCube(); } // sphere mesh @@ -70,6 +68,123 @@ namespace Skylicht } } + void CPrimitiveRenderer::initCube() + { + IVideoDriver* driver = getVideoDriver(); + + // Irrlicht Engine Mesh Buffer instance + // http://irrlicht.sourceforge.net/docu/classirr_1_1scene_1_1_c_mesh_buffer.html + IMeshBuffer* meshBuffer = new CMeshBuffer(driver->getVertexDescriptor(EVT_STANDARD), EIT_16BIT); + IIndexBuffer* ib = meshBuffer->getIndexBuffer(); + IVertexBuffer* vb = meshBuffer->getVertexBuffer(); + + // Create vertices + video::SColor clr1(255, 255, 0, 0); + video::SColor clr2(255, 0, 255, 0); + video::SColor clr3(255, 0, 0, 255); + video::SColor clr4(255, 255, 255, 255); + video::SColor clr5(255, 255, 0, 255); + video::SColor clr6(255, 255, 255, 0); + + + vb->reallocate(12); + + video::S3DVertex Vertices[] = { + // back + video::S3DVertex(0, 0, 0, 0, 0, -1, clr1, 0, 1), + video::S3DVertex(1, 0, 0, 0, 0, -1, clr1, 1, 1), + video::S3DVertex(1, 1, 0, 0, 0, -1, clr1, 1, 0), + video::S3DVertex(0, 1, 0, 0, 0, -1, clr1, 1, 0), + + // front + video::S3DVertex(0, 0, 1, 0, 0, 1, clr2, 0, 1), + video::S3DVertex(1, 0, 1, 0, 0, 1, clr2, 1, 1), + video::S3DVertex(1, 1, 1, 0, 0, 1, clr2, 1, 0), + video::S3DVertex(0, 1, 1, 0, 0, 1, clr2, 1, 0), + + // bottom + video::S3DVertex(0, 0, 0, 0, -1, 0, clr3, 0, 1), + video::S3DVertex(0, 0, 1, 0, -1, 0, clr3, 1, 1), + video::S3DVertex(1, 0, 1, 0, -1, 0, clr3, 1, 0), + video::S3DVertex(1, 0, 0, 0, -1, 0, clr3, 1, 0), + + // top + video::S3DVertex(0, 1, 0, 0, 1, 0, clr4, 0, 1), + video::S3DVertex(0, 1, 1, 0, 1, 0, clr4, 1, 1), + video::S3DVertex(1, 1, 1, 0, 1, 0, clr4, 1, 0), + video::S3DVertex(1, 1, 0, 0, 1, 0, clr4, 1, 0), + + // left + video::S3DVertex(1, 0, 0, -1, 0, 0, clr5, 0, 1), + video::S3DVertex(1, 0, 1, -1, 0, 0, clr5, 1, 1), + video::S3DVertex(1, 1, 1, -1, 0, 0, clr5, 1, 0), + video::S3DVertex(1, 1, 0, -1, 0, 0, clr5, 1, 0), + + // right + video::S3DVertex(0, 0, 0, 1, 0, 0, clr5, 0, 1), + video::S3DVertex(0, 0, 1, 1, 0, 0, clr5, 1, 1), + video::S3DVertex(0, 1, 1, 1, 0, 0, clr5, 1, 0), + video::S3DVertex(0, 1, 0, 1, 0, 0, clr5, 1, 0), + }; + + for (u32 i = 0; i < 24; ++i) + { + Vertices[i].Pos -= core::vector3df(0.5f, 0.5f, 0.5f); + vb->addVertex(&Vertices[i]); + } + + // cube mesh + // Create indices + const u16 u[36] = + { + // back + 0,2,1, + 0,3,2, + + // front + 4,5,6, + 4,6,7, + + // bottom + 8,10,9, + 8,11,10, + + // top + 12,13,14, + 12,14,15, + + // left + 16,18,17, + 16,19,18, + + // right + 20,21,22, + 20,22,23 + }; + + ib->set_used(36); + + for (u32 i = 0; i < 36; ++i) + 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(); + + meshBuffer->recalculateBoundingBox(); + mesh->recalculateBoundingBox(); + + m_mesh[CPrimiviteData::Cube] = mesh; + m_materials[CPrimiviteData::Cube] = mat; + + meshBuffer->drop(); + } + void CPrimitiveRenderer::initMesh(IMesh* primitiveMesh, CPrimiviteData::EPrimitive primitive) { CMesh* mesh = new CMesh(); diff --git a/Projects/Skylicht/Components/Source/Primitive/CPrimitiveRenderer.h b/Projects/Skylicht/Components/Source/Primitive/CPrimitiveRenderer.h index f45371aaf..69d0e81ab 100644 --- a/Projects/Skylicht/Components/Source/Primitive/CPrimitiveRenderer.h +++ b/Projects/Skylicht/Components/Source/Primitive/CPrimitiveRenderer.h @@ -47,6 +47,8 @@ namespace Skylicht void initMesh(IMesh* primitiveMesh, CPrimiviteData::EPrimitive primitive); + void initCube(); + virtual void beginQuery(CEntityManager* entityManager); virtual void onQuery(CEntityManager* entityManager, CEntity* entity); diff --git a/Projects/Skylicht/Engine/Source/Culling/CCullingSystem.cpp b/Projects/Skylicht/Engine/Source/Culling/CCullingSystem.cpp index e7aa6da42..8b89d22dd 100644 --- a/Projects/Skylicht/Engine/Source/Culling/CCullingSystem.cpp +++ b/Projects/Skylicht/Engine/Source/Culling/CCullingSystem.cpp @@ -74,7 +74,7 @@ namespace Skylicht { CWorldTransformData* transform = (CWorldTransformData*)entity->getDataByIndex(CWorldTransformData::DataTypeIndex); CWorldInverseTransformData* invTransform = (CWorldInverseTransformData*)entity->getDataByIndex(CWorldInverseTransformData::DataTypeIndex); - + { m_cullings.push_back(culling); diff --git a/Projects/Skylicht/Engine/Source/Culling/CCullingSystem.h b/Projects/Skylicht/Engine/Source/Culling/CCullingSystem.h index 49f358529..7abbc85be 100644 --- a/Projects/Skylicht/Engine/Source/Culling/CCullingSystem.h +++ b/Projects/Skylicht/Engine/Source/Culling/CCullingSystem.h @@ -35,7 +35,10 @@ namespace Skylicht { struct SBBoxAndMaterial { + // Local BBox to check culling core::aabbox3df BBox; + + // Material to check render pipeline cull ArrayMaterial* Materials; SBBoxAndMaterial(const core::aabbox3df& box, ArrayMaterial* m) @@ -60,14 +63,14 @@ namespace Skylicht virtual void beginQuery(CEntityManager* entityManager); - virtual void onQuery(CEntityManager *entityManager, CEntity *entity); + virtual void onQuery(CEntityManager* entityManager, CEntity* entity); - virtual void init(CEntityManager *entityManager); + virtual void init(CEntityManager* entityManager); - virtual void update(CEntityManager *entityManager); + virtual void update(CEntityManager* entityManager); - virtual void render(CEntityManager *entityManager); + virtual void render(CEntityManager* entityManager); - virtual void postRender(CEntityManager *entityManager); + virtual void postRender(CEntityManager* entityManager); }; } \ No newline at end of file diff --git a/Projects/Skylicht/Engine/Source/Lighting/CDirectionalLight.cpp b/Projects/Skylicht/Engine/Source/Lighting/CDirectionalLight.cpp index 56c6dfc5a..b66cdd848 100644 --- a/Projects/Skylicht/Engine/Source/Lighting/CDirectionalLight.cpp +++ b/Projects/Skylicht/Engine/Source/Lighting/CDirectionalLight.cpp @@ -40,6 +40,7 @@ namespace Skylicht { // default 2 bounce m_bakeBounce = 2; + m_castShadow = true; } CDirectionalLight::~CDirectionalLight() diff --git a/Projects/Skylicht/Engine/Source/RenderPipeline/CShadowMapRP.cpp b/Projects/Skylicht/Engine/Source/RenderPipeline/CShadowMapRP.cpp index 68b1a781f..8918386fd 100644 --- a/Projects/Skylicht/Engine/Source/RenderPipeline/CShadowMapRP.cpp +++ b/Projects/Skylicht/Engine/Source/RenderPipeline/CShadowMapRP.cpp @@ -140,10 +140,13 @@ namespace Skylicht return; // use direction light + bool castShadow = true; + CDirectionalLight* light = CShaderLighting::getDirectionalLight(); if (light != NULL) { m_lightDirection = light->getDirection(); + castShadow = light->isCastShadow(); } m_csm->update(camera, m_lightDirection); @@ -170,7 +173,8 @@ namespace Skylicht m_currentCSM = i; - entityManager->cullingAndRender(); + if (castShadow) + entityManager->cullingAndRender(); } // todo