Graphics: Add GraphicalMesh and Model classes
This commit is contained in:
parent
a1e0ae3f38
commit
a9e9ef2524
|
|
@ -23,6 +23,7 @@ int main()
|
|||
Nz::RenderWindow window;
|
||||
|
||||
Nz::MeshParams meshParams;
|
||||
meshParams.storage = Nz::DataStorage_Software;
|
||||
meshParams.matrix = Nz::Matrix4f::Rotate(Nz::EulerAnglesf(0.f, 90.f, 180.f)) * Nz::Matrix4f::Scale(Nz::Vector3f(0.002f));
|
||||
meshParams.vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout_XYZ_Normal_UV);
|
||||
|
||||
|
|
@ -42,16 +43,7 @@ int main()
|
|||
return __LINE__;
|
||||
}
|
||||
|
||||
Nz::StaticMesh* drfreakMesh = static_cast<Nz::StaticMesh*>(drfreak->GetSubMesh(0));
|
||||
|
||||
const Nz::VertexBuffer* drfreakVB = drfreakMesh->GetVertexBuffer();
|
||||
const Nz::IndexBuffer* drfreakIB = drfreakMesh->GetIndexBuffer();
|
||||
|
||||
// Index buffer
|
||||
std::cout << "Index count: " << drfreakIB->GetIndexCount() << std::endl;
|
||||
|
||||
// Vertex buffer
|
||||
std::cout << "Vertex count: " << drfreakVB->GetVertexCount() << std::endl;
|
||||
std::shared_ptr<Nz::GraphicalMesh> gfxMesh = std::make_shared<Nz::GraphicalMesh>(drfreak);
|
||||
|
||||
// Texture
|
||||
Nz::ImageRef drfreakImage = Nz::Image::LoadFromFile("resources/Spaceship/Texture/diffuse.png");
|
||||
|
|
@ -101,16 +93,20 @@ int main()
|
|||
|
||||
std::shared_ptr<Nz::TextureSampler> textureSampler = device->InstantiateTextureSampler({});
|
||||
|
||||
Nz::Material material(Nz::BasicMaterial::GetSettings());
|
||||
material.EnableDepthBuffer(true);
|
||||
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>(Nz::BasicMaterial::GetSettings());
|
||||
material->EnableDepthBuffer(true);
|
||||
|
||||
Nz::BasicMaterial basicMat(material);
|
||||
Nz::BasicMaterial basicMat(*material);
|
||||
basicMat.EnableAlphaTest(false);
|
||||
basicMat.SetAlphaMap(alphaTexture);
|
||||
basicMat.SetAlphaSampler(textureSampler);
|
||||
basicMat.SetDiffuseMap(texture);
|
||||
basicMat.SetDiffuseSampler(textureSampler);
|
||||
|
||||
Nz::Model model(std::move(gfxMesh));
|
||||
for (std::size_t i = 0; i < model.GetSubMeshCount(); ++i)
|
||||
model.SetMaterial(i, material);
|
||||
|
||||
Nz::PredefinedInstanceData instanceUboOffsets = Nz::PredefinedInstanceData::GetOffsets();
|
||||
Nz::PredefinedViewerData viewerUboOffsets = Nz::PredefinedViewerData::GetOffsets();
|
||||
const Nz::BasicMaterial::UniformOffsets& materialSettingOffsets = Nz::BasicMaterial::GetOffsets();
|
||||
|
|
@ -126,29 +122,11 @@ int main()
|
|||
Nz::AccessByOffset<float&>(materialSettings.data(), materialSettingOffsets.alphaThreshold) = 0.5f;
|
||||
Nz::AccessByOffset<Nz::Vector4f&>(materialSettings.data(), materialSettingOffsets.diffuseColor) = Nz::Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
std::shared_ptr<Nz::RenderPipelineLayout> renderPipelineLayout = material.GetSettings()->GetRenderPipelineLayout();
|
||||
|
||||
std::shared_ptr<Nz::AbstractBuffer> matSettingUBO = device->InstantiateBuffer(Nz::BufferType_Uniform);
|
||||
if (!matSettingUBO->Initialize(materialSettings.size(), Nz::BufferUsage_DeviceLocal | Nz::BufferUsage_Dynamic))
|
||||
{
|
||||
NazaraError("Failed to create mat setting UBO");
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
matSettingUBO->Fill(materialSettings.data(), 0, materialSettings.size());
|
||||
|
||||
std::vector<Nz::RenderPipelineInfo::VertexBufferData> vertexBuffers = {
|
||||
{
|
||||
0,
|
||||
drfreakVB->GetVertexDeclaration()
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<std::uint8_t> instanceDataBuffer(instanceUboOffsets.totalSize);
|
||||
|
||||
Nz::ModelInstance modelInstance(material.GetSettings());
|
||||
Nz::ModelInstance modelInstance(material->GetSettings());
|
||||
{
|
||||
material.UpdateShaderBinding(modelInstance.GetShaderBinding());
|
||||
material->UpdateShaderBinding(modelInstance.GetShaderBinding());
|
||||
|
||||
Nz::AccessByOffset<Nz::Matrix4f&>(instanceDataBuffer.data(), instanceUboOffsets.worldMatrixOffset) = Nz::Matrix4f::Translate(Nz::Vector3f::Forward() * 2 + Nz::Vector3f::Right());
|
||||
|
||||
|
|
@ -156,9 +134,9 @@ int main()
|
|||
instanceDataUBO->Fill(instanceDataBuffer.data(), 0, instanceDataBuffer.size());
|
||||
}
|
||||
|
||||
Nz::ModelInstance modelInstance2(material.GetSettings());
|
||||
Nz::ModelInstance modelInstance2(material->GetSettings());
|
||||
{
|
||||
material.UpdateShaderBinding(modelInstance2.GetShaderBinding());
|
||||
material->UpdateShaderBinding(modelInstance2.GetShaderBinding());
|
||||
|
||||
Nz::AccessByOffset<Nz::Matrix4f&>(instanceDataBuffer.data(), instanceUboOffsets.worldMatrixOffset) = Nz::Matrix4f::Translate(Nz::Vector3f::Forward() * 2 + Nz::Vector3f::Right() * 3.f);
|
||||
|
||||
|
|
@ -168,31 +146,9 @@ int main()
|
|||
|
||||
std::shared_ptr<Nz::AbstractBuffer> viewerDataUBO = Nz::Graphics::Instance()->GetViewerDataUBO();
|
||||
|
||||
std::shared_ptr<Nz::RenderPipeline> pipeline = material.GetPipeline()->GetRenderPipeline(vertexBuffers);
|
||||
|
||||
Nz::RenderDevice* renderDevice = window.GetRenderDevice().get();
|
||||
|
||||
Nz::RenderWindowImpl* windowImpl = window.GetImpl();
|
||||
std::shared_ptr<Nz::CommandPool> commandPool = windowImpl->CreateCommandPool(Nz::QueueType::Graphics);
|
||||
|
||||
Nz::RenderBuffer* renderBufferIB = static_cast<Nz::RenderBuffer*>(drfreakIB->GetBuffer()->GetImpl());
|
||||
Nz::RenderBuffer* renderBufferVB = static_cast<Nz::RenderBuffer*>(drfreakVB->GetBuffer()->GetImpl());
|
||||
|
||||
if (!renderBufferIB->Synchronize(renderDevice))
|
||||
{
|
||||
NazaraError("Failed to synchronize render buffer");
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
if (!renderBufferVB->Synchronize(renderDevice))
|
||||
{
|
||||
NazaraError("Failed to synchronize render buffer");
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
Nz::AbstractBuffer* indexBufferImpl = renderBufferIB->GetHardwareBuffer(renderDevice);
|
||||
Nz::AbstractBuffer* vertexBufferImpl = renderBufferVB->GetHardwareBuffer(renderDevice);
|
||||
|
||||
Nz::CommandBufferPtr drawCommandBuffer;
|
||||
auto RebuildCommandBuffer = [&]
|
||||
{
|
||||
|
|
@ -214,17 +170,19 @@ int main()
|
|||
builder.SetScissor(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });
|
||||
builder.SetViewport(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });
|
||||
|
||||
builder.BindIndexBuffer(indexBufferImpl);
|
||||
builder.BindPipeline(*pipeline);
|
||||
builder.BindVertexBuffer(0, vertexBufferImpl);
|
||||
for (Nz::ModelInstance& modelInstance : { std::ref(modelInstance), std::ref(modelInstance2) })
|
||||
{
|
||||
builder.BindShaderBinding(modelInstance.GetShaderBinding());
|
||||
|
||||
builder.BindShaderBinding(modelInstance.GetShaderBinding());
|
||||
for (std::size_t i = 0; i < model.GetSubMeshCount(); ++i)
|
||||
{
|
||||
builder.BindIndexBuffer(model.GetIndexBuffer(i).get());
|
||||
builder.BindVertexBuffer(0, model.GetVertexBuffer(i).get());
|
||||
builder.BindPipeline(*model.GetRenderPipeline(i));
|
||||
|
||||
builder.DrawIndexed(drfreakIB->GetIndexCount());
|
||||
|
||||
builder.BindShaderBinding(modelInstance2.GetShaderBinding());
|
||||
|
||||
builder.DrawIndexed(drfreakIB->GetIndexCount());
|
||||
builder.DrawIndexed(model.GetIndexCount(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.EndRenderPass();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GRAPHICALMESH_HPP
|
||||
#define NAZARA_GRAPHICALMESH_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API GraphicalMesh
|
||||
{
|
||||
public:
|
||||
GraphicalMesh(const Mesh* mesh);
|
||||
GraphicalMesh(const GraphicalMesh&) = delete;
|
||||
GraphicalMesh(GraphicalMesh&&) noexcept = default;
|
||||
~GraphicalMesh() = default;
|
||||
|
||||
inline const std::shared_ptr<AbstractBuffer>& GetIndexBuffer(std::size_t subMesh) const;
|
||||
inline std::size_t GetIndexCount(std::size_t subMesh) const;
|
||||
inline const std::shared_ptr<AbstractBuffer>& GetVertexBuffer(std::size_t subMesh) const;
|
||||
inline const VertexDeclarationConstRef& GetVertexDeclaration(std::size_t subMesh) const;
|
||||
inline std::size_t GetSubMeshCount() const;
|
||||
|
||||
GraphicalMesh& operator=(const GraphicalMesh&) = delete;
|
||||
GraphicalMesh& operator=(GraphicalMesh&&) noexcept = default;
|
||||
|
||||
private:
|
||||
struct GraphicalSubMesh
|
||||
{
|
||||
std::shared_ptr<AbstractBuffer> indexBuffer;
|
||||
std::shared_ptr<AbstractBuffer> vertexBuffer;
|
||||
std::size_t indexCount;
|
||||
VertexDeclarationConstRef vertexDeclaration;
|
||||
};
|
||||
|
||||
std::vector<GraphicalSubMesh> m_subMeshes;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/GraphicalMesh.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICALMESH_HPP
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/GraphicalMesh.hpp>
|
||||
#include <cassert>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline const std::shared_ptr<AbstractBuffer>& GraphicalMesh::GetIndexBuffer(std::size_t subMesh) const
|
||||
{
|
||||
assert(subMesh < m_subMeshes.size());
|
||||
return m_subMeshes[subMesh].indexBuffer;
|
||||
}
|
||||
|
||||
inline std::size_t GraphicalMesh::GetIndexCount(std::size_t subMesh) const
|
||||
{
|
||||
assert(subMesh < m_subMeshes.size());
|
||||
return m_subMeshes[subMesh].indexCount;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<AbstractBuffer>& GraphicalMesh::GetVertexBuffer(std::size_t subMesh) const
|
||||
{
|
||||
assert(subMesh < m_subMeshes.size());
|
||||
return m_subMeshes[subMesh].vertexBuffer;
|
||||
}
|
||||
|
||||
inline const VertexDeclarationConstRef& GraphicalMesh::GetVertexDeclaration(std::size_t subMesh) const
|
||||
{
|
||||
assert(subMesh < m_subMeshes.size());
|
||||
return m_subMeshes[subMesh].vertexDeclaration;
|
||||
}
|
||||
|
||||
inline std::size_t GraphicalMesh::GetSubMeshCount() const
|
||||
{
|
||||
return m_subMeshes.size();
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_MODEL_HPP
|
||||
#define NAZARA_MODEL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Renderer/RenderPipeline.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class GraphicalMesh;
|
||||
class Material;
|
||||
|
||||
class NAZARA_GRAPHICS_API Model
|
||||
{
|
||||
public:
|
||||
Model(std::shared_ptr<GraphicalMesh> graphicalMesh);
|
||||
Model(const Model&) = delete;
|
||||
Model(Model&&) noexcept = default;
|
||||
~Model() = default;
|
||||
|
||||
const std::shared_ptr<AbstractBuffer>& GetIndexBuffer(std::size_t subMeshIndex) const;
|
||||
std::size_t GetIndexCount(std::size_t subMeshIndex) const;
|
||||
const std::shared_ptr<RenderPipeline>& GetRenderPipeline(std::size_t subMeshIndex) const;
|
||||
const std::shared_ptr<AbstractBuffer>& GetVertexBuffer(std::size_t subMeshIndex) const;
|
||||
inline std::size_t GetSubMeshCount() const;
|
||||
|
||||
inline void SetMaterial(std::size_t subMeshIndex, std::shared_ptr<Material> material);
|
||||
|
||||
Model& operator=(const Model&) = delete;
|
||||
Model& operator=(Model&&) noexcept = default;
|
||||
|
||||
private:
|
||||
struct SubMeshData
|
||||
{
|
||||
std::shared_ptr<Material> material;
|
||||
std::vector<RenderPipelineInfo::VertexBufferData> vertexBufferData;
|
||||
};
|
||||
|
||||
std::shared_ptr<GraphicalMesh> m_graphicalMesh;
|
||||
std::vector<SubMeshData> m_subMeshes;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/Model.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Model.hpp>
|
||||
#include <cassert>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline std::size_t Model::GetSubMeshCount() const
|
||||
{
|
||||
return m_subMeshes.size();
|
||||
}
|
||||
|
||||
inline void Model::SetMaterial(std::size_t subMeshIndex, std::shared_ptr<Material> material)
|
||||
{
|
||||
assert(subMeshIndex < m_subMeshes.size());
|
||||
m_subMeshes[subMeshIndex].material = std::move(material);
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/GraphicalMesh.hpp>
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Utility/SoftwareBuffer.hpp>
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <cassert>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
GraphicalMesh::GraphicalMesh(const Mesh* mesh)
|
||||
{
|
||||
assert(mesh->GetAnimationType() == AnimationType_Static);
|
||||
|
||||
RenderDevice& renderDevice = Graphics::Instance()->GetRenderDevice();
|
||||
|
||||
m_subMeshes.reserve(mesh->GetSubMeshCount());
|
||||
for (std::size_t i = 0; i < mesh->GetSubMeshCount(); ++i)
|
||||
{
|
||||
const SubMesh* subMesh = mesh->GetSubMesh(i);
|
||||
|
||||
const StaticMesh* staticMesh = static_cast<const StaticMesh*>(subMesh);
|
||||
|
||||
const IndexBuffer* indexBuffer = staticMesh->GetIndexBuffer();
|
||||
const VertexBuffer* vertexBuffer = staticMesh->GetVertexBuffer();
|
||||
|
||||
assert(indexBuffer->GetBuffer()->GetStorage() == DataStorage_Software);
|
||||
const SoftwareBuffer* indexBufferContent = static_cast<const SoftwareBuffer*>(indexBuffer->GetBuffer()->GetImpl());
|
||||
|
||||
assert(vertexBuffer->GetBuffer()->GetStorage() == DataStorage_Software);
|
||||
const SoftwareBuffer* vertexBufferContent = static_cast<const SoftwareBuffer*>(vertexBuffer->GetBuffer()->GetImpl());
|
||||
|
||||
auto& submeshData = m_subMeshes.emplace_back();
|
||||
submeshData.indexBuffer = renderDevice.InstantiateBuffer(BufferType_Index);
|
||||
if (!submeshData.indexBuffer->Initialize(indexBuffer->GetStride() * indexBuffer->GetIndexCount(), BufferUsage_DeviceLocal))
|
||||
throw std::runtime_error("failed to create index buffer");
|
||||
|
||||
if (!submeshData.indexBuffer->Fill(indexBufferContent->GetData() + indexBuffer->GetStartOffset(), 0, indexBuffer->GetEndOffset() - indexBuffer->GetStartOffset()))
|
||||
throw std::runtime_error("failed to fill index buffer");
|
||||
|
||||
submeshData.indexCount = indexBuffer->GetIndexCount();
|
||||
|
||||
submeshData.vertexBuffer = renderDevice.InstantiateBuffer(BufferType_Vertex);
|
||||
if (!submeshData.vertexBuffer->Initialize(vertexBuffer->GetStride() * vertexBuffer->GetVertexCount(), BufferUsage_DeviceLocal))
|
||||
throw std::runtime_error("failed to create vertex buffer");
|
||||
|
||||
if (!submeshData.vertexBuffer->Fill(vertexBufferContent->GetData() + vertexBuffer->GetStartOffset(), 0, vertexBuffer->GetEndOffset() - vertexBuffer->GetStartOffset()))
|
||||
throw std::runtime_error("failed to fill vertex buffer");
|
||||
|
||||
submeshData.vertexDeclaration = vertexBuffer->GetVertexDeclaration();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Model.hpp>
|
||||
#include <Nazara/Graphics/GraphicalMesh.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline Model::Model(std::shared_ptr<GraphicalMesh> graphicalMesh) :
|
||||
m_graphicalMesh(std::move(graphicalMesh))
|
||||
{
|
||||
m_subMeshes.reserve(m_graphicalMesh->GetSubMeshCount());
|
||||
for (std::size_t i = 0; i < m_graphicalMesh->GetSubMeshCount(); ++i)
|
||||
{
|
||||
auto& subMeshData = m_subMeshes.emplace_back();
|
||||
//subMeshData.material = DefaultMaterial; //< TODO
|
||||
subMeshData.vertexBufferData = {
|
||||
{
|
||||
0,
|
||||
m_graphicalMesh->GetVertexDeclaration(i)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const std::shared_ptr<AbstractBuffer>& Model::GetIndexBuffer(std::size_t subMeshIndex) const
|
||||
{
|
||||
return m_graphicalMesh->GetIndexBuffer(subMeshIndex);
|
||||
}
|
||||
|
||||
std::size_t Model::GetIndexCount(std::size_t subMeshIndex) const
|
||||
{
|
||||
return m_graphicalMesh->GetIndexCount(subMeshIndex);
|
||||
}
|
||||
|
||||
const std::shared_ptr<RenderPipeline>& Model::GetRenderPipeline(std::size_t subMeshIndex) const
|
||||
{
|
||||
assert(subMeshIndex < m_subMeshes.size());
|
||||
const auto& subMeshData = m_subMeshes[subMeshIndex];
|
||||
return subMeshData.material->GetPipeline()->GetRenderPipeline(subMeshData.vertexBufferData);
|
||||
}
|
||||
|
||||
const std::shared_ptr<AbstractBuffer>& Model::GetVertexBuffer(std::size_t subMeshIndex) const
|
||||
{
|
||||
return m_graphicalMesh->GetVertexBuffer(subMeshIndex);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue