Graphics: WIP (almost working)

This commit is contained in:
Jérôme Leclercq
2020-10-30 23:08:48 +01:00
parent 73e86407b3
commit 89609570f4
28 changed files with 1036 additions and 2262 deletions

View File

@@ -17,18 +17,20 @@ namespace Nz
{
namespace
{
constexpr std::size_t AlphaMapBinding = 0;
constexpr std::size_t DiffuseMapBinding = 1;
constexpr std::size_t TextureOverlayBinding = 2;
const UInt8 r_fragmentShader[] = {
#include <Nazara/Graphics/Resources/Shaders/basicmaterial.frag.shader.h>
};
const UInt8 r_vertexShader[] = {
#include <Nazara/Graphics/Resources/Shaders/basicmaterial.vert.shader.h>
};
}
BasicMaterial::BasicMaterial(Material* material) :
BasicMaterial::BasicMaterial(Material& material) :
m_material(material)
{
NazaraAssert(material, "Invalid material");
// Most common case: don't fetch texture indexes as a little optimization
const std::shared_ptr<const MaterialSettings>& materialSettings = material->GetSettings();
const std::shared_ptr<const MaterialSettings>& materialSettings = material.GetSettings();
if (materialSettings == s_materialSettings)
{
m_textureIndexes = s_textureIndexes;
@@ -51,17 +53,17 @@ namespace Nz
{
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_uniformBlockIndex), BufferAccess_ReadOnly);
return *AccessByOffset<const float>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold);
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_ReadOnly);
return AccessByOffset<const float&>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold);
}
Color BasicMaterial::GetDiffuseColor() const
{
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_uniformBlockIndex), BufferAccess_ReadOnly);
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_ReadOnly);
const float* colorPtr = AccessByOffset<const float>(mapper.GetPointer(), m_uniformOffsets.diffuseColor);
const float* colorPtr = AccessByOffset<const float*>(mapper.GetPointer(), m_uniformOffsets.diffuseColor);
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
}
@@ -69,16 +71,16 @@ namespace Nz
{
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_uniformBlockIndex), BufferAccess_WriteOnly);
*AccessByOffset<float>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold) = alphaThreshold;
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_WriteOnly);
AccessByOffset<float&>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold) = alphaThreshold;
}
void BasicMaterial::SetDiffuseColor(const Color& diffuse)
{
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_uniformBlockIndex), BufferAccess_WriteOnly);
float* colorPtr = AccessByOffset<float>(mapper.GetPointer(), m_uniformOffsets.diffuseColor);
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_WriteOnly);
float* colorPtr = AccessByOffset<float*>(mapper.GetPointer(), m_uniformOffsets.diffuseColor);
colorPtr[0] = diffuse.r / 255.f;
colorPtr[1] = diffuse.g / 255.f;
colorPtr[2] = diffuse.b / 255.f;
@@ -92,31 +94,6 @@ namespace Nz
bool BasicMaterial::Initialize()
{
RenderPipelineLayoutInfo info;
info.bindings.assign({
{
"MaterialAlphaMap",
ShaderBindingType_Texture,
ShaderStageType_Fragment,
AlphaMapBinding
},
{
"MaterialDiffuseMap",
ShaderBindingType_Texture,
ShaderStageType_Fragment,
DiffuseMapBinding
},
{
"TextureOverlay",
ShaderBindingType_Texture,
ShaderStageType_Fragment,
TextureOverlayBinding
}
});
s_renderPipelineLayout = RenderPipelineLayout::New();
s_renderPipelineLayout->Create(info);
FieldOffsets fieldOffsets(StructLayout_Std140);
s_uniformOffsets.diffuseColor = fieldOffsets.AddField(StructFieldType_Float4);
@@ -140,15 +117,37 @@ namespace Nz
static_assert(sizeof(Vector4f) == 4 * sizeof(float), "Vector4f is expected to be exactly 4 floats wide");
std::vector<UInt8> defaultValues(fieldOffsets.GetSize());
*AccessByOffset<Vector4f>(defaultValues.data(), s_uniformOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
*AccessByOffset<float>(defaultValues.data(), s_uniformOffsets.alphaThreshold) = 0.2f;
AccessByOffset<Vector4f&>(defaultValues.data(), s_uniformOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
AccessByOffset<float&>(defaultValues.data(), s_uniformOffsets.alphaThreshold) = 0.2f;
std::vector<MaterialSettings::Texture> textures;
s_textureIndexes.alpha = textures.size();
textures.push_back({
"MaterialAlphaMap",
"Alpha",
ImageType_2D
});
s_textureIndexes.diffuse = textures.size();
textures.push_back({
"MaterialDiffuseMap",
"Diffuse",
ImageType_2D
});
predefinedBinding[PredefinedShaderBinding_TexOverlay] = textures.size();
textures.push_back({
"TextureOverlay",
"Overlay",
ImageType_2D
});
std::vector<MaterialSettings::UniformBlock> uniformBlocks;
s_uniformBlockIndex = uniformBlocks.size();
uniformBlocks.assign({
{
"BasicSettings",
fieldOffsets.GetSize(),
"BasicSettings",
"MaterialBasicSettings",
std::move(variables),
std::move(defaultValues)
@@ -157,47 +156,28 @@ namespace Nz
std::vector<MaterialSettings::SharedUniformBlock> sharedUniformBlock;
predefinedBinding[PredefinedShaderBinding_UboInstanceData] = sharedUniformBlock.size();
predefinedBinding[PredefinedShaderBinding_UboInstanceData] = textures.size() + uniformBlocks.size() + sharedUniformBlock.size();
sharedUniformBlock.push_back(PredefinedInstanceData::GetUniformBlock());
predefinedBinding[PredefinedShaderBinding_UboViewerData] = sharedUniformBlock.size();
predefinedBinding[PredefinedShaderBinding_UboViewerData] = textures.size() + uniformBlocks.size() + sharedUniformBlock.size();
sharedUniformBlock.push_back(PredefinedViewerData::GetUniformBlock());
std::vector<MaterialSettings::Texture> textures;
s_textureIndexes.alpha = textures.size();
textures.push_back({
"Alpha",
ImageType_2D,
"MaterialAlphaMap"
});
s_textureIndexes.diffuse = textures.size();
textures.push_back({
"Diffuse",
ImageType_2D,
"MaterialDiffuseMap"
});
// Shaders
MaterialSettings::DefaultShaders defaultShaders;
defaultShaders[UnderlyingCast(ShaderStageType::Fragment)] = Graphics::Instance()->GetRenderDevice().InstantiateShaderStage(Nz::ShaderStageType::Fragment, Nz::ShaderLanguage::NazaraBinary, r_fragmentShader, sizeof(r_fragmentShader));
defaultShaders[UnderlyingCast(ShaderStageType::Vertex)] = Graphics::Instance()->GetRenderDevice().InstantiateShaderStage(Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraBinary, r_vertexShader, sizeof(r_vertexShader));
predefinedBinding[PredefinedShaderBinding_TexOverlay] = textures.size();
textures.push_back({
"Overlay",
ImageType_2D,
"TextureOverlay"
});
s_materialSettings = std::make_shared<MaterialSettings>(std::move(textures), std::move(uniformBlocks), std::move(sharedUniformBlock), predefinedBinding);
s_materialSettings = std::make_shared<MaterialSettings>(std::move(textures), std::move(uniformBlocks), std::move(sharedUniformBlock), predefinedBinding, std::move(defaultShaders));
return true;
}
void BasicMaterial::Uninitialize()
{
s_renderPipelineLayout.Reset();
s_materialSettings.reset();
}
std::shared_ptr<MaterialSettings> BasicMaterial::s_materialSettings;
std::size_t BasicMaterial::s_uniformBlockIndex;
RenderPipelineLayoutRef BasicMaterial::s_renderPipelineLayout;
BasicMaterial::TextureIndexes BasicMaterial::s_textureIndexes;
BasicMaterial::UniformOffsets BasicMaterial::s_uniformOffsets;
}