Skip to content

Commit

Permalink
Merge pull request #3 from kochol/shaders
Browse files Browse the repository at this point in the history
The new Material system added
  • Loading branch information
kochol authored May 5, 2020
2 parents 619b513 + c639f91 commit 73bbf1a
Show file tree
Hide file tree
Showing 28 changed files with 870 additions and 47 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@
.fips-settings.yml
*.pyc
*.ktx
tests/07-gltf/assets/Buggy.gltf
tests/07-gltf/assets/Buggy0.bin
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ done! it's ready to rock.

# Changes

## Ariyana Game Engine 0.4

- Implement material system
- Phong lighting
- Directional light and omni light
- Fix some bugs

## Ariyana Game Engine 0.3

- Adding gltf mesh loader
Expand Down
2 changes: 2 additions & 0 deletions src/3d/FrameData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <LinearAllocator.h>
#include <cstdint>
#include "core/containers/Array.hpp"
#include "sx/math.h"

namespace ari::en
{
Expand All @@ -13,6 +14,7 @@ namespace ari::en
core::Array<Node3D*> Nodes;
uint32_t FrameNumber = 0;
Camera* CameraObj;
sx_vec3 CameraPos;
int FrameDataTurnIndex = 0;

}; // FrameData
Expand Down
6 changes: 3 additions & 3 deletions src/3d/MeshNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ namespace ari::en
{
if (Mesh.IsValid())
{
sx_mat4 mvp = gfx::GetViewProjMatrix() * _finalMat[_frameTurnIndex];
gfx::SetWorldMatrix(_finalMat[_frameTurnIndex]);

auto mesh = core::ObjectPool<gfx::Mesh>::GetByIndex(Mesh.Index);
for (auto sub_mesh_hdl: mesh->SubMeshes)
{
if (sub_mesh_hdl.IsValid())
{
const auto sub_mesh = core::ObjectPool<gfx::SubMesh>::GetByIndex(sub_mesh_hdl.Index);
gfx::ApplyPipeline(sub_mesh->Pipeline);
gfx::SetMaterialShader(sub_mesh->Material);
gfx::ApplyPipelineAndMaterial(sub_mesh->Pipeline, &sub_mesh->Material);
gfx::ApplyBindings(sub_mesh->Binding);
ApplyUniforms(gfx::ShaderStage::VertexShader, 0, &mvp, sizeof(sx_mat4));
gfx::Draw(0, sub_mesh->ElementsCount, 1);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/3d/RenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ namespace ari::en
// TODO: Set viewport
gfx::Viewport* pViewport = m_pFrameDataCurrent->CameraObj->GetViewport();
gfx::SetViewProjMatrix(m_pFrameDataCurrent->CameraObj->_view, m_pFrameDataCurrent->CameraObj->_proj);
gfx::SetCameraPosition(m_pFrameDataCurrent->CameraPos);
}
for (auto node : m_pFrameDataCurrent->Nodes)
{
Expand Down
19 changes: 12 additions & 7 deletions src/3d/SceneSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace ari::en
m_pFrameDataTransforms = &m_aFrameData[m_FameDataTurnIndex];
m_pFrameDataTransforms->FrameNumber = gfx::GetFrameNumber();
m_pFrameDataTransforms->CameraObj = m_pActiveCamera;
m_pFrameDataTransforms->CameraPos = m_pActiveCamera->Position;
m_pFrameDataTransforms->Nodes.Clear();

// Get all entities and calc transforms
Expand All @@ -57,7 +58,7 @@ namespace ari::en
rect = io::GetWindowSize(TargetWindow);
}
m_pActiveCamera->_proj = sx_mat4_perspectiveFOV(sx_torad(m_pActiveCamera->Fov),
float(rect.width) / float(rect.height), m_pActiveCamera->zNear, m_pActiveCamera->zFar, true);
float(rect.width) / float(rect.height), m_pActiveCamera->zNear, m_pActiveCamera->zFar, true);
}

m_FameDataTurnIndex++;
Expand Down Expand Up @@ -99,7 +100,7 @@ namespace ari::en
}
}

void SceneSystem::CalcTransform(Node3D* node, sx_mat4* parentMat)
void SceneSystem::CalcTransform(Node3D* node, Node3D* parent)
{
sx_mat4 m;
if (node->has_mat)
Expand All @@ -112,22 +113,26 @@ namespace ari::en
node->Rotation.x, node->Rotation.y, node->Rotation.z,
node->Position.x, node->Position.y, node->Position.z);
}
if (parentMat)
node->_finalMat[m_FameDataTurnIndex] = m * (*parentMat);
if (parent)
{
node->_finalMat[m_FameDataTurnIndex] = parent->_finalMat[m_FameDataTurnIndex] * m;
}
else
{
node->_finalMat[m_FameDataTurnIndex] = m;
parentMat = &node->_finalMat[m_FameDataTurnIndex];
}
parent = node;

if (node->_isRenderable)
{
// Add it to frame data
m_pFrameDataTransforms->Nodes.Add(node);
}
node->GetChildren([parentMat, this](Node* n)
node->GetChildren([parent, this](Node* n)
{
if (n->GetBaseId() == Node3D::Id)
{
CalcTransform(reinterpret_cast<Node3D*>(n), parentMat);
CalcTransform(reinterpret_cast<Node3D*>(n), parent);
}
});
} // CalcTransform
Expand Down
2 changes: 1 addition & 1 deletion src/3d/SceneSystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace ari::en
* m_pFrameDataTransforms, // This is the transform calculated nodes
* m_pFrameDataVisible; // This is the visible nodes that must be rendered.

void CalcTransform(Node3D* node, sx_mat4* parentMat);
void CalcTransform(Node3D* node, Node3D* parent);

}; // SceneSystem

Expand Down
69 changes: 52 additions & 17 deletions src/3d/private/gltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,21 @@ namespace ari::en
core::String BasePath;
};

core::Array<core::KeyValuePair<gfx::PipelineSetup, gfx::PipelineHandle>> g_aGltfPipelines;

gfx::PipelineHandle GetPipelineHandle(const gfx::PipelineSetup& setup)
{
for (auto& pair: g_aGltfPipelines)
{
const auto& p = pair.Key();
if (p == setup)
return pair.Value();
}
const auto pipe = gfx::CreatePipeline(setup);
g_aGltfPipelines.Add({ setup, pipe });
return pipe;
}

void SetPipelineAttribute(gfx::VertexAttrSetup& attr, cgltf_attribute* gltf_attr)
{
switch (gltf_attr->data->component_type)
Expand Down Expand Up @@ -330,8 +345,8 @@ namespace ari::en


// parse the meshes
core::ObjectPool<gfx::Mesh>::Setup(64);
core::ObjectPool<gfx::SubMesh>::Setup(128);
core::ObjectPool<gfx::Mesh>::Setup(512);
core::ObjectPool<gfx::SubMesh>::Setup(512);
p_scene_data->NumMeshes = int(gltf->meshes_count);
p_scene_data->Meshes.Reserve(p_scene_data->NumMeshes);
for (int i = 0; i < p_scene_data->NumMeshes; i++)
Expand All @@ -355,25 +370,31 @@ namespace ari::en
gfx::Bindings bindings;

// Set the textures
if (gltf_prim->material
&& gltf_prim->material->has_pbr_metallic_roughness
&& gltf_prim->material->pbr_metallic_roughness.base_color_texture.texture)
if (gltf_prim->material)
{
int tex_index = gltf_prim->material->pbr_metallic_roughness.base_color_texture.texture - gltf->textures;
bindings.fsTextures[0] = p_scene_data->Textures[tex_index];
pipeline_setup.shader = gfx::GetShader(gfx::ShaderType::BasicTexture);
}
else
{
pipeline_setup.shader = gfx::GetShader(gfx::ShaderType::Basic);
if (gltf_prim->material->has_pbr_metallic_roughness)
{
if (gltf_prim->material->pbr_metallic_roughness.base_color_texture.texture)
{
int tex_index = gltf_prim->material->pbr_metallic_roughness.base_color_texture.texture - gltf->textures;
bindings.fsTextures[0] = p_scene_data->Textures[tex_index];
}
core::Memory::Copy(gltf_prim->material->pbr_metallic_roughness.base_color_factor, sub_mesh->Material.BaseColor.f, 16);
}
else if(gltf_prim->material->has_pbr_specular_glossiness)
{
core::Memory::Copy(gltf_prim->material->pbr_specular_glossiness.diffuse_factor, sub_mesh->Material.BaseColor.f, 16);
}
}
pipeline_setup.shader = gfx::GetShader(gfx::ShaderType::Basic);

sub_mesh->Type = gfx::PrimitiveType(int(gltf_prim->type));
if (gltf_prim->indices)
{
// Add indices
const int accessor_index = int(gltf_prim->indices - gltf->accessors);
sub_mesh->IndexBuffer = p_scene_data->Accessors[accessor_index].GfxBuffer;
bindings.indexBufferOffset = p_scene_data->Accessors[accessor_index].Offset;
sub_mesh->ElementsCount = int(gltf_prim->indices->count);
pipeline_setup.index_type = gfx::IndexType::Uint16;
bindings.indexBuffer = sub_mesh->IndexBuffer;
Expand All @@ -394,7 +415,6 @@ namespace ari::en
case cgltf_attribute_type_position:
sub_mesh->Position = accessor->GfxBuffer;
buffer_index = 0;
// TODO: add bounding box
if (accessor->HasMax)
{
sub_mesh->AABB.xmax = accessor->Max[0];
Expand All @@ -407,21 +427,26 @@ namespace ari::en
break;
case cgltf_attribute_type_texcoord:
sub_mesh->Texcoord = accessor->GfxBuffer;
if (sub_mesh->Material.HasVertexColor)
continue;
buffer_index = 1;
sub_mesh->Material.HasTexcoord = true;
break;
case cgltf_attribute_type_normal:
continue;
sub_mesh->Normal = accessor->GfxBuffer;
buffer_index = 2;
sub_mesh->Material.HasNormal = true;
break;
case cgltf_attribute_type_tangent:
sub_mesh->Tangent = accessor->GfxBuffer;
buffer_index = 3;
break;
case cgltf_attribute_type_color:
sub_mesh->Color = p_scene_data->Accessors[accessor_index].GfxBuffer;
buffer_index = 2;
buffer_index = 1;
pipeline_setup.shader = gfx::GetShader(gfx::ShaderType::BasicVertexColor);
sub_mesh->Material.HasVertexColor = true;
sub_mesh->Material.HasTexcoord = false;
break;
case cgltf_attribute_type_joints:
sub_mesh->Joints = p_scene_data->Accessors[accessor_index].GfxBuffer;
Expand All @@ -442,8 +467,18 @@ namespace ari::en
bindings.vertexBufferOffsets[buffer_index] = accessor->Offset;
}
}

sub_mesh->Pipeline = gfx::CreatePipeline(pipeline_setup);
if (!sub_mesh->Material.HasTexcoord && !sub_mesh->Material.HasVertexColor && sub_mesh->Material.HasNormal)
{
// set the normal to stage 1
pipeline_setup.layout.attrs[1] = pipeline_setup.layout.attrs[2];
pipeline_setup.layout.attrs[1].bufferIndex = 1;
pipeline_setup.layout.attrs[2] = pipeline_setup.layout.attrs[7];
bindings.vertexBufferOffsets[1] = bindings.vertexBufferOffsets[2];
bindings.vertexBuffers[1] = bindings.vertexBuffers[2];
bindings.vertexBufferOffsets[2] = bindings.vertexBufferOffsets[7];
bindings.vertexBuffers[2] = bindings.vertexBuffers[7];
}
sub_mesh->Pipeline = GetPipelineHandle(pipeline_setup);
sub_mesh->Binding = gfx::CreateBinding(bindings);
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/core/containers/Array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class Array

/// increase capacity to hold at least numElements more elements
void Reserve(int numElements);
/// fill the array with dummy data
void FillDumyData();
/// trim capacity to size (this involves a re-alloc)
void Trim();
/// clear the array (deletes elements, keeps capacity)
Expand Down Expand Up @@ -322,6 +324,12 @@ void Array<TYPE>::Reserve(int numElements)
}
}

template<class TYPE>
inline void Array<TYPE>::FillDumyData()
{
this->buffer.end = this->buffer.cap;
}

//------------------------------------------------------------------------------
template <class TYPE>
void Array<TYPE>::Trim()
Expand Down
2 changes: 1 addition & 1 deletion src/en/World.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ namespace ari::en
template<class T, class BASE>
ComponentHandle<T> World::CreateComponent()
{
core::MemoryPool<BASE>::Setup(102400);
core::MemoryPool<BASE>::Setup(302400);
uint32_t i;
const uint32_t h = core::HandleManager<BASE>::GetNewHandle(i);

Expand Down
5 changes: 5 additions & 0 deletions src/gfx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ fips_begin_module(ari_gfx)
fips_files(
Application.hpp
gfx.hpp gfx.cpp
Material.hpp
MaterialInstance.hpp
MaterialParams.hpp
Mesh.hpp
SubMesh.hpp
Vertices.hpp
Expand Down Expand Up @@ -31,6 +34,8 @@ fips_begin_module(ari_gfx)
fips_libs(GLESv3 EGL android log)
endif()

fips_dir(shaders)
sokol_shader(mesh.glsl ${slang})
fips_dir(shaders/basic)
sokol_shader(basic.glsl ${slang})

Expand Down
37 changes: 37 additions & 0 deletions src/gfx/Material.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include "gfx.hpp"
#include "core/string/StringAtom.hpp"

namespace ari::gfx
{
struct MaterialUniformInfo
{
core::StringAtom Name;
int Size;
int Offset;
ShaderStage Stage;
bool SystemData; //! This uniform is filled by engine or can be set by user
};

//! The material base class. This class dose not store the uniform params. They are in MaterialInstance
struct Material
{
bool HasTexcoord = false;
bool HasVertexColor = false;
bool HasNormal = false;

// User controlled values
float SpecularStrength = 1.0f;
sx_vec4 BaseColor = sx_vec4f(1.f, 1.f, 1.f, 1.f);

sg_shader_desc* shader_desc = nullptr;
ShaderHandle shader;
const core::Array<MaterialUniformInfo>* Uniforms;
int VS_UniformSize;
int FS_UniformSize;
core::Array<float> Vs_UniformData;
core::Array<float> Fs_UniformData;
};

} // namespace ari::gfx
14 changes: 14 additions & 0 deletions src/gfx/MaterialInstance.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

namespace ari::gfx
{
struct MaterialInstance
{
// Ambient color
// Diffuse color
// Specular color
// Textures
// Parent Material
};

} // namespace ari::gfx
10 changes: 10 additions & 0 deletions src/gfx/MaterialParams.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

namespace ari::gfx
{
struct MaterialParams
{

};

} // namespace ari::gfx
2 changes: 2 additions & 0 deletions src/gfx/SubMesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "core/containers/Array.hpp"
#include "gfx.hpp"
#include "core/defines.hpp"
#include "gfx/Material.hpp"

namespace ari::gfx
{
Expand All @@ -22,6 +23,7 @@ namespace ari::gfx
int ElementsCount;
gfx::PipelineHandle Pipeline;
gfx::BindingHandle Binding;
gfx::Material Material;
sx_aabb AABB = {{SX_FLOAT_MAX, SX_FLOAT_MAX, SX_FLOAT_MAX,
-SX_FLOAT_MAX, -SX_FLOAT_MAX, -SX_FLOAT_MAX}};
};
Expand Down
Loading

0 comments on commit 73bbf1a

Please sign in to comment.