From 392a23eeb14491444c7a5f450695c96ab92b9ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Wed, 26 May 2021 22:23:30 +0200 Subject: [PATCH] Add Std140Debug "example" (using OpenGL directly to debug stuff) --- examples/Std140Debug/main.cpp | 174 +++++++++++++++++++++++++++++++++ examples/Std140Debug/xmake.lua | 5 + xmake.lua | 5 +- 3 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 examples/Std140Debug/main.cpp create mode 100644 examples/Std140Debug/xmake.lua diff --git a/examples/Std140Debug/main.cpp b/examples/Std140Debug/main.cpp new file mode 100644 index 000000000..4cbe0c1ed --- /dev/null +++ b/examples/Std140Debug/main.cpp @@ -0,0 +1,174 @@ +#include +#include +#include +#include +#include +#include +#include + +const char fragmentSource[] = R"( +#version 310 es + +#if GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif + +layout(binding = 3, std140) uniform LightParameters +{ + mat4 projectionMatrix; + mat4 invProjectionMatrix; + mat4 viewMatrix; + mat4 invViewMatrix; + mat4 viewProjMatrix; + mat4 invViewProjMatrix; + vec2 renderTargetSize; + vec2 invRenderTargetSize; + vec3 eyePosition; +}; + +void main() +{ +} +)"; + +const char vertexSource[] = R"( +#version 310 es + +void main() +{ + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); +} +)"; + +template +std::vector SortIndexes(const std::vector& vec, Compare&& compare) +{ + std::vector p(vec.size()); + std::iota(p.begin(), p.end(), 0); + std::sort(p.begin(), p.end(), [&](std::size_t i, std::size_t j) { return compare(vec[i], vec[j]); }); + + return p; +} + +int main() +{ + Nz::Renderer::Config rendererConfig; + rendererConfig.preferredAPI = Nz::RenderAPI::OpenGL; + + Nz::Modules nazara(rendererConfig); + if (Nz::Renderer::Instance()->QueryAPI() != Nz::RenderAPI::OpenGL) + { + std::cout << "This program only works with OpenGL" << std::endl; + return EXIT_FAILURE; + } + + std::shared_ptr device = std::static_pointer_cast(Nz::Renderer::Instance()->InstanciateRenderDevice(0)); + + std::string err; + + // Fragment shader + Nz::GL::Shader fragmentShader; + if (!fragmentShader.Create(*device, GL_FRAGMENT_SHADER)) + { + std::cerr << "Failed to create fragment shader" << std::endl; + return EXIT_FAILURE; + } + + fragmentShader.SetSource(fragmentSource, sizeof(fragmentSource)); + fragmentShader.Compile(); + + if (!fragmentShader.GetCompilationStatus(&err)) + { + std::cerr << "Failed to compile fragment shader: " << err << std::endl; + return EXIT_FAILURE; + } + + // Vertex shader + Nz::GL::Shader vertexShader; + if (!vertexShader.Create(*device, GL_VERTEX_SHADER)) + { + std::cerr << "Failed to create vertex shader" << std::endl; + return EXIT_FAILURE; + } + + vertexShader.SetSource(vertexSource, sizeof(vertexSource)); + vertexShader.Compile(); + + if (!vertexShader.GetCompilationStatus(&err)) + { + std::cerr << "Failed to compile vertex shader: " << err << std::endl; + return EXIT_FAILURE; + } + + // Program + Nz::GL::Program program; + if (!program.Create(*device)) + { + std::cerr << "Failed to create program" << std::endl; + return EXIT_FAILURE; + } + + program.AttachShader(fragmentShader.GetObjectId()); + program.AttachShader(vertexShader.GetObjectId()); + program.Link(); + + if (!program.GetLinkStatus(&err)) + { + std::cerr << "Failed to link program: " << err << std::endl; + return EXIT_FAILURE; + } + + // Get infos + GLuint blockIndex = program.GetUniformBlockIndex("LightParameters"); + if (blockIndex == GL_INVALID_INDEX) + { + std::cerr << "Failed to find uniform block in program" << std::endl; + return EXIT_FAILURE; + } + + std::vector uniformIndices = program.GetActiveUniformBlockUniformIndices(blockIndex); + + std::vector offsets = program.GetActiveUniforms(uniformIndices.size(), reinterpret_cast(uniformIndices.data()), GL_UNIFORM_OFFSET); + + auto p = SortIndexes(offsets, std::less()); + + std::vector computedOffsets; + + Nz::FieldOffsets fieldOffsets(Nz::StructLayout::Std140); + computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true)); + computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true)); + computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true)); + computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true)); + computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true)); + computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true)); + computedOffsets.push_back(fieldOffsets.AddField(Nz::StructFieldType::Float2)); + computedOffsets.push_back(fieldOffsets.AddField(Nz::StructFieldType::Float2)); + computedOffsets.push_back(fieldOffsets.AddField(Nz::StructFieldType::Float3)); + + + GLint dataSize; + program.GetActiveUniformBlock(blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &dataSize); + + if (fieldOffsets.GetAlignedSize() != dataSize) + std::cout << "size mismatch (computed " << fieldOffsets.GetAlignedSize() << ", reference has " << dataSize << ")" << std::endl;; + + if (computedOffsets.size() != uniformIndices.size()) + { + std::cout << "member count mismatch" << std::endl; + return EXIT_FAILURE; + } + + for (std::size_t i = 0; i < uniformIndices.size(); ++i) + { + GLint realOffset = offsets[p[i]]; + std::cout << program.GetActiveUniformName(uniformIndices[p[i]]) << ": " << realOffset; + if (realOffset != computedOffsets[i]) + std::cout << " ERR"; + + std::cout << std::endl; + } + + return EXIT_SUCCESS; +} diff --git a/examples/Std140Debug/xmake.lua b/examples/Std140Debug/xmake.lua new file mode 100644 index 000000000..f72858562 --- /dev/null +++ b/examples/Std140Debug/xmake.lua @@ -0,0 +1,5 @@ +target("Std140Debug") + set_group("Examples") + set_kind("binary") + add_deps("NazaraOpenGLRenderer") + add_files("main.cpp") diff --git a/xmake.lua b/xmake.lua index f86f987c6..7eab59c56 100644 --- a/xmake.lua +++ b/xmake.lua @@ -194,8 +194,9 @@ rule("build_rendererplugins") after_load(function (target) if target:kind() == "binary" and target:dep("NazaraRenderer") then for name, _ in pairs(modules) do - if name:match("^.+Renderer$") then - target:add("deps", "Nazara" .. name, {inherit = false}) + local depName = "Nazara" .. name + if name:match("^.+Renderer$") and target:dep(depName) == nil then -- don't overwrite dependency + target:add("deps", depName, {inherit = false}) end end end