From 7581c6744a3d6dca5ae7060765818509fca49af8 Mon Sep 17 00:00:00 2001 From: Ghali Boucetta Date: Sun, 1 Sep 2024 16:21:20 +0200 Subject: [PATCH 01/89] add OpenGL and the base for the system of autodetermination of the Graphics API --- CMakeLists.txt | 356 +++++++++++++----------- CMakePresets.json | 3 +- Engine/Render/CMakeLists.txt | 5 +- examples/glHelloTriangle/CMakeLists.txt | 9 + examples/glHelloTriangle/main.cpp | 161 +++++++++++ examples/glHelloTriangle/shader.frag | 6 + examples/glHelloTriangle/shader.vert | 8 + 7 files changed, 381 insertions(+), 167 deletions(-) create mode 100644 examples/glHelloTriangle/CMakeLists.txt create mode 100644 examples/glHelloTriangle/main.cpp create mode 100644 examples/glHelloTriangle/shader.frag create mode 100644 examples/glHelloTriangle/shader.vert diff --git a/CMakeLists.txt b/CMakeLists.txt index f32e1ef..4bba684 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,12 +4,24 @@ project(StoneEngine LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED YES) -set(USE_SYSTEM_GLM OFF CACHE BOOL "Uses glm from system libraries") -set(USE_SYSTEM_BOOST ON CACHE BOOL "Uses boost from system libraries") -set(SKIP_TESTS ON CACHE BOOL "Disables tests") -set(USE_SYSTEM_PAUSE OFF CACHE BOOL "Enables the use of Windows' pause after ending console only programs. (Windows only)") -set(FULL_CONFIGURE ON CACHE BOOL "Full configure project (may be used in pipeline to avoid the setup of all the dependencies)") -set(ENABLE_DOCS OFF CACHE BOOL "Builds documentation with doxygen") +option(USE_SYSTEM_GLM "Uses glm from system libraries" OFF) +option(USE_SYSTEM_BOOST "Uses boost from system libraries" ON) +option(SKIP_TESTS "Disables tests" ON) +option(USE_SYSTEM_PAUSE "Enables the use of Windows' pause after ending console only programs. (Windows only)" OFF) +option(FULL_CONFIGURE "Full configure project (may be used in pipeline to avoid the setup of all the dependencies)" ON) +option(ENABLE_DOCS "Builds documentation with doxygen" OFF) + +set(VALID_GRAPHICS_APIs "AUTO" "VULKAN" "OPENGL") +option(GRAPHICS_API "Configures the graphics API to use, can be AUTO, VULKAN, OPENGL" "AUTO") + +string(TOUPPER ${GRAPHICS_API} tmp) +set(GRAPHICS_API "${tmp}") +unset(tmp) + +if (NOT GRAPHICS_API IN_LIST VALID_GRAPHICS_APIs) + list(JOIN VALID_GRAPHICS_APIs ", " lst_str) + message(FATAL_ERROR "Expecting GRAPHICS_API value to be in the list [${lst_str}]") +endif () # TODO: dependencies are not mandatory set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") @@ -19,166 +31,186 @@ include(OSDetection) include(FetchContent) -if ( FULL_CONFIGURE ) - # Require Vulkan - find_package(Vulkan) - find_package(Python REQUIRED COMPONENTS Interpreter) - - if ( ${Python_VERSION_MAJOR} STRLESS 3 AND ${Python_VERSION_MINOR} STRLESS 10 ) - message(FATAL_ERROR "Got bad version of python: ${Python_VERSION}") - endif () - - file(DOWNLOAD https://raw.githubusercontent.com/nothings/stb/013ac3beddff3dbffafd5177e7972067cd2b5083/stb_image.h - ${CMAKE_BINARY_DIR}/include/stb_image.h - EXPECTED_HASH SHA256=594c2fe35d49488b4382dbfaec8f98366defca819d916ac95becf3e75f4200b3 - ) - - # Require ShaderC (google's shader compiler, compatible with GLSL or HLSL) - FetchContent_Declare( - shaderc - GIT_REPOSITORY https://github.com/google/shaderc - GIT_TAG 9a658e242ad4d1a4b3491383c1c58c780e3c01ff # tag/v2024.1 - ) - FetchContent_GetProperties(shaderc) - - if ( NOT shaderc_POPULATED ) - FetchContent_Populate(shaderc) - set($ENV{GIT_SYNC_DEPS_QUIET} 1) - execute_process( - COMMAND ${Python_EXECUTABLE} utils/git-sync-deps - WORKING_DIRECTORY ${shaderc_SOURCE_DIR} - COMMAND_ERROR_IS_FATAL ANY - OUTPUT_FILE git-sync-deps.out - ) - - set(SHADERC_SKIP_TESTS ON CACHE INTERNAL "Disables tests in ShaderC") - set(SHADERC_SKIP_EXAMPLES ON CACHE INTERNAL "Disables examples in ShaderC") - set(SHADERC_SKIP_INSTALL ON CACHE INTERNAL "Disables installation in ShaderC") - - add_subdirectory(${shaderc_SOURCE_DIR} ${shaderc_BINARY_DIR}) - endif () - - # Fetches GLM - if ( USE_SYSTEM_GLM ) - find_package(glm) - - if ( NOT GLM_FOUND ) - message(STATUS "Couldn't find glm in system, will use online source instead") - endif () - else () - message(STATUS "Will fetch glm from online source") - endif () - - if ( NOT GLM_FOUND ) - FetchContent_Declare( - glm - GIT_REPOSITORY https://github.com/g-truc/glm.git - GIT_TAG 33b0eb9fa336ffd8551024b1d2690e418014553b # refs/tags/1.0.0 - ) - - set(GLM_ENABLE_CXX_17 ON CACHE INTERNAL "Forces C++17 in GLM") - - FetchContent_MakeAvailable(glm) - set(GLM_FOUND ON) - set_target_properties(glm PROPERTIES SYSTEM ON) - endif () - - # Fetches GoogleTest only if needed - if ( NOT SKIP_TESTS ) - FetchContent_Declare( - gtest - GIT_REPOSITORY https://github.com/google/googletest - GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571 - ) - - # For Windows: Prevent overriding the parent project's compiler/linker settings - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - FetchContent_MakeAvailable(gtest) - set_target_properties(gtest PROPERTIES SYSTEM ON) - - if ( NOT SKIP_TESTS ) - enable_testing() - endif () - endif () - - # Setup Glfw - FetchContent_Declare( - glfw - GIT_REPOSITORY https://github.com/glfw/glfw - GIT_TAG 7b6aead9fb88b3623e3b3725ebb42670cbe4c579 # tag/3.4 - ) - FetchContent_GetProperties(glfw) - - if ( NOT glfw_POPULATED ) - FetchContent_Populate(glfw) - - set(GLFW_BUILD_EXAMPLES OFF CACHE INTERNAL "Build the GLFW example programs") - set(GLFW_BUILD_TESTS OFF CACHE INTERNAL "Build the GLFW test programs") - set(GLFW_BUILD_DOCS OFF CACHE INTERNAL "Build the GLFW documentation") - set(GLFW_INSTALL OFF CACHE INTERNAL "Generate installation target") - - if ( STONE_ENGINE_OS_NAME STREQUAL Linux ) - set(GLFW_BUILD_WAYLAND OFF CACHE INTERNAL "Enables the use of Wayland (Linux only)") - set(GLFW_BUILD_X11 ON CACHE INTERNAL "Enables the use of X11 (Linux only)") - endif () - - add_subdirectory(${glfw_SOURCE_DIR} ${glfw_BINARY_DIR}) - endif () - - set_target_properties(glfw PROPERTIES SYSTEM ON) - - # Setup Json - FetchContent_Declare( - json - GIT_REPOSITORY https://github.com/nlohmann/json - GIT_TAG 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03 # tag/v3.11.3 - ) - FetchContent_MakeAvailable(json) - add_library(json ALIAS nlohmann_json) - - set_target_properties(nlohmann_json PROPERTIES SYSTEM ON) - - # Setup Assimp - FetchContent_Declare( - assimp - GIT_REPOSITORY https://github.com/assimp/assimp - GIT_TAG 8b9ed34eaa3e6ad24254cb7e058fb9150f66b865 # tag/v5.4.0 - ) - set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) - set(ASSIMP_BUILD_TESTS OFF CACHE BOOL "" FORCE) - set(ASSIMP_INJECT_DEBUG_POSTFIX OFF CACHE BOOL "" FORCE) - set(ASSIMP_INSTALL OFF CACHE BOOL "" FORCE) - FetchContent_MakeAvailable(assimp) - - set_target_properties(assimp PROPERTIES SYSTEM ON) - - if ( USE_SYSTEM_BOOST ) - find_package(Boost 1.74.0) - endif () - - if ( NOT USE_SYSTEM_BOOST OR NOT Boost_FOUND ) - set(BOOST_GIT_TAG a7090e8ce184501cfc9e80afa6cafb5bfd3b371c) # tag/boost-1.74.0 - FetchContent_Declare(Boost - GIT_REPOSITORY https://github.com/boostorg/boost - GIT_TAG ${BOOST_GIT_TAG} - ) - if ( NOT Boost_POPULATED ) - message(STATUS "Fetching Boost from git repository") - - FetchContent_Populate(Boost) - - message(STATUS "Configuring Boost") - add_subdirectory(${boost_SOURCE_DIR} ${boost_BINARY_DIR} EXCLUDE_FROM_ALL) - endif () - endif () + +if (GRAPHICS_API STREQUAL "AUTO") + set(GRAPHICS_API "OPENGL") +endif () + +if (FULL_CONFIGURE) + add_library(gfx_api INTERFACE) + if (GRAPHICS_API STREQUAL "VULKAN") + # Require Vulkan + message(STATUS "Setup gfx_api to use Vulkan rendering API") + find_package(Vulkan REQUIRED) + target_link_libraries(gfx_api INTERFACE ${Vulkan_LIBRARIES}) + target_include_directories(gfx_api INTERFACE ${Vulkan_INCLUDE_DIRS}) + elseif (GRAPHICS_API STREQUAL "OPENGL") + message(STATUS "Setup gfx_api to use OPENGL rendering API") + find_package(OpenGL REQUIRED) + find_package(GLEW REQUIRED) + target_link_libraries(gfx_api INTERFACE OpenGL GLEW) + target_include_directories(gfx_api INTERFACE ${GLEW_INCLUDE_DIRS}) + else () + message(FATAL_ERROR "Unexpected value for GRAPHICS_API, unknown API ${GRAPHICS_API}") + endif() + + find_package(Python REQUIRED COMPONENTS Interpreter) + + if (${Python_VERSION_MAJOR} STRLESS 3 AND ${Python_VERSION_MINOR} STRLESS 10) + message(FATAL_ERROR "Got bad version of python: ${Python_VERSION}") + endif () + + file(DOWNLOAD https://raw.githubusercontent.com/nothings/stb/013ac3beddff3dbffafd5177e7972067cd2b5083/stb_image.h + ${CMAKE_BINARY_DIR}/include/stb_image.h + EXPECTED_HASH SHA256=594c2fe35d49488b4382dbfaec8f98366defca819d916ac95becf3e75f4200b3 + ) + + # Require ShaderC (google's shader compiler, compatible with GLSL or HLSL) + FetchContent_Declare( + shaderc + GIT_REPOSITORY https://github.com/google/shaderc + GIT_TAG 9a658e242ad4d1a4b3491383c1c58c780e3c01ff # tag/v2024.1 + ) + FetchContent_GetProperties(shaderc) + + if (NOT shaderc_POPULATED) + FetchContent_Populate(shaderc) + set($ENV{GIT_SYNC_DEPS_QUIET} 1) + execute_process( + COMMAND ${Python_EXECUTABLE} utils/git-sync-deps + WORKING_DIRECTORY ${shaderc_SOURCE_DIR} + COMMAND_ERROR_IS_FATAL ANY + OUTPUT_FILE git-sync-deps.out + ) + + set(SHADERC_SKIP_TESTS ON CACHE INTERNAL "Disables tests in ShaderC") + set(SHADERC_SKIP_EXAMPLES ON CACHE INTERNAL "Disables examples in ShaderC") + set(SHADERC_SKIP_INSTALL ON CACHE INTERNAL "Disables installation in ShaderC") + + add_subdirectory(${shaderc_SOURCE_DIR} ${shaderc_BINARY_DIR}) + endif () + + # Fetches GLM + if (USE_SYSTEM_GLM) + find_package(glm) + + if (NOT GLM_FOUND) + message(STATUS "Couldn't find glm in system, will use online source instead") + endif () + else () + message(STATUS "Will fetch glm from online source") + endif () + + if (NOT GLM_FOUND) + FetchContent_Declare( + glm + GIT_REPOSITORY https://github.com/g-truc/glm.git + GIT_TAG 33b0eb9fa336ffd8551024b1d2690e418014553b # refs/tags/1.0.0 + ) + + set(GLM_ENABLE_CXX_17 ON CACHE INTERNAL "Forces C++17 in GLM") + + FetchContent_MakeAvailable(glm) + set(GLM_FOUND ON) + set_target_properties(glm PROPERTIES SYSTEM ON) + endif () + + # Fetches GoogleTest only if needed + if (NOT SKIP_TESTS) + FetchContent_Declare( + gtest + GIT_REPOSITORY https://github.com/google/googletest + GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571 + ) + + # For Windows: Prevent overriding the parent project's compiler/linker settings + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(gtest) + set_target_properties(gtest PROPERTIES SYSTEM ON) + + if (NOT SKIP_TESTS) + enable_testing() + endif () + endif () + + # Setup Glfw + FetchContent_Declare( + glfw + GIT_REPOSITORY https://github.com/glfw/glfw + GIT_TAG 7b6aead9fb88b3623e3b3725ebb42670cbe4c579 # tag/3.4 + ) + FetchContent_GetProperties(glfw) + + if (NOT glfw_POPULATED) + FetchContent_Populate(glfw) + + set(GLFW_BUILD_EXAMPLES OFF CACHE INTERNAL "Build the GLFW example programs") + set(GLFW_BUILD_TESTS OFF CACHE INTERNAL "Build the GLFW test programs") + set(GLFW_BUILD_DOCS OFF CACHE INTERNAL "Build the GLFW documentation") + set(GLFW_INSTALL OFF CACHE INTERNAL "Generate installation target") + + if (STONE_ENGINE_OS_NAME STREQUAL Linux) + set(GLFW_BUILD_WAYLAND OFF CACHE INTERNAL "Enables the use of Wayland (Linux only)") + set(GLFW_BUILD_X11 ON CACHE INTERNAL "Enables the use of X11 (Linux only)") + endif () + + add_subdirectory(${glfw_SOURCE_DIR} ${glfw_BINARY_DIR}) + endif () + + set_target_properties(glfw PROPERTIES SYSTEM ON) + + # Setup Json + FetchContent_Declare( + json + GIT_REPOSITORY https://github.com/nlohmann/json + GIT_TAG 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03 # tag/v3.11.3 + ) + FetchContent_MakeAvailable(json) + add_library(json ALIAS nlohmann_json) + + set_target_properties(nlohmann_json PROPERTIES SYSTEM ON) + + # Setup Assimp + FetchContent_Declare( + assimp + GIT_REPOSITORY https://github.com/assimp/assimp + GIT_TAG 8b9ed34eaa3e6ad24254cb7e058fb9150f66b865 # tag/v5.4.0 + ) + set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) + set(ASSIMP_BUILD_TESTS OFF CACHE BOOL "" FORCE) + set(ASSIMP_INJECT_DEBUG_POSTFIX OFF CACHE BOOL "" FORCE) + set(ASSIMP_INSTALL OFF CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(assimp) + + set_target_properties(assimp PROPERTIES SYSTEM ON) + + if (USE_SYSTEM_BOOST) + find_package(Boost 1.74.0) + endif () + + if (NOT USE_SYSTEM_BOOST OR NOT Boost_FOUND) + set(BOOST_GIT_TAG a7090e8ce184501cfc9e80afa6cafb5bfd3b371c) # tag/boost-1.74.0 + FetchContent_Declare(Boost + GIT_REPOSITORY https://github.com/boostorg/boost + GIT_TAG ${BOOST_GIT_TAG} + ) + if (NOT Boost_POPULATED) + message(STATUS "Fetching Boost from git repository") + + FetchContent_Populate(Boost) + + message(STATUS "Configuring Boost") + add_subdirectory(${boost_SOURCE_DIR} ${boost_BINARY_DIR} EXCLUDE_FROM_ALL) + endif () + endif () endif () add_subdirectory(Engine) -if ( FULL_CONFIGURE ) - add_subdirectory(examples) +if (FULL_CONFIGURE) + add_subdirectory(examples) endif () -if ( ENABLE_DOCS ) - include(Doxygen) +if (ENABLE_DOCS) + include(Doxygen) endif () diff --git a/CMakePresets.json b/CMakePresets.json index 658eb54..1c6642c 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -25,7 +25,8 @@ "SKIP_TESTS": { "type": "BOOL", "value": "OFF" - } + }, + "GRAPHICS_API": "AUTO" }, "condition": { "type": "notEquals", diff --git a/Engine/Render/CMakeLists.txt b/Engine/Render/CMakeLists.txt index ee0271c..d6bba38 100644 --- a/Engine/Render/CMakeLists.txt +++ b/Engine/Render/CMakeLists.txt @@ -1,8 +1,5 @@ setup_module( NAME render - TARGET_DEPS logging widgets utils - VARIABLE_DEPS Vulkan_LIBRARIES Vulkan_INCLUDE_DIRS - SPECIAL_HEADER_PATHS ${Vulkan_INCLUDE_DIRS} - SPECIAL_LIBS ${Vulkan_LIBRARIES} + TARGET_DEPS logging widgets utils gfx_api FATAL_ERROR ) diff --git a/examples/glHelloTriangle/CMakeLists.txt b/examples/glHelloTriangle/CMakeLists.txt new file mode 100644 index 0000000..b3dd2ec --- /dev/null +++ b/examples/glHelloTriangle/CMakeLists.txt @@ -0,0 +1,9 @@ +set(NAME glHelloTriangle) + +add_executable(${NAME} EXCLUDE_FROM_ALL main.cpp) +target_include_directories(${NAME} PRIVATE ${PROJECT_BINARY_DIR}/include) +target_link_libraries(${NAME} + PRIVATE glfw + PRIVATE glm + PRIVATE gfx_api +) diff --git a/examples/glHelloTriangle/main.cpp b/examples/glHelloTriangle/main.cpp new file mode 100644 index 0000000..0c3bf30 --- /dev/null +++ b/examples/glHelloTriangle/main.cpp @@ -0,0 +1,161 @@ +#include +#include +#include +#include +#include +#include +#include + +GLuint LoadShaders(const char *vertex_file_path, const char *fragment_file_path) { + // Create the shaders + GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + // Read the Vertex Shader code from the file + std::string VertexShaderCode; + std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); + if (VertexShaderStream.is_open()) { + std::stringstream sstr; + sstr << VertexShaderStream.rdbuf(); + VertexShaderCode = sstr.str(); + VertexShaderStream.close(); + } else { + std::cerr << "Impossible to open " << vertex_file_path + << ". Are you in the right directory ? Don't forget to read the FAQ !" << std::endl; + + exit(1); + } + + // Read the Fragment Shader code from the file + std::string FragmentShaderCode; + std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); + if (FragmentShaderStream.is_open()) { + std::stringstream sstr; + sstr << FragmentShaderStream.rdbuf(); + FragmentShaderCode = sstr.str(); + FragmentShaderStream.close(); + } + + GLint Result = GL_FALSE; + int InfoLogLength; + + // Compile Vertex Shader + std::cout << "Compiling shader : " << vertex_file_path << std::endl; + const char *VertexSourcePointer = VertexShaderCode.c_str(); + glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL); + glCompileShader(VertexShaderID); + + // Check Vertex Shader + glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if (InfoLogLength > 0) { + std::vector VertexShaderErrorMessage(InfoLogLength + 1); + glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); + printf("%s\n", &VertexShaderErrorMessage[0]); + } + + // Compile Fragment Shader + std::cout << "Compiling shader : " << fragment_file_path << std::endl; + const char *FragmentSourcePointer = FragmentShaderCode.c_str(); + glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL); + glCompileShader(FragmentShaderID); + + // Check Fragment Shader + glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if (InfoLogLength > 0) { + std::vector FragmentShaderErrorMessage(InfoLogLength + 1); + glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]); + std::cerr << FragmentShaderErrorMessage.data() << "\n"; + } + + // Link the program + std::cout << "Linking program" << std::endl; + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + // Check the program + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if (InfoLogLength > 0) { + std::vector ProgramErrorMessage(InfoLogLength + 1); + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); + std::cerr << ProgramErrorMessage.data() << std::endl; + } + + glDetachShader(ProgramID, VertexShaderID); + glDetachShader(ProgramID, FragmentShaderID); + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} + +int main() { + if (!glfwInit()) { + std::cerr << "Failed to initialize GLFW" << std::endl; + return EXIT_FAILURE; + } + + glfwWindowHint(GLFW_SAMPLES, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + GLFWwindow *window = glfwCreateWindow(1024, 768, "Tutorial 01", nullptr, nullptr); + if (window == nullptr) { + std::cerr << "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. " + << "Try the 2.1 version of the tutorials." << std::endl; + glfwTerminate(); + return -1; + } + + glfwMakeContextCurrent(window); + glewExperimental = true; + if (glewInit() != GLEW_OK) { + std::cerr << "Failed to initialize GLEW" << std::endl; + return -1; + } + + GLuint VertexArrayID; + glGenVertexArrays(1, &VertexArrayID); + glBindVertexArray(VertexArrayID); + + constexpr static GLfloat g_vertex_buffer_data[] = { + -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + }; + + GLuint vertexBuffer; + glGenBuffers(1, &vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); + + glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); + glfwSetKeyCallback(window, [](GLFWwindow *win, const int key, int, const int action, int) { + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + glfwSetWindowShouldClose(win, GLFW_TRUE); + } + }); + + GLuint programID = LoadShaders("shader.vert", "shader.frag"); + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnableVertexAttribArray(0); + glUseProgram(programID); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + glDrawArrays(GL_TRIANGLES, 0, 3); + glDisableVertexAttribArray(0); + + glfwSwapBuffers(window); + } + + return EXIT_SUCCESS; +} diff --git a/examples/glHelloTriangle/shader.frag b/examples/glHelloTriangle/shader.frag new file mode 100644 index 0000000..98cd43a --- /dev/null +++ b/examples/glHelloTriangle/shader.frag @@ -0,0 +1,6 @@ +#version 330 core + +out vec3 color; +void main(){ + color = vec3(1,0,0); +} \ No newline at end of file diff --git a/examples/glHelloTriangle/shader.vert b/examples/glHelloTriangle/shader.vert new file mode 100644 index 0000000..95b818f --- /dev/null +++ b/examples/glHelloTriangle/shader.vert @@ -0,0 +1,8 @@ +#version 330 core + +layout (location = 0) in vec3 vertexPosition_modelspace; + +void main() { + gl_Position.xyz = vertexPosition_modelspace; + gl_Position.w = 1.0; +} From 82b7255ae964b37380a2d356c9c2cdfa41c0df70 Mon Sep 17 00:00:00 2001 From: amasson Date: Mon, 2 Sep 2024 00:51:59 +0200 Subject: [PATCH 02/89] OpenGL Renderer --- .../include/Render/OpenGL/OpenGLRenderer.hpp | 38 +++++ .../Render/OpenGL/RendererSettings.hpp | 15 ++ .../src/Render/OpenGL/OpenGLRenderer.cpp | 147 ++++++++++++++++ Engine/Window/src/Window/GlfwWindow.cpp | 29 +++- examples/glHelloTriangle/CMakeLists.txt | 9 - examples/glHelloTriangle/main.cpp | 161 ------------------ examples/glHelloTriangle/shader.frag | 6 - examples/glHelloTriangle/shader.vert | 8 - 8 files changed, 225 insertions(+), 188 deletions(-) create mode 100644 Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp create mode 100644 Engine/Render/include/Render/OpenGL/RendererSettings.hpp create mode 100644 Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp delete mode 100644 examples/glHelloTriangle/CMakeLists.txt delete mode 100644 examples/glHelloTriangle/main.cpp delete mode 100644 examples/glHelloTriangle/shader.frag delete mode 100644 examples/glHelloTriangle/shader.vert diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp new file mode 100644 index 0000000..0dd32b8 --- /dev/null +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -0,0 +1,38 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Render/OpenGL/RendererSettings.hpp" +#include "Render/Renderer.hpp" + +namespace Stone::Scene { +class WorldNode; +} + +namespace Stone::Render::OpenGL { + +class OpenGLRenderer : public Renderer { +public: + OpenGLRenderer() = delete; + explicit OpenGLRenderer(RendererSettings &settings); + OpenGLRenderer(const OpenGLRenderer &) = delete; + + ~OpenGLRenderer() override; + + /** Renderer */ + + void updateDataForWorld(const std::shared_ptr &world) override; + void renderWorld(const std::shared_ptr &world) override; + + void updateFrameSize(std::pair size) override; + +private: + std::pair _frameSize; + + void _initOpenGL(); + + unsigned int programID; + unsigned int vertexBuffer; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/include/Render/OpenGL/RendererSettings.hpp b/Engine/Render/include/Render/OpenGL/RendererSettings.hpp new file mode 100644 index 0000000..217b777 --- /dev/null +++ b/Engine/Render/include/Render/OpenGL/RendererSettings.hpp @@ -0,0 +1,15 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include +#include + + +namespace Stone::Render::OpenGL { + +struct RendererSettings { + std::pair frame_size = {}; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp new file mode 100644 index 0000000..dfd2514 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -0,0 +1,147 @@ +// Copyright 2024 Stone-Engine + + +#include "Render/OpenGL/OpenGLRenderer.hpp" + +#include +#include +#include +#include +#include +#include +#include + + +namespace Stone::Render::OpenGL { + +OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) + : Renderer(), _frameSize(settings.frame_size), programID(0), vertexBuffer(0) { + std::cout << "OpenGLRenderer created" << std::endl; + _initOpenGL(); +} + +OpenGLRenderer::~OpenGLRenderer() { + std::cout << "OpenGLRenderer destroyed" << std::endl; +} + +void OpenGLRenderer::updateDataForWorld(const std::shared_ptr &world) { + (void)world; +} + +void OpenGLRenderer::renderWorld(const std::shared_ptr &world) { + (void)world; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnableVertexAttribArray(0); + glUseProgram(programID); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + glDrawArrays(GL_TRIANGLES, 0, 3); + glDisableVertexAttribArray(0); +} + +void OpenGLRenderer::updateFrameSize(std::pair size) { + _frameSize = size; +} + +void OpenGLRenderer::_initOpenGL() { + + glewExperimental = true; + if (glewInit() != GLEW_OK) { + throw std::runtime_error("Failed to initialize GLEW"); + } + + GLuint VertexArrayID; + glGenVertexArrays(1, &VertexArrayID); + glBindVertexArray(VertexArrayID); + + constexpr static GLfloat g_vertex_buffer_data[] = { + -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + }; + + glGenBuffers(1, &vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); + + GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + // Read the Vertex Shader code from the file + std::string VertexShaderCode = R"( +#version 330 core + +layout (location = 0) in vec3 vertexPosition_modelspace; + +void main() { + gl_Position.xyz = vertexPosition_modelspace; + gl_Position.w = 1.0; +} +)"; + + // Read the Fragment Shader code from the file + std::string FragmentShaderCode = R"( +#version 330 core + +out vec3 color; +void main(){ + color = vec3(1,0,0); +} +)"; + + GLint Result = GL_FALSE; + int InfoLogLength; + + // Compile Vertex Shader + std::cout << "Compiling shader" << std::endl; + const char *VertexSourcePointer = VertexShaderCode.c_str(); + glShaderSource(VertexShaderID, 1, &VertexSourcePointer, nullptr); + glCompileShader(VertexShaderID); + + // Check Vertex Shader + glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if (InfoLogLength > 0) { + std::vector VertexShaderErrorMessage(InfoLogLength + 1); + glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]); + printf("%s\n", &VertexShaderErrorMessage[0]); + } + + // Compile Fragment Shader + std::cout << "Compiling shader" << std::endl; + const char *FragmentSourcePointer = FragmentShaderCode.c_str(); + glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, nullptr); + glCompileShader(FragmentShaderID); + + // Check Fragment Shader + glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if (InfoLogLength > 0) { + std::vector FragmentShaderErrorMessage(InfoLogLength + 1); + glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]); + std::cerr << FragmentShaderErrorMessage.data() << "\n"; + } + + // Link the program + std::cout << "Linking program" << std::endl; + programID = glCreateProgram(); + glAttachShader(programID, VertexShaderID); + glAttachShader(programID, FragmentShaderID); + glLinkProgram(programID); + + // Check the program + glGetProgramiv(programID, GL_LINK_STATUS, &Result); + glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if (InfoLogLength > 0) { + std::vector ProgramErrorMessage(InfoLogLength + 1); + glGetProgramInfoLog(programID, InfoLogLength, nullptr, &ProgramErrorMessage[0]); + std::cerr << ProgramErrorMessage.data() << std::endl; + } + + glDetachShader(programID, VertexShaderID); + glDetachShader(programID, FragmentShaderID); + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); +} + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Window/src/Window/GlfwWindow.cpp b/Engine/Window/src/Window/GlfwWindow.cpp index 9ea677f..25791a3 100644 --- a/Engine/Window/src/Window/GlfwWindow.cpp +++ b/Engine/Window/src/Window/GlfwWindow.cpp @@ -2,7 +2,14 @@ #include "Window/GlfwWindow.hpp" +#ifdef STONE_RENDERER_VULKAN #include "Render/Vulkan/VulkanRenderer.hpp" +#elif defined(STONE_RENDERER_OPENGL) +#include "Render/OpenGL/OpenGLRenderer.hpp" +#else +#include "Render/OpenGL/OpenGLRenderer.hpp" +#endif + #include "Scene/Node/WorldNode.hpp" #include @@ -12,8 +19,15 @@ namespace Stone::Window { GlfwWindow::GlfwWindow(const std::shared_ptr &app, const WindowSettings &settings) : Window(app, settings), _glfwWindow(nullptr) { - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_RESIZABLE, settings.resizable ? GLFW_TRUE : GLFW_FALSE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); +#ifdef STONE_RENDERER_VULKAN + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); +#else // def STONE_RENDERER_OPENGL + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); +#endif GLFWwindow *sharingContext = nullptr; if (!settings.shareContext.expired()) { @@ -39,9 +53,10 @@ GlfwWindow::GlfwWindow(const std::shared_ptr &app, const WindowSettings &se _elapsedTime = glfwGetTime(); if (!_renderer) { + +#ifdef STONE_RENDERER_VULKAN Render::Vulkan::RendererSettings rendererSettings; rendererSettings.app_name = settings.title; - uint32_t glfwExtensionCount = 0; const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); rendererSettings.instanceExt = std::vector(glfwExtensions, glfwExtensions + glfwExtensionCount); @@ -49,13 +64,19 @@ GlfwWindow::GlfwWindow(const std::shared_ptr &app, const WindowSettings &se VkSurfaceKHR *surface) { return glfwCreateWindowSurface(instance, _glfwWindow, allocator, surface); }; - rendererSettings.frame_size = { static_cast(settings.width), static_cast(settings.height), }; - _renderer = std::make_shared(rendererSettings); +#else + Render::OpenGL::RendererSettings rendererSettings; + rendererSettings.frame_size = { + static_cast(settings.width), + static_cast(settings.height), + }; + _renderer = std::make_shared(rendererSettings); +#endif } _world->setRenderer(_renderer); diff --git a/examples/glHelloTriangle/CMakeLists.txt b/examples/glHelloTriangle/CMakeLists.txt deleted file mode 100644 index b3dd2ec..0000000 --- a/examples/glHelloTriangle/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set(NAME glHelloTriangle) - -add_executable(${NAME} EXCLUDE_FROM_ALL main.cpp) -target_include_directories(${NAME} PRIVATE ${PROJECT_BINARY_DIR}/include) -target_link_libraries(${NAME} - PRIVATE glfw - PRIVATE glm - PRIVATE gfx_api -) diff --git a/examples/glHelloTriangle/main.cpp b/examples/glHelloTriangle/main.cpp deleted file mode 100644 index 0c3bf30..0000000 --- a/examples/glHelloTriangle/main.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -GLuint LoadShaders(const char *vertex_file_path, const char *fragment_file_path) { - // Create the shaders - GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); - GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); - - // Read the Vertex Shader code from the file - std::string VertexShaderCode; - std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); - if (VertexShaderStream.is_open()) { - std::stringstream sstr; - sstr << VertexShaderStream.rdbuf(); - VertexShaderCode = sstr.str(); - VertexShaderStream.close(); - } else { - std::cerr << "Impossible to open " << vertex_file_path - << ". Are you in the right directory ? Don't forget to read the FAQ !" << std::endl; - - exit(1); - } - - // Read the Fragment Shader code from the file - std::string FragmentShaderCode; - std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); - if (FragmentShaderStream.is_open()) { - std::stringstream sstr; - sstr << FragmentShaderStream.rdbuf(); - FragmentShaderCode = sstr.str(); - FragmentShaderStream.close(); - } - - GLint Result = GL_FALSE; - int InfoLogLength; - - // Compile Vertex Shader - std::cout << "Compiling shader : " << vertex_file_path << std::endl; - const char *VertexSourcePointer = VertexShaderCode.c_str(); - glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL); - glCompileShader(VertexShaderID); - - // Check Vertex Shader - glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); - glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); - if (InfoLogLength > 0) { - std::vector VertexShaderErrorMessage(InfoLogLength + 1); - glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); - printf("%s\n", &VertexShaderErrorMessage[0]); - } - - // Compile Fragment Shader - std::cout << "Compiling shader : " << fragment_file_path << std::endl; - const char *FragmentSourcePointer = FragmentShaderCode.c_str(); - glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL); - glCompileShader(FragmentShaderID); - - // Check Fragment Shader - glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); - glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); - if (InfoLogLength > 0) { - std::vector FragmentShaderErrorMessage(InfoLogLength + 1); - glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]); - std::cerr << FragmentShaderErrorMessage.data() << "\n"; - } - - // Link the program - std::cout << "Linking program" << std::endl; - GLuint ProgramID = glCreateProgram(); - glAttachShader(ProgramID, VertexShaderID); - glAttachShader(ProgramID, FragmentShaderID); - glLinkProgram(ProgramID); - - // Check the program - glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); - glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); - if (InfoLogLength > 0) { - std::vector ProgramErrorMessage(InfoLogLength + 1); - glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); - std::cerr << ProgramErrorMessage.data() << std::endl; - } - - glDetachShader(ProgramID, VertexShaderID); - glDetachShader(ProgramID, FragmentShaderID); - - glDeleteShader(VertexShaderID); - glDeleteShader(FragmentShaderID); - - return ProgramID; -} - -int main() { - if (!glfwInit()) { - std::cerr << "Failed to initialize GLFW" << std::endl; - return EXIT_FAILURE; - } - - glfwWindowHint(GLFW_SAMPLES, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - - GLFWwindow *window = glfwCreateWindow(1024, 768, "Tutorial 01", nullptr, nullptr); - if (window == nullptr) { - std::cerr << "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. " - << "Try the 2.1 version of the tutorials." << std::endl; - glfwTerminate(); - return -1; - } - - glfwMakeContextCurrent(window); - glewExperimental = true; - if (glewInit() != GLEW_OK) { - std::cerr << "Failed to initialize GLEW" << std::endl; - return -1; - } - - GLuint VertexArrayID; - glGenVertexArrays(1, &VertexArrayID); - glBindVertexArray(VertexArrayID); - - constexpr static GLfloat g_vertex_buffer_data[] = { - -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - }; - - GLuint vertexBuffer; - glGenBuffers(1, &vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); - - glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); - glfwSetKeyCallback(window, [](GLFWwindow *win, const int key, int, const int action, int) { - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - glfwSetWindowShouldClose(win, GLFW_TRUE); - } - }); - - GLuint programID = LoadShaders("shader.vert", "shader.frag"); - - while (!glfwWindowShouldClose(window)) { - glfwPollEvents(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnableVertexAttribArray(0); - glUseProgram(programID); - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - glDrawArrays(GL_TRIANGLES, 0, 3); - glDisableVertexAttribArray(0); - - glfwSwapBuffers(window); - } - - return EXIT_SUCCESS; -} diff --git a/examples/glHelloTriangle/shader.frag b/examples/glHelloTriangle/shader.frag deleted file mode 100644 index 98cd43a..0000000 --- a/examples/glHelloTriangle/shader.frag +++ /dev/null @@ -1,6 +0,0 @@ -#version 330 core - -out vec3 color; -void main(){ - color = vec3(1,0,0); -} \ No newline at end of file diff --git a/examples/glHelloTriangle/shader.vert b/examples/glHelloTriangle/shader.vert deleted file mode 100644 index 95b818f..0000000 --- a/examples/glHelloTriangle/shader.vert +++ /dev/null @@ -1,8 +0,0 @@ -#version 330 core - -layout (location = 0) in vec3 vertexPosition_modelspace; - -void main() { - gl_Position.xyz = vertexPosition_modelspace; - gl_Position.w = 1.0; -} From 38878bbff3454f32c6baf3cabae25e17493b6795 Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 3 Sep 2024 23:52:28 +0200 Subject: [PATCH 03/89] glfw get framebuffer size for settings --- Engine/Window/src/Window/GlfwWindow.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Engine/Window/src/Window/GlfwWindow.cpp b/Engine/Window/src/Window/GlfwWindow.cpp index 25791a3..2de3046 100644 --- a/Engine/Window/src/Window/GlfwWindow.cpp +++ b/Engine/Window/src/Window/GlfwWindow.cpp @@ -20,13 +20,15 @@ namespace Stone::Window { GlfwWindow::GlfwWindow(const std::shared_ptr &app, const WindowSettings &settings) : Window(app, settings), _glfwWindow(nullptr) { glfwWindowHint(GLFW_RESIZABLE, settings.resizable ? GLFW_TRUE : GLFW_FALSE); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); #ifdef STONE_RENDERER_VULKAN glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); #else // def STONE_RENDERER_OPENGL + glfwWindowHint(GLFW_SAMPLES, 0); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_DEPTH_BITS, 32); #endif GLFWwindow *sharingContext = nullptr; @@ -44,6 +46,8 @@ GlfwWindow::GlfwWindow(const std::shared_ptr &app, const WindowSettings &se throw std::runtime_error("Failed to create GLFW window"); } + glfwSetWindowSizeLimits(_glfwWindow, 300, 200, GLFW_DONT_CARE, GLFW_DONT_CARE); + glfwMakeContextCurrent(_glfwWindow); _initializeWindowCallbacks(); @@ -54,6 +58,8 @@ GlfwWindow::GlfwWindow(const std::shared_ptr &app, const WindowSettings &se if (!_renderer) { + int frameBufferWidth, frameBufferHeight; + glfwGetFramebufferSize(_glfwWindow, &frameBufferWidth, &frameBufferHeight); #ifdef STONE_RENDERER_VULKAN Render::Vulkan::RendererSettings rendererSettings; rendererSettings.app_name = settings.title; @@ -65,15 +71,15 @@ GlfwWindow::GlfwWindow(const std::shared_ptr &app, const WindowSettings &se return glfwCreateWindowSurface(instance, _glfwWindow, allocator, surface); }; rendererSettings.frame_size = { - static_cast(settings.width), - static_cast(settings.height), + static_cast(frameBufferWidth), + static_cast(frameBufferHeight), }; _renderer = std::make_shared(rendererSettings); #else Render::OpenGL::RendererSettings rendererSettings; rendererSettings.frame_size = { - static_cast(settings.width), - static_cast(settings.height), + static_cast(frameBufferWidth), + static_cast(frameBufferHeight), }; _renderer = std::make_shared(rendererSettings); #endif From f9f27b2b6e14f68ab2d0847dd5768e0c27a39263 Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 3 Sep 2024 23:53:24 +0200 Subject: [PATCH 04/89] OpenGL Renderer object match --- .../OpenGL/Renderable/InstancedMeshNode.hpp | 31 ++++++++++++ .../src/Render/OpenGL/Renderable/Material.hpp | 30 +++++++++++ .../src/Render/OpenGL/Renderable/Mesh.hpp | 48 ++++++++++++++++++ .../src/Render/OpenGL/Renderable/MeshNode.hpp | 30 +++++++++++ .../src/Render/OpenGL/Renderable/Shader.hpp | 30 +++++++++++ .../src/Render/OpenGL/Renderable/SkinMesh.hpp | 50 +++++++++++++++++++ .../Render/OpenGL/Renderable/SkinMeshNode.hpp | 31 ++++++++++++ .../src/Render/OpenGL/Renderable/Texture.hpp | 30 +++++++++++ 8 files changed, 280 insertions(+) create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/Material.hpp create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp diff --git a/Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp new file mode 100644 index 0000000..4334182 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp @@ -0,0 +1,31 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Node/InstancedMeshNode.hpp" + +#include + +namespace Stone::Render::OpenGL { + +class InstancedMeshNode : public Scene::IRendererObject { +public: + InstancedMeshNode(const std::shared_ptr &instancedMeshNode, + const std::shared_ptr &renderer) + : _instancedMeshNode(instancedMeshNode), _renderer(renderer) { + } + + ~InstancedMeshNode() override { + } + + void render(Scene::RenderContext &context) override { + (void)context; + } + +private: + std::weak_ptr _instancedMeshNode; + std::weak_ptr _renderer; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp new file mode 100644 index 0000000..19bbad9 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp @@ -0,0 +1,30 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Renderable/Material.hpp" + +#include + +namespace Stone::Render::OpenGL { + +class Material : public Scene::IRendererObject { +public: + Material(const std::shared_ptr &material, const std::shared_ptr &renderer) + : _material(material), _renderer(renderer) { + } + + ~Material() override { + } + + void render(Scene::RenderContext &context) override { + (void)context; + } + +private: + std::weak_ptr _material; + std::weak_ptr _renderer; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp new file mode 100644 index 0000000..66b4ee3 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp @@ -0,0 +1,48 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Renderable/Mesh.hpp" + +#include + +namespace Stone::Render::OpenGL { + +class DynamicMesh : public Scene::IRendererObject { +public: + DynamicMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) + : _mesh(mesh), _renderer(renderer) { + } + + ~DynamicMesh() override { + } + + void render(Scene::RenderContext &context) override { + (void)context; + } + +private: + std::weak_ptr _mesh; + std::weak_ptr _renderer; +}; + +class StaticMesh : public Scene::IRendererObject { +public: + StaticMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) + : _mesh(mesh), _renderer(renderer) { + } + + ~StaticMesh() override { + } + + void render(Scene::RenderContext &context) override { + (void)context; + } + +private: + std::weak_ptr _mesh; + std::weak_ptr _renderer; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp new file mode 100644 index 0000000..bd20d75 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp @@ -0,0 +1,30 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Node/MeshNode.hpp" + +#include + +namespace Stone::Render::OpenGL { + +class MeshNode : public Scene::IRendererObject { +public: + MeshNode(const std::shared_ptr &meshNode, const std::shared_ptr &renderer) + : _meshNode(meshNode), _renderer(renderer) { + } + + ~MeshNode() override { + } + + void render(Scene::RenderContext &context) override { + (void)context; + } + +private: + std::weak_ptr _meshNode; + std::weak_ptr _renderer; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp new file mode 100644 index 0000000..b32631b --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp @@ -0,0 +1,30 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Renderable/Shader.hpp" + +#include + +namespace Stone::Render::OpenGL { + +class Shader : public Scene::IRendererObject { +public: + Shader(const std::shared_ptr &shader, const std::shared_ptr &renderer) + : _shader(shader), _renderer(renderer) { + } + + ~Shader() override { + } + + void render(Scene::RenderContext &context) override { + (void)context; + } + +private: + std::weak_ptr _shader; + std::weak_ptr _renderer; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp new file mode 100644 index 0000000..ac942f9 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp @@ -0,0 +1,50 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Renderable/SkinMesh.hpp" + +#include + +namespace Stone::Render::OpenGL { + +class DynamicSkinMesh : public Scene::IRendererObject { +public: + DynamicSkinMesh(const std::shared_ptr &skinMesh, + const std::shared_ptr &renderer) + : _skinMesh(skinMesh), _renderer(renderer) { + } + + ~DynamicSkinMesh() override { + } + + void render(Scene::RenderContext &context) override { + (void)context; + } + +private: + std::weak_ptr _skinMesh; + std::weak_ptr _renderer; +}; + +class StaticSkinMesh : public Scene::IRendererObject { +public: + StaticSkinMesh(const std::shared_ptr &skinMesh, + const std::shared_ptr &renderer) + : _skinMesh(skinMesh), _renderer(renderer) { + } + + ~StaticSkinMesh() override { + } + + void render(Scene::RenderContext &context) override { + (void)context; + } + +private: + std::weak_ptr _skinMesh; + std::weak_ptr _renderer; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp new file mode 100644 index 0000000..a12a65c --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp @@ -0,0 +1,31 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Node/SkinMeshNode.hpp" + +#include + +namespace Stone::Render::OpenGL { + +class SkinMeshNode : public Scene::IRendererObject { +public: + SkinMeshNode(const std::shared_ptr &skinMeshNode, + const std::shared_ptr &renderer) + : _skinMeshNode(skinMeshNode), _renderer(renderer) { + } + + ~SkinMeshNode() override { + } + + void render(Scene::RenderContext &context) override { + (void)context; + } + +private: + std::weak_ptr _skinMeshNode; + std::weak_ptr _renderer; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp new file mode 100644 index 0000000..f3dc539 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp @@ -0,0 +1,30 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Renderable/Texture.hpp" + +#include + +namespace Stone::Render::OpenGL { + +class Texture : public Scene::IRendererObject { +public: + Texture(const std::shared_ptr &texture, const std::shared_ptr &renderer) + : _texture(texture), _renderer(renderer) { + } + + ~Texture() override { + } + + void render(Scene::RenderContext &context) override { + (void)context; + } + +private: + std::weak_ptr _texture; + std::weak_ptr _renderer; +}; + +} // namespace Stone::Render::OpenGL From 3f6ccfdf3b46ef521d58886e1745ce93a4ee2384 Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 3 Sep 2024 23:53:55 +0200 Subject: [PATCH 05/89] OpenGL RendererObjectManager --- .../Render/OpenGL/RendererObjectManager.cpp | 51 +++++++++++++++++++ .../Render/OpenGL/RendererObjectManager.hpp | 35 +++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp create mode 100644 Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp diff --git a/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp b/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp new file mode 100644 index 0000000..baf04e3 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp @@ -0,0 +1,51 @@ +// Copyright 2024 Stone-Engine + +#include "RendererObjectManager.hpp" + +#include "Renderable/InstancedMeshNode.hpp" +#include "Renderable/Material.hpp" +#include "Renderable/Mesh.hpp" +#include "Renderable/MeshNode.hpp" +#include "Renderable/Shader.hpp" +#include "Renderable/SkinMesh.hpp" +#include "Renderable/SkinMeshNode.hpp" +#include "Renderable/Texture.hpp" + + +#define UPDATE_RENDERER_OBJECT(RenderableClass, object) \ + void RendererObjectManager::update##RenderableClass(const std::shared_ptr &(object)) { \ + Scene::RendererObjectManager::update##RenderableClass((object)); \ + \ + auto new##RenderableClass = std::make_shared((object), _renderer); \ + setRendererObjectTo((object).get(), new##RenderableClass); \ + } + + +namespace Stone::Render::OpenGL { + +RendererObjectManager::RendererObjectManager(std::shared_ptr renderer) + : _renderer(std::move(renderer)) { +} + + +UPDATE_RENDERER_OBJECT(MeshNode, meshNode) + +UPDATE_RENDERER_OBJECT(InstancedMeshNode, instancedMeshNode) + +UPDATE_RENDERER_OBJECT(SkinMeshNode, skinMeshNode) + +UPDATE_RENDERER_OBJECT(Material, material) + +UPDATE_RENDERER_OBJECT(DynamicMesh, dynamicMesh) + +UPDATE_RENDERER_OBJECT(StaticMesh, staticMesh) + +UPDATE_RENDERER_OBJECT(DynamicSkinMesh, dynamicSkinMesh) + +UPDATE_RENDERER_OBJECT(StaticSkinMesh, staticSkinMesh) + +UPDATE_RENDERER_OBJECT(Texture, texture) + +UPDATE_RENDERER_OBJECT(Shader, shader) + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp b/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp new file mode 100644 index 0000000..1d1b495 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp @@ -0,0 +1,35 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Scene/RendererObjectManager.hpp" + +namespace Stone::Render::OpenGL { + +class OpenGLRenderer; + +class RendererObjectManager : public Scene::RendererObjectManager { + +public: + explicit RendererObjectManager(std::shared_ptr renderer); + RendererObjectManager(const RendererObjectManager &other) = default; + + ~RendererObjectManager() override = default; + + void updateMeshNode(const std::shared_ptr &meshNode) override; + void updateInstancedMeshNode(const std::shared_ptr &instancedMeshNode) override; + void updateSkinMeshNode(const std::shared_ptr &skinMeshNode) override; + void updateMaterial(const std::shared_ptr &material) override; + void updateDynamicMesh(const std::shared_ptr &mesh) override; + void updateStaticMesh(const std::shared_ptr &mesh) override; + void updateDynamicSkinMesh(const std::shared_ptr &skinmesh) override; + void updateStaticSkinMesh(const std::shared_ptr &skinmesh) override; + void updateTexture(const std::shared_ptr &texture) override; + void updateShader(const std::shared_ptr &shader) override; + + +private: + std::shared_ptr _renderer; +}; + +} // namespace Stone::Render::OpenGL From 337f77df01406a6f5ab7ddeac44f6136805ffcc8 Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 3 Sep 2024 23:54:04 +0200 Subject: [PATCH 06/89] render context structure --- .../Render/src/Render/OpenGL/RenderContext.hpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Engine/Render/src/Render/OpenGL/RenderContext.hpp diff --git a/Engine/Render/src/Render/OpenGL/RenderContext.hpp b/Engine/Render/src/Render/OpenGL/RenderContext.hpp new file mode 100644 index 0000000..7762825 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/RenderContext.hpp @@ -0,0 +1,17 @@ +// Copyright 2024 StoneEngine + +#pragma once + +#include "Scene/RenderContext.hpp" + +#include + +namespace Stone::Render::OpenGL { + +class OpenGLRenderer; + +struct RenderContext : public Scene::RenderContext { + OpenGLRenderer *renderer; +}; + +} // namespace Stone::Render::OpenGL From b985faf7e65ea9287ca2613d0e4d22a9a0869d23 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 4 Sep 2024 00:11:35 +0200 Subject: [PATCH 07/89] OpenGLRenderer using RenderContext and RendererObjectManager --- .../include/Render/OpenGL/OpenGLRenderer.hpp | 5 - .../src/Render/OpenGL/OpenGLRenderer.cpp | 152 ++++-------------- 2 files changed, 35 insertions(+), 122 deletions(-) diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index 0dd32b8..ca32e39 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -28,11 +28,6 @@ class OpenGLRenderer : public Renderer { private: std::pair _frameSize; - - void _initOpenGL(); - - unsigned int programID; - unsigned int vertexBuffer; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index dfd2514..f29c088 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -3,21 +3,32 @@ #include "Render/OpenGL/OpenGLRenderer.hpp" -#include +#include "RenderContext.hpp" +#include "RendererObjectManager.hpp" +#include "Scene/Node/WorldNode.hpp" + #include -#include -#include -#include -#include -#include namespace Stone::Render::OpenGL { -OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) - : Renderer(), _frameSize(settings.frame_size), programID(0), vertexBuffer(0) { +static void initializeOpenGL() { + static bool initialized = false; + if (!initialized) { + glewExperimental = true; + if (glewInit() != GLEW_OK) { + throw std::runtime_error("Failed to initialize GLEW"); + } + initialized = true; + } +} + +OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) : Renderer(), _frameSize(settings.frame_size) { + + initializeOpenGL(); + std::cout << "OpenGLRenderer created" << std::endl; - _initOpenGL(); + std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; } OpenGLRenderer::~OpenGLRenderer() { @@ -25,123 +36,30 @@ OpenGLRenderer::~OpenGLRenderer() { } void OpenGLRenderer::updateDataForWorld(const std::shared_ptr &world) { - (void)world; + OpenGL::RendererObjectManager manager(std::dynamic_pointer_cast(shared_from_this())); + world->traverseTopDown([&manager](const std::shared_ptr &node) { + auto renderElement = std::dynamic_pointer_cast(node); + if (renderElement && renderElement->isDirty()) { + manager.updateRenderable(node); + } + }); } void OpenGLRenderer::renderWorld(const std::shared_ptr &world) { - (void)world; - + glViewport(0, 0, static_cast(_frameSize.first), static_cast(_frameSize.second)); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnableVertexAttribArray(0); - glUseProgram(programID); - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - glDrawArrays(GL_TRIANGLES, 0, 3); - glDisableVertexAttribArray(0); -} - -void OpenGLRenderer::updateFrameSize(std::pair size) { - _frameSize = size; -} - -void OpenGLRenderer::_initOpenGL() { - - glewExperimental = true; - if (glewInit() != GLEW_OK) { - throw std::runtime_error("Failed to initialize GLEW"); - } - GLuint VertexArrayID; - glGenVertexArrays(1, &VertexArrayID); - glBindVertexArray(VertexArrayID); + OpenGL::RenderContext context; + context.renderer = this; - constexpr static GLfloat g_vertex_buffer_data[] = { - -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - }; - - glGenBuffers(1, &vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); - - GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); - GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); - - // Read the Vertex Shader code from the file - std::string VertexShaderCode = R"( -#version 330 core - -layout (location = 0) in vec3 vertexPosition_modelspace; - -void main() { - gl_Position.xyz = vertexPosition_modelspace; - gl_Position.w = 1.0; + world->initializeRenderContext(context); + world->render(context); } -)"; - - // Read the Fragment Shader code from the file - std::string FragmentShaderCode = R"( -#version 330 core -out vec3 color; -void main(){ - color = vec3(1,0,0); +void OpenGLRenderer::updateFrameSize(std::pair size) { + _frameSize = size; } -)"; - - GLint Result = GL_FALSE; - int InfoLogLength; - - // Compile Vertex Shader - std::cout << "Compiling shader" << std::endl; - const char *VertexSourcePointer = VertexShaderCode.c_str(); - glShaderSource(VertexShaderID, 1, &VertexSourcePointer, nullptr); - glCompileShader(VertexShaderID); - - // Check Vertex Shader - glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); - glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); - if (InfoLogLength > 0) { - std::vector VertexShaderErrorMessage(InfoLogLength + 1); - glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]); - printf("%s\n", &VertexShaderErrorMessage[0]); - } - - // Compile Fragment Shader - std::cout << "Compiling shader" << std::endl; - const char *FragmentSourcePointer = FragmentShaderCode.c_str(); - glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, nullptr); - glCompileShader(FragmentShaderID); - - // Check Fragment Shader - glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); - glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); - if (InfoLogLength > 0) { - std::vector FragmentShaderErrorMessage(InfoLogLength + 1); - glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]); - std::cerr << FragmentShaderErrorMessage.data() << "\n"; - } - // Link the program - std::cout << "Linking program" << std::endl; - programID = glCreateProgram(); - glAttachShader(programID, VertexShaderID); - glAttachShader(programID, FragmentShaderID); - glLinkProgram(programID); - - // Check the program - glGetProgramiv(programID, GL_LINK_STATUS, &Result); - glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &InfoLogLength); - if (InfoLogLength > 0) { - std::vector ProgramErrorMessage(InfoLogLength + 1); - glGetProgramInfoLog(programID, InfoLogLength, nullptr, &ProgramErrorMessage[0]); - std::cerr << ProgramErrorMessage.data() << std::endl; - } - - glDetachShader(programID, VertexShaderID); - glDetachShader(programID, FragmentShaderID); - - glDeleteShader(VertexShaderID); - glDeleteShader(FragmentShaderID); -} } // namespace Stone::Render::OpenGL From 8dee2b28bbca0c9988e849d82168346ece1c51b3 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 4 Sep 2024 00:11:48 +0200 Subject: [PATCH 08/89] check glfw init failure --- Engine/Window/src/Window/App.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Engine/Window/src/Window/App.cpp b/Engine/Window/src/Window/App.cpp index d803e3a..6ab4382 100644 --- a/Engine/Window/src/Window/App.cpp +++ b/Engine/Window/src/Window/App.cpp @@ -11,7 +11,9 @@ namespace Stone::Window { App::App() : std::enable_shared_from_this(), _windows() { - glfwInit(); + if (glfwInit() == GLFW_FALSE) { + throw std::runtime_error("Failed to initialize GLFW"); + } } App::~App() { From dcd5ab597748304537053583de816ed3c8c8a6ad Mon Sep 17 00:00:00 2001 From: Arthur MASSON Date: Wed, 4 Sep 2024 18:07:51 +0200 Subject: [PATCH 09/89] OpenGL mesh render wip --- .../include/Render/OpenGL/OpenGLRenderer.hpp | 3 + .../src/Render/OpenGL/OpenGLRenderer.cpp | 5 +- .../src/Render/OpenGL/Renderable/Mesh.hpp | 100 +++++++++++++++++- .../src/Render/OpenGL/Renderable/MeshNode.hpp | 38 ++++++- .../src/Render/OpenGL/RendererInternals.hpp | 24 +++++ .../Vulkan/VulkanRenderable/MeshNode.cpp | 1 + .../Scene/src/Scene/RendererObjectManager.cpp | 8 ++ 7 files changed, 173 insertions(+), 6 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/RendererInternals.hpp diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index ca32e39..5159795 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -28,6 +28,9 @@ class OpenGLRenderer : public Renderer { private: std::pair _frameSize; + + std::unique_ptr _internals; + friend class RendererInternals; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index f29c088..953e6f7 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -23,12 +23,15 @@ static void initializeOpenGL() { } } -OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) : Renderer(), _frameSize(settings.frame_size) { +OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) : Renderer(), _frameSize(settings.frame_size), + _internals(nullptr) { initializeOpenGL(); std::cout << "OpenGLRenderer created" << std::endl; std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; + + _internals = std::make_unique(); } OpenGLRenderer::~OpenGLRenderer() { diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp index 66b4ee3..17c2753 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp @@ -9,10 +9,102 @@ namespace Stone::Render::OpenGL { -class DynamicMesh : public Scene::IRendererObject { +struct VRAMMesh { + + VRAMMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) { + (void)renderer; + if (mesh == nullptr) { + return; + } + + glGenVertexArrays(1, &elementsBuffer); + if (elementsBuffer == 0) { + throw std::runtime_error("Failed to generate vertex array buffer"); + } + + glGenBuffers(1, &verticesBuffer); + if (verticesBuffer == 0) { + glDeleteVertexArrays(1, &elementsBuffer); + throw std::runtime_error("Failed to generate indices buffer"); + } + + glGenBuffers(1, &indicesBuffer); + if (indicesBuffer == 0) { + glDeleteBuffers(1, &verticesBuffer); + glDeleteVertexArrays(1, &elementsBuffer); + throw std::runtime_error("Failed to generate indices buffer"); + } + + glBindVertexArray(elementsBuffer); + + glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer); + glBufferData(GL_ARRAY_BUFFER, mesh->getVertices().size() * sizeof(Scene::Vertex), mesh->getVertices().data(), + GL_STATIC_DRAW); + + numIndices = mesh->getIndices().size(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(uint32_t), mesh->getIndices().data(), GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), + (void *)offsetof(Scene::Vertex, position)); + + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), (void *)offsetof(Scene::Vertex, normal)); + + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), + (void *)offsetof(Scene::Vertex, tangent)); + + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), + (void *)offsetof(Scene::Vertex, bitangent)); + + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), (void *)offsetof(Scene::Vertex, uv)); + } + + ~VRAMMesh() { + if (verticesBuffer != 0) { + glDeleteBuffers(1, &verticesBuffer); + } + if (indicesBuffer != 0) { + glDeleteBuffers(1, &indicesBuffer); + } + if (elementsBuffer != 0) { + glDeleteVertexArrays(1, &elementsBuffer); + } + } + + GLuint verticesBuffer = 0; + GLuint indicesBuffer = 0; + GLuint elementsBuffer = 0; + GLsizei numIndices = 0; +}; + +class RendererMesh : public Scene::IRendererObject { + +public: + RendererMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) + : _vramMesh(mesh, renderer) { + } + + ~RendererMesh() override { + } + + const VRAMMesh &getVRAMMesh() const { + return _vramMesh; + } + +private: + VRAMMesh _vramMesh; +}; + + +class DynamicMesh : public RendererMesh { public: DynamicMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) - : _mesh(mesh), _renderer(renderer) { + : RendererMesh(mesh, renderer), _mesh(mesh), _renderer(renderer) { } ~DynamicMesh() override { @@ -27,10 +119,10 @@ class DynamicMesh : public Scene::IRendererObject { std::weak_ptr _renderer; }; -class StaticMesh : public Scene::IRendererObject { +class StaticMesh : public RendererMesh { public: StaticMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) - : _mesh(mesh), _renderer(renderer) { + : RendererMesh(mesh->getSourceMesh(), renderer), _mesh(mesh), _renderer(renderer) { } ~StaticMesh() override { diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp index bd20d75..a28f9ab 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp @@ -2,11 +2,21 @@ #pragma once +#include "Mesh.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Node/MeshNode.hpp" +#include "Scene/Renderable/Mesh.hpp" #include +template +const std::shared_ptr &first_non_null(const std::shared_ptr &ptr, const Args &...args) { + if (ptr != nullptr) { + return ptr; + } + return first_non_null(args...); +} + namespace Stone::Render::OpenGL { class MeshNode : public Scene::IRendererObject { @@ -19,7 +29,33 @@ class MeshNode : public Scene::IRendererObject { } void render(Scene::RenderContext &context) override { - (void)context; + assert(_meshNode.expired() == false); + + auto meshNode = _meshNode.lock(); + auto mesh = meshNode->getMesh(); + if (mesh == nullptr) { + return; + } + + auto rendererMesh = mesh->getRendererObject(); + if (rendererMesh == nullptr) { + return; + } + + auto material = first_non_null(meshNode->getMaterial(), mesh->getDefaultMaterial(), ); + + const VRAMMesh &vramMesh = rendererMesh->getVRAMMesh(); + + // TODO: Retrieve the corect shader program to use + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + // TODO: Send uniforms from context to shader + + // Send material uniforms to program } private: diff --git a/Engine/Render/src/Render/OpenGL/RendererInternals.hpp b/Engine/Render/src/Render/OpenGL/RendererInternals.hpp new file mode 100644 index 0000000..e7335db --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/RendererInternals.hpp @@ -0,0 +1,24 @@ +// Copyright 2024 StoneEngine + +#pragma once + +#include "Scene/RenderContext.hpp" + +#include "Renderable/Material.hpp" + +namespace Stone::Render::OpenGL { + +class RendererInternals { +public: + RendererInternals() = default; + RendererInternals(const RendererInternals &other) = delete; + + ~RendererInternals() = default; + + static RendererInternals& getFrom(OpenGLRenderer &renderer) { + return *(renderer._internals); + } + +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp index 476a67c..4ecc269 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp @@ -389,6 +389,7 @@ void MeshNode::_createDescriptorPool(const std::shared_ptr &swapChain if (shader) { material->forEachTextures( [&](const std::pair> &texture) { + (void)texture; VkDescriptorPoolSize poolSize = {}; poolSize.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; poolSize.descriptorCount = swapChain->getImageCount(); diff --git a/Engine/Scene/src/Scene/RendererObjectManager.cpp b/Engine/Scene/src/Scene/RendererObjectManager.cpp index 0161cf8..52bb96e 100644 --- a/Engine/Scene/src/Scene/RendererObjectManager.cpp +++ b/Engine/Scene/src/Scene/RendererObjectManager.cpp @@ -70,18 +70,26 @@ void RendererObjectManager::updateMaterial(const std::shared_ptr &mate } void RendererObjectManager::updateDynamicMesh(const std::shared_ptr &mesh) { + if (mesh->getDefaultMaterial()) + updateMaterial(mesh->getDefaultMaterial()); mesh->markUndirty(); } void RendererObjectManager::updateStaticMesh(const std::shared_ptr &mesh) { + if (mesh->getDefaultMaterial()) + updateMaterial(mesh->getDefaultMaterial()); mesh->markUndirty(); } void RendererObjectManager::updateDynamicSkinMesh(const std::shared_ptr &skinmesh) { + if (skinmesh->getDefaultMaterial()) + updateMaterial(skinmesh->getDefaultMaterial()); skinmesh->markUndirty(); } void RendererObjectManager::updateStaticSkinMesh(const std::shared_ptr &skinmesh) { + if (skinmesh->getDefaultMaterial()) + updateMaterial(skinmesh->getDefaultMaterial()); skinmesh->markUndirty(); } From 5a76c98247a69be3cc0093ec65b9db67a84dbcc0 Mon Sep 17 00:00:00 2001 From: Arthur MASSON Date: Wed, 4 Sep 2024 19:02:49 +0200 Subject: [PATCH 10/89] Renderer defaults instance --- Engine/Render/include/Render/Renderer.hpp | 2 +- .../include/Render/Vulkan/VulkanRenderer.hpp | 2 ++ .../src/Render/Vulkan/RenderContext.hpp | 2 +- .../Render/Vulkan/RendererObjectManager.hpp | 2 +- .../Vulkan/VulkanRenderable/MeshNode.cpp | 1 - .../src/Render/Vulkan/VulkanRenderer.cpp | 2 ++ .../Vulkan/VulkanRenderer_ISceneRenderer.cpp | 5 ++- Engine/Scene/include/Scene.hpp | 5 ++- Engine/Scene/include/Scene/Node/Node.hpp | 2 +- .../include/Scene/Renderable/IRenderable.hpp | 2 +- .../include/Scene/Renderable/Material.hpp | 4 +-- .../Scene/{ => Renderer}/ISceneRenderer.hpp | 5 +++ .../Scene/{ => Renderer}/RenderContext.hpp | 0 .../Scene/Renderer/RendererDefaults.hpp | 33 +++++++++++++++++++ .../{ => Renderer}/RendererObjectManager.hpp | 0 Engine/Scene/include/SceneTypes.hpp | 2 +- .../src/Scene/Node/InstancedMeshNode.cpp | 2 -- Engine/Scene/src/Scene/Node/MeshNode.cpp | 1 - Engine/Scene/src/Scene/Node/PivotNode.cpp | 2 -- Engine/Scene/src/Scene/Node/SkinMeshNode.cpp | 1 - Engine/Scene/src/Scene/RenderContext.cpp | 3 -- .../Scene/src/Scene/Renderable/Material.cpp | 6 ++-- Engine/Scene/src/Scene/Renderable/Mesh.cpp | 2 -- Engine/Scene/src/Scene/Renderable/Shader.cpp | 1 - .../Scene/src/Scene/Renderable/SkinMesh.cpp | 1 - Engine/Scene/src/Scene/Renderable/Texture.cpp | 1 - .../src/Scene/Renderer/RenderContext.cpp | 3 ++ .../src/Scene/Renderer/RendererDefaults.cpp | 19 +++++++++++ .../{ => Renderer}/RendererObjectManager.cpp | 2 +- 29 files changed, 84 insertions(+), 29 deletions(-) rename Engine/Scene/include/Scene/{ => Renderer}/ISceneRenderer.hpp (78%) rename Engine/Scene/include/Scene/{ => Renderer}/RenderContext.hpp (100%) create mode 100644 Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp rename Engine/Scene/include/Scene/{ => Renderer}/RendererObjectManager.hpp (100%) delete mode 100644 Engine/Scene/src/Scene/RenderContext.cpp create mode 100644 Engine/Scene/src/Scene/Renderer/RenderContext.cpp create mode 100644 Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp rename Engine/Scene/src/Scene/{ => Renderer}/RendererObjectManager.cpp (98%) diff --git a/Engine/Render/include/Render/Renderer.hpp b/Engine/Render/include/Render/Renderer.hpp index 70138de..8e8f08a 100644 --- a/Engine/Render/include/Render/Renderer.hpp +++ b/Engine/Render/include/Render/Renderer.hpp @@ -2,7 +2,7 @@ #pragma once -#include "Scene/ISceneRenderer.hpp" +#include "Scene/Renderer/ISceneRenderer.hpp" #include diff --git a/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp b/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp index a43fffa..6902d13 100644 --- a/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp +++ b/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp @@ -28,6 +28,7 @@ class VulkanRenderer : public Renderer { /** Renderer */ void updateDataForWorld(const std::shared_ptr &world) override; + const std::unique_ptr &getRendererDefaults() const override; void renderWorld(const std::shared_ptr &world) override; void updateFrameSize(std::pair size) override; @@ -49,6 +50,7 @@ class VulkanRenderer : public Renderer { std::shared_ptr _renderPass; std::shared_ptr _framesRenderer; std::shared_ptr _swapChain; + std::unique_ptr _rendererDefaults; }; } // namespace Stone::Render::Vulkan diff --git a/Engine/Render/src/Render/Vulkan/RenderContext.hpp b/Engine/Render/src/Render/Vulkan/RenderContext.hpp index 9e06f86..ec5f831 100644 --- a/Engine/Render/src/Render/Vulkan/RenderContext.hpp +++ b/Engine/Render/src/Render/Vulkan/RenderContext.hpp @@ -2,7 +2,7 @@ #pragma once -#include "Scene/RenderContext.hpp" +#include "Scene/Renderer/RenderContext.hpp" #include diff --git a/Engine/Render/src/Render/Vulkan/RendererObjectManager.hpp b/Engine/Render/src/Render/Vulkan/RendererObjectManager.hpp index a0c7c5c..6687e6e 100644 --- a/Engine/Render/src/Render/Vulkan/RendererObjectManager.hpp +++ b/Engine/Render/src/Render/Vulkan/RendererObjectManager.hpp @@ -2,7 +2,7 @@ #pragma once -#include "Scene/RendererObjectManager.hpp" +#include "Scene/Renderer/RendererObjectManager.hpp" #include diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp index 476a67c..bf274a1 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp @@ -13,7 +13,6 @@ #include "Scene/Renderable/Mesh.hpp" #include "Scene/Renderable/Shader.hpp" #include "Scene/Renderable/Texture.hpp" -#include "Scene/RenderContext.hpp" #include "Texture.hpp" #include "Utils/FileSystem.hpp" diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp index 4e9e940..25bb7b4 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp @@ -1,6 +1,7 @@ // Copyright 2024 Stone-Engine #include "Render/Vulkan/VulkanRenderer.hpp" +#include "Scene/Renderer/RendererDefaults.hpp" #include "Device.hpp" #include "FramesRenderer.hpp" @@ -19,6 +20,7 @@ VulkanRenderer::VulkanRenderer(RendererSettings &settings) : Renderer() { _renderPass = std::make_shared(_device, swapChainProperties.surfaceFormat.format); _swapChain = std::make_shared(_device, _renderPass->getRenderPass(), swapChainProperties); _framesRenderer = std::make_shared(_device, _swapChain->getImageCount()); + _rendererDefaults = std::make_unique(); assert(_framesRenderer->getImageCount() == _swapChain->getImageCount()); } diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp index 425ff21..e6c840c 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp @@ -7,7 +7,6 @@ #include "RendererObjectManager.hpp" #include "RenderPass.hpp" #include "Scene.hpp" -#include "Scene/ISceneRenderer.hpp" #include "SwapChain.hpp" namespace Stone::Render::Vulkan { @@ -22,6 +21,10 @@ void VulkanRenderer::updateDataForWorld(const std::shared_ptr }); } +const std::unique_ptr &VulkanRenderer::getRendererDefaults() const { + return _rendererDefaults; +} + void VulkanRenderer::renderWorld(const std::shared_ptr &world) { if (!_framesRenderer) { diff --git a/Engine/Scene/include/Scene.hpp b/Engine/Scene/include/Scene.hpp index 17d723a..417432a 100644 --- a/Engine/Scene/include/Scene.hpp +++ b/Engine/Scene/include/Scene.hpp @@ -16,6 +16,9 @@ #include "Scene/Renderable/Shader.hpp" #include "Scene/Renderable/SkinMesh.hpp" #include "Scene/Renderable/Texture.hpp" -#include "Scene/RenderContext.hpp" +#include "Scene/Renderer/ISceneRenderer.hpp" +#include "Scene/Renderer/RenderContext.hpp" +#include "Scene/Renderer/RendererDefaults.hpp" +#include "Scene/Renderer/RendererObjectManager.hpp" #include "Scene/Transform.hpp" #include "Scene/Vertex.hpp" diff --git a/Engine/Scene/include/Scene/Node/Node.hpp b/Engine/Scene/include/Scene/Node/Node.hpp index a29ffb9..4937d53 100644 --- a/Engine/Scene/include/Scene/Node/Node.hpp +++ b/Engine/Scene/include/Scene/Node/Node.hpp @@ -5,7 +5,7 @@ #include "Core/Object.hpp" #include "Logging/TermColor.hpp" #include "Scene/Node/NodeMacros.hpp" -#include "Scene/RenderContext.hpp" +#include "Scene/Renderer/RenderContext.hpp" #include #include diff --git a/Engine/Scene/include/Scene/Renderable/IRenderable.hpp b/Engine/Scene/include/Scene/Renderable/IRenderable.hpp index 4d0ecf5..46e42a2 100644 --- a/Engine/Scene/include/Scene/Renderable/IRenderable.hpp +++ b/Engine/Scene/include/Scene/Renderable/IRenderable.hpp @@ -2,7 +2,7 @@ #pragma once -#include "Scene/RenderContext.hpp" +#include "Scene/Renderer/RenderContext.hpp" #include "Utils/SigSlot.hpp" namespace Stone::Scene { diff --git a/Engine/Scene/include/Scene/Renderable/Material.hpp b/Engine/Scene/include/Scene/Renderable/Material.hpp index 6f09d4c..d3b6b96 100644 --- a/Engine/Scene/include/Scene/Renderable/Material.hpp +++ b/Engine/Scene/include/Scene/Renderable/Material.hpp @@ -119,7 +119,7 @@ class Material : public Core::Object, public IRenderable { * * @return The vertex shader as a shared pointer to Shader. */ - [[nodiscard]] std::shared_ptr getVertexShader() const; + [[nodiscard]] const std::shared_ptr &getVertexShader() const; /** * @brief Set the fragment shader used by the Material. @@ -133,7 +133,7 @@ class Material : public Core::Object, public IRenderable { * * @return The fragment shader as a shared pointer to Shader. */ - [[nodiscard]] std::shared_ptr getFragmentShader() const; + [[nodiscard]] const std::shared_ptr &getFragmentShader() const; protected: std::unordered_map> _textures; /**< Map of texture parameters. */ diff --git a/Engine/Scene/include/Scene/ISceneRenderer.hpp b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp similarity index 78% rename from Engine/Scene/include/Scene/ISceneRenderer.hpp rename to Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp index 260bc92..988165e 100644 --- a/Engine/Scene/include/Scene/ISceneRenderer.hpp +++ b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp @@ -18,6 +18,11 @@ class ISceneRenderer { */ virtual void updateDataForWorld(const std::shared_ptr &world) = 0; + /** + * @brief Get the renderer defaults. + */ + [[nodiscard]] virtual const std::unique_ptr &getRendererDefaults() const = 0; + /** * @brief Request the renderer to render the world from the given world root node. */ diff --git a/Engine/Scene/include/Scene/RenderContext.hpp b/Engine/Scene/include/Scene/Renderer/RenderContext.hpp similarity index 100% rename from Engine/Scene/include/Scene/RenderContext.hpp rename to Engine/Scene/include/Scene/Renderer/RenderContext.hpp diff --git a/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp b/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp new file mode 100644 index 0000000..ef3bce8 --- /dev/null +++ b/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp @@ -0,0 +1,33 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "SceneTypes.hpp" + +namespace Stone::Scene { + +/** + * @brief Default values for a renderer. + */ +class RendererDefaults { +public: + + RendererDefaults(); + RendererDefaults(const RendererDefaults&) = delete; + + ~RendererDefaults() = default; + + /** + * @brief Get the default material used when a mesh has no material set. + */ + const std::shared_ptr& getDefaultMaterial() const; + + void setDefaultMaterial(const std::shared_ptr &material); + +private: + + std::shared_ptr _defaultMaterial; + +}; + +} // namespace Stone::Scene diff --git a/Engine/Scene/include/Scene/RendererObjectManager.hpp b/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp similarity index 100% rename from Engine/Scene/include/Scene/RendererObjectManager.hpp rename to Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp diff --git a/Engine/Scene/include/SceneTypes.hpp b/Engine/Scene/include/SceneTypes.hpp index 31e64a7..ce1d867 100644 --- a/Engine/Scene/include/SceneTypes.hpp +++ b/Engine/Scene/include/SceneTypes.hpp @@ -2,7 +2,7 @@ #pragma once -#include "Scene/RenderContext.hpp" +#include "Scene/Renderer/RenderContext.hpp" #include "Scene/Transform.hpp" #include "Scene/Vertex.hpp" diff --git a/Engine/Scene/src/Scene/Node/InstancedMeshNode.cpp b/Engine/Scene/src/Scene/Node/InstancedMeshNode.cpp index f685d42..7f221f2 100644 --- a/Engine/Scene/src/Scene/Node/InstancedMeshNode.cpp +++ b/Engine/Scene/src/Scene/Node/InstancedMeshNode.cpp @@ -2,8 +2,6 @@ #include "Scene/Node/InstancedMeshNode.hpp" -#include "Scene/RendererObjectManager.hpp" - namespace Stone::Scene { STONE_NODE_IMPLEMENTATION(InstancedMeshNode) diff --git a/Engine/Scene/src/Scene/Node/MeshNode.cpp b/Engine/Scene/src/Scene/Node/MeshNode.cpp index 4e2ef29..40444a4 100644 --- a/Engine/Scene/src/Scene/Node/MeshNode.cpp +++ b/Engine/Scene/src/Scene/Node/MeshNode.cpp @@ -4,7 +4,6 @@ #include "Scene/Renderable/Material.hpp" #include "Scene/Renderable/Mesh.hpp" -#include "Scene/RendererObjectManager.hpp" namespace Stone::Scene { diff --git a/Engine/Scene/src/Scene/Node/PivotNode.cpp b/Engine/Scene/src/Scene/Node/PivotNode.cpp index 1c00484..04d2cc3 100644 --- a/Engine/Scene/src/Scene/Node/PivotNode.cpp +++ b/Engine/Scene/src/Scene/Node/PivotNode.cpp @@ -2,8 +2,6 @@ #include "Scene/Node/PivotNode.hpp" -#include - namespace Stone::Scene { STONE_NODE_IMPLEMENTATION(PivotNode) diff --git a/Engine/Scene/src/Scene/Node/SkinMeshNode.cpp b/Engine/Scene/src/Scene/Node/SkinMeshNode.cpp index c2f3f7d..b7aa600 100644 --- a/Engine/Scene/src/Scene/Node/SkinMeshNode.cpp +++ b/Engine/Scene/src/Scene/Node/SkinMeshNode.cpp @@ -5,7 +5,6 @@ #include "Scene/Node/SkeletonNode.hpp" #include "Scene/Renderable/Material.hpp" #include "Scene/Renderable/SkinMesh.hpp" -#include "Scene/RendererObjectManager.hpp" namespace Stone::Scene { diff --git a/Engine/Scene/src/Scene/RenderContext.cpp b/Engine/Scene/src/Scene/RenderContext.cpp deleted file mode 100644 index cb8c179..0000000 --- a/Engine/Scene/src/Scene/RenderContext.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright 2024 Stone-Engine - -#include "Scene/RenderContext.hpp" diff --git a/Engine/Scene/src/Scene/Renderable/Material.cpp b/Engine/Scene/src/Scene/Renderable/Material.cpp index 5f8ebe2..d25e6fc 100644 --- a/Engine/Scene/src/Scene/Renderable/Material.cpp +++ b/Engine/Scene/src/Scene/Renderable/Material.cpp @@ -3,7 +3,7 @@ #include "Scene/Renderable/Material.hpp" #include "Scene/Renderable/Texture.hpp" -#include "Scene/RendererObjectManager.hpp" +#include "Scene/Renderer/RendererObjectManager.hpp" #include "Utils/Glm.hpp" namespace Stone::Scene { @@ -89,7 +89,7 @@ void Material::setVertexShader(std::shared_ptr vertexShader) { markDirty(); } -std::shared_ptr Material::getVertexShader() const { +const std::shared_ptr &Material::getVertexShader() const { return _vertexShader; } @@ -98,7 +98,7 @@ void Material::setFragmentShader(std::shared_ptr fragmentShader) { markDirty(); } -std::shared_ptr Material::getFragmentShader() const { +const std::shared_ptr &Material::getFragmentShader() const { return _fragmentShader; } diff --git a/Engine/Scene/src/Scene/Renderable/Mesh.cpp b/Engine/Scene/src/Scene/Renderable/Mesh.cpp index 7695e03..532545f 100644 --- a/Engine/Scene/src/Scene/Renderable/Mesh.cpp +++ b/Engine/Scene/src/Scene/Renderable/Mesh.cpp @@ -2,8 +2,6 @@ #include "Scene/Renderable/Mesh.hpp" -#include "Scene/RendererObjectManager.hpp" - namespace Stone::Scene { std::ostream &DynamicMesh::writeToStream(std::ostream &stream, bool closing_bracer) const { diff --git a/Engine/Scene/src/Scene/Renderable/Shader.cpp b/Engine/Scene/src/Scene/Renderable/Shader.cpp index 3c07a11..12f2a38 100644 --- a/Engine/Scene/src/Scene/Renderable/Shader.cpp +++ b/Engine/Scene/src/Scene/Renderable/Shader.cpp @@ -2,7 +2,6 @@ #include "Scene/Renderable/Shader.hpp" -#include "Scene/RendererObjectManager.hpp" #include "Utils/StringExt.hpp" #include diff --git a/Engine/Scene/src/Scene/Renderable/SkinMesh.cpp b/Engine/Scene/src/Scene/Renderable/SkinMesh.cpp index 4789075..72a74fd 100644 --- a/Engine/Scene/src/Scene/Renderable/SkinMesh.cpp +++ b/Engine/Scene/src/Scene/Renderable/SkinMesh.cpp @@ -3,7 +3,6 @@ #include "Scene/Renderable/SkinMesh.hpp" #include "Scene/Node/SkeletonNode.hpp" -#include "Scene/RendererObjectManager.hpp" namespace Stone::Scene { diff --git a/Engine/Scene/src/Scene/Renderable/Texture.cpp b/Engine/Scene/src/Scene/Renderable/Texture.cpp index 0d0f2f4..0ae9b36 100644 --- a/Engine/Scene/src/Scene/Renderable/Texture.cpp +++ b/Engine/Scene/src/Scene/Renderable/Texture.cpp @@ -3,7 +3,6 @@ #include "Scene/Renderable/Texture.hpp" #include "Core/Image/ImageSource.hpp" -#include "Scene/RendererObjectManager.hpp" namespace Stone::Scene { diff --git a/Engine/Scene/src/Scene/Renderer/RenderContext.cpp b/Engine/Scene/src/Scene/Renderer/RenderContext.cpp new file mode 100644 index 0000000..d97979f --- /dev/null +++ b/Engine/Scene/src/Scene/Renderer/RenderContext.cpp @@ -0,0 +1,3 @@ +// Copyright 2024 Stone-Engine + +#include "Scene/Renderer/RenderContext.hpp" diff --git a/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp b/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp new file mode 100644 index 0000000..ca8793b --- /dev/null +++ b/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp @@ -0,0 +1,19 @@ +// Copyright 2024 Stone-Engine + +#include "Scene/Renderer/RendererDefaults.hpp" + +namespace Stone::Scene { + +RendererDefaults::RendererDefaults() { + _defaultMaterial = std::make_shared(); +} + +const std::shared_ptr& RendererDefaults::getDefaultMaterial() const { + return _defaultMaterial; +} + +void RendererDefaults::setDefaultMaterial(const std::shared_ptr &material) { + _defaultMaterial = material; +} + +} // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/RendererObjectManager.cpp b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp similarity index 98% rename from Engine/Scene/src/Scene/RendererObjectManager.cpp rename to Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp index 0161cf8..cd838a4 100644 --- a/Engine/Scene/src/Scene/RendererObjectManager.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp @@ -1,6 +1,6 @@ // Copyright 2024 Stone-Engine -#include "Scene/RendererObjectManager.hpp" +#include "Scene/Renderer/RendererObjectManager.hpp" #include "Scene.hpp" From 9106cbf61560771c5af8fd53bdcb59cd32dec470 Mon Sep 17 00:00:00 2001 From: Arthur MASSON Date: Wed, 4 Sep 2024 19:21:35 +0200 Subject: [PATCH 11/89] OpenGL default material --- Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp | 3 +++ Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp | 9 +++++++-- Engine/Render/src/Render/OpenGL/RenderContext.hpp | 6 ++---- Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp | 9 ++++++++- Engine/Render/src/Render/OpenGL/RendererInternals.hpp | 2 +- .../Render/src/Render/OpenGL/RendererObjectManager.hpp | 2 +- 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index 5159795..70a7040 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -22,6 +22,7 @@ class OpenGLRenderer : public Renderer { /** Renderer */ void updateDataForWorld(const std::shared_ptr &world) override; + const std::unique_ptr &getRendererDefaults() const override; void renderWorld(const std::shared_ptr &world) override; void updateFrameSize(std::pair size) override; @@ -31,6 +32,8 @@ class OpenGLRenderer : public Renderer { std::unique_ptr _internals; friend class RendererInternals; + + std::unique_ptr _defaults; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index 953e6f7..6374b9e 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -6,6 +6,8 @@ #include "RenderContext.hpp" #include "RendererObjectManager.hpp" #include "Scene/Node/WorldNode.hpp" +#include "RendererInternals.hpp" +#include "Scene/Renderer/RendererDefaults.hpp" #include @@ -32,6 +34,7 @@ OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) : Renderer(), _frameS std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; _internals = std::make_unique(); + _defaults = std::make_unique(); } OpenGLRenderer::~OpenGLRenderer() { @@ -48,14 +51,16 @@ void OpenGLRenderer::updateDataForWorld(const std::shared_ptr }); } +const std::unique_ptr &OpenGLRenderer::getRendererDefaults() const { + return _defaults; +} + void OpenGLRenderer::renderWorld(const std::shared_ptr &world) { glViewport(0, 0, static_cast(_frameSize.first), static_cast(_frameSize.second)); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); OpenGL::RenderContext context; - context.renderer = this; - world->initializeRenderContext(context); world->render(context); } diff --git a/Engine/Render/src/Render/OpenGL/RenderContext.hpp b/Engine/Render/src/Render/OpenGL/RenderContext.hpp index 7762825..53c1856 100644 --- a/Engine/Render/src/Render/OpenGL/RenderContext.hpp +++ b/Engine/Render/src/Render/OpenGL/RenderContext.hpp @@ -2,7 +2,7 @@ #pragma once -#include "Scene/RenderContext.hpp" +#include "Scene/Renderer/RenderContext.hpp" #include @@ -10,8 +10,6 @@ namespace Stone::Render::OpenGL { class OpenGLRenderer; -struct RenderContext : public Scene::RenderContext { - OpenGLRenderer *renderer; -}; +struct RenderContext : public Scene::RenderContext {}; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp index a28f9ab..d4a51bd 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp @@ -6,9 +6,15 @@ #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Node/MeshNode.hpp" #include "Scene/Renderable/Mesh.hpp" +#include "Scene/Renderer/RendererDefaults.hpp" #include +template +const std::shared_ptr &first_non_null(const std::shared_ptr &ptr) { + return ptr; +} + template const std::shared_ptr &first_non_null(const std::shared_ptr &ptr, const Args &...args) { if (ptr != nullptr) { @@ -29,6 +35,7 @@ class MeshNode : public Scene::IRendererObject { } void render(Scene::RenderContext &context) override { + (void)context; assert(_meshNode.expired() == false); auto meshNode = _meshNode.lock(); @@ -42,7 +49,7 @@ class MeshNode : public Scene::IRendererObject { return; } - auto material = first_non_null(meshNode->getMaterial(), mesh->getDefaultMaterial(), ); + auto material = first_non_null(meshNode->getMaterial(), mesh->getDefaultMaterial(), _renderer.lock()->getRendererDefaults()->getDefaultMaterial()); const VRAMMesh &vramMesh = rendererMesh->getVRAMMesh(); diff --git a/Engine/Render/src/Render/OpenGL/RendererInternals.hpp b/Engine/Render/src/Render/OpenGL/RendererInternals.hpp index e7335db..9344631 100644 --- a/Engine/Render/src/Render/OpenGL/RendererInternals.hpp +++ b/Engine/Render/src/Render/OpenGL/RendererInternals.hpp @@ -2,7 +2,7 @@ #pragma once -#include "Scene/RenderContext.hpp" +#include "Scene/Renderer/RenderContext.hpp" #include "Renderable/Material.hpp" diff --git a/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp b/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp index 1d1b495..ff6d7fb 100644 --- a/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp +++ b/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp @@ -2,7 +2,7 @@ #pragma once -#include "Scene/RendererObjectManager.hpp" +#include "Scene/Renderer/RendererObjectManager.hpp" namespace Stone::Render::OpenGL { From b4bfd5930ac7e8a9b0af0c221e280a48ef21db16 Mon Sep 17 00:00:00 2001 From: Arthur MASSON Date: Wed, 4 Sep 2024 19:24:58 +0200 Subject: [PATCH 12/89] fix material instanciation --- Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp b/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp index ca8793b..24d4166 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp @@ -1,6 +1,7 @@ // Copyright 2024 Stone-Engine #include "Scene/Renderer/RendererDefaults.hpp" +#include "Scene/Renderable/Material.hpp" namespace Stone::Scene { From 8ffd0aed05849cbd6d02801679bfdb88029a9775 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 4 Sep 2024 22:34:44 +0200 Subject: [PATCH 13/89] OpenGL generate textures --- .../Core/include/Core/Image/ImageSource.hpp | 2 +- .../src/Render/OpenGL/Renderable/Texture.hpp | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/Engine/Core/include/Core/Image/ImageSource.hpp b/Engine/Core/include/Core/Image/ImageSource.hpp index eb6d503..f89ecc7 100644 --- a/Engine/Core/include/Core/Image/ImageSource.hpp +++ b/Engine/Core/include/Core/Image/ImageSource.hpp @@ -33,7 +33,7 @@ class ImageSource : public Assets::Resource { [[nodiscard]] Size getSize() const; void unloadData(); - void loadData(bool force); + void loadData(bool force = false); [[nodiscard]] bool isLoaded() const; [[nodiscard]] std::shared_ptr getLoadedImage() const; diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp index f3dc539..f669b49 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp @@ -2,6 +2,8 @@ #pragma once +#include "Core/Image/ImageData.hpp" +#include "Core/Image/ImageSource.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Texture.hpp" @@ -9,22 +11,86 @@ namespace Stone::Render::OpenGL { +GLuint convert(Core::Image::Channel channel) { + switch (channel) { + case Core::Image::Channel::GREY: return GL_RED; + case Core::Image::Channel::DUAL: return GL_RG; + case Core::Image::Channel::RGB: return GL_RGB; + case Core::Image::Channel::RGBA: return GL_RGBA; + default: return GL_RGBA; + } +} + +GLuint convert(Scene::TextureFilter filter) { + switch (filter) { + case Scene::TextureFilter::Nearest: return GL_NEAREST; + case Scene::TextureFilter::Linear: return GL_LINEAR; + case Scene::TextureFilter::Cubic: return GL_LINEAR; + default: return GL_LINEAR; + } +} + +GLuint convert(Scene::TextureWrap wrap) { + switch (wrap) { + case Scene::TextureWrap::Repeat: return GL_REPEAT; + case Scene::TextureWrap::MirroredRepeat: return GL_MIRRORED_REPEAT; + case Scene::TextureWrap::ClampToEdge: return GL_CLAMP_TO_EDGE; + case Scene::TextureWrap::ClampToBorder: return GL_CLAMP_TO_BORDER; + default: return GL_REPEAT; + } +} + + class Texture : public Scene::IRendererObject { public: Texture(const std::shared_ptr &texture, const std::shared_ptr &renderer) : _texture(texture), _renderer(renderer) { + + std::shared_ptr imageSource = texture->getImage(); + if (imageSource == nullptr) { + return; + } + + imageSource->loadData(); + std::shared_ptr imageData = imageSource->getLoadedImage(); + + int bpp = static_cast(imageData->getChannels()); + GLuint format = convert(imageData->getChannels()); + glGenTextures(1, &_buffer); + if (_buffer == 0) { + std::runtime_error("Failed to create texture buffer."); + } + glBindTexture(GL_TEXTURE_2D, _buffer); + glTexImage2D(GL_TEXTURE_2D, 0, format, imageData->getSize().x, imageData->getSize().y, 0, format, + GL_UNSIGNED_BYTE, imageData->getData()); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, convert(texture->getWrap())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, convert(texture->getWrap())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert(texture->getMinFilter())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert(texture->getMagFilter())); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); } ~Texture() override { + if (_buffer != 0) { + glDeleteTextures(1, &_buffer); + } } void render(Scene::RenderContext &context) override { (void)context; } + GLuint getBuffer() const { + return _buffer; + } + private: std::weak_ptr _texture; std::weak_ptr _renderer; + + GLuint _buffer = 0; }; } // namespace Stone::Render::OpenGL From f65fd5bd5640af87649914564dbb2187a0434230 Mon Sep 17 00:00:00 2001 From: Arthur Masson Date: Thu, 5 Sep 2024 17:50:14 +0200 Subject: [PATCH 14/89] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a78d4e6..e27b7f8 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ apt install vulkan-tools libvulkan-dev vulkan-validationlayers-dev apt install libglfw3-dev libglm-dev apt install libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev zlib1g-dev apt install libboost-all-dev +apt install glew-utils libglew-dev ``` ```bash From b0a9a87e670f3d7a2e022c6930ae45f7e6f01122 Mon Sep 17 00:00:00 2001 From: amasson Date: Sat, 5 Oct 2024 00:30:20 +0200 Subject: [PATCH 15/89] OpenGL texture channel --- Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp index f669b49..c8e17dc 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp @@ -54,7 +54,6 @@ class Texture : public Scene::IRendererObject { imageSource->loadData(); std::shared_ptr imageData = imageSource->getLoadedImage(); - int bpp = static_cast(imageData->getChannels()); GLuint format = convert(imageData->getChannels()); glGenTextures(1, &_buffer); if (_buffer == 0) { From ab3020a93fe14c19ff140c75c16bfe4446b393ca Mon Sep 17 00:00:00 2001 From: amasson Date: Sat, 5 Oct 2024 00:35:04 +0200 Subject: [PATCH 16/89] Scene fragment shader --- .../include/Scene/Renderable/IRenderable.hpp | 3 +- .../include/Scene/Renderable/Material.hpp | 24 +++------------- .../Scene/include/Scene/Renderable/Shader.hpp | 28 +++++++++++++------ .../include/Scene/Renderer/ISceneRenderer.hpp | 2 +- .../Scene/Renderer/RendererDefaults.hpp | 23 ++++++--------- .../Scene/Renderer/RendererObjectManager.hpp | 2 +- Engine/Scene/include/SceneTypes.hpp | 3 +- .../Scene/src/Scene/Renderable/Material.cpp | 13 ++------- Engine/Scene/src/Scene/Renderable/Shader.cpp | 28 ++++++++++++------- .../src/Scene/Renderer/RendererDefaults.cpp | 12 +++----- .../Scene/Renderer/RendererObjectManager.cpp | 18 +++++------- 11 files changed, 70 insertions(+), 86 deletions(-) diff --git a/Engine/Scene/include/Scene/Renderable/IRenderable.hpp b/Engine/Scene/include/Scene/Renderable/IRenderable.hpp index 46e42a2..f19f317 100644 --- a/Engine/Scene/include/Scene/Renderable/IRenderable.hpp +++ b/Engine/Scene/include/Scene/Renderable/IRenderable.hpp @@ -77,7 +77,8 @@ class IRenderable { */ template [[nodiscard]] std::shared_ptr getRendererObject() const { - return std::dynamic_pointer_cast(_rendererObject); + assert(std::dynamic_pointer_cast(_rendererObject) != nullptr); + return std::static_pointer_cast(_rendererObject); } protected: diff --git a/Engine/Scene/include/Scene/Renderable/Material.hpp b/Engine/Scene/include/Scene/Renderable/Material.hpp index d3b6b96..635a63c 100644 --- a/Engine/Scene/include/Scene/Renderable/Material.hpp +++ b/Engine/Scene/include/Scene/Renderable/Material.hpp @@ -12,7 +12,7 @@ namespace Stone::Scene { class Texture; -class Shader; +class FragmentShader; /** * @brief The Material class represents a material used for rendering objects in the scene. @@ -107,42 +107,26 @@ class Material : public Core::Object, public IRenderable { */ void forEachScalars(const std::function &)> &lambda); - /** - * @brief Set the vertex shader used by the Material. - * - * @param vertexShader The vertex shader to set. - */ - void setVertexShader(std::shared_ptr vertexShader); - - /** - * @brief Get the vertex shader used by the Material. - * - * @return The vertex shader as a shared pointer to Shader. - */ - [[nodiscard]] const std::shared_ptr &getVertexShader() const; - /** * @brief Set the fragment shader used by the Material. * * @param fragmentShader The fragment shader to set. */ - void setFragmentShader(std::shared_ptr fragmentShader); + void setFragmentShader(std::shared_ptr fragmentShader); /** * @brief Get the fragment shader used by the Material. * * @return The fragment shader as a shared pointer to Shader. */ - [[nodiscard]] const std::shared_ptr &getFragmentShader() const; + [[nodiscard]] const std::shared_ptr &getFragmentShader() const; protected: std::unordered_map> _textures; /**< Map of texture parameters. */ std::unordered_map _vectors; /**< Map of vector parameters. */ std::unordered_map _scalars; /**< Map of scalar parameters. */ - std::shared_ptr - _vertexShader; /**< The vertex shader used by the material. nullptr means using the standard shader. */ - std::shared_ptr + std::shared_ptr _fragmentShader; /**< The fragment shader used by the material. nullptr means using the standard shader. */ }; diff --git a/Engine/Scene/include/Scene/Renderable/Shader.hpp b/Engine/Scene/include/Scene/Renderable/Shader.hpp index 723b0f5..f5c1c41 100644 --- a/Engine/Scene/include/Scene/Renderable/Shader.hpp +++ b/Engine/Scene/include/Scene/Renderable/Shader.hpp @@ -12,8 +12,8 @@ namespace Stone::Scene { /** * @brief The Shader class represents a shader used in rendering. */ -class Shader : public Core::Object, public IRenderable { - STONE_OBJECT(Shader); +class AShader : public Core::Object, public IRenderable { + STONE_ABSTRACT_OBJECT(AShader); public: enum class ContentType { @@ -23,15 +23,15 @@ class Shader : public Core::Object, public IRenderable { CompiledFile, /** The content is a link to a file containing the compiled bytes. */ }; - Shader() = default; - explicit Shader(const std::string &content); - Shader(ContentType contentType, std::string content); - Shader(const Shader &other) = default; + AShader() = default; + explicit AShader(const std::string &content); + AShader(ContentType contentType, std::string content); + AShader(const AShader &other) = default; - ~Shader() override = default; + ~AShader() override = default; /** - * @brief Write the Shader object to an output stream. + * @brief Write the shader object to an output stream. * * @param stream The output stream to write to. * @param closing_bracer Flag indicating whether to write a closing brace after the object. @@ -96,4 +96,16 @@ class Shader : public Core::Object, public IRenderable { int _maxLocation = -1; /** The cached maximum value from the locations. */ }; +class FragmentShader : public AShader { + STONE_OBJECT(FragmentShader); + +public: + FragmentShader() = default; + explicit FragmentShader(const std::string &content); + FragmentShader(ContentType contentType, std::string content); + FragmentShader(const FragmentShader &other) = default; + + ~FragmentShader() override = default; +}; + } // namespace Stone::Scene diff --git a/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp index 988165e..489290b 100644 --- a/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp +++ b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp @@ -21,7 +21,7 @@ class ISceneRenderer { /** * @brief Get the renderer defaults. */ - [[nodiscard]] virtual const std::unique_ptr &getRendererDefaults() const = 0; + [[nodiscard]] virtual const class RendererDefaults &getRendererDefaults() const = 0; /** * @brief Request the renderer to render the world from the given world root node. diff --git a/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp b/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp index ef3bce8..35e6340 100644 --- a/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp +++ b/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp @@ -11,23 +11,18 @@ namespace Stone::Scene { */ class RendererDefaults { public: + RendererDefaults(); + RendererDefaults(const RendererDefaults &) = delete; - RendererDefaults(); - RendererDefaults(const RendererDefaults&) = delete; - - ~RendererDefaults() = default; + ~RendererDefaults() = default; - /** - * @brief Get the default material used when a mesh has no material set. - */ - const std::shared_ptr& getDefaultMaterial() const; - - void setDefaultMaterial(const std::shared_ptr &material); - -private: - - std::shared_ptr _defaultMaterial; + /** + * @brief Get the default material used when a mesh has no material set. + */ + const std::shared_ptr &getDefaultMaterial() const; +protected: + std::shared_ptr _defaultMaterial; }; } // namespace Stone::Scene diff --git a/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp b/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp index 0467c0f..01d1459 100644 --- a/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp +++ b/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp @@ -89,7 +89,7 @@ class RendererObjectManager { * @brief Updates the renderer data for a given shader. * @param shader The shader to be updated. */ - virtual void updateShader(const std::shared_ptr &shader); + virtual void updateFragmentShader(const std::shared_ptr &shader); protected: /** diff --git a/Engine/Scene/include/SceneTypes.hpp b/Engine/Scene/include/SceneTypes.hpp index ce1d867..c2cae1c 100644 --- a/Engine/Scene/include/SceneTypes.hpp +++ b/Engine/Scene/include/SceneTypes.hpp @@ -27,7 +27,8 @@ class WorldNode; /** Renderable */ class Texture; class Material; -class Shader; +class AShader; +class FragmentShader; class IMeshObject; class IMeshInterface; diff --git a/Engine/Scene/src/Scene/Renderable/Material.cpp b/Engine/Scene/src/Scene/Renderable/Material.cpp index d25e6fc..a628243 100644 --- a/Engine/Scene/src/Scene/Renderable/Material.cpp +++ b/Engine/Scene/src/Scene/Renderable/Material.cpp @@ -84,21 +84,12 @@ void Material::forEachScalars(const std::function vertexShader) { - _vertexShader = std::move(vertexShader); - markDirty(); -} - -const std::shared_ptr &Material::getVertexShader() const { - return _vertexShader; -} - -void Material::setFragmentShader(std::shared_ptr fragmentShader) { +void Material::setFragmentShader(std::shared_ptr fragmentShader) { _fragmentShader = std::move(fragmentShader); markDirty(); } -const std::shared_ptr &Material::getFragmentShader() const { +const std::shared_ptr &Material::getFragmentShader() const { return _fragmentShader; } diff --git a/Engine/Scene/src/Scene/Renderable/Shader.cpp b/Engine/Scene/src/Scene/Renderable/Shader.cpp index 12f2a38..7d9c2c8 100644 --- a/Engine/Scene/src/Scene/Renderable/Shader.cpp +++ b/Engine/Scene/src/Scene/Renderable/Shader.cpp @@ -8,7 +8,7 @@ namespace Stone::Scene { -Shader::Shader(const std::string &content) +AShader::AShader(const std::string &content) : Object(), IRenderable(), _contentType(ContentType::SourceFile), _content(content) { if (string_ends_with(content, ".glsl")) { _contentType = ContentType::SourceFile; @@ -21,11 +21,11 @@ Shader::Shader(const std::string &content) } } -Shader::Shader(ContentType contentType, std::string content) +AShader::AShader(ContentType contentType, std::string content) : Object(), IRenderable(), _contentType(contentType), _content(std::move(content)) { } -std::ostream &Shader::writeToStream(std::ostream &stream, bool closing_bracer) const { +std::ostream &AShader::writeToStream(std::ostream &stream, bool closing_bracer) const { Object::writeToStream(stream, false); stream << ",function:\"" << _function << '"'; switch (_contentType) { @@ -46,24 +46,24 @@ std::ostream &Shader::writeToStream(std::ostream &stream, bool closing_bracer) c return stream; } -std::pair Shader::getContent() const { +std::pair AShader::getContent() const { return {_contentType, _content}; } -const std::string &Shader::getFunction() const { +const std::string &AShader::getFunction() const { return _function; } -void Shader::setFunction(const std::string &function) { +void AShader::setFunction(const std::string &function) { _function = function; markDirty(); } -int Shader::getMaxLocation() const { +int AShader::getMaxLocation() const { return _maxLocation; } -int Shader::getLocation(const std::string &name) const { +int AShader::getLocation(const std::string &name) const { auto it = _locations.find(name); if (it == _locations.end()) { return -1; @@ -71,13 +71,13 @@ int Shader::getLocation(const std::string &name) const { return it->second; } -void Shader::setContent(ContentType contentType, std::string content) { +void AShader::setContent(ContentType contentType, std::string content) { _contentType = contentType; _content = std::move(content); markDirty(); } -void Shader::setLocation(const std::string &name, int location) { +void AShader::setLocation(const std::string &name, int location) { _locations[name] = location; if (location > _maxLocation) { _maxLocation = location; @@ -85,4 +85,12 @@ void Shader::setLocation(const std::string &name, int location) { markDirty(); } +FragmentShader::FragmentShader(const std::string &content) : AShader(content) { +} + +FragmentShader::FragmentShader(ContentType contentType, std::string content) + : AShader(contentType, std::move(content)) { +} + + } // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp b/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp index 24d4166..ec96fec 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp @@ -1,20 +1,16 @@ // Copyright 2024 Stone-Engine #include "Scene/Renderer/RendererDefaults.hpp" + #include "Scene/Renderable/Material.hpp" namespace Stone::Scene { -RendererDefaults::RendererDefaults() { - _defaultMaterial = std::make_shared(); -} - -const std::shared_ptr& RendererDefaults::getDefaultMaterial() const { - return _defaultMaterial; +RendererDefaults::RendererDefaults() : _defaultMaterial(nullptr) { } -void RendererDefaults::setDefaultMaterial(const std::shared_ptr &material) { - _defaultMaterial = material; +const std::shared_ptr &RendererDefaults::getDefaultMaterial() const { + return _defaultMaterial; } } // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp index 0cd8462..ef6ba1f 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp @@ -19,7 +19,7 @@ const std::unordered_map updateCastedFunctions = { CASTED_FUNCTION_MAP_ENTRY(SkinMeshNode), CASTED_FUNCTION_MAP_ENTRY(Material), CASTED_FUNCTION_MAP_ENTRY(DynamicMesh), CASTED_FUNCTION_MAP_ENTRY(StaticMesh), CASTED_FUNCTION_MAP_ENTRY(DynamicSkinMesh), CASTED_FUNCTION_MAP_ENTRY(StaticSkinMesh), - CASTED_FUNCTION_MAP_ENTRY(Texture), CASTED_FUNCTION_MAP_ENTRY(Shader), + CASTED_FUNCTION_MAP_ENTRY(Texture), CASTED_FUNCTION_MAP_ENTRY(FragmentShader), }; void RendererObjectManager::updateRenderable(const std::shared_ptr &renderable) { @@ -54,13 +54,9 @@ void RendererObjectManager::updateSkinMeshNode(const std::shared_ptr &material) { - auto vertexShader = material->getVertexShader(); - if (vertexShader && vertexShader->isDirty()) { - updateShader(vertexShader); - } auto fragmentShader = material->getFragmentShader(); if (fragmentShader && fragmentShader->isDirty()) { - updateShader(fragmentShader); + updateFragmentShader(fragmentShader); } material->forEachTextures([this](std::pair> &it) { if (it.second->isDirty()) @@ -70,25 +66,25 @@ void RendererObjectManager::updateMaterial(const std::shared_ptr &mate } void RendererObjectManager::updateDynamicMesh(const std::shared_ptr &mesh) { - if (mesh->getDefaultMaterial()) + if (mesh->getDefaultMaterial() && mesh->getDefaultMaterial()->isDirty()) updateMaterial(mesh->getDefaultMaterial()); mesh->markUndirty(); } void RendererObjectManager::updateStaticMesh(const std::shared_ptr &mesh) { - if (mesh->getDefaultMaterial()) + if (mesh->getDefaultMaterial() && mesh->getDefaultMaterial()->isDirty()) updateMaterial(mesh->getDefaultMaterial()); mesh->markUndirty(); } void RendererObjectManager::updateDynamicSkinMesh(const std::shared_ptr &skinmesh) { - if (skinmesh->getDefaultMaterial()) + if (skinmesh->getDefaultMaterial() && skinmesh->getDefaultMaterial()->isDirty()) updateMaterial(skinmesh->getDefaultMaterial()); skinmesh->markUndirty(); } void RendererObjectManager::updateStaticSkinMesh(const std::shared_ptr &skinmesh) { - if (skinmesh->getDefaultMaterial()) + if (skinmesh->getDefaultMaterial() && skinmesh->getDefaultMaterial()->isDirty()) updateMaterial(skinmesh->getDefaultMaterial()); skinmesh->markUndirty(); } @@ -97,7 +93,7 @@ void RendererObjectManager::updateTexture(const std::shared_ptr &textur texture->markUndirty(); } -void RendererObjectManager::updateShader(const std::shared_ptr &shader) { +void RendererObjectManager::updateFragmentShader(const std::shared_ptr &shader) { shader->markUndirty(); } From 97eabce27ed9b5f68285c72868be24123ce02418 Mon Sep 17 00:00:00 2001 From: amasson Date: Sat, 5 Oct 2024 17:33:24 +0200 Subject: [PATCH 17/89] Compile and link opengl shaders with default materials --- .../include/Render/OpenGL/OpenGLRenderer.hpp | 13 +- .../include/Render/Vulkan/VulkanRenderer.hpp | 2 +- .../src/Render/OpenGL/OpenGLRenderer.cpp | 31 ++-- .../OpenGL/Renderable/InstancedMeshNode.hpp | 5 +- .../src/Render/OpenGL/Renderable/Material.hpp | 92 +++++++++- .../src/Render/OpenGL/Renderable/Mesh.hpp | 13 +- .../src/Render/OpenGL/Renderable/MeshNode.hpp | 57 +++--- .../src/Render/OpenGL/Renderable/Shader.cpp | 166 ++++++++++++++++++ .../src/Render/OpenGL/Renderable/Shader.hpp | 70 +++++++- .../src/Render/OpenGL/Renderable/SkinMesh.hpp | 10 +- .../Render/OpenGL/Renderable/SkinMeshNode.hpp | 5 +- .../src/Render/OpenGL/Renderable/Texture.hpp | 14 +- .../src/Render/OpenGL/RendererDefaults.cpp | 18 ++ .../src/Render/OpenGL/RendererDefaults.hpp | 41 +++++ .../src/Render/OpenGL/RendererInternals.hpp | 24 --- .../Render/OpenGL/RendererObjectManager.cpp | 4 +- .../Render/OpenGL/RendererObjectManager.hpp | 2 +- .../src/Render/Vulkan/Device/VulkanDevice.cpp | 1 + .../Render/Vulkan/RendererObjectManager.cpp | 4 +- .../Render/Vulkan/RendererObjectManager.hpp | 2 +- .../Vulkan/VulkanRenderable/Material.cpp | 3 - .../Vulkan/VulkanRenderable/Material.hpp | 2 +- .../Render/Vulkan/VulkanRenderable/Mesh.cpp | 3 - .../Render/Vulkan/VulkanRenderable/Mesh.hpp | 2 +- .../Render/Vulkan/VulkanRenderable/Shader.cpp | 5 +- .../Render/Vulkan/VulkanRenderable/Shader.hpp | 6 +- .../Vulkan/VulkanRenderer_ISceneRenderer.cpp | 4 +- .../include/Scene/Renderer/ISceneRenderer.hpp | 4 +- .../Scene/Renderer/RendererDefaults.hpp | 6 +- .../src/Scene/Renderer/RendererDefaults.cpp | 6 +- Engine/Window/src/Window/GlfwWindow.cpp | 4 +- examples/scop/main.cpp | 12 +- 32 files changed, 486 insertions(+), 145 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/Shader.cpp create mode 100644 Engine/Render/src/Render/OpenGL/RendererDefaults.cpp create mode 100644 Engine/Render/src/Render/OpenGL/RendererDefaults.hpp delete mode 100644 Engine/Render/src/Render/OpenGL/RendererInternals.hpp diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index 70a7040..6eb36f9 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -11,6 +11,8 @@ class WorldNode; namespace Stone::Render::OpenGL { +class RendererDefaults; + class OpenGLRenderer : public Renderer { public: OpenGLRenderer() = delete; @@ -22,18 +24,17 @@ class OpenGLRenderer : public Renderer { /** Renderer */ void updateDataForWorld(const std::shared_ptr &world) override; - const std::unique_ptr &getRendererDefaults() const override; + const Scene::RendererDefaults &getRendererDefaults() const override; void renderWorld(const std::shared_ptr &world) override; void updateFrameSize(std::pair size) override; + void initialize(); + const RendererDefaults &getOpenGLRendererDefaults() const; + private: std::pair _frameSize; - - std::unique_ptr _internals; - friend class RendererInternals; - - std::unique_ptr _defaults; + std::unique_ptr _defaults; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp b/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp index 6902d13..0acccf9 100644 --- a/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp +++ b/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp @@ -28,7 +28,7 @@ class VulkanRenderer : public Renderer { /** Renderer */ void updateDataForWorld(const std::shared_ptr &world) override; - const std::unique_ptr &getRendererDefaults() const override; + const Scene::RendererDefaults &getRendererDefaults() const override; void renderWorld(const std::shared_ptr &world) override; void updateFrameSize(std::pair size) override; diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index 6374b9e..e82a91a 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -4,9 +4,9 @@ #include "Render/OpenGL/OpenGLRenderer.hpp" #include "RenderContext.hpp" +#include "RendererDefaults.hpp" #include "RendererObjectManager.hpp" #include "Scene/Node/WorldNode.hpp" -#include "RendererInternals.hpp" #include "Scene/Renderer/RendererDefaults.hpp" #include @@ -25,16 +25,8 @@ static void initializeOpenGL() { } } -OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) : Renderer(), _frameSize(settings.frame_size), - _internals(nullptr) { - - initializeOpenGL(); - - std::cout << "OpenGLRenderer created" << std::endl; - std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; - - _internals = std::make_unique(); - _defaults = std::make_unique(); +OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) + : Renderer(), _frameSize(settings.frame_size), _defaults(nullptr) { } OpenGLRenderer::~OpenGLRenderer() { @@ -42,7 +34,7 @@ OpenGLRenderer::~OpenGLRenderer() { } void OpenGLRenderer::updateDataForWorld(const std::shared_ptr &world) { - OpenGL::RendererObjectManager manager(std::dynamic_pointer_cast(shared_from_this())); + OpenGL::RendererObjectManager manager(std::static_pointer_cast(shared_from_this())); world->traverseTopDown([&manager](const std::shared_ptr &node) { auto renderElement = std::dynamic_pointer_cast(node); if (renderElement && renderElement->isDirty()) { @@ -51,8 +43,8 @@ void OpenGLRenderer::updateDataForWorld(const std::shared_ptr }); } -const std::unique_ptr &OpenGLRenderer::getRendererDefaults() const { - return _defaults; +const Scene::RendererDefaults &OpenGLRenderer::getRendererDefaults() const { + return *_defaults; } void OpenGLRenderer::renderWorld(const std::shared_ptr &world) { @@ -69,5 +61,16 @@ void OpenGLRenderer::updateFrameSize(std::pair size) { _frameSize = size; } +void OpenGLRenderer::initialize() { + initializeOpenGL(); + std::cout << "OpenGLRenderer created" << std::endl; + std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; + _defaults = std::make_unique(std::static_pointer_cast(shared_from_this())); +} + +const RendererDefaults &OpenGLRenderer::getOpenGLRendererDefaults() const { + return *_defaults; +} + } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp index 4334182..285e605 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp @@ -11,8 +11,7 @@ namespace Stone::Render::OpenGL { class InstancedMeshNode : public Scene::IRendererObject { public: - InstancedMeshNode(const std::shared_ptr &instancedMeshNode, - const std::shared_ptr &renderer) + InstancedMeshNode(Scene::InstancedMeshNode &instancedMeshNode, const std::shared_ptr &renderer) : _instancedMeshNode(instancedMeshNode), _renderer(renderer) { } @@ -24,7 +23,7 @@ class InstancedMeshNode : public Scene::IRendererObject { } private: - std::weak_ptr _instancedMeshNode; + Scene::InstancedMeshNode &_instancedMeshNode; std::weak_ptr _renderer; }; diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp index 19bbad9..dd134ba 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp @@ -2,29 +2,115 @@ #pragma once +#include "../RendererDefaults.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Material.hpp" #include +#include +#include namespace Stone::Render::OpenGL { class Material : public Scene::IRendererObject { public: - Material(const std::shared_ptr &material, const std::shared_ptr &renderer) + Material(Scene::Material &material, const std::shared_ptr &renderer) : _material(material), _renderer(renderer) { } ~Material() override { + if (_gl_meshProgram != 0) + glDeleteProgram(_gl_meshProgram); + if (_gl_skinMeshProgram != 0) + glDeleteProgram(_gl_skinMeshProgram); + if (_gl_instancedMeshProgram != 0) + glDeleteProgram(_gl_instancedMeshProgram); } void render(Scene::RenderContext &context) override { - (void)context; + auto getLoc = [this](const char *name) -> GLint { + GLint loc = glGetUniformLocation(_lastUsedProgram, name); + if (loc == -1) { + throw std::runtime_error("Failed to get location of uniform: " + std::string(name)); + } + return loc; + }; + + glUniformMatrix4fv(getLoc("u_mat_projection"), 1, GL_FALSE, glm::value_ptr(context.mvp.projMatrix)); + glUniformMatrix4fv(getLoc("u_mat_view"), 1, GL_FALSE, glm::value_ptr(context.mvp.viewMatrix)); + glUniformMatrix4fv(getLoc("u_mat_model"), 1, GL_FALSE, glm::value_ptr(context.mvp.modelMatrix)); + } + + void makeMeshProgram() { + if (_gl_meshProgram != 0) + return; + + if (_renderer.expired()) + return; + + auto renderer = _renderer.lock(); + + auto vertexShader = renderer->getOpenGLRendererDefaults().getMeshVertexShader(); + + assert(vertexShader != nullptr); + + // std::shared_ptr fragmentShader = + // _material.getFragmentShader() ? _material.getFragmentShader() : + // renderer->getOpenGLRendererDefaults().getFragmentShader(); + + // assert(fragmentShader != nullptr); + + auto glFragmentShader = renderer->getOpenGLRendererDefaults().getFragmentShader(); + // fragmentShader->getRendererObject(); + + _gl_meshProgram = glCreateProgram(); + glAttachShader(_gl_meshProgram, vertexShader->getGLShader()); + glAttachShader(_gl_meshProgram, glFragmentShader->getGLShader()); + glLinkProgram(_gl_meshProgram); + + GLint success; + glGetProgramiv(_gl_meshProgram, GL_LINK_STATUS, &success); + if (!success) { + GLchar infoLog[1024]; + glGetProgramInfoLog(_gl_meshProgram, 1024, nullptr, infoLog); + throw std::runtime_error("Failed to link program: " + std::string(infoLog)); + } + } + + void makeSkinMeshProgram() { + if (_gl_skinMeshProgram != 0) + return; + } + + void makeInstancedMeshProgram() { + if (_gl_instancedMeshProgram != 0) + return; + } + + void useMeshProgram() { + glUseProgram(_gl_meshProgram); + _lastUsedProgram = _gl_meshProgram; + } + + void useSkinMeshProgram() { + glUseProgram(_gl_skinMeshProgram); + _lastUsedProgram = _gl_skinMeshProgram; + } + + void useInstancedMeshProgram() { + glUseProgram(_gl_instancedMeshProgram); + _lastUsedProgram = _gl_instancedMeshProgram; } private: - std::weak_ptr _material; + Scene::Material &_material; std::weak_ptr _renderer; + + GLuint _gl_meshProgram = 0; + GLuint _gl_skinMeshProgram = 0; + GLuint _gl_instancedMeshProgram = 0; + + GLuint _lastUsedProgram = 0; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp index 17c2753..a6b0726 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp @@ -103,8 +103,9 @@ class RendererMesh : public Scene::IRendererObject { class DynamicMesh : public RendererMesh { public: - DynamicMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) - : RendererMesh(mesh, renderer), _mesh(mesh), _renderer(renderer) { + DynamicMesh(Scene::DynamicMesh &mesh, const std::shared_ptr &renderer) + : RendererMesh(std::static_pointer_cast(mesh.shared_from_this()), renderer), _mesh(mesh), + _renderer(renderer) { } ~DynamicMesh() override { @@ -115,14 +116,14 @@ class DynamicMesh : public RendererMesh { } private: - std::weak_ptr _mesh; + Scene::DynamicMesh &_mesh; std::weak_ptr _renderer; }; class StaticMesh : public RendererMesh { public: - StaticMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) - : RendererMesh(mesh->getSourceMesh(), renderer), _mesh(mesh), _renderer(renderer) { + StaticMesh(Scene::StaticMesh &mesh, const std::shared_ptr &renderer) + : RendererMesh(mesh.getSourceMesh(), renderer), _mesh(mesh), _renderer(renderer) { } ~StaticMesh() override { @@ -133,7 +134,7 @@ class StaticMesh : public RendererMesh { } private: - std::weak_ptr _mesh; + Scene::StaticMesh &_mesh; std::weak_ptr _renderer; }; diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp index d4a51bd..5a4e023 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp @@ -2,6 +2,7 @@ #pragma once +#include "Material.hpp" #include "Mesh.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Node/MeshNode.hpp" @@ -10,63 +11,59 @@ #include -template -const std::shared_ptr &first_non_null(const std::shared_ptr &ptr) { - return ptr; -} - -template -const std::shared_ptr &first_non_null(const std::shared_ptr &ptr, const Args &...args) { - if (ptr != nullptr) { - return ptr; - } - return first_non_null(args...); -} - namespace Stone::Render::OpenGL { class MeshNode : public Scene::IRendererObject { public: - MeshNode(const std::shared_ptr &meshNode, const std::shared_ptr &renderer) + MeshNode(Scene::MeshNode &meshNode, const std::shared_ptr &renderer) : _meshNode(meshNode), _renderer(renderer) { - } - ~MeshNode() override { + std::shared_ptr usedMaterial = + meshNode.getMaterial() ? meshNode.getMaterial() + : meshNode.getMesh() != nullptr && meshNode.getMesh()->getDefaultMaterial() != nullptr + ? meshNode.getMesh()->getDefaultMaterial() + : renderer->getRendererDefaults().getMaterial(); + + usedMaterial->getRendererObject()->makeMeshProgram(); } - void render(Scene::RenderContext &context) override { - (void)context; - assert(_meshNode.expired() == false); + ~MeshNode() override = default; - auto meshNode = _meshNode.lock(); - auto mesh = meshNode->getMesh(); - if (mesh == nullptr) { + void render(Scene::RenderContext &context) override { + auto mesh = _meshNode.getMesh(); + if (mesh == nullptr) return; - } auto rendererMesh = mesh->getRendererObject(); if (rendererMesh == nullptr) { return; } + const VRAMMesh &vramMesh = rendererMesh->getVRAMMesh(); - auto material = first_non_null(meshNode->getMaterial(), mesh->getDefaultMaterial(), _renderer.lock()->getRendererDefaults()->getDefaultMaterial()); + std::shared_ptr sceneMaterial = _meshNode.getMaterial() ? _meshNode.getMaterial() + : mesh->getDefaultMaterial() + ? mesh->getDefaultMaterial() + : context.renderer->getRendererDefaults().getMaterial(); - const VRAMMesh &vramMesh = rendererMesh->getVRAMMesh(); + assert(sceneMaterial != nullptr); + assert(sceneMaterial->isDirty() == false); + + std::shared_ptr material = sceneMaterial->getRendererObject(); - // TODO: Retrieve the corect shader program to use + material->useMeshProgram(); + material->render(context); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); - // TODO: Send uniforms from context to shader - - // Send material uniforms to program + glBindVertexArray(vramMesh.elementsBuffer); + glDrawElements(GL_TRIANGLES, vramMesh.numIndices, GL_UNSIGNED_INT, 0); } private: - std::weak_ptr _meshNode; + Scene::MeshNode &_meshNode; std::weak_ptr _renderer; }; diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Shader.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Shader.cpp new file mode 100644 index 0000000..c7e437c --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/Shader.cpp @@ -0,0 +1,166 @@ +// Copyright 2024 Stone-Engine + +#include "Shader.hpp" + +namespace Stone::Render::OpenGL { + +GLuint compileSource(const std::string &source, GLenum type) { + GLuint shaderId = glCreateShader(type); + if (shaderId == 0) { + throw std::runtime_error("Failed to create shader."); + } + + const char *source_c = source.c_str(); + glShaderSource(shaderId, 1, &source_c, nullptr); + glCompileShader(shaderId); + + GLint compiled = 0; + glGetShaderiv(shaderId, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint log_length = 0; + glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &log_length); + + std::vector log(log_length); + glGetShaderInfoLog(shaderId, log_length, &log_length, log.data()); + + glDeleteShader(shaderId); + + throw std::runtime_error("Failed to compile shader: " + std::string(log.data())); + } + + return shaderId; +} + +GLuint loadSpirv(const char *spirv_content, GLsizei spirv_length, GLenum type) { + (void)type; + + GLuint shaderId = glCreateShader(GL_VERTEX_SHADER); + if (shaderId == 0) { + throw std::runtime_error("Failed to create shader."); + } + + glShaderBinary(1, &shaderId, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, spirv_content, spirv_length); + glSpecializeShader(shaderId, "main", 0, nullptr, nullptr); + + int compiled = 0; + glGetShaderiv(shaderId, GL_COMPILE_STATUS, &compiled); + + if (!compiled) { + GLint log_length = 0; + glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &log_length); + + std::vector log(log_length); + glGetShaderInfoLog(shaderId, log_length, &log_length, log.data()); + + glDeleteShader(shaderId); + + throw std::runtime_error("Failed to compile shader: " + std::string(log.data())); + } + + return shaderId; +} + +const char *basicVertexShaderSource = R"shader( +#version 400 core + +layout (location = 0) in vec3 position; +layout (location = 1) in vec3 normal; +layout (location = 2) in vec3 tangent; +layout (location = 3) in vec3 bitangent; +layout (location = 4) in vec2 uv; + +uniform mat3 u_mat_normal; +uniform mat4 u_mat_projection; +uniform mat4 u_mat_view; +uniform mat4 u_mat_model; +uniform vec3 u_camera_position; + +out VS_OUT { + vec4 position; + vec3 wposition; + vec2 uv; + vec3 wnormal; + vec3 wtangent; + vec3 wbitangent; +} vs_out; + +void main() +{ + vs_out.wposition = vec3(u_mat_model * vec4(position, 1.0)); + gl_Position = u_mat_projection * u_mat_view * vec4(vs_out.wposition, 1.0); + vs_out.position = gl_Position; + vs_out.wnormal = u_mat_normal * normal; + vs_out.wtangent = u_mat_normal * tangent; + vs_out.wbitangent = u_mat_normal * bitangent; + vs_out.uv = uv; +}; + +)shader"; + +const char *basicSkinVertexShaderSource = R"shader( +#version 400 core + +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 normal; +layout(location = 2) in vec2 uv; +layout(location = 3) in ivec4 boneIDs; +layout(location = 4) in vec4 boneWeights; + +out vec3 fragNormal; +out vec2 fragUV; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +const int MAX_BONES = 100; +uniform mat4 bones[MAX_BONES]; + +void main() { + fragNormal = normal; + fragUV = uv; + + mat4 boneTransform = mat4(0.0); + for (int i = 0; i < 4; i++) { + boneTransform += boneWeights[i] * bones[boneIDs[i]]; + } + + gl_Position = projection * view * model * boneTransform * vec4(position, 1.0); +} + +)shader"; + +const char *basicFragmentShaderSource = R"shader( +#version 400 core + +out vec4 FragColor; + +void main() { + FragColor = vec4(1.0, 0.0, 0.0, 1.0); +} + +)shader"; + +std::shared_ptr VertexShader::makeStandardMeshShader(const std::shared_ptr &renderer) { + auto sourceShader = std::make_shared(basicVertexShaderSource); + auto glShader = std::make_shared(*sourceShader, renderer); + return glShader; +} + +std::shared_ptr +VertexShader::makeStandardSkinMeshShader(const std::shared_ptr &renderer) { + auto sourceShader = std::make_shared(basicSkinVertexShaderSource); + auto glShader = std::make_shared(*sourceShader, renderer); + return glShader; +} + +std::shared_ptr +FragmentShader::makeStandardMeshShader(const std::shared_ptr &renderer) { + auto sceneShader = + std::make_shared(Scene::AShader::ContentType::SourceCode, basicFragmentShaderSource); + auto glShader = std::make_shared(*sceneShader, renderer); + return glShader; +} + + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp index b32631b..6110781 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp @@ -4,27 +4,87 @@ #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Shader.hpp" +#include "Utils/FileSystem.hpp" #include namespace Stone::Render::OpenGL { -class Shader : public Scene::IRendererObject { +GLuint compileSource(const std::string &source, GLenum type); + +GLuint loadSpirv(const char *spirv_content, GLsizei spirv_length, GLenum type); + +class ShaderBase : public Scene::IRendererObject { public: - Shader(const std::shared_ptr &shader, const std::shared_ptr &renderer) + ShaderBase(Scene::AShader &shader, const std::shared_ptr &renderer, GLenum type) : _shader(shader), _renderer(renderer) { + + auto [contentType, content] = shader.getContent(); + + using ContentType = Scene::AShader::ContentType; + switch (contentType) { + case ContentType::SourceCode: _gl_shader = compileSource(content, type); break; + case ContentType::SourceFile: _gl_shader = compileSource(Utils::readTextFile(content), type); break; + case ContentType::CompiledCode: _gl_shader = loadSpirv(content.data(), content.size(), type); break; + case ContentType::CompiledFile: + auto fileContent = Utils::readBinaryFile(content); + _gl_shader = loadSpirv(fileContent.data(), fileContent.size(), type); + break; + } } - ~Shader() override { + ~ShaderBase() override { + if (_gl_shader != 0) + glDeleteShader(_gl_shader); } void render(Scene::RenderContext &context) override { (void)context; } -private: - std::weak_ptr _shader; + GLuint getGLShader() const { + return _gl_shader; + } + +protected: + Scene::AShader &_shader; std::weak_ptr _renderer; + + GLuint _gl_shader = 0; +}; + +class SourceVertexShader : public Scene::AShader { + STONE_OBJECT(SourceVertexShader); + +public: + SourceVertexShader(const std::string &source) : Scene::AShader(ContentType::SourceCode, source) { + } + + SourceVertexShader(const SourceVertexShader &other) = delete; + + ~SourceVertexShader() override = default; }; +class VertexShader : public ShaderBase { +public: + VertexShader(Scene::AShader &shader, const std::shared_ptr &renderer) + : ShaderBase(shader, renderer, GL_VERTEX_SHADER) { + } + + static std::shared_ptr makeStandardMeshShader(const std::shared_ptr &renderer); + static std::shared_ptr makeStandardSkinMeshShader(const std::shared_ptr &renderer); +}; + +class FragmentShader : public ShaderBase { +public: + FragmentShader(Scene::AShader &shader, const std::shared_ptr &renderer) + : ShaderBase(shader, renderer, GL_FRAGMENT_SHADER) { + } + + static std::shared_ptr makeStandardMeshShader(const std::shared_ptr &renderer); + +protected: +}; + + } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp index ac942f9..45856ac 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp @@ -11,8 +11,7 @@ namespace Stone::Render::OpenGL { class DynamicSkinMesh : public Scene::IRendererObject { public: - DynamicSkinMesh(const std::shared_ptr &skinMesh, - const std::shared_ptr &renderer) + DynamicSkinMesh(Scene::DynamicSkinMesh &skinMesh, const std::shared_ptr &renderer) : _skinMesh(skinMesh), _renderer(renderer) { } @@ -24,14 +23,13 @@ class DynamicSkinMesh : public Scene::IRendererObject { } private: - std::weak_ptr _skinMesh; + Scene::DynamicSkinMesh &_skinMesh; std::weak_ptr _renderer; }; class StaticSkinMesh : public Scene::IRendererObject { public: - StaticSkinMesh(const std::shared_ptr &skinMesh, - const std::shared_ptr &renderer) + StaticSkinMesh(Scene::StaticSkinMesh &skinMesh, const std::shared_ptr &renderer) : _skinMesh(skinMesh), _renderer(renderer) { } @@ -43,7 +41,7 @@ class StaticSkinMesh : public Scene::IRendererObject { } private: - std::weak_ptr _skinMesh; + Scene::StaticSkinMesh &_skinMesh; std::weak_ptr _renderer; }; diff --git a/Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp index a12a65c..ea89dbd 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp @@ -11,8 +11,7 @@ namespace Stone::Render::OpenGL { class SkinMeshNode : public Scene::IRendererObject { public: - SkinMeshNode(const std::shared_ptr &skinMeshNode, - const std::shared_ptr &renderer) + SkinMeshNode(Scene::SkinMeshNode &skinMeshNode, const std::shared_ptr &renderer) : _skinMeshNode(skinMeshNode), _renderer(renderer) { } @@ -24,7 +23,7 @@ class SkinMeshNode : public Scene::IRendererObject { } private: - std::weak_ptr _skinMeshNode; + Scene::SkinMeshNode &_skinMeshNode; std::weak_ptr _renderer; }; diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp index c8e17dc..b57e1e9 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp @@ -43,10 +43,10 @@ GLuint convert(Scene::TextureWrap wrap) { class Texture : public Scene::IRendererObject { public: - Texture(const std::shared_ptr &texture, const std::shared_ptr &renderer) + Texture(Scene::Texture &texture, const std::shared_ptr &renderer) : _texture(texture), _renderer(renderer) { - std::shared_ptr imageSource = texture->getImage(); + std::shared_ptr imageSource = texture.getImage(); if (imageSource == nullptr) { return; } @@ -63,10 +63,10 @@ class Texture : public Scene::IRendererObject { glTexImage2D(GL_TEXTURE_2D, 0, format, imageData->getSize().x, imageData->getSize().y, 0, format, GL_UNSIGNED_BYTE, imageData->getData()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, convert(texture->getWrap())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, convert(texture->getWrap())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert(texture->getMinFilter())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert(texture->getMagFilter())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, convert(texture.getWrap())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, convert(texture.getWrap())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert(texture.getMinFilter())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert(texture.getMagFilter())); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); } @@ -86,7 +86,7 @@ class Texture : public Scene::IRendererObject { } private: - std::weak_ptr _texture; + Scene::Texture &_texture; std::weak_ptr _renderer; GLuint _buffer = 0; diff --git a/Engine/Render/src/Render/OpenGL/RendererDefaults.cpp b/Engine/Render/src/Render/OpenGL/RendererDefaults.cpp new file mode 100644 index 0000000..b874a75 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/RendererDefaults.cpp @@ -0,0 +1,18 @@ +// Copyright 2024 StoneEngine + +#include "RendererDefaults.hpp" + +#include "Scene/Renderable/Material.hpp" + +namespace Stone::Render::OpenGL { + +RendererDefaults::RendererDefaults(const std::shared_ptr &renderer) : Scene::RendererDefaults() { + _material = std::make_shared(); + + _meshFragmentShader = FragmentShader::makeStandardMeshShader(renderer); + _meshVertexShader = VertexShader::makeStandardMeshShader(renderer); + _skinMeshVertexShader = VertexShader::makeStandardSkinMeshShader(renderer); + // _instancedMeshVertexShader = VertexShader::makeStandardInstancedMeshShader(renderer); +} + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/RendererDefaults.hpp b/Engine/Render/src/Render/OpenGL/RendererDefaults.hpp new file mode 100644 index 0000000..c91dbd0 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/RendererDefaults.hpp @@ -0,0 +1,41 @@ +// Copyright 2024 StoneEngine + +#pragma once + +#include "Renderable/Shader.hpp" +#include "Scene/Renderer/RendererDefaults.hpp" + +namespace Stone::Render::OpenGL { + +class RendererDefaults : public Scene::RendererDefaults { +public: + explicit RendererDefaults(const std::shared_ptr &renderer); + RendererDefaults(const RendererDefaults &other) = delete; + + ~RendererDefaults() override = default; + + const std::shared_ptr &getFragmentShader() const { + return _meshFragmentShader; + } + + const std::shared_ptr &getMeshVertexShader() const { + return _meshVertexShader; + } + + const std::shared_ptr &getSkinMeshVertexShader() const { + return _skinMeshVertexShader; + } + + const std::shared_ptr &getInstancedMeshVertexShader() const { + return _instancedMeshVertexShader; + } + +protected: + std::shared_ptr _meshFragmentShader; + + std::shared_ptr _meshVertexShader; + std::shared_ptr _skinMeshVertexShader; + std::shared_ptr _instancedMeshVertexShader; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/RendererInternals.hpp b/Engine/Render/src/Render/OpenGL/RendererInternals.hpp deleted file mode 100644 index 9344631..0000000 --- a/Engine/Render/src/Render/OpenGL/RendererInternals.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2024 StoneEngine - -#pragma once - -#include "Scene/Renderer/RenderContext.hpp" - -#include "Renderable/Material.hpp" - -namespace Stone::Render::OpenGL { - -class RendererInternals { -public: - RendererInternals() = default; - RendererInternals(const RendererInternals &other) = delete; - - ~RendererInternals() = default; - - static RendererInternals& getFrom(OpenGLRenderer &renderer) { - return *(renderer._internals); - } - -}; - -} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp b/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp index baf04e3..35b9f51 100644 --- a/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp +++ b/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp @@ -16,7 +16,7 @@ void RendererObjectManager::update##RenderableClass(const std::shared_ptr &(object)) { \ Scene::RendererObjectManager::update##RenderableClass((object)); \ \ - auto new##RenderableClass = std::make_shared((object), _renderer); \ + auto new##RenderableClass = std::make_shared(*(object), _renderer); \ setRendererObjectTo((object).get(), new##RenderableClass); \ } @@ -46,6 +46,6 @@ UPDATE_RENDERER_OBJECT(StaticSkinMesh, staticSkinMesh) UPDATE_RENDERER_OBJECT(Texture, texture) -UPDATE_RENDERER_OBJECT(Shader, shader) +UPDATE_RENDERER_OBJECT(FragmentShader, shader) } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp b/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp index ff6d7fb..64fbb70 100644 --- a/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp +++ b/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp @@ -25,7 +25,7 @@ class RendererObjectManager : public Scene::RendererObjectManager { void updateDynamicSkinMesh(const std::shared_ptr &skinmesh) override; void updateStaticSkinMesh(const std::shared_ptr &skinmesh) override; void updateTexture(const std::shared_ptr &texture) override; - void updateShader(const std::shared_ptr &shader) override; + void updateFragmentShader(const std::shared_ptr &shader) override; private: diff --git a/Engine/Render/src/Render/Vulkan/Device/VulkanDevice.cpp b/Engine/Render/src/Render/Vulkan/Device/VulkanDevice.cpp index ed67e23..5e19d31 100644 --- a/Engine/Render/src/Render/Vulkan/Device/VulkanDevice.cpp +++ b/Engine/Render/src/Render/Vulkan/Device/VulkanDevice.cpp @@ -14,6 +14,7 @@ VulkanDevice::VulkanDevice(std::shared_ptr core) : _core(std::move(c } VulkanDevice::~VulkanDevice() { + _core.reset(); } void VulkanDevice::waitIdle() const { diff --git a/Engine/Render/src/Render/Vulkan/RendererObjectManager.cpp b/Engine/Render/src/Render/Vulkan/RendererObjectManager.cpp index 93c7cb5..38678d4 100644 --- a/Engine/Render/src/Render/Vulkan/RendererObjectManager.cpp +++ b/Engine/Render/src/Render/Vulkan/RendererObjectManager.cpp @@ -65,8 +65,8 @@ void RendererObjectManager::updateTexture(const std::shared_ptr setRendererObjectTo(texture.get(), newTexture); } -void RendererObjectManager::updateShader(const std::shared_ptr &shader) { - Scene::RendererObjectManager::updateShader(shader); +void RendererObjectManager::updateFragmentShader(const std::shared_ptr &shader) { + Scene::RendererObjectManager::updateFragmentShader(shader); if (shader->getRendererObject()) { return; diff --git a/Engine/Render/src/Render/Vulkan/RendererObjectManager.hpp b/Engine/Render/src/Render/Vulkan/RendererObjectManager.hpp index 6687e6e..7cfdf5a 100644 --- a/Engine/Render/src/Render/Vulkan/RendererObjectManager.hpp +++ b/Engine/Render/src/Render/Vulkan/RendererObjectManager.hpp @@ -32,7 +32,7 @@ class RendererObjectManager : public Scene::RendererObjectManager { void updateTexture(const std::shared_ptr &texture) override; - void updateShader(const std::shared_ptr &shader) override; + void updateFragmentShader(const std::shared_ptr &shader) override; private: std::shared_ptr _renderer; diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Material.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Material.cpp index 656a8ed..2dc58a8 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Material.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Material.cpp @@ -9,9 +9,6 @@ Material::Material(const std::shared_ptr &material, const std:: (void)renderer; } -Material::~Material() { -} - void Material::render(Scene::RenderContext &context) { (void)context; } diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Material.hpp b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Material.hpp index 78b4399..a579256 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Material.hpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Material.hpp @@ -23,7 +23,7 @@ class Material : public Scene::IRendererObject { public: Material(const std::shared_ptr &material, const std::shared_ptr &renderer); - ~Material() override; + ~Material() override = default; void render(Scene::RenderContext &context) override; }; diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Mesh.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Mesh.cpp index 19568b9..2ae7810 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Mesh.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Mesh.cpp @@ -9,9 +9,6 @@ Mesh::Mesh(const std::shared_ptr &mesh, const std::shared_pt (void)renderer; } -Mesh::~Mesh() { -} - void Mesh::render(Scene::RenderContext &context) { assert(dynamic_cast(&context)); auto vulkanContext = reinterpret_cast(&context); diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Mesh.hpp b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Mesh.hpp index b081a5a..faeabbb 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Mesh.hpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Mesh.hpp @@ -23,7 +23,7 @@ class Mesh : public Scene::IRendererObject { public: Mesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer); - ~Mesh() override; + ~Mesh() override = default; void render(Scene::RenderContext &context) override; }; diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Shader.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Shader.cpp index 0c1d8fb..f592382 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Shader.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Shader.cpp @@ -4,14 +4,11 @@ namespace Stone::Render::Vulkan { -Shader::Shader(const std::shared_ptr &shader, const std::shared_ptr &renderer) { +Shader::Shader(const std::shared_ptr &shader, const std::shared_ptr &renderer) { (void)shader; (void)renderer; } -Shader::~Shader() { -} - void Shader::render(Scene::RenderContext &context) { (void)context; } diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Shader.hpp b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Shader.hpp index 307e3ff..fe4541c 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderable/Shader.hpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderable/Shader.hpp @@ -7,7 +7,7 @@ #include namespace Stone::Scene { -class Shader; +class FragmentShader; } // namespace Stone::Scene namespace Stone::Render::Vulkan { @@ -16,8 +16,8 @@ class VulkanRenderer; class Shader : public Scene::IRendererObject { public: - Shader(const std::shared_ptr &shader, const std::shared_ptr &renderer); - ~Shader() override; + Shader(const std::shared_ptr &shader, const std::shared_ptr &renderer); + ~Shader() override = default; void render(Scene::RenderContext &context) override; }; diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp index e6c840c..41cb787 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp @@ -21,8 +21,8 @@ void VulkanRenderer::updateDataForWorld(const std::shared_ptr }); } -const std::unique_ptr &VulkanRenderer::getRendererDefaults() const { - return _rendererDefaults; +const Scene::RendererDefaults &VulkanRenderer::getRendererDefaults() const { + return *_rendererDefaults; } void VulkanRenderer::renderWorld(const std::shared_ptr &world) { diff --git a/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp index 489290b..b1dc093 100644 --- a/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp +++ b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp @@ -8,6 +8,8 @@ namespace Stone::Scene { +class RendererDefaults; + /** * @brief Interface for a scene renderer. */ @@ -21,7 +23,7 @@ class ISceneRenderer { /** * @brief Get the renderer defaults. */ - [[nodiscard]] virtual const class RendererDefaults &getRendererDefaults() const = 0; + [[nodiscard]] virtual const RendererDefaults &getRendererDefaults() const = 0; /** * @brief Request the renderer to render the world from the given world root node. diff --git a/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp b/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp index 35e6340..705ba88 100644 --- a/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp +++ b/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp @@ -14,15 +14,15 @@ class RendererDefaults { RendererDefaults(); RendererDefaults(const RendererDefaults &) = delete; - ~RendererDefaults() = default; + virtual ~RendererDefaults() = default; /** * @brief Get the default material used when a mesh has no material set. */ - const std::shared_ptr &getDefaultMaterial() const; + const std::shared_ptr &getMaterial() const; protected: - std::shared_ptr _defaultMaterial; + std::shared_ptr _material; }; } // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp b/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp index ec96fec..2212cfd 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp @@ -6,11 +6,11 @@ namespace Stone::Scene { -RendererDefaults::RendererDefaults() : _defaultMaterial(nullptr) { +RendererDefaults::RendererDefaults() : _material(nullptr) { } -const std::shared_ptr &RendererDefaults::getDefaultMaterial() const { - return _defaultMaterial; +const std::shared_ptr &RendererDefaults::getMaterial() const { + return _material; } } // namespace Stone::Scene diff --git a/Engine/Window/src/Window/GlfwWindow.cpp b/Engine/Window/src/Window/GlfwWindow.cpp index 2de3046..9635cd8 100644 --- a/Engine/Window/src/Window/GlfwWindow.cpp +++ b/Engine/Window/src/Window/GlfwWindow.cpp @@ -81,7 +81,9 @@ GlfwWindow::GlfwWindow(const std::shared_ptr &app, const WindowSettings &se static_cast(frameBufferWidth), static_cast(frameBufferHeight), }; - _renderer = std::make_shared(rendererSettings); + auto renderer = std::make_shared(rendererSettings); + renderer->initialize(); + _renderer = renderer; #endif } diff --git a/examples/scop/main.cpp b/examples/scop/main.cpp index c49b569..666f02f 100644 --- a/examples/scop/main.cpp +++ b/examples/scop/main.cpp @@ -85,9 +85,9 @@ int main(int argc, char **argv) { meshNode->setMaterial(stone_material); // Create a shader from a file - auto stone_shader = std::make_shared("shaders/frag.spv"); - stone_shader->setLocation("diffuse", 1); - stone_material->setFragmentShader(stone_shader); + // auto stone_shader = std::make_shared("shaders/frag.spv"); + // stone_shader->setLocation("diffuse", 1); + // stone_material->setFragmentShader(stone_shader); // Create a second MeshNode with the same mesh auto meshRotatingNode = window->getWorld()->addChild(); @@ -97,9 +97,9 @@ int main(int argc, char **argv) { secondMeshNode->setMesh(mesh); // Create a blue material that takes no texture as everything is in the shader code - auto blueShader = std::make_shared("shaders/frag-blue.glsl"); - auto blueMaterial = std::make_shared(); - blueMaterial->setFragmentShader(blueShader); + // auto blueShader = std::make_shared("shaders/frag-blue.glsl"); + // auto blueMaterial = std::make_shared(); + // blueMaterial->setFragmentShader(blueShader); secondMeshNode->setMaterial(stone_material /* blueMaterial */); // Create a camera moving around the scene From a80422a45eebd3ab9f8a4b10a934cb5dc72eb7d7 Mon Sep 17 00:00:00 2001 From: amasson Date: Sat, 5 Oct 2024 17:44:52 +0200 Subject: [PATCH 18/89] fix format --- Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp index 25bb7b4..2c40045 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp @@ -1,11 +1,11 @@ // Copyright 2024 Stone-Engine #include "Render/Vulkan/VulkanRenderer.hpp" -#include "Scene/Renderer/RendererDefaults.hpp" #include "Device.hpp" #include "FramesRenderer.hpp" #include "RenderPass.hpp" +#include "Scene/Renderer/RendererDefaults.hpp" #include "SwapChain.hpp" namespace Stone::Render::Vulkan { From d697bf008ca7862854ea7b188ddb4d500b8845e5 Mon Sep 17 00:00:00 2001 From: amasson Date: Fri, 18 Oct 2024 07:56:23 +0200 Subject: [PATCH 19/89] MacOS compilation --- CMakeLists.txt | 6 +++++- Engine/Scene/src/Scene/Geometry.cpp | 4 ++-- README.md | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 20c3ea6..7afaddf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,11 @@ if (FULL_CONFIGURE) message(STATUS "Setup gfx_api to use OPENGL rendering API") find_package(OpenGL REQUIRED) find_package(GLEW REQUIRED) - target_link_libraries(gfx_api INTERFACE OpenGL GLEW) + if (APPLE) + target_link_libraries(gfx_api INTERFACE "-framework OpenGL" GLEW::GLEW) + else () + target_link_libraries(gfx_api INTERFACE OpenGL::GL GLEW::GLEW) + endif () target_include_directories(gfx_api INTERFACE ${GLEW_INCLUDE_DIRS}) else () message(FATAL_ERROR "Unexpected value for GRAPHICS_API, unknown API ${GRAPHICS_API}") diff --git a/Engine/Scene/src/Scene/Geometry.cpp b/Engine/Scene/src/Scene/Geometry.cpp index 32a1318..41d750e 100644 --- a/Engine/Scene/src/Scene/Geometry.cpp +++ b/Engine/Scene/src/Scene/Geometry.cpp @@ -19,8 +19,8 @@ std::pair, std::vector> generateGeometryMesh(co std::vector indices; std::vector vertices; - const float phiStep = M_PIf32 / (float)rings; - const float thetaStep = 2 * M_PIf32 / (float)rings; + const float phiStep = M_PI / (float)rings; + const float thetaStep = 2 * M_PI / (float)rings; for (int i = 0; i <= rings; i++) { const float phi = (float)i * phiStep; diff --git a/README.md b/README.md index e27b7f8..cd91dbe 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ A 42 student's game engine using Vulkan & C++ ! ## Build and install ```bash +# Linux debian based apt install build-essential cmake ninja-build apt install vulkan-tools libvulkan-dev vulkan-validationlayers-dev apt install libglfw3-dev libglm-dev @@ -13,6 +14,22 @@ apt install libboost-all-dev apt install glew-utils libglew-dev ``` +```bash +# Mac OS +brew install cmake +ninja +glew +assimp +glm +glfw +boost +vulkan-extensionlayer +mesa + +clang-format +brew install glslang +``` + ```bash make ``` From 31c5f44de604f8a1e26034d7c66bea32d716e125 Mon Sep 17 00:00:00 2001 From: amasson Date: Fri, 18 Oct 2024 19:36:56 +0200 Subject: [PATCH 20/89] Separate render api requirements --- Engine/Render/CMakeLists.txt | 18 ++++++++++--- .../test/OpenGL/test_OpenGLRenderer.cpp | 25 +++++++++++++++++++ .../test/{ => Vulkan}/test_VulkanRenderer.cpp | 2 ++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp rename Engine/Render/test/{ => Vulkan}/test_VulkanRenderer.cpp (99%) diff --git a/Engine/Render/CMakeLists.txt b/Engine/Render/CMakeLists.txt index b7ce0a4..d90e96e 100644 --- a/Engine/Render/CMakeLists.txt +++ b/Engine/Render/CMakeLists.txt @@ -1,9 +1,21 @@ -setup_module( + +if (GRAPHICS_API STREQUAL "VULKAN") + setup_module( NAME render TARGET_DEPS logging widgets utils gfx_api VARIABLE_DEPS Vulkan_LIBRARIES Vulkan_INCLUDE_DIRS SPECIAL_HEADER_PATHS ${Vulkan_INCLUDE_DIRS} SPECIAL_LIBS ${Vulkan_LIBRARIES} - ENABLE_TESTS FATAL_ERROR -) + ) +elseif (GRAPHICS_API STREQUAL "OPENGL") + setup_module( + NAME render + TARGET_DEPS logging widgets utils gfx_api + VARIABLE_DEPS OpenGL::GL GLEW::GLEW + SPECIAL_LIBS OpenGL::GL GLEW::GLEW + FATAL_ERROR + ) +else () + message(FATAL_ERROR "Unexpected value for GRAPHICS_API, unknown API ${GRAPHICS_API}") +endif() diff --git a/Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp b/Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp new file mode 100644 index 0000000..39b955a --- /dev/null +++ b/Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp @@ -0,0 +1,25 @@ +/* +#include "Render/OpenGL/RendererSettings.hpp" +#include "Render/OpenGL/OpenGLRenderer.hpp" + +#include + +using namespace Stone::Render::OpenGL; +using namespace Stone::Scene; + +TEST(OpenGLRender, InstanciateCore) { + RendererSettings settings; + + try { + OpenGLRenderer renderer(settings); + } catch (const std::runtime_error &e) { + if (std::string(e.what()) == "Failed to create window surface !") { + SUCCEED(); + } else { + FAIL() << e.what(); + } + } catch (const std::exception &e) { + FAIL() << e.what(); + } +} +*/ \ No newline at end of file diff --git a/Engine/Render/test/test_VulkanRenderer.cpp b/Engine/Render/test/Vulkan/test_VulkanRenderer.cpp similarity index 99% rename from Engine/Render/test/test_VulkanRenderer.cpp rename to Engine/Render/test/Vulkan/test_VulkanRenderer.cpp index 5fa067f..9b0ca5e 100644 --- a/Engine/Render/test/test_VulkanRenderer.cpp +++ b/Engine/Render/test/Vulkan/test_VulkanRenderer.cpp @@ -1,3 +1,4 @@ +/* #include "Render/Vulkan/RendererSettings.hpp" #include "Render/Vulkan/VulkanRenderer.hpp" @@ -21,3 +22,4 @@ TEST(VulkanRender, InstanciateCore) { FAIL() << e.what(); } } +*/ \ No newline at end of file From ad455f3d9ca0bf9b8e6e9325e39ae883f4755fbf Mon Sep 17 00:00:00 2001 From: amasson Date: Fri, 18 Oct 2024 20:09:07 +0200 Subject: [PATCH 21/89] add shaderc on MacOS readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cd91dbe..3dbdbf4 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ glfw boost vulkan-extensionlayer mesa +shaderc clang-format brew install glslang From 78598b0810e0c30dd2f52acec6d4d37c66512aba Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 20 Oct 2024 13:02:59 +0200 Subject: [PATCH 22/89] fix format --- Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp | 2 +- Engine/Render/test/Vulkan/test_VulkanRenderer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp b/Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp index 39b955a..c31452f 100644 --- a/Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp +++ b/Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp @@ -22,4 +22,4 @@ TEST(OpenGLRender, InstanciateCore) { FAIL() << e.what(); } } -*/ \ No newline at end of file +*/ diff --git a/Engine/Render/test/Vulkan/test_VulkanRenderer.cpp b/Engine/Render/test/Vulkan/test_VulkanRenderer.cpp index 9b0ca5e..0df9598 100644 --- a/Engine/Render/test/Vulkan/test_VulkanRenderer.cpp +++ b/Engine/Render/test/Vulkan/test_VulkanRenderer.cpp @@ -22,4 +22,4 @@ TEST(VulkanRender, InstanciateCore) { FAIL() << e.what(); } } -*/ \ No newline at end of file +*/ From cc7e9c8f44a9e4c282e85cf4c8eba229f37d2b2a Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 20 Oct 2024 13:08:12 +0200 Subject: [PATCH 23/89] fix format --- Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp b/Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp index c31452f..7fd296d 100644 --- a/Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp +++ b/Engine/Render/test/OpenGL/test_OpenGLRenderer.cpp @@ -1,6 +1,6 @@ /* -#include "Render/OpenGL/RendererSettings.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Render/OpenGL/RendererSettings.hpp" #include From 1ab3f84d91ed5ae1a490d27b8ef5aca3c9648e96 Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 20 Oct 2024 13:14:35 +0200 Subject: [PATCH 24/89] Use linear mipmap texture filter #52 --- .../src/Render/OpenGL/Renderable/Texture.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp index b57e1e9..d218e60 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp @@ -21,12 +21,12 @@ GLuint convert(Core::Image::Channel channel) { } } -GLuint convert(Scene::TextureFilter filter) { +GLuint convert(Scene::TextureFilter filter, bool mipmap) { switch (filter) { - case Scene::TextureFilter::Nearest: return GL_NEAREST; - case Scene::TextureFilter::Linear: return GL_LINEAR; - case Scene::TextureFilter::Cubic: return GL_LINEAR; - default: return GL_LINEAR; + case Scene::TextureFilter::Nearest: return mipmap ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; + case Scene::TextureFilter::Linear: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; + case Scene::TextureFilter::Cubic: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; + default: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; } } @@ -65,8 +65,8 @@ class Texture : public Scene::IRendererObject { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, convert(texture.getWrap())); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, convert(texture.getWrap())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert(texture.getMinFilter())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert(texture.getMagFilter())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert(texture.getMinFilter(), true)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert(texture.getMagFilter(), false)); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); } From 4c287cd2beac988faef3cb8b67fd0dffe435c8ff Mon Sep 17 00:00:00 2001 From: amasson Date: Mon, 21 Oct 2024 08:01:48 +0200 Subject: [PATCH 25/89] Add wireframeshape to renderer object manager --- Engine/Scene/include/Scene.hpp | 1 + .../Scene/include/Scene/Renderer/RendererObjectManager.hpp | 6 ++++++ Engine/Scene/include/SceneTypes.hpp | 1 + Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp | 7 ++++++- 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Engine/Scene/include/Scene.hpp b/Engine/Scene/include/Scene.hpp index 417432a..40dc375 100644 --- a/Engine/Scene/include/Scene.hpp +++ b/Engine/Scene/include/Scene.hpp @@ -10,6 +10,7 @@ #include "Scene/Node/PivotNode.hpp" #include "Scene/Node/SkeletonNode.hpp" #include "Scene/Node/SkinMeshNode.hpp" +#include "Scene/Node/WireframeShape.hpp" #include "Scene/Node/WorldNode.hpp" #include "Scene/Renderable/Material.hpp" #include "Scene/Renderable/Mesh.hpp" diff --git a/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp b/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp index 01d1459..b32622c 100644 --- a/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp +++ b/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp @@ -79,6 +79,12 @@ class RendererObjectManager { */ virtual void updateStaticSkinMesh(const std::shared_ptr &skinmesh); + /** + * @brief Updates the renderer data for a given wireframe shape. + * @param wireframe shape The wireframe shape to be updated. + */ + virtual void updateWireframeShape(const std::shared_ptr &shape); + /** * @brief Updates the renderer data for a given texture. * @param texture The texture to be updated. diff --git a/Engine/Scene/include/SceneTypes.hpp b/Engine/Scene/include/SceneTypes.hpp index c2cae1c..e0a5e18 100644 --- a/Engine/Scene/include/SceneTypes.hpp +++ b/Engine/Scene/include/SceneTypes.hpp @@ -38,5 +38,6 @@ class Skeleton; class ISkinMeshInterface; class DynamicSkinMesh; class StaticSkinMesh; +class WireframeShape; } // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp index ef6ba1f..01f5f67 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp @@ -19,7 +19,8 @@ const std::unordered_map updateCastedFunctions = { CASTED_FUNCTION_MAP_ENTRY(SkinMeshNode), CASTED_FUNCTION_MAP_ENTRY(Material), CASTED_FUNCTION_MAP_ENTRY(DynamicMesh), CASTED_FUNCTION_MAP_ENTRY(StaticMesh), CASTED_FUNCTION_MAP_ENTRY(DynamicSkinMesh), CASTED_FUNCTION_MAP_ENTRY(StaticSkinMesh), - CASTED_FUNCTION_MAP_ENTRY(Texture), CASTED_FUNCTION_MAP_ENTRY(FragmentShader), + CASTED_FUNCTION_MAP_ENTRY(WireframeShape), CASTED_FUNCTION_MAP_ENTRY(Texture), + CASTED_FUNCTION_MAP_ENTRY(FragmentShader), }; void RendererObjectManager::updateRenderable(const std::shared_ptr &renderable) { @@ -89,6 +90,10 @@ void RendererObjectManager::updateStaticSkinMesh(const std::shared_ptrmarkUndirty(); } +void RendererObjectManager::updateWireframeShape(const std::shared_ptr &shape) { + shape->markUndirty(); +} + void RendererObjectManager::updateTexture(const std::shared_ptr &texture) { texture->markUndirty(); } From 4fb3e23b0867b9ca538121dbafb877b4b6bb845a Mon Sep 17 00:00:00 2001 From: amasson Date: Mon, 21 Oct 2024 08:02:31 +0200 Subject: [PATCH 26/89] Base Node definition not using macro --- Engine/Scene/include/Scene/Node/Node.hpp | 5 ++++- Engine/Scene/include/Scene/Node/NodeMacros.hpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Engine/Scene/include/Scene/Node/Node.hpp b/Engine/Scene/include/Scene/Node/Node.hpp index 4937d53..d260939 100644 --- a/Engine/Scene/include/Scene/Node/Node.hpp +++ b/Engine/Scene/include/Scene/Node/Node.hpp @@ -22,7 +22,7 @@ class WorldNode; * the node hierarchy, updating and rendering nodes, and accessing node properties. */ class Node : public Core::Object { - STONE_NODE(Node); + STONE_OBJECT(Node); public: explicit Node(const std::string &name = "node"); @@ -39,6 +39,9 @@ class Node : public Core::Object { */ std::ostream &writeToStream(std::ostream &stream, bool closing_bracer) const override; + const static std::string nodeClassName; + virtual const char *getNodeClassName() const; + /** * @brief Updates the node. * diff --git a/Engine/Scene/include/Scene/Node/NodeMacros.hpp b/Engine/Scene/include/Scene/Node/NodeMacros.hpp index 16f002e..d64b7f0 100644 --- a/Engine/Scene/include/Scene/Node/NodeMacros.hpp +++ b/Engine/Scene/include/Scene/Node/NodeMacros.hpp @@ -8,7 +8,7 @@ \ public: \ static const std::string nodeClassName; \ - virtual const char *getNodeClassName() const; + const char *getNodeClassName() const override; /** * @brief Macro to use inside an abstract node class to make the engine reconize this class as a node. From 24daacc19ffe64fad0398f82bc1dd023cb6371bc Mon Sep 17 00:00:00 2001 From: amasson Date: Fri, 1 Nov 2024 08:56:19 +0100 Subject: [PATCH 27/89] Using int as possible material location --- .../Vulkan/VulkanRenderable/MeshNode.cpp | 33 ++++++++++++--- .../include/Scene/Renderable/Material.hpp | 30 ++++++++------ .../Scene/src/Scene/Renderable/Material.cpp | 41 ++++++++++--------- .../Scene/Renderer/RendererObjectManager.cpp | 2 +- 4 files changed, 68 insertions(+), 38 deletions(-) diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp index 710b86f..bc16555 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp @@ -81,12 +81,23 @@ void MeshNode::_createDescriptorSetLayout() { auto material = _sceneMeshNode.lock()->getMaterial(); if (material) { - auto shader = material->getFragmentShader(); + auto shader = material->getFragmentShader(); // TODO: Take default fragment shader if none is found if (shader) { material->forEachTextures( - [&](const std::pair> &texture) { + [&](const std::pair> &texture) { VkDescriptorSetLayoutBinding samplerLayoutBinding; - samplerLayoutBinding.binding = shader->getLocation(texture.first); + + // TODO: Factor this code in scene function + int location = -1; + if (std::holds_alternative(texture.first)) { + location = std::get(texture.first); + } else if (std::holds_alternative(texture.first)) { + location = shader->getLocation(std::get(texture.first)); + } + if (location == -1) { + return; + } + samplerLayoutBinding.binding = location; samplerLayoutBinding.descriptorCount = 1; samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; @@ -387,7 +398,7 @@ void MeshNode::_createDescriptorPool(const std::shared_ptr &swapChain auto shader = material->getFragmentShader(); if (shader) { material->forEachTextures( - [&](const std::pair> &texture) { + [&](const std::pair> &texture) { (void)texture; VkDescriptorPoolSize poolSize = {}; poolSize.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; @@ -450,7 +461,17 @@ void MeshNode::_createDescriptorSets(const std::shared_ptr &swapChain auto shader = material->getFragmentShader(); if (shader) { material->forEachTextures( - [&](const std::pair> &texture) { + [&](const std::pair> &texture) { + int location = -1; + if (std::holds_alternative(texture.first)) { + location = std::get(texture.first); + } else if (std::holds_alternative(texture.first)) { + location = shader->getLocation(std::get(texture.first)); + } + if (location == -1) { + return; + } + auto textureObject = texture.second->getRendererObject(); imagesInfo.push_back({}); @@ -462,7 +483,7 @@ void MeshNode::_createDescriptorSets(const std::shared_ptr &swapChain VkWriteDescriptorSet descriptorWrite = {}; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptorWrite.dstSet = _descriptorSets[i]; - descriptorWrite.dstBinding = shader->getLocation(texture.first); + descriptorWrite.dstBinding = location; descriptorWrite.dstArrayElement = 0; descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; descriptorWrite.descriptorCount = 1; diff --git a/Engine/Scene/include/Scene/Renderable/Material.hpp b/Engine/Scene/include/Scene/Renderable/Material.hpp index 635a63c..0968dd5 100644 --- a/Engine/Scene/include/Scene/Renderable/Material.hpp +++ b/Engine/Scene/include/Scene/Renderable/Material.hpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace Stone::Scene { @@ -24,6 +25,8 @@ class Material : public Core::Object, public IRenderable { STONE_OBJECT(Material) public: + using Location = std::variant; + Material() = default; Material(const Material &other) = default; @@ -44,7 +47,7 @@ class Material : public Core::Object, public IRenderable { * @param name The name of the texture parameter. * @param texture The texture to set. */ - void setTextureParameter(const std::string &name, std::shared_ptr texture); + void setTextureParameter(const Location &name, std::shared_ptr texture); /** * @brief Get a texture parameter from the Material. @@ -52,7 +55,7 @@ class Material : public Core::Object, public IRenderable { * @param name The name of the texture parameter. * @return The texture parameter as a shared pointer to Texture. */ - [[nodiscard]] std::shared_ptr getTextureParameter(const std::string &name) const; + [[nodiscard]] std::shared_ptr getTextureParameter(const Location &location) const; /** * @brief Set a vector parameter for the Material. @@ -60,7 +63,7 @@ class Material : public Core::Object, public IRenderable { * @param name The name of the vector parameter. * @param vector The vector to set. */ - void setVectorParameter(const std::string &name, const glm::vec3 &vector); + void setVectorParameter(const Location &name, const glm::vec3 &vector); /** * @brief Get a vector parameter from the Material. @@ -68,7 +71,7 @@ class Material : public Core::Object, public IRenderable { * @param name The name of the vector parameter. * @return The vector parameter as a glm::vec3. */ - [[nodiscard]] glm::vec3 getVectorParameter(const std::string &name) const; + [[nodiscard]] glm::vec3 getVectorParameter(const Location &name) const; /** * @brief Set a scalar parameter for the Material. @@ -76,7 +79,7 @@ class Material : public Core::Object, public IRenderable { * @param name The name of the scalar parameter. * @param scalar The scalar value to set. */ - void setScalarParameter(const std::string &name, float scalar); + void setScalarParameter(const Location &name, float scalar); /** * @brief Get a scalar parameter from the Material. @@ -84,28 +87,29 @@ class Material : public Core::Object, public IRenderable { * @param name The name of the scalar parameter. * @return The scalar parameter as a float. */ - [[nodiscard]] float getScalarParameter(const std::string &name) const; + [[nodiscard]] float getScalarParameter(const Location &name) const; /** * @brief Iterate over all texture parameters in the Material. * * @param lambda The lambda function to call for each texture parameter. */ - void forEachTextures(const std::function> &)> &lambda); + void + forEachTextures(const std::function> &)> &lambda); /** * @brief Iterate over all vector parameters in the Material. * * @param lambda The lambda function to call for each vector parameter. */ - void forEachVectors(const std::function &)> &lambda); + void forEachVectors(const std::function &)> &lambda); /** * @brief Iterate over all scalar parameters in the Material. * * @param lambda The lambda function to call for each scalar parameter. */ - void forEachScalars(const std::function &)> &lambda); + void forEachScalars(const std::function &)> &lambda); /** * @brief Set the fragment shader used by the Material. @@ -122,12 +126,14 @@ class Material : public Core::Object, public IRenderable { [[nodiscard]] const std::shared_ptr &getFragmentShader() const; protected: - std::unordered_map> _textures; /**< Map of texture parameters. */ - std::unordered_map _vectors; /**< Map of vector parameters. */ - std::unordered_map _scalars; /**< Map of scalar parameters. */ + std::unordered_map> _textures; /**< Map of texture parameters. */ + std::unordered_map _vectors; /**< Map of vector parameters. */ + std::unordered_map _scalars; /**< Map of scalar parameters. */ std::shared_ptr _fragmentShader; /**< The fragment shader used by the material. nullptr means using the standard shader. */ }; +std::ostream &operator<<(std::ostream &stream, const Material::Location &location); + } // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Renderable/Material.cpp b/Engine/Scene/src/Scene/Renderable/Material.cpp index a628243..80df27a 100644 --- a/Engine/Scene/src/Scene/Renderable/Material.cpp +++ b/Engine/Scene/src/Scene/Renderable/Material.cpp @@ -25,39 +25,39 @@ std::ostream &Material::writeToStream(std::ostream &stream, bool closing_bracer) return stream; } -void Material::setTextureParameter(const std::string &name, std::shared_ptr texture) { - _textures[name] = std::move(texture); +void Material::setTextureParameter(const Location &location, std::shared_ptr texture) { + _textures[location] = std::move(texture); markDirty(); } -std::shared_ptr Material::getTextureParameter(const std::string &name) const { - auto it = _textures.find(name); +std::shared_ptr Material::getTextureParameter(const Location &location) const { + auto it = _textures.find(location); if (it != _textures.end()) { return it->second; } return nullptr; } -void Material::setVectorParameter(const std::string &name, const glm::vec3 &vector) { - _vectors[name] = vector; +void Material::setVectorParameter(const Location &location, const glm::vec3 &vector) { + _vectors[location] = vector; markDirty(); } -glm::vec3 Material::getVectorParameter(const std::string &name) const { - auto it = _vectors.find(name); +glm::vec3 Material::getVectorParameter(const Location &location) const { + auto it = _vectors.find(location); if (it != _vectors.end()) { return it->second; } return glm::vec3(0.0f); } -void Material::setScalarParameter(const std::string &name, float scalar) { - _scalars[name] = scalar; +void Material::setScalarParameter(const Location &location, float scalar) { + _scalars[location] = scalar; markDirty(); } -float Material::getScalarParameter(const std::string &name) const { - auto it = _scalars.find(name); +float Material::getScalarParameter(const Location &location) const { + auto it = _scalars.find(location); if (it != _scalars.end()) { return it->second; } @@ -65,21 +65,20 @@ float Material::getScalarParameter(const std::string &name) const { } void Material::forEachTextures( - const std::function> &)> &lambda) { - for (auto &it : _textures) { + const std::function> &)> &lambda) { + for (const auto &it : _textures) { lambda(it); } } -void Material::forEachVectors(const std::function &)> &lambda) { - for (auto &it : _vectors) { +void Material::forEachVectors(const std::function &)> &lambda) { + for (const auto &it : _vectors) { lambda(it); } } -void Material::forEachScalars(const std::function &)> &lambda) { - for (auto &it : _scalars) { - it.second += 1; +void Material::forEachScalars(const std::function &)> &lambda) { + for (const auto &it : _scalars) { lambda(it); } } @@ -93,4 +92,8 @@ const std::shared_ptr &Material::getFragmentShader() const { return _fragmentShader; } +std::ostream &operator<<(std::ostream &stream, const Material::Location &location) { + return stream; +} + } // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp index 01f5f67..35d75d1 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp @@ -59,7 +59,7 @@ void RendererObjectManager::updateMaterial(const std::shared_ptr &mate if (fragmentShader && fragmentShader->isDirty()) { updateFragmentShader(fragmentShader); } - material->forEachTextures([this](std::pair> &it) { + material->forEachTextures([this](const std::pair> &it) { if (it.second->isDirty()) updateTexture(it.second); }); From b8711d8a40f0e49675748b24e3e71ec492bf3339 Mon Sep 17 00:00:00 2001 From: amasson Date: Fri, 1 Nov 2024 12:48:38 +0100 Subject: [PATCH 28/89] write Meterial Location to stream --- Engine/Scene/src/Scene/Renderable/Material.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Engine/Scene/src/Scene/Renderable/Material.cpp b/Engine/Scene/src/Scene/Renderable/Material.cpp index 80df27a..a587ffd 100644 --- a/Engine/Scene/src/Scene/Renderable/Material.cpp +++ b/Engine/Scene/src/Scene/Renderable/Material.cpp @@ -93,6 +93,11 @@ const std::shared_ptr &Material::getFragmentShader() const { } std::ostream &operator<<(std::ostream &stream, const Material::Location &location) { + if (std::holds_alternative(location)) { + stream << std::get(location); + } else { + stream << std::get(location); + } return stream; } From 37fef21e3d754e48e3f57214a4591b3b96c0962c Mon Sep 17 00:00:00 2001 From: amasson Date: Fri, 1 Nov 2024 12:52:09 +0100 Subject: [PATCH 29/89] fix clang --- .../src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp index ae24f58..19cad24 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp @@ -93,7 +93,9 @@ void VulkanRenderer::_recordCommandBuffer(VkCommandBuffer commandBuffer, ImageCo } std::array clearValues = {}; - clearValues[0].color = {0.0f, 0.0f, 0.0f, 1.0f}; + clearValues[0].color = { + {0.0f, 0.0f, 0.0f, 1.0f} + }; clearValues[1].depthStencil = {1.0f, 0}; VkRenderPassBeginInfo renderPassInfo = {}; From d9cbf4586bd38a54a779c021ea4c85fe48419418 Mon Sep 17 00:00:00 2001 From: amasson Date: Fri, 1 Nov 2024 13:15:42 +0100 Subject: [PATCH 30/89] prepare asset resources tests --- Engine/Scene/test/test_AssetResource.cpp | 16 ++++++++++++++++ Resources/unit_tests_root/simple_json.json | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 Engine/Scene/test/test_AssetResource.cpp create mode 100644 Resources/unit_tests_root/simple_json.json diff --git a/Engine/Scene/test/test_AssetResource.cpp b/Engine/Scene/test/test_AssetResource.cpp new file mode 100644 index 0000000..75b8a13 --- /dev/null +++ b/Engine/Scene/test/test_AssetResource.cpp @@ -0,0 +1,16 @@ +#include "Core/Assets/Bundle.hpp" +#include "Scene/Assets/AssetResource.hpp" + +#include + +using namespace Stone::Scene; + +TEST(AssetResource, FindBundle) { + auto bundle = std::make_shared("test/"); + + auto resource = bundle->loadResource("test.stone"); + + // TODO: Implement tests that parse fbx, dae, obj, and other formats + // and check if the meshes, textures, materials, and other assets are loaded correctly + // check if metadatas are loaded correctly +} diff --git a/Resources/unit_tests_root/simple_json.json b/Resources/unit_tests_root/simple_json.json new file mode 100644 index 0000000..c8073cb --- /dev/null +++ b/Resources/unit_tests_root/simple_json.json @@ -0,0 +1,21 @@ +{ + "Name": "Stone", + "Function": "Engine", + "Renderers": [ + { + "Name": "OpenGL", + "Performance": "Medium", + "Ready": true + }, + { + "Name": "Vulkan", + "Performance": "High", + "Ready": true + }, + { + "Name": "Metal", + "Performance": "High", + "Ready": false + } + ] +} \ No newline at end of file From af094f698c1ee101e17754907a6f7eb2b924eec1 Mon Sep 17 00:00:00 2001 From: amasson Date: Mon, 4 Nov 2024 19:29:47 +0100 Subject: [PATCH 31/89] tidy naming --- .../include/Scene/Renderable/Material.hpp | 22 +++++++++---------- Engine/Scene/src/Scene/Geometry.cpp | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Engine/Scene/include/Scene/Renderable/Material.hpp b/Engine/Scene/include/Scene/Renderable/Material.hpp index 0968dd5..dd6ee24 100644 --- a/Engine/Scene/include/Scene/Renderable/Material.hpp +++ b/Engine/Scene/include/Scene/Renderable/Material.hpp @@ -44,15 +44,15 @@ class Material : public Core::Object, public IRenderable { /** * @brief Set a texture parameter for the Material. * - * @param name The name of the texture parameter. + * @param location The location of the texture parameter. * @param texture The texture to set. */ - void setTextureParameter(const Location &name, std::shared_ptr texture); + void setTextureParameter(const Location &location, std::shared_ptr texture); /** * @brief Get a texture parameter from the Material. * - * @param name The name of the texture parameter. + * @param location The location of the texture parameter. * @return The texture parameter as a shared pointer to Texture. */ [[nodiscard]] std::shared_ptr getTextureParameter(const Location &location) const; @@ -60,34 +60,34 @@ class Material : public Core::Object, public IRenderable { /** * @brief Set a vector parameter for the Material. * - * @param name The name of the vector parameter. + * @param location The location of the vector parameter. * @param vector The vector to set. */ - void setVectorParameter(const Location &name, const glm::vec3 &vector); + void setVectorParameter(const Location &location, const glm::vec3 &vector); /** * @brief Get a vector parameter from the Material. * - * @param name The name of the vector parameter. + * @param location The location of the vector parameter. * @return The vector parameter as a glm::vec3. */ - [[nodiscard]] glm::vec3 getVectorParameter(const Location &name) const; + [[nodiscard]] glm::vec3 getVectorParameter(const Location &location) const; /** * @brief Set a scalar parameter for the Material. * - * @param name The name of the scalar parameter. + * @param location The location of the scalar parameter. * @param scalar The scalar value to set. */ - void setScalarParameter(const Location &name, float scalar); + void setScalarParameter(const Location &location, float scalar); /** * @brief Get a scalar parameter from the Material. * - * @param name The name of the scalar parameter. + * @param location The location of the scalar parameter. * @return The scalar parameter as a float. */ - [[nodiscard]] float getScalarParameter(const Location &name) const; + [[nodiscard]] float getScalarParameter(const Location &location) const; /** * @brief Iterate over all texture parameters in the Material. diff --git a/Engine/Scene/src/Scene/Geometry.cpp b/Engine/Scene/src/Scene/Geometry.cpp index 41d750e..dc3e3db 100644 --- a/Engine/Scene/src/Scene/Geometry.cpp +++ b/Engine/Scene/src/Scene/Geometry.cpp @@ -19,8 +19,8 @@ std::pair, std::vector> generateGeometryMesh(co std::vector indices; std::vector vertices; - const float phiStep = M_PI / (float)rings; - const float thetaStep = 2 * M_PI / (float)rings; + const float phiStep = (float)M_PI / (float)rings; + const float thetaStep = 2.0f * (float)M_PI / (float)rings; for (int i = 0; i <= rings; i++) { const float phi = (float)i * phiStep; From 208d95a5c2eac4de2ac59ceaffe2aca1361cfea7 Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 5 Nov 2024 19:30:10 +0100 Subject: [PATCH 32/89] Update renderer objects undirty #63 --- .../Render/OpenGL/RendererObjectManager.cpp | 2 +- .../Render/Vulkan/RendererObjectManager.cpp | 10 ++++----- .../Scene/Renderer/RendererObjectManager.hpp | 12 +--------- .../Scene/Renderer/RendererObjectManager.cpp | 22 ++++--------------- 4 files changed, 11 insertions(+), 35 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp b/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp index 35b9f51..a2172a1 100644 --- a/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp +++ b/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp @@ -17,7 +17,7 @@ Scene::RendererObjectManager::update##RenderableClass((object)); \ \ auto new##RenderableClass = std::make_shared(*(object), _renderer); \ - setRendererObjectTo((object).get(), new##RenderableClass); \ + updateRendererObject(*(object), new##RenderableClass); \ } diff --git a/Engine/Render/src/Render/Vulkan/RendererObjectManager.cpp b/Engine/Render/src/Render/Vulkan/RendererObjectManager.cpp index 38678d4..0bfb97d 100644 --- a/Engine/Render/src/Render/Vulkan/RendererObjectManager.cpp +++ b/Engine/Render/src/Render/Vulkan/RendererObjectManager.cpp @@ -29,7 +29,7 @@ void RendererObjectManager::updateMeshNode(const std::shared_ptr(meshNode, _renderer); - setRendererObjectTo(meshNode.get(), newMeshNode); + updateRendererObject(*meshNode, newMeshNode); } void RendererObjectManager::updateMaterial(const std::shared_ptr &material) { @@ -40,7 +40,7 @@ void RendererObjectManager::updateMaterial(const std::shared_ptr(material, _renderer); - setRendererObjectTo(material.get(), newMaterial); + updateRendererObject(*material, newMaterial); } void RendererObjectManager::updateDynamicMesh(const std::shared_ptr &mesh) { @@ -51,7 +51,7 @@ void RendererObjectManager::updateDynamicMesh(const std::shared_ptr(mesh, _renderer); - setRendererObjectTo(mesh.get(), newMesh); + updateRendererObject(*mesh, newMesh); } void RendererObjectManager::updateTexture(const std::shared_ptr &texture) { @@ -62,7 +62,7 @@ void RendererObjectManager::updateTexture(const std::shared_ptr } auto newTexture = std::make_shared(texture, _renderer); - setRendererObjectTo(texture.get(), newTexture); + updateRendererObject(*texture, newTexture); } void RendererObjectManager::updateFragmentShader(const std::shared_ptr &shader) { @@ -73,7 +73,7 @@ void RendererObjectManager::updateFragmentShader(const std::shared_ptr(shader, _renderer); - setRendererObjectTo(shader.get(), newShader); + updateRendererObject(*shader, newShader); } } // namespace Stone::Render::Vulkan diff --git a/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp b/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp index b32622c..a55d1c0 100644 --- a/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp +++ b/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp @@ -107,17 +107,7 @@ class RendererObjectManager { * @param element The render element to set the renderer object to. * @param rendererObject The renderer object to set. */ - static void setRendererObjectTo(IRenderable *element, const std::shared_ptr &rendererObject); - - /** - * @brief Marks the given element as undirty. - * - * This class is friend with IRenderable, so it can access the protected method markUndirty but its - * inheriting classes can't. - * - * @param element The render element to mark as undirty. - */ - static void markElementUndirty(IRenderable *element); + static void updateRendererObject(IRenderable &element, const std::shared_ptr &rendererObject); }; } // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp index 35d75d1..63a470b 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp @@ -35,7 +35,6 @@ void RendererObjectManager::updateMeshNode(const std::shared_ptr &mesh updateMaterial(meshNode->getMaterial()); if (meshNode->getMesh() && meshNode->getMesh()->isDirty()) updateRenderable(meshNode->getMesh()); - meshNode->markUndirty(); } void RendererObjectManager::updateInstancedMeshNode(const std::shared_ptr &instancedMeshNode) { @@ -43,7 +42,6 @@ void RendererObjectManager::updateInstancedMeshNode(const std::shared_ptrgetMaterial()); if (instancedMeshNode->getMesh() && instancedMeshNode->getMesh()->isDirty()) updateRenderable(instancedMeshNode->getMesh()); - instancedMeshNode->markUndirty(); } void RendererObjectManager::updateSkinMeshNode(const std::shared_ptr &skinMeshNode) { @@ -51,7 +49,6 @@ void RendererObjectManager::updateSkinMeshNode(const std::shared_ptrgetMaterial()); if (skinMeshNode->getSkinMesh() && skinMeshNode->getSkinMesh()->isDirty()) updateRenderable(skinMeshNode->getSkinMesh()); - skinMeshNode->markUndirty(); } void RendererObjectManager::updateMaterial(const std::shared_ptr &material) { @@ -63,52 +60,41 @@ void RendererObjectManager::updateMaterial(const std::shared_ptr &mate if (it.second->isDirty()) updateTexture(it.second); }); - material->markUndirty(); } void RendererObjectManager::updateDynamicMesh(const std::shared_ptr &mesh) { if (mesh->getDefaultMaterial() && mesh->getDefaultMaterial()->isDirty()) updateMaterial(mesh->getDefaultMaterial()); - mesh->markUndirty(); } void RendererObjectManager::updateStaticMesh(const std::shared_ptr &mesh) { if (mesh->getDefaultMaterial() && mesh->getDefaultMaterial()->isDirty()) updateMaterial(mesh->getDefaultMaterial()); - mesh->markUndirty(); } void RendererObjectManager::updateDynamicSkinMesh(const std::shared_ptr &skinmesh) { if (skinmesh->getDefaultMaterial() && skinmesh->getDefaultMaterial()->isDirty()) updateMaterial(skinmesh->getDefaultMaterial()); - skinmesh->markUndirty(); } void RendererObjectManager::updateStaticSkinMesh(const std::shared_ptr &skinmesh) { if (skinmesh->getDefaultMaterial() && skinmesh->getDefaultMaterial()->isDirty()) updateMaterial(skinmesh->getDefaultMaterial()); - skinmesh->markUndirty(); } void RendererObjectManager::updateWireframeShape(const std::shared_ptr &shape) { - shape->markUndirty(); } void RendererObjectManager::updateTexture(const std::shared_ptr &texture) { - texture->markUndirty(); } void RendererObjectManager::updateFragmentShader(const std::shared_ptr &shader) { - shader->markUndirty(); } -void RendererObjectManager::setRendererObjectTo(IRenderable *element, - const std::shared_ptr &rendererObject) { - element->setRendererObject(rendererObject); -} - -void RendererObjectManager::markElementUndirty(IRenderable *element) { - element->markUndirty(); +void RendererObjectManager::updateRendererObject(IRenderable &element, + const std::shared_ptr &rendererObject) { + element.setRendererObject(rendererObject); + element.markUndirty(); } } // namespace Stone::Scene From 6cb59aabad54f4aaca67ac182663da0efde3b65a Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 12 Nov 2024 12:10:52 +0100 Subject: [PATCH 33/89] material foreach split parameters from pair --- .../Vulkan/VulkanRenderable/MeshNode.cpp | 27 ++++++++++--------- .../include/Scene/Renderable/Material.hpp | 7 +++-- .../Scene/src/Scene/Renderable/Material.cpp | 12 ++++----- .../Scene/Renderer/RendererObjectManager.cpp | 7 ++--- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp index bc16555..6eb8aa1 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderable/MeshNode.cpp @@ -84,15 +84,17 @@ void MeshNode::_createDescriptorSetLayout() { auto shader = material->getFragmentShader(); // TODO: Take default fragment shader if none is found if (shader) { material->forEachTextures( - [&](const std::pair> &texture) { + [&](const Scene::Material::Location &loc, const std::shared_ptr &texture) { + (void)texture; + VkDescriptorSetLayoutBinding samplerLayoutBinding; // TODO: Factor this code in scene function int location = -1; - if (std::holds_alternative(texture.first)) { - location = std::get(texture.first); - } else if (std::holds_alternative(texture.first)) { - location = shader->getLocation(std::get(texture.first)); + if (std::holds_alternative(loc)) { + location = std::get(loc); + } else if (std::holds_alternative(loc)) { + location = shader->getLocation(std::get(loc)); } if (location == -1) { return; @@ -398,7 +400,8 @@ void MeshNode::_createDescriptorPool(const std::shared_ptr &swapChain auto shader = material->getFragmentShader(); if (shader) { material->forEachTextures( - [&](const std::pair> &texture) { + [&](const Scene::Material::Location &location, const std::shared_ptr &texture) { + (void)location; (void)texture; VkDescriptorPoolSize poolSize = {}; poolSize.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; @@ -461,18 +464,18 @@ void MeshNode::_createDescriptorSets(const std::shared_ptr &swapChain auto shader = material->getFragmentShader(); if (shader) { material->forEachTextures( - [&](const std::pair> &texture) { + [&](const Scene::Material::Location &loc, const std::shared_ptr &texture) { int location = -1; - if (std::holds_alternative(texture.first)) { - location = std::get(texture.first); - } else if (std::holds_alternative(texture.first)) { - location = shader->getLocation(std::get(texture.first)); + if (std::holds_alternative(loc)) { + location = std::get(loc); + } else if (std::holds_alternative(loc)) { + location = shader->getLocation(std::get(loc)); } if (location == -1) { return; } - auto textureObject = texture.second->getRendererObject(); + auto textureObject = texture->getRendererObject(); imagesInfo.push_back({}); VkDescriptorImageInfo &imageInfo(imagesInfo.back()); diff --git a/Engine/Scene/include/Scene/Renderable/Material.hpp b/Engine/Scene/include/Scene/Renderable/Material.hpp index dd6ee24..9a2f712 100644 --- a/Engine/Scene/include/Scene/Renderable/Material.hpp +++ b/Engine/Scene/include/Scene/Renderable/Material.hpp @@ -94,22 +94,21 @@ class Material : public Core::Object, public IRenderable { * * @param lambda The lambda function to call for each texture parameter. */ - void - forEachTextures(const std::function> &)> &lambda); + void forEachTextures(const std::function &)> &lambda) const; /** * @brief Iterate over all vector parameters in the Material. * * @param lambda The lambda function to call for each vector parameter. */ - void forEachVectors(const std::function &)> &lambda); + void forEachVectors(const std::function &lambda) const; /** * @brief Iterate over all scalar parameters in the Material. * * @param lambda The lambda function to call for each scalar parameter. */ - void forEachScalars(const std::function &)> &lambda); + void forEachScalars(const std::function &lambda) const; /** * @brief Set the fragment shader used by the Material. diff --git a/Engine/Scene/src/Scene/Renderable/Material.cpp b/Engine/Scene/src/Scene/Renderable/Material.cpp index a587ffd..2b79d9f 100644 --- a/Engine/Scene/src/Scene/Renderable/Material.cpp +++ b/Engine/Scene/src/Scene/Renderable/Material.cpp @@ -65,21 +65,21 @@ float Material::getScalarParameter(const Location &location) const { } void Material::forEachTextures( - const std::function> &)> &lambda) { + const std::function &)> &lambda) const { for (const auto &it : _textures) { - lambda(it); + lambda(it.first, it.second); } } -void Material::forEachVectors(const std::function &)> &lambda) { +void Material::forEachVectors(const std::function &lambda) const { for (const auto &it : _vectors) { - lambda(it); + lambda(it.first, it.second); } } -void Material::forEachScalars(const std::function &)> &lambda) { +void Material::forEachScalars(const std::function &lambda) const { for (const auto &it : _scalars) { - lambda(it); + lambda(it.first, it.second); } } diff --git a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp index 63a470b..f5e7cad 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp @@ -56,9 +56,10 @@ void RendererObjectManager::updateMaterial(const std::shared_ptr &mate if (fragmentShader && fragmentShader->isDirty()) { updateFragmentShader(fragmentShader); } - material->forEachTextures([this](const std::pair> &it) { - if (it.second->isDirty()) - updateTexture(it.second); + material->forEachTextures([this](const Material::Location &loc, const std::shared_ptr &texture) { + (void)loc; + if (texture->isDirty()) + updateTexture(texture); }); } From 69f6d07fe0eefb08619b1994b9f99068228db6ce Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 12 Nov 2024 12:59:10 +0100 Subject: [PATCH 34/89] Shader generator functions --- .../Scene/include/Scene/Renderable/Shader.hpp | 2 +- .../include/Scene/Shader/ShaderGenerator.hpp | 20 +++++++ .../include/Scene/Shader/ShaderParameters.hpp | 53 +++++++++++++++++++ .../Scene/Assets/AssetResource_AssimpLoad.cpp | 10 ++-- .../src/Scene/Shader/ShaderGenerator.cpp | 51 ++++++++++++++++++ .../src/Scene/Shader/ShaderParameters.cpp | 53 +++++++++++++++++++ 6 files changed, 183 insertions(+), 6 deletions(-) create mode 100644 Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp create mode 100644 Engine/Scene/include/Scene/Shader/ShaderParameters.hpp create mode 100644 Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp create mode 100644 Engine/Scene/src/Scene/Shader/ShaderParameters.cpp diff --git a/Engine/Scene/include/Scene/Renderable/Shader.hpp b/Engine/Scene/include/Scene/Renderable/Shader.hpp index f5c1c41..cb4d06d 100644 --- a/Engine/Scene/include/Scene/Renderable/Shader.hpp +++ b/Engine/Scene/include/Scene/Renderable/Shader.hpp @@ -89,7 +89,7 @@ class AShader : public Core::Object, public IRenderable { private: ContentType _contentType = ContentType::SourceCode; /** The type of the content. */ - std::string _content = "#version 450 core\n"; /** The content of the shader. */ + std::string _content = "#version 400 core\n"; /** The content of the shader. */ std::string _function = "main"; /** The function to call in the shader. */ std::unordered_map _locations = {}; /** The binding locations of the variables in the shader. */ diff --git a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp new file mode 100644 index 0000000..705073d --- /dev/null +++ b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp @@ -0,0 +1,20 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Scene/Shader/ShaderParameters.hpp" + +namespace Stone::Scene { + +class ShaderGenerator { + + +public: + ShaderGenerator() = default; + + ~ShaderGenerator() = default; + + void generateFragmentShader(const ShaderParameters ¶ms, std::ostream &output); +}; + +} // namespace Stone::Scene diff --git a/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp b/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp new file mode 100644 index 0000000..caec228 --- /dev/null +++ b/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp @@ -0,0 +1,53 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Scene/Renderable/IMeshObject.hpp" + +namespace Stone::Scene { + +#define FOR_EACH_SHADER_PARAMETERS(__WithParam) \ + __WithParam(diffuse) __WithParam(specular) __WithParam(ambient) __WithParam(emissive) __WithParam(shininess) \ + __WithParam(opacity) __WithParam(roughness) __WithParam(metallic) __WithParam(normal) __WithParam(occlusion) \ + __WithParam(height) + +struct ShaderParameters { + + enum class Type : uint8_t { + None = 0, + Scalar, + Vector, + Texture, + }; + + union { + struct { +#define __DECLARE_PARAM(param) Type param : 2; + FOR_EACH_SHADER_PARAMETERS(__DECLARE_PARAM) + }; + uint32_t data; // sizeof() should be greater or equal to the struct size + }; + bool _; + +#define __INITIALIZE_PARAM(param) param(Type::None), + ShaderParameters(); + + void setParamWithName(const std::string &name, Type value); + + void setFromMaterial(const Scene::Material &material); + + bool operator==(const ShaderParameters &other) const { + return data == other.data; + } +}; + +} // namespace Stone::Scene + +namespace std { +template <> +struct hash { + std::size_t operator()(const Stone::Scene::ShaderParameters ¶ms) const noexcept { + return std::hash()(params.data); + } +}; +} // namespace std diff --git a/Engine/Scene/src/Scene/Assets/AssetResource_AssimpLoad.cpp b/Engine/Scene/src/Scene/Assets/AssetResource_AssimpLoad.cpp index 0525e49..223daf5 100644 --- a/Engine/Scene/src/Scene/Assets/AssetResource_AssimpLoad.cpp +++ b/Engine/Scene/src/Scene/Assets/AssetResource_AssimpLoad.cpp @@ -214,16 +214,16 @@ void loadMaterial(AssetResource &assetResource, const aiMaterial *material) { addMaterialTexture(assetResource, material, newMaterial, aiTextureType_AMBIENT, "ambient"); addMaterialTexture(assetResource, material, newMaterial, aiTextureType_EMISSIVE, "emissive"); addMaterialTexture(assetResource, material, newMaterial, aiTextureType_HEIGHT, "height"); - addMaterialTexture(assetResource, material, newMaterial, aiTextureType_NORMALS, "normals"); + addMaterialTexture(assetResource, material, newMaterial, aiTextureType_NORMALS, "normal"); addMaterialTexture(assetResource, material, newMaterial, aiTextureType_SHININESS, "shininess"); addMaterialTexture(assetResource, material, newMaterial, aiTextureType_OPACITY, "opacity"); addMaterialTexture(assetResource, material, newMaterial, aiTextureType_DISPLACEMENT, "displacement"); addMaterialTexture(assetResource, material, newMaterial, aiTextureType_LIGHTMAP, "lightmap"); addMaterialTexture(assetResource, material, newMaterial, aiTextureType_REFLECTION, "reflection"); - addMaterialTexture(assetResource, material, newMaterial, aiTextureType_BASE_COLOR, "color"); - addMaterialTexture(assetResource, material, newMaterial, aiTextureType_NORMAL_CAMERA, "normal_camera"); - addMaterialTexture(assetResource, material, newMaterial, aiTextureType_EMISSION_COLOR, "emission_color"); - addMaterialTexture(assetResource, material, newMaterial, aiTextureType_METALNESS, "metalness"); + addMaterialTexture(assetResource, material, newMaterial, aiTextureType_BASE_COLOR, "diffuse"); + addMaterialTexture(assetResource, material, newMaterial, aiTextureType_NORMAL_CAMERA, "normal"); + addMaterialTexture(assetResource, material, newMaterial, aiTextureType_EMISSION_COLOR, "emissive"); + addMaterialTexture(assetResource, material, newMaterial, aiTextureType_METALNESS, "metallic"); addMaterialTexture(assetResource, material, newMaterial, aiTextureType_DIFFUSE_ROUGHNESS, "roughness"); addMaterialTexture(assetResource, material, newMaterial, aiTextureType_AMBIENT_OCCLUSION, "occlusion"); addMaterialTexture(assetResource, material, newMaterial, aiTextureType_SHEEN, "sheen"); diff --git a/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp b/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp new file mode 100644 index 0000000..81aa4ab --- /dev/null +++ b/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp @@ -0,0 +1,51 @@ +// Copyright 2024 Stone-Engine + +#include "Scene/Shader/ShaderGenerator.hpp" + +namespace Stone::Scene { + + +void ShaderGenerator::generateFragmentShader(const ShaderParameters ¶ms, std::ostream &output) { + std::ostream &source = output; + + source << R"(#version 400 core + +in FRAG_DATA { + vec3 wposition; + vec2 uv; + vec3 wnormal; + vec3 wtangent; + vec3 wbitangent; +} fs_in; + +layout (location = 0) out vec3 gPosition; +layout (location = 1) out vec3 gNormal; +layout (location = 2) out vec4 gAlbedoSpec; + +)"; + + auto add_uniform_param = [&source](const char *name, ShaderParameters::Type type) { + if (type == ShaderParameters::Type::Texture) { + source << "uniform sampler2D " << name << ";" << std::endl; + } else if (type == ShaderParameters::Type::Vector) { + source << "uniform vec3 " << name << ";" << std::endl; + } else if (type == ShaderParameters::Type::Scalar) { + source << "uniform float " << name << ";" << std::endl; + } + }; + +#define __ADD_UNIFORM_PARAM(PARAM) add_uniform_param(#PARAM, params.PARAM); + + FOR_EACH_SHADER_PARAMETERS(__ADD_UNIFORM_PARAM); + + source << R"( +void main() { + gPosition = fs_in.wposition; + gNormal = normalize(fs_in.wnormal); + gAlbedoSpec = vec4(1.0, 0.0, 0.0, 1.0); +} +)"; +} + + +} // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp new file mode 100644 index 0000000..49cf4d8 --- /dev/null +++ b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp @@ -0,0 +1,53 @@ +// Copyright 2024 Stone-Engine + +#include "Scene/Shader/ShaderParameters.hpp" + +#include "Scene/Renderable/Material.hpp" + +namespace Stone::Scene { + +#define __INITIALIZE_PARAM(param) param(Type::None), +ShaderParameters::ShaderParameters() : FOR_EACH_SHADER_PARAMETERS(__INITIALIZE_PARAM) _() { +} + +void ShaderParameters::setParamWithName(const std::string &name, Type value) { + using ParamSetter = std::function; + + const static std::unordered_map paramSetters = { +#define __MAP_NAME_TO_PARAM(param) \ + {#param, [](ShaderParameters &matParams, Type value) { \ + matParams.param = value; \ + }}, + FOR_EACH_SHADER_PARAMETERS(__MAP_NAME_TO_PARAM)}; + + auto it = paramSetters.find(name); + if (it != paramSetters.end()) { + it->second(*this, value); + } +} + +void ShaderParameters::setFromMaterial(const Material &material) { + material.forEachScalars([this](const Material::Location &location, float value) { + (void)value; + if (std::holds_alternative(location)) { + const std::string &name(std::get(location)); + setParamWithName(name, Type::Scalar); + } + }); + material.forEachVectors([this](const Material::Location &location, glm::vec3 value) { + (void)value; + if (std::holds_alternative(location)) { + const std::string &name(std::get(location)); + setParamWithName(name, Type::Vector); + } + }); + material.forEachTextures([this](const Material::Location &location, auto value) { + (void)value; + if (std::holds_alternative(location)) { + const std::string &name(std::get(location)); + setParamWithName(name, Type::Texture); + } + }); +} + +} // namespace Stone::Scene From 131253c9ac4ef961fa826e78071c7f4a030af9af Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 12 Nov 2024 12:59:34 +0100 Subject: [PATCH 35/89] shader generator example program --- examples/glsl_generator/CMakeLists.txt | 5 + examples/glsl_generator/main.cpp | 107 +++++++++++++++++++++ examples/glsl_generator/shader_params.json | 13 +++ 3 files changed, 125 insertions(+) create mode 100644 examples/glsl_generator/CMakeLists.txt create mode 100644 examples/glsl_generator/main.cpp create mode 100644 examples/glsl_generator/shader_params.json diff --git a/examples/glsl_generator/CMakeLists.txt b/examples/glsl_generator/CMakeLists.txt new file mode 100644 index 0000000..28af4ac --- /dev/null +++ b/examples/glsl_generator/CMakeLists.txt @@ -0,0 +1,5 @@ +set(NAME glsl_generator) + +add_executable(${NAME} EXCLUDE_FROM_ALL main.cpp) +target_include_directories(${NAME} PRIVATE ${PROJECT_BINARY_DIR}/include) +target_link_libraries(${NAME} PRIVATE scene) diff --git a/examples/glsl_generator/main.cpp b/examples/glsl_generator/main.cpp new file mode 100644 index 0000000..d681b88 --- /dev/null +++ b/examples/glsl_generator/main.cpp @@ -0,0 +1,107 @@ +#include "config.h" +#include "Scene/Shader/ShaderGenerator.hpp" +#include "Utils/FileSystem.hpp" +#include "Utils/Json.hpp" + +#include +#include +#include +#include +#include +#include + +static time_t getLastmodifiedTimeOfFile(const char *filename) { + struct stat result; + if (stat(filename, &result) == 0) { + auto mod_time = result.st_mtime; + return mod_time; + } else + throw std::runtime_error("File does not exist"); +} + +Stone::Scene::ShaderParameters parseShaderParameters(const Stone::Json::Value &json) { + Stone::Scene::ShaderParameters params; + + auto ¶ms_obj = json.get(); + + for (auto [key, value] : params_obj) { + Stone::Scene::ShaderParameters::Type type; + if (value.is()) { + const std::string &type_str = value.get(); + if (type_str == "scalar") + type = Stone::Scene::ShaderParameters::Type::Scalar; + else if (type_str == "vector") + type = Stone::Scene::ShaderParameters::Type::Vector; + else if (type_str == "texture") + type = Stone::Scene::ShaderParameters::Type::Texture; + else + throw std::runtime_error("Invalid type " + type_str); + } else + throw std::runtime_error("Invalid type for key " + key); + params.setParamWithName(key, type); + } + + return params; +} + +std::string to_string(Stone::Scene::ShaderParameters::Type type) { + switch (type) { + case Stone::Scene::ShaderParameters::Type::None: return "none"; + case Stone::Scene::ShaderParameters::Type::Scalar: return "scalar"; + case Stone::Scene::ShaderParameters::Type::Vector: return "vector"; + case Stone::Scene::ShaderParameters::Type::Texture: return "texture"; + } + return ""; +} + +void generateShaderOutput(const char *input_file, const char *output_file) { + + Stone::Json::Value input_json; + Stone::Json::Value::parseFile(input_file, input_json); + + std::ofstream output_stream(output_file, std::ios::out | std::ios::trunc); + + Stone::Scene::ShaderParameters params = parseShaderParameters(input_json); + + Stone::Scene::ShaderGenerator generator; + std::cout << "Generating shader: {" << std::endl; +#define __PRINT_SHADER_PARAM(param) std::cout << " -" << #param << " " << to_string(params.param) << std::endl; + FOR_EACH_SHADER_PARAMETERS(__PRINT_SHADER_PARAM) + std::cout << "}" << std::endl; + + generator.generateFragmentShader(params, output_stream); +} + +std::string input; +std::string output; + +void generateShader() { + try { + generateShaderOutput(input.c_str(), output.c_str()); + } catch (const std::exception &e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + +int main(int argc, const char *argv[]) { + if (argc < 3) + return 1; + + input = argv[1]; + output = argv[2]; + + generateShader(); + + if (argc >= 4 && std::string(argv[3]) == "-f") { + while (true) { + time_t last_modified = getLastmodifiedTimeOfFile(input.c_str()); + while (last_modified == getLastmodifiedTimeOfFile(input.c_str())) { + // sleep for a short period + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + } + + generateShader(); + } + return 0; + } +} diff --git a/examples/glsl_generator/shader_params.json b/examples/glsl_generator/shader_params.json new file mode 100644 index 0000000..1af66a1 --- /dev/null +++ b/examples/glsl_generator/shader_params.json @@ -0,0 +1,13 @@ +{ + "diffuse": "texture", + "specular": "texture", + "ambient": "scalar", + "emissive": "vector", + "shininess": "scalar", + "opacity": "texture", + "roughness": "scalar", + "metallic": "vector", + "normal": "vector", + "occlusion": "scalar", + "height": "vector" +} \ No newline at end of file From fa05dace526ab3e3e7f3c19f0644a4fc2b28f9f5 Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 12 Nov 2024 13:02:54 +0100 Subject: [PATCH 36/89] remove default material from render defaults --- Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp | 9 ++++----- Engine/Render/src/Render/OpenGL/RendererDefaults.cpp | 2 -- Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp | 8 -------- Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp | 6 +----- 4 files changed, 5 insertions(+), 20 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp index 5a4e023..1e99075 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp @@ -22,7 +22,7 @@ class MeshNode : public Scene::IRendererObject { meshNode.getMaterial() ? meshNode.getMaterial() : meshNode.getMesh() != nullptr && meshNode.getMesh()->getDefaultMaterial() != nullptr ? meshNode.getMesh()->getDefaultMaterial() - : renderer->getRendererDefaults().getMaterial(); + : nullptr; usedMaterial->getRendererObject()->makeMeshProgram(); } @@ -40,10 +40,9 @@ class MeshNode : public Scene::IRendererObject { } const VRAMMesh &vramMesh = rendererMesh->getVRAMMesh(); - std::shared_ptr sceneMaterial = _meshNode.getMaterial() ? _meshNode.getMaterial() - : mesh->getDefaultMaterial() - ? mesh->getDefaultMaterial() - : context.renderer->getRendererDefaults().getMaterial(); + std::shared_ptr sceneMaterial = _meshNode.getMaterial() ? _meshNode.getMaterial() + : mesh->getDefaultMaterial() ? mesh->getDefaultMaterial() + : nullptr; assert(sceneMaterial != nullptr); assert(sceneMaterial->isDirty() == false); diff --git a/Engine/Render/src/Render/OpenGL/RendererDefaults.cpp b/Engine/Render/src/Render/OpenGL/RendererDefaults.cpp index b874a75..f038af2 100644 --- a/Engine/Render/src/Render/OpenGL/RendererDefaults.cpp +++ b/Engine/Render/src/Render/OpenGL/RendererDefaults.cpp @@ -7,8 +7,6 @@ namespace Stone::Render::OpenGL { RendererDefaults::RendererDefaults(const std::shared_ptr &renderer) : Scene::RendererDefaults() { - _material = std::make_shared(); - _meshFragmentShader = FragmentShader::makeStandardMeshShader(renderer); _meshVertexShader = VertexShader::makeStandardMeshShader(renderer); _skinMeshVertexShader = VertexShader::makeStandardSkinMeshShader(renderer); diff --git a/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp b/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp index 705ba88..17ab055 100644 --- a/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp +++ b/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp @@ -15,14 +15,6 @@ class RendererDefaults { RendererDefaults(const RendererDefaults &) = delete; virtual ~RendererDefaults() = default; - - /** - * @brief Get the default material used when a mesh has no material set. - */ - const std::shared_ptr &getMaterial() const; - -protected: - std::shared_ptr _material; }; } // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp b/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp index 2212cfd..ff3bfb8 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp @@ -6,11 +6,7 @@ namespace Stone::Scene { -RendererDefaults::RendererDefaults() : _material(nullptr) { -} - -const std::shared_ptr &RendererDefaults::getMaterial() const { - return _material; +RendererDefaults::RendererDefaults() { } } // namespace Stone::Scene From dd22faa30443bbca6494ce093dac286a03a005e3 Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 12 Nov 2024 22:42:48 +0100 Subject: [PATCH 37/89] Replace RendererDefaults with Resources --- .../include/Render/OpenGL/OpenGLRenderer.hpp | 7 +- .../include/Render/Vulkan/VulkanRenderer.hpp | 2 - .../src/Render/OpenGL/OpenGLRenderer.cpp | 15 ++-- .../src/Render/OpenGL/OpenGLResources.cpp | 12 +++ .../src/Render/OpenGL/OpenGLResources.hpp | 23 ++++++ .../src/Render/OpenGL/Renderable/Material.hpp | 74 +------------------ .../src/Render/OpenGL/Renderable/MeshNode.hpp | 5 +- .../src/Render/OpenGL/RendererDefaults.cpp | 16 ---- .../src/Render/OpenGL/RendererDefaults.hpp | 41 ---------- .../src/Render/Vulkan/VulkanRenderer.cpp | 2 - .../Vulkan/VulkanRenderer_ISceneRenderer.cpp | 4 - Engine/Scene/include/Scene.hpp | 1 - .../include/Scene/Renderer/ISceneRenderer.hpp | 7 -- .../Scene/Renderer/RendererDefaults.hpp | 20 ----- .../src/Scene/Renderer/RendererDefaults.cpp | 12 --- 15 files changed, 45 insertions(+), 196 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/OpenGLResources.cpp create mode 100644 Engine/Render/src/Render/OpenGL/OpenGLResources.hpp delete mode 100644 Engine/Render/src/Render/OpenGL/RendererDefaults.cpp delete mode 100644 Engine/Render/src/Render/OpenGL/RendererDefaults.hpp delete mode 100644 Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp delete mode 100644 Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index 6eb36f9..9f5f820 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -11,7 +11,7 @@ class WorldNode; namespace Stone::Render::OpenGL { -class RendererDefaults; +class OpenGLResources; class OpenGLRenderer : public Renderer { public: @@ -24,17 +24,16 @@ class OpenGLRenderer : public Renderer { /** Renderer */ void updateDataForWorld(const std::shared_ptr &world) override; - const Scene::RendererDefaults &getRendererDefaults() const override; void renderWorld(const std::shared_ptr &world) override; void updateFrameSize(std::pair size) override; void initialize(); - const RendererDefaults &getOpenGLRendererDefaults() const; + const OpenGLResources &getOpenGLResources() const; private: std::pair _frameSize; - std::unique_ptr _defaults; + std::unique_ptr _resources; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp b/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp index 0acccf9..a43fffa 100644 --- a/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp +++ b/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp @@ -28,7 +28,6 @@ class VulkanRenderer : public Renderer { /** Renderer */ void updateDataForWorld(const std::shared_ptr &world) override; - const Scene::RendererDefaults &getRendererDefaults() const override; void renderWorld(const std::shared_ptr &world) override; void updateFrameSize(std::pair size) override; @@ -50,7 +49,6 @@ class VulkanRenderer : public Renderer { std::shared_ptr _renderPass; std::shared_ptr _framesRenderer; std::shared_ptr _swapChain; - std::unique_ptr _rendererDefaults; }; } // namespace Stone::Render::Vulkan diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index e82a91a..0d74a7f 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -3,11 +3,10 @@ #include "Render/OpenGL/OpenGLRenderer.hpp" +#include "OpenGLResources.hpp" #include "RenderContext.hpp" -#include "RendererDefaults.hpp" #include "RendererObjectManager.hpp" #include "Scene/Node/WorldNode.hpp" -#include "Scene/Renderer/RendererDefaults.hpp" #include @@ -26,7 +25,7 @@ static void initializeOpenGL() { } OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) - : Renderer(), _frameSize(settings.frame_size), _defaults(nullptr) { + : Renderer(), _frameSize(settings.frame_size), _resources(nullptr) { } OpenGLRenderer::~OpenGLRenderer() { @@ -43,10 +42,6 @@ void OpenGLRenderer::updateDataForWorld(const std::shared_ptr }); } -const Scene::RendererDefaults &OpenGLRenderer::getRendererDefaults() const { - return *_defaults; -} - void OpenGLRenderer::renderWorld(const std::shared_ptr &world) { glViewport(0, 0, static_cast(_frameSize.first), static_cast(_frameSize.second)); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); @@ -65,11 +60,11 @@ void OpenGLRenderer::initialize() { initializeOpenGL(); std::cout << "OpenGLRenderer created" << std::endl; std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; - _defaults = std::make_unique(std::static_pointer_cast(shared_from_this())); + _resources = std::make_unique(std::static_pointer_cast(shared_from_this())); } -const RendererDefaults &OpenGLRenderer::getOpenGLRendererDefaults() const { - return *_defaults; +const OpenGLResources &OpenGLRenderer::getOpenGLResources() const { + return *_resources; } diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp new file mode 100644 index 0000000..939fc11 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -0,0 +1,12 @@ +// Copyright 2024 Stone-Engine + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Render/OpenGL/OpenGLResources.hpp" + +namespace Stone::Render::OpenGL { + +OpenGLResources::OpenGLResources(const std::shared_ptr &renderer) : _renderer(renderer) { +} + + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp new file mode 100644 index 0000000..6aecf42 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp @@ -0,0 +1,23 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include + +namespace Stone::Render::OpenGL { + +class OpenGLRenderer; + +class OpenGLResources { +public: + OpenGLResources() = default; + + OpenGLResources(const std::shared_ptr &renderer); + + virtual ~OpenGLResources() = default; + +private: + std::weak_ptr _renderer; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp index dd134ba..15fe8aa 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp @@ -2,7 +2,6 @@ #pragma once -#include "../RendererDefaults.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Material.hpp" @@ -28,78 +27,7 @@ class Material : public Scene::IRendererObject { } void render(Scene::RenderContext &context) override { - auto getLoc = [this](const char *name) -> GLint { - GLint loc = glGetUniformLocation(_lastUsedProgram, name); - if (loc == -1) { - throw std::runtime_error("Failed to get location of uniform: " + std::string(name)); - } - return loc; - }; - - glUniformMatrix4fv(getLoc("u_mat_projection"), 1, GL_FALSE, glm::value_ptr(context.mvp.projMatrix)); - glUniformMatrix4fv(getLoc("u_mat_view"), 1, GL_FALSE, glm::value_ptr(context.mvp.viewMatrix)); - glUniformMatrix4fv(getLoc("u_mat_model"), 1, GL_FALSE, glm::value_ptr(context.mvp.modelMatrix)); - } - - void makeMeshProgram() { - if (_gl_meshProgram != 0) - return; - - if (_renderer.expired()) - return; - - auto renderer = _renderer.lock(); - - auto vertexShader = renderer->getOpenGLRendererDefaults().getMeshVertexShader(); - - assert(vertexShader != nullptr); - - // std::shared_ptr fragmentShader = - // _material.getFragmentShader() ? _material.getFragmentShader() : - // renderer->getOpenGLRendererDefaults().getFragmentShader(); - - // assert(fragmentShader != nullptr); - - auto glFragmentShader = renderer->getOpenGLRendererDefaults().getFragmentShader(); - // fragmentShader->getRendererObject(); - - _gl_meshProgram = glCreateProgram(); - glAttachShader(_gl_meshProgram, vertexShader->getGLShader()); - glAttachShader(_gl_meshProgram, glFragmentShader->getGLShader()); - glLinkProgram(_gl_meshProgram); - - GLint success; - glGetProgramiv(_gl_meshProgram, GL_LINK_STATUS, &success); - if (!success) { - GLchar infoLog[1024]; - glGetProgramInfoLog(_gl_meshProgram, 1024, nullptr, infoLog); - throw std::runtime_error("Failed to link program: " + std::string(infoLog)); - } - } - - void makeSkinMeshProgram() { - if (_gl_skinMeshProgram != 0) - return; - } - - void makeInstancedMeshProgram() { - if (_gl_instancedMeshProgram != 0) - return; - } - - void useMeshProgram() { - glUseProgram(_gl_meshProgram); - _lastUsedProgram = _gl_meshProgram; - } - - void useSkinMeshProgram() { - glUseProgram(_gl_skinMeshProgram); - _lastUsedProgram = _gl_skinMeshProgram; - } - - void useInstancedMeshProgram() { - glUseProgram(_gl_instancedMeshProgram); - _lastUsedProgram = _gl_instancedMeshProgram; + (void)context; } private: diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp index 1e99075..294830b 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp @@ -2,12 +2,12 @@ #pragma once +#include "../OpenGLResources.hpp" #include "Material.hpp" #include "Mesh.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Node/MeshNode.hpp" #include "Scene/Renderable/Mesh.hpp" -#include "Scene/Renderer/RendererDefaults.hpp" #include @@ -23,8 +23,6 @@ class MeshNode : public Scene::IRendererObject { : meshNode.getMesh() != nullptr && meshNode.getMesh()->getDefaultMaterial() != nullptr ? meshNode.getMesh()->getDefaultMaterial() : nullptr; - - usedMaterial->getRendererObject()->makeMeshProgram(); } ~MeshNode() override = default; @@ -49,7 +47,6 @@ class MeshNode : public Scene::IRendererObject { std::shared_ptr material = sceneMaterial->getRendererObject(); - material->useMeshProgram(); material->render(context); glEnable(GL_DEPTH_TEST); diff --git a/Engine/Render/src/Render/OpenGL/RendererDefaults.cpp b/Engine/Render/src/Render/OpenGL/RendererDefaults.cpp deleted file mode 100644 index f038af2..0000000 --- a/Engine/Render/src/Render/OpenGL/RendererDefaults.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2024 StoneEngine - -#include "RendererDefaults.hpp" - -#include "Scene/Renderable/Material.hpp" - -namespace Stone::Render::OpenGL { - -RendererDefaults::RendererDefaults(const std::shared_ptr &renderer) : Scene::RendererDefaults() { - _meshFragmentShader = FragmentShader::makeStandardMeshShader(renderer); - _meshVertexShader = VertexShader::makeStandardMeshShader(renderer); - _skinMeshVertexShader = VertexShader::makeStandardSkinMeshShader(renderer); - // _instancedMeshVertexShader = VertexShader::makeStandardInstancedMeshShader(renderer); -} - -} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/RendererDefaults.hpp b/Engine/Render/src/Render/OpenGL/RendererDefaults.hpp deleted file mode 100644 index c91dbd0..0000000 --- a/Engine/Render/src/Render/OpenGL/RendererDefaults.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2024 StoneEngine - -#pragma once - -#include "Renderable/Shader.hpp" -#include "Scene/Renderer/RendererDefaults.hpp" - -namespace Stone::Render::OpenGL { - -class RendererDefaults : public Scene::RendererDefaults { -public: - explicit RendererDefaults(const std::shared_ptr &renderer); - RendererDefaults(const RendererDefaults &other) = delete; - - ~RendererDefaults() override = default; - - const std::shared_ptr &getFragmentShader() const { - return _meshFragmentShader; - } - - const std::shared_ptr &getMeshVertexShader() const { - return _meshVertexShader; - } - - const std::shared_ptr &getSkinMeshVertexShader() const { - return _skinMeshVertexShader; - } - - const std::shared_ptr &getInstancedMeshVertexShader() const { - return _instancedMeshVertexShader; - } - -protected: - std::shared_ptr _meshFragmentShader; - - std::shared_ptr _meshVertexShader; - std::shared_ptr _skinMeshVertexShader; - std::shared_ptr _instancedMeshVertexShader; -}; - -} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp index 2c40045..4e9e940 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp @@ -5,7 +5,6 @@ #include "Device.hpp" #include "FramesRenderer.hpp" #include "RenderPass.hpp" -#include "Scene/Renderer/RendererDefaults.hpp" #include "SwapChain.hpp" namespace Stone::Render::Vulkan { @@ -20,7 +19,6 @@ VulkanRenderer::VulkanRenderer(RendererSettings &settings) : Renderer() { _renderPass = std::make_shared(_device, swapChainProperties.surfaceFormat.format); _swapChain = std::make_shared(_device, _renderPass->getRenderPass(), swapChainProperties); _framesRenderer = std::make_shared(_device, _swapChain->getImageCount()); - _rendererDefaults = std::make_unique(); assert(_framesRenderer->getImageCount() == _swapChain->getImageCount()); } diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp index 19cad24..c185868 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp @@ -21,10 +21,6 @@ void VulkanRenderer::updateDataForWorld(const std::shared_ptr }); } -const Scene::RendererDefaults &VulkanRenderer::getRendererDefaults() const { - return *_rendererDefaults; -} - void VulkanRenderer::renderWorld(const std::shared_ptr &world) { if (!_framesRenderer) { diff --git a/Engine/Scene/include/Scene.hpp b/Engine/Scene/include/Scene.hpp index 40dc375..b4549c2 100644 --- a/Engine/Scene/include/Scene.hpp +++ b/Engine/Scene/include/Scene.hpp @@ -19,7 +19,6 @@ #include "Scene/Renderable/Texture.hpp" #include "Scene/Renderer/ISceneRenderer.hpp" #include "Scene/Renderer/RenderContext.hpp" -#include "Scene/Renderer/RendererDefaults.hpp" #include "Scene/Renderer/RendererObjectManager.hpp" #include "Scene/Transform.hpp" #include "Scene/Vertex.hpp" diff --git a/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp index b1dc093..260bc92 100644 --- a/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp +++ b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp @@ -8,8 +8,6 @@ namespace Stone::Scene { -class RendererDefaults; - /** * @brief Interface for a scene renderer. */ @@ -20,11 +18,6 @@ class ISceneRenderer { */ virtual void updateDataForWorld(const std::shared_ptr &world) = 0; - /** - * @brief Get the renderer defaults. - */ - [[nodiscard]] virtual const RendererDefaults &getRendererDefaults() const = 0; - /** * @brief Request the renderer to render the world from the given world root node. */ diff --git a/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp b/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp deleted file mode 100644 index 17ab055..0000000 --- a/Engine/Scene/include/Scene/Renderer/RendererDefaults.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2024 Stone-Engine - -#pragma once - -#include "SceneTypes.hpp" - -namespace Stone::Scene { - -/** - * @brief Default values for a renderer. - */ -class RendererDefaults { -public: - RendererDefaults(); - RendererDefaults(const RendererDefaults &) = delete; - - virtual ~RendererDefaults() = default; -}; - -} // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp b/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp deleted file mode 100644 index ff3bfb8..0000000 --- a/Engine/Scene/src/Scene/Renderer/RendererDefaults.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2024 Stone-Engine - -#include "Scene/Renderer/RendererDefaults.hpp" - -#include "Scene/Renderable/Material.hpp" - -namespace Stone::Scene { - -RendererDefaults::RendererDefaults() { -} - -} // namespace Stone::Scene From f5e96e27fd0c91af00f36f7fcb7fddcc61ff10de Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 13 Nov 2024 08:43:25 +0100 Subject: [PATCH 38/89] Separate texture header and implementation --- .../src/Render/OpenGL/Renderable/Texture.cpp | 36 ++++++++++++ .../src/Render/OpenGL/Renderable/Texture.hpp | 56 +++++-------------- 2 files changed, 51 insertions(+), 41 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp new file mode 100644 index 0000000..6676ec2 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp @@ -0,0 +1,36 @@ +// Copyright 2024 Stone-Engine + +#include "Texture.hpp" + +namespace Stone::Render::OpenGL { + +GLuint convert(Core::Image::Channel channel) { + switch (channel) { + case Core::Image::Channel::GREY: return GL_RED; + case Core::Image::Channel::DUAL: return GL_RG; + case Core::Image::Channel::RGB: return GL_RGB; + case Core::Image::Channel::RGBA: return GL_RGBA; + default: return GL_RGBA; + } +} + +GLuint convert(Scene::TextureFilter filter, bool mipmap) { + switch (filter) { + case Scene::TextureFilter::Nearest: return mipmap ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; + case Scene::TextureFilter::Linear: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; + case Scene::TextureFilter::Cubic: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; + default: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; + } +} + +GLuint convert(Scene::TextureWrap wrap) { + switch (wrap) { + case Scene::TextureWrap::Repeat: return GL_REPEAT; + case Scene::TextureWrap::MirroredRepeat: return GL_MIRRORED_REPEAT; + case Scene::TextureWrap::ClampToEdge: return GL_CLAMP_TO_EDGE; + case Scene::TextureWrap::ClampToBorder: return GL_CLAMP_TO_BORDER; + default: return GL_REPEAT; + } +} + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp index d218e60..0147b7e 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp @@ -11,40 +11,17 @@ namespace Stone::Render::OpenGL { -GLuint convert(Core::Image::Channel channel) { - switch (channel) { - case Core::Image::Channel::GREY: return GL_RED; - case Core::Image::Channel::DUAL: return GL_RG; - case Core::Image::Channel::RGB: return GL_RGB; - case Core::Image::Channel::RGBA: return GL_RGBA; - default: return GL_RGBA; - } -} - -GLuint convert(Scene::TextureFilter filter, bool mipmap) { - switch (filter) { - case Scene::TextureFilter::Nearest: return mipmap ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; - case Scene::TextureFilter::Linear: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; - case Scene::TextureFilter::Cubic: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; - default: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; - } -} - -GLuint convert(Scene::TextureWrap wrap) { - switch (wrap) { - case Scene::TextureWrap::Repeat: return GL_REPEAT; - case Scene::TextureWrap::MirroredRepeat: return GL_MIRRORED_REPEAT; - case Scene::TextureWrap::ClampToEdge: return GL_CLAMP_TO_EDGE; - case Scene::TextureWrap::ClampToBorder: return GL_CLAMP_TO_BORDER; - default: return GL_REPEAT; - } -} +GLuint convert(Core::Image::Channel channel); + +GLuint convert(Scene::TextureFilter filter, bool mipmap); + +GLuint convert(Scene::TextureWrap wrap); class Texture : public Scene::IRendererObject { public: - Texture(Scene::Texture &texture, const std::shared_ptr &renderer) - : _texture(texture), _renderer(renderer) { + Texture(Scene::Texture &texture, const std::shared_ptr &renderer) : _gl_texture(0) { + (void)renderer; std::shared_ptr imageSource = texture.getImage(); if (imageSource == nullptr) { @@ -55,11 +32,11 @@ class Texture : public Scene::IRendererObject { std::shared_ptr imageData = imageSource->getLoadedImage(); GLuint format = convert(imageData->getChannels()); - glGenTextures(1, &_buffer); - if (_buffer == 0) { + glGenTextures(1, &_gl_texture); + if (_gl_texture == 0) { std::runtime_error("Failed to create texture buffer."); } - glBindTexture(GL_TEXTURE_2D, _buffer); + glBindTexture(GL_TEXTURE_2D, _gl_texture); glTexImage2D(GL_TEXTURE_2D, 0, format, imageData->getSize().x, imageData->getSize().y, 0, format, GL_UNSIGNED_BYTE, imageData->getData()); @@ -72,8 +49,8 @@ class Texture : public Scene::IRendererObject { } ~Texture() override { - if (_buffer != 0) { - glDeleteTextures(1, &_buffer); + if (_gl_texture != 0) { + glDeleteTextures(1, &_gl_texture); } } @@ -81,15 +58,12 @@ class Texture : public Scene::IRendererObject { (void)context; } - GLuint getBuffer() const { - return _buffer; + GLuint getGlTexture() const { + return _gl_texture; } private: - Scene::Texture &_texture; - std::weak_ptr _renderer; - - GLuint _buffer = 0; + GLuint _gl_texture = 0; }; } // namespace Stone::Render::OpenGL From 1defeb0139e828b3feecd7acbdc58da4a88a6ad1 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 13 Nov 2024 08:51:22 +0100 Subject: [PATCH 39/89] fix format --- Engine/Render/src/Render/OpenGL/OpenGLResources.cpp | 3 ++- Engine/Scene/src/Scene/Shader/ShaderParameters.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index 939fc11..961eae7 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -1,8 +1,9 @@ // Copyright 2024 Stone-Engine -#include "Render/OpenGL/OpenGLRenderer.hpp" #include "Render/OpenGL/OpenGLResources.hpp" +#include "Render/OpenGL/OpenGLRenderer.hpp" + namespace Stone::Render::OpenGL { OpenGLResources::OpenGLResources(const std::shared_ptr &renderer) : _renderer(renderer) { diff --git a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp index 49cf4d8..3361caf 100644 --- a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp +++ b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp @@ -13,11 +13,11 @@ ShaderParameters::ShaderParameters() : FOR_EACH_SHADER_PARAMETERS(__INITIALIZE_P void ShaderParameters::setParamWithName(const std::string &name, Type value) { using ParamSetter = std::function; - const static std::unordered_map paramSetters = { #define __MAP_NAME_TO_PARAM(param) \ {#param, [](ShaderParameters &matParams, Type value) { \ matParams.param = value; \ }}, + const static std::unordered_map paramSetters = { FOR_EACH_SHADER_PARAMETERS(__MAP_NAME_TO_PARAM)}; auto it = paramSetters.find(name); From 292287dfc81c955a4a70d54e4660ce9442eb1eb9 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 13 Nov 2024 09:15:01 +0100 Subject: [PATCH 40/89] OpenGL shader uutilities --- .../{Renderable/Shader.cpp => GlShaders.cpp} | 116 +++++++++++++----- Engine/Render/src/Render/OpenGL/GlShaders.hpp | 97 +++++++++++++++ .../OpenGL/Renderable/FragmentShader.hpp | 24 ++++ .../src/Render/OpenGL/Renderable/Shader.hpp | 90 -------------- .../Render/OpenGL/RendererObjectManager.cpp | 2 +- 5 files changed, 210 insertions(+), 119 deletions(-) rename Engine/Render/src/Render/OpenGL/{Renderable/Shader.cpp => GlShaders.cpp} (50%) create mode 100644 Engine/Render/src/Render/OpenGL/GlShaders.hpp create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp delete mode 100644 Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Shader.cpp b/Engine/Render/src/Render/OpenGL/GlShaders.cpp similarity index 50% rename from Engine/Render/src/Render/OpenGL/Renderable/Shader.cpp rename to Engine/Render/src/Render/OpenGL/GlShaders.cpp index c7e437c..6674bb1 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Shader.cpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.cpp @@ -1,6 +1,11 @@ // Copyright 2024 Stone-Engine -#include "Shader.hpp" +#include "GlShaders.hpp" + +#include "Scene/Shader/ShaderGenerator.hpp" + +#include +#include namespace Stone::Render::OpenGL { @@ -75,8 +80,7 @@ uniform mat4 u_mat_view; uniform mat4 u_mat_model; uniform vec3 u_camera_position; -out VS_OUT { - vec4 position; +out FRAG_DATA { vec3 wposition; vec2 uv; vec3 wnormal; @@ -88,7 +92,6 @@ void main() { vs_out.wposition = vec3(u_mat_model * vec4(position, 1.0)); gl_Position = u_mat_projection * u_mat_view * vec4(vs_out.wposition, 1.0); - vs_out.position = gl_Position; vs_out.wnormal = u_mat_normal * normal; vs_out.wtangent = u_mat_normal * tangent; vs_out.wbitangent = u_mat_normal * bitangent; @@ -102,9 +105,11 @@ const char *basicSkinVertexShaderSource = R"shader( layout(location = 0) in vec3 position; layout(location = 1) in vec3 normal; -layout(location = 2) in vec2 uv; -layout(location = 3) in ivec4 boneIDs; -layout(location = 4) in vec4 boneWeights; +layout(location = 2) in vec3 tangent; +layout(location = 3) in vec3 bitangent; +layout(location = 4) in vec2 uv; +layout(location = 5) in vec4 boneWeights; +layout(location = 6) in ivec4 boneIDs; out vec3 fragNormal; out vec2 fragUV; @@ -130,36 +135,91 @@ void main() { )shader"; -const char *basicFragmentShaderSource = R"shader( -#version 400 core +std::unique_ptr GlVertexShader::makeStandardMeshShader() { + auto glShader = std::make_unique(basicVertexShaderSource); + return glShader; +} -out vec4 FragColor; +std::unique_ptr GlVertexShader::makeStandardSkinMeshShader() { + auto glShader = std::make_unique(basicSkinVertexShaderSource); + return glShader; +} -void main() { - FragColor = vec4(1.0, 0.0, 0.0, 1.0); +std::unique_ptr GlVertexShader::makeStandardInstancedMeshShader() { + throw std::runtime_error("Not implemented."); } -)shader"; +std::unique_ptr GlFragmentShader::makeStandardShader(const Scene::ShaderParameters ¶ms) { + std::stringstream source; + Scene::ShaderGenerator generator; + generator.generateFragmentShader(params, source); + return std::make_unique(source.str().c_str()); +} -std::shared_ptr VertexShader::makeStandardMeshShader(const std::shared_ptr &renderer) { - auto sourceShader = std::make_shared(basicVertexShaderSource); - auto glShader = std::make_shared(*sourceShader, renderer); - return glShader; + +GlShaderProgram::GlShaderProgram(const GlVertexShader &vertexShader, const GlFragmentShader &fragmentShader) + : _gl_program(0) { + _gl_program = glCreateProgram(); + glAttachShader(_gl_program, vertexShader.getGLShader()); + glAttachShader(_gl_program, fragmentShader.getGLShader()); + glLinkProgram(_gl_program); + + GLint success; + glGetProgramiv(_gl_program, GL_LINK_STATUS, &success); + if (!success) { + GLint log_length = 0; + glGetProgramiv(_gl_program, GL_INFO_LOG_LENGTH, &log_length); + + std::vector log(log_length); + glGetProgramInfoLog(_gl_program, log_length, &log_length, log.data()); + + glDeleteProgram(_gl_program); + + throw std::runtime_error("Failed to link program: " + std::string(log.data())); + } } -std::shared_ptr -VertexShader::makeStandardSkinMeshShader(const std::shared_ptr &renderer) { - auto sourceShader = std::make_shared(basicSkinVertexShaderSource); - auto glShader = std::make_shared(*sourceShader, renderer); - return glShader; +GlShaderProgram::~GlShaderProgram() { + if (_gl_program != 0) + glDeleteProgram(_gl_program); } -std::shared_ptr -FragmentShader::makeStandardMeshShader(const std::shared_ptr &renderer) { - auto sceneShader = - std::make_shared(Scene::AShader::ContentType::SourceCode, basicFragmentShaderSource); - auto glShader = std::make_shared(*sceneShader, renderer); - return glShader; +GLuint GlShaderProgram::getGlProgram() const { + return _gl_program; +} + +void GlShaderProgram::use() const { + glUseProgram(_gl_program); +} + +GLint GlShaderProgram::getUniformLocation(const std::string &name) const { + return glGetUniformLocation(_gl_program, name.c_str()); +} + +GLint GlShaderProgram::getUniformLocation(const Scene::Material::Location &location) const { + if (std::holds_alternative(location)) { + const std::string &name(std::get(location)); + return getUniformLocation(name); + } else if (std::holds_alternative(location)) { + return std::get(location); + } + return -1; +} + +void GlShaderProgram::setUniform(Scene::Material::Location location, float scalar) const { + glUniform1f(getUniformLocation(location), scalar); +} + +void GlShaderProgram::setUniform(Scene::Material::Location location, const glm::vec3 &vec3) const { + glUniform3fv(getUniformLocation(location), 1, glm::value_ptr(vec3)); +} + +void GlShaderProgram::setUniform(Scene::Material::Location location, const Texture &texture) const { + glUniform1i(getUniformLocation(location), texture.getGlTexture()); +} + +void GlShaderProgram::setUniform(Scene::Material::Location location, const glm::mat4 &mat4) const { + glUniformMatrix4fv(getUniformLocation(location), 1, GL_FALSE, glm::value_ptr(mat4)); } diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.hpp b/Engine/Render/src/Render/OpenGL/GlShaders.hpp new file mode 100644 index 0000000..e84594c --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/GlShaders.hpp @@ -0,0 +1,97 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Renderable/Texture.hpp" +#include "Scene/Renderable/Material.hpp" +#include "Scene/Renderable/Shader.hpp" +#include "Scene/Shader/ShaderParameters.hpp" +#include "Utils/FileSystem.hpp" + +#include + +namespace Stone::Render::OpenGL { + +GLuint compileSource(const std::string &source, GLenum type); + +GLuint loadSpirv(const char *spirv_content, GLsizei spirv_length, GLenum type); + +class GlShaderBase { +public: + GlShaderBase(const Scene::AShader &shader, GLenum type) { + + auto [contentType, content] = shader.getContent(); + + using ContentType = Scene::AShader::ContentType; + switch (contentType) { + case ContentType::SourceCode: _gl_shader = compileSource(content, type); break; + case ContentType::SourceFile: _gl_shader = compileSource(Utils::readTextFile(content), type); break; + case ContentType::CompiledCode: _gl_shader = loadSpirv(content.data(), content.size(), type); break; + case ContentType::CompiledFile: + auto fileContent = Utils::readBinaryFile(content); + _gl_shader = loadSpirv(fileContent.data(), fileContent.size(), type); + break; + } + } + + GlShaderBase(const char *source, GLenum type) { + _gl_shader = compileSource(source, type); + } + + virtual ~GlShaderBase() { + if (_gl_shader != 0) + glDeleteShader(_gl_shader); + } + + GLuint getGLShader() const { + return _gl_shader; + } + +protected: + GLuint _gl_shader = 0; +}; + +class GlVertexShader : public GlShaderBase { +public: + GlVertexShader(const char *source) : GlShaderBase(source, GL_VERTEX_SHADER) { + } + + static std::unique_ptr makeStandardMeshShader(); + static std::unique_ptr makeStandardSkinMeshShader(); + static std::unique_ptr makeStandardInstancedMeshShader(); +}; + +class GlFragmentShader : public GlShaderBase { +public: + GlFragmentShader(const Scene::AShader &shader) : GlShaderBase(shader, GL_FRAGMENT_SHADER) { + } + + GlFragmentShader(const char *source) : GlShaderBase(source, GL_FRAGMENT_SHADER) { + } + + static std::unique_ptr makeStandardShader(const Scene::ShaderParameters ¶ms); +}; + +class GlShaderProgram { +public: + GlShaderProgram(const GlVertexShader &vertexShader, const GlFragmentShader &fragmentShader); + + virtual ~GlShaderProgram(); + + GLuint getGlProgram() const; + + void use() const; + + GLint getUniformLocation(const std::string &name) const; + GLint getUniformLocation(const Scene::Material::Location &location) const; + + void setUniform(Scene::Material::Location location, float scalar) const; + void setUniform(Scene::Material::Location location, const glm::vec3 &vec3) const; + void setUniform(Scene::Material::Location location, const Texture &texture) const; + void setUniform(Scene::Material::Location location, const glm::mat4 &mat4) const; + +private: + GLuint _gl_program; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp b/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp new file mode 100644 index 0000000..0a28d0e --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp @@ -0,0 +1,24 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Renderable/Shader.hpp" + +namespace Stone::Render::OpenGL { + +class FragmentShader : public Scene::IRendererObject { +public: + FragmentShader(Scene::FragmentShader &fragmentShader, const std::shared_ptr &renderer) { + (void)fragmentShader; + (void)renderer; + } + + void render(Scene::RenderContext &context) override { + (void)context; + } + +private: +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp deleted file mode 100644 index 6110781..0000000 --- a/Engine/Render/src/Render/OpenGL/Renderable/Shader.hpp +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2024 Stone-Engine - -#pragma once - -#include "Render/OpenGL/OpenGLRenderer.hpp" -#include "Scene/Renderable/Shader.hpp" -#include "Utils/FileSystem.hpp" - -#include - -namespace Stone::Render::OpenGL { - -GLuint compileSource(const std::string &source, GLenum type); - -GLuint loadSpirv(const char *spirv_content, GLsizei spirv_length, GLenum type); - -class ShaderBase : public Scene::IRendererObject { -public: - ShaderBase(Scene::AShader &shader, const std::shared_ptr &renderer, GLenum type) - : _shader(shader), _renderer(renderer) { - - auto [contentType, content] = shader.getContent(); - - using ContentType = Scene::AShader::ContentType; - switch (contentType) { - case ContentType::SourceCode: _gl_shader = compileSource(content, type); break; - case ContentType::SourceFile: _gl_shader = compileSource(Utils::readTextFile(content), type); break; - case ContentType::CompiledCode: _gl_shader = loadSpirv(content.data(), content.size(), type); break; - case ContentType::CompiledFile: - auto fileContent = Utils::readBinaryFile(content); - _gl_shader = loadSpirv(fileContent.data(), fileContent.size(), type); - break; - } - } - - ~ShaderBase() override { - if (_gl_shader != 0) - glDeleteShader(_gl_shader); - } - - void render(Scene::RenderContext &context) override { - (void)context; - } - - GLuint getGLShader() const { - return _gl_shader; - } - -protected: - Scene::AShader &_shader; - std::weak_ptr _renderer; - - GLuint _gl_shader = 0; -}; - -class SourceVertexShader : public Scene::AShader { - STONE_OBJECT(SourceVertexShader); - -public: - SourceVertexShader(const std::string &source) : Scene::AShader(ContentType::SourceCode, source) { - } - - SourceVertexShader(const SourceVertexShader &other) = delete; - - ~SourceVertexShader() override = default; -}; - -class VertexShader : public ShaderBase { -public: - VertexShader(Scene::AShader &shader, const std::shared_ptr &renderer) - : ShaderBase(shader, renderer, GL_VERTEX_SHADER) { - } - - static std::shared_ptr makeStandardMeshShader(const std::shared_ptr &renderer); - static std::shared_ptr makeStandardSkinMeshShader(const std::shared_ptr &renderer); -}; - -class FragmentShader : public ShaderBase { -public: - FragmentShader(Scene::AShader &shader, const std::shared_ptr &renderer) - : ShaderBase(shader, renderer, GL_FRAGMENT_SHADER) { - } - - static std::shared_ptr makeStandardMeshShader(const std::shared_ptr &renderer); - -protected: -}; - - -} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp b/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp index a2172a1..4aaee7a 100644 --- a/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp +++ b/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp @@ -2,11 +2,11 @@ #include "RendererObjectManager.hpp" +#include "Renderable/FragmentShader.hpp" #include "Renderable/InstancedMeshNode.hpp" #include "Renderable/Material.hpp" #include "Renderable/Mesh.hpp" #include "Renderable/MeshNode.hpp" -#include "Renderable/Shader.hpp" #include "Renderable/SkinMesh.hpp" #include "Renderable/SkinMeshNode.hpp" #include "Renderable/Texture.hpp" From b18aefefc5e751e448e0ff031fc21c5148113942 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 13 Nov 2024 17:59:47 +0100 Subject: [PATCH 41/89] Use shader collection --- .../include/Render/OpenGL/OpenGLRenderer.hpp | 2 +- .../src/Render/OpenGL/OpenGLRenderer.cpp | 2 +- .../src/Render/OpenGL/OpenGLResources.cpp | 53 ++++++++++++- .../src/Render/OpenGL/OpenGLResources.hpp | 23 +++++- .../src/Render/OpenGL/ShaderCollection.cpp | 76 +++++++++++++++++++ .../src/Render/OpenGL/ShaderCollection.hpp | 50 ++++++++++++ .../include/Scene/Renderable/IMeshObject.hpp | 6 ++ 7 files changed, 205 insertions(+), 7 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/ShaderCollection.cpp create mode 100644 Engine/Render/src/Render/OpenGL/ShaderCollection.hpp diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index 9f5f820..1888de0 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -33,7 +33,7 @@ class OpenGLRenderer : public Renderer { private: std::pair _frameSize; - std::unique_ptr _resources; + std::shared_ptr _resources; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index 0d74a7f..578a723 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -60,7 +60,7 @@ void OpenGLRenderer::initialize() { initializeOpenGL(); std::cout << "OpenGLRenderer created" << std::endl; std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; - _resources = std::make_unique(std::static_pointer_cast(shared_from_this())); + _resources = std::make_shared(std::static_pointer_cast(shared_from_this())); } const OpenGLResources &OpenGLRenderer::getOpenGLResources() const { diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index 961eae7..bb69e1b 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -1,13 +1,60 @@ -// Copyright 2024 Stone-Engine +// Copyright 2024 StoneEngine -#include "Render/OpenGL/OpenGLResources.hpp" +#include "OpenGLResources.hpp" -#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Renderable/Material.hpp" +#include "ShaderCollection.hpp" namespace Stone::Render::OpenGL { OpenGLResources::OpenGLResources(const std::shared_ptr &renderer) : _renderer(renderer) { } +const std::unique_ptr &OpenGLResources::getMeshVertexShader() { + if (_meshVertexShader == nullptr) { + _meshVertexShader = GlVertexShader::makeStandardMeshShader(); + } + return _meshVertexShader; +} + +const std::unique_ptr &OpenGLResources::getSkinMeshVertexShader() { + if (_skinMeshVertexShader == nullptr) { + _skinMeshVertexShader = GlVertexShader::makeStandardSkinMeshShader(); + } + return _skinMeshVertexShader; +} + +const std::unique_ptr &OpenGLResources::getInstancedMeshVertexShader() { + if (_instancedMeshVertexShader == nullptr) { + _instancedMeshVertexShader = GlVertexShader::makeStandardInstancedMeshShader(); + } + return _instancedMeshVertexShader; +} + +GlVertexShader *OpenGLResources::getVertexShader(Scene::MeshType meshType) { + switch (meshType) { + case Scene::MeshType::Standard: return getMeshVertexShader().get(); + case Scene::MeshType::Skin: return getSkinMeshVertexShader().get(); + case Scene::MeshType::Instanced: return getInstancedMeshVertexShader().get(); + default: return nullptr; + } +} + + +const std::unique_ptr &OpenGLResources::getFragmentShader(Scene::ShaderParameters params) { + auto it = _fragmentShaders.find(params); + if (it == _fragmentShaders.end()) { + return (_fragmentShaders[params] = GlFragmentShader::makeStandardShader(params)); + } else { + return it->second; + } +} + +const std::unique_ptr &OpenGLResources::getDefaultShaderCollection() { + if (_defaultShaderCollection == nullptr) { + _defaultShaderCollection = std::make_unique(shared_from_this()); + } + return _defaultShaderCollection; +} } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp index 6aecf42..e5352f9 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp @@ -2,13 +2,15 @@ #pragma once -#include +#include "GlShaders.hpp" +#include "Scene/Shader/ShaderParameters.hpp" +#include "ShaderCollection.hpp" namespace Stone::Render::OpenGL { class OpenGLRenderer; -class OpenGLResources { +class OpenGLResources : std::enable_shared_from_this { public: OpenGLResources() = default; @@ -16,8 +18,25 @@ class OpenGLResources { virtual ~OpenGLResources() = default; + const std::unique_ptr &getMeshVertexShader(); + const std::unique_ptr &getSkinMeshVertexShader(); + const std::unique_ptr &getInstancedMeshVertexShader(); + GlVertexShader *getVertexShader(Scene::MeshType meshType); + + const std::unique_ptr &getFragmentShader(Scene::ShaderParameters params); + + const std::unique_ptr &getDefaultShaderCollection(); + private: std::weak_ptr _renderer; + + std::unique_ptr _meshVertexShader; + std::unique_ptr _skinMeshVertexShader; + std::unique_ptr _instancedMeshVertexShader; + + std::unordered_map> _fragmentShaders; + + std::unique_ptr _defaultShaderCollection; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/ShaderCollection.cpp b/Engine/Render/src/Render/OpenGL/ShaderCollection.cpp new file mode 100644 index 0000000..ea40099 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/ShaderCollection.cpp @@ -0,0 +1,76 @@ +// Copyright 2024 Stone-Engine + +#include "ShaderCollection.hpp" + +#include "GlShaders.hpp" +#include "OpenGLResources.hpp" +#include "Render/OpenGL/OpenGLRenderer.hpp" + +namespace Stone::Render::OpenGL { + +void ShaderCollection::makeMeshProgram() { + if (_meshProgram != nullptr) + return; + + assert(_resources.expired() == false); + + auto &vertexShader = _resources.lock()->getMeshVertexShader(); + assert(vertexShader != nullptr); + + _meshProgram = std::make_unique(*vertexShader, *_glFragmentShader); +} + +void ShaderCollection::makeSkinMeshProgram() { + if (_skinMeshProgram != nullptr) + return; + + assert(_resources.expired() == false); + + auto &vertexShader = _resources.lock()->getSkinMeshVertexShader(); + assert(vertexShader != nullptr); + + _skinMeshProgram = std::make_unique(*vertexShader, *_glFragmentShader); +} + +void ShaderCollection::makeInstancedMeshProgram() { + if (_instancedMeshProgram != nullptr) + return; + + assert(_resources.expired() == false); + + auto &vertexShader = _resources.lock()->getInstancedMeshVertexShader(); + assert(vertexShader != nullptr); + + _instancedMeshProgram = std::make_unique(*vertexShader, *_glFragmentShader); +} + +void ShaderCollection::makeProgram(Scene::MeshType meshType) { + switch (meshType) { + case Scene::MeshType::Standard: makeMeshProgram(); break; + case Scene::MeshType::Skin: makeSkinMeshProgram(); break; + case Scene::MeshType::Instanced: makeInstancedMeshProgram(); break; + } +} + +const std::unique_ptr &ShaderCollection::getMeshProgram() const { + return _meshProgram; +} + +const std::unique_ptr &ShaderCollection::getSkinMeshProgram() const { + return _skinMeshProgram; +} + +const std::unique_ptr &ShaderCollection::getInstancedMeshProgram() const { + return _instancedMeshProgram; +} + +GlShaderProgram *ShaderCollection::getProgram(Scene::MeshType meshType) const { + switch (meshType) { + case Scene::MeshType::Standard: return _meshProgram.get(); + case Scene::MeshType::Skin: return _skinMeshProgram.get(); + case Scene::MeshType::Instanced: return _instancedMeshProgram.get(); + } + return nullptr; +} + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/ShaderCollection.hpp b/Engine/Render/src/Render/OpenGL/ShaderCollection.hpp new file mode 100644 index 0000000..9c9e791 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/ShaderCollection.hpp @@ -0,0 +1,50 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "GlShaders.hpp" +#include "Scene/Renderable/Material.hpp" +#include "Scene/Renderable/Shader.hpp" + +namespace Stone::Render::OpenGL { + +class ShaderCollection { +public: + ShaderCollection(const std::shared_ptr &resources) : _resources(resources) { + Scene::ShaderParameters params; + _glFragmentShader = GlFragmentShader::makeStandardShader(params); + } + + ShaderCollection(Scene::FragmentShader &shader, const std::shared_ptr &resources) + : _resources(resources) { + _glFragmentShader = std::make_unique(shader); + } + + ShaderCollection(Scene::Material &material, const std::shared_ptr &Resources) + : _resources(Resources) { + Scene::ShaderParameters params; + params.setFromMaterial(material); + _glFragmentShader = GlFragmentShader::makeStandardShader(params); + } + + void makeMeshProgram(); + void makeSkinMeshProgram(); + void makeInstancedMeshProgram(); + void makeProgram(Scene::MeshType meshType); + + const std::unique_ptr &getMeshProgram() const; + const std::unique_ptr &getSkinMeshProgram() const; + const std::unique_ptr &getInstancedMeshProgram() const; + GlShaderProgram *getProgram(Scene::MeshType meshType) const; + +protected: + std::weak_ptr _resources; + + std::unique_ptr _meshProgram = nullptr; + std::unique_ptr _skinMeshProgram = nullptr; + std::unique_ptr _instancedMeshProgram = nullptr; + + std::unique_ptr _glFragmentShader; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Scene/include/Scene/Renderable/IMeshObject.hpp b/Engine/Scene/include/Scene/Renderable/IMeshObject.hpp index 51d708a..d7d727d 100644 --- a/Engine/Scene/include/Scene/Renderable/IMeshObject.hpp +++ b/Engine/Scene/include/Scene/Renderable/IMeshObject.hpp @@ -9,6 +9,12 @@ namespace Stone::Scene { class Material; +enum class MeshType : uint8_t { + Standard = 0, + Skin = 1, + Instanced = 2, +}; + /** * @brief Interface for a mesh object of any type. * From 78f479dea442a88dac4c1a10464e4d33c38dbea8 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 13 Nov 2024 19:16:14 +0100 Subject: [PATCH 42/89] Gbuffer structure for render pipeline --- .../include/Render/OpenGL/OpenGLRenderer.hpp | 2 + Engine/Render/src/Render/OpenGL/GBuffer.hpp | 54 +++++++++++++++++++ Engine/Render/src/Render/OpenGL/GlShaders.cpp | 1 + .../src/Render/OpenGL/OpenGLRenderer.cpp | 26 ++++++--- .../src/Render/OpenGL/RenderContext.hpp | 5 +- 5 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/GBuffer.hpp diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index 1888de0..878de82 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -12,6 +12,7 @@ class WorldNode; namespace Stone::Render::OpenGL { class OpenGLResources; +struct GBuffer; class OpenGLRenderer : public Renderer { public: @@ -34,6 +35,7 @@ class OpenGLRenderer : public Renderer { private: std::pair _frameSize; std::shared_ptr _resources; + std::unique_ptr _gBuffer; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GBuffer.hpp b/Engine/Render/src/Render/OpenGL/GBuffer.hpp new file mode 100644 index 0000000..9534c49 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/GBuffer.hpp @@ -0,0 +1,54 @@ +// Copyright 2024 StoneEngine + +#include + +namespace Stone::Render::OpenGL { + +struct GBuffer { + + GBuffer(unsigned int width, unsigned int height) : width(width), height(height) { + glGenFramebuffers(1, &gBuffer); + glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); + + glGenTextures(1, &gPosition); + glBindTexture(GL_TEXTURE_2D, gPosition); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0); + + glGenTextures(1, &gNormal); + glBindTexture(GL_TEXTURE_2D, gNormal); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormal, 0); + + glGenTextures(1, &gAlbedoSpec); + glBindTexture(GL_TEXTURE_2D, gAlbedoSpec); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gAlbedoSpec, 0); + + unsigned int attachments[3] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2}; + glDrawBuffers(3, attachments); + } + + ~GBuffer() { + glDeleteFramebuffers(1, &gBuffer); + glDeleteTextures(1, &gPosition); + glDeleteTextures(1, &gNormal); + glDeleteTextures(1, &gAlbedoSpec); + } + + unsigned int width; + unsigned int height; + + GLuint gBuffer; + GLuint gPosition; + GLuint gNormal; + GLuint gAlbedoSpec; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlShaders.cpp index 6674bb1..70e8c7c 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.cpp @@ -214,6 +214,7 @@ void GlShaderProgram::setUniform(Scene::Material::Location location, const glm:: glUniform3fv(getUniformLocation(location), 1, glm::value_ptr(vec3)); } +// FIXME: Implement a real way to bind textures to the shader void GlShaderProgram::setUniform(Scene::Material::Location location, const Texture &texture) const { glUniform1i(getUniformLocation(location), texture.getGlTexture()); } diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index 578a723..b5c7284 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -15,17 +15,18 @@ namespace Stone::Render::OpenGL { static void initializeOpenGL() { static bool initialized = false; - if (!initialized) { - glewExperimental = true; - if (glewInit() != GLEW_OK) { - throw std::runtime_error("Failed to initialize GLEW"); - } - initialized = true; + if (initialized) + return; + + glewExperimental = true; + if (glewInit() != GLEW_OK) { + throw std::runtime_error("Failed to initialize GLEW"); } + initialized = true; } -OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) - : Renderer(), _frameSize(settings.frame_size), _resources(nullptr) { +OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) : Renderer(), _frameSize(), _resources(nullptr) { + updateFrameSize(settings.frame_size); } OpenGLRenderer::~OpenGLRenderer() { @@ -43,17 +44,26 @@ void OpenGLRenderer::updateDataForWorld(const std::shared_ptr } void OpenGLRenderer::renderWorld(const std::shared_ptr &world) { + + // Reset framebuffers + glViewport(0, 0, static_cast(_frameSize.first), static_cast(_frameSize.second)); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); OpenGL::RenderContext context; + context.renderer = std::static_pointer_cast(shared_from_this()); + context.gBuffer = _gBuffer.get(); + world->initializeRenderContext(context); world->render(context); } void OpenGLRenderer::updateFrameSize(std::pair size) { _frameSize = size; + if (_gBuffer) + _gBuffer.reset(); + _gBuffer = std::make_unique(_frameSize.first, _frameSize.second); } void OpenGLRenderer::initialize() { diff --git a/Engine/Render/src/Render/OpenGL/RenderContext.hpp b/Engine/Render/src/Render/OpenGL/RenderContext.hpp index 53c1856..425deb5 100644 --- a/Engine/Render/src/Render/OpenGL/RenderContext.hpp +++ b/Engine/Render/src/Render/OpenGL/RenderContext.hpp @@ -2,6 +2,7 @@ #pragma once +#include "GBuffer.hpp" #include "Scene/Renderer/RenderContext.hpp" #include @@ -10,6 +11,8 @@ namespace Stone::Render::OpenGL { class OpenGLRenderer; -struct RenderContext : public Scene::RenderContext {}; +struct RenderContext : public Scene::RenderContext { + GBuffer *gBuffer; +}; } // namespace Stone::Render::OpenGL From e7843a3a3880209e45c93e3148f1212510a4f84c Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 13 Nov 2024 23:13:01 +0100 Subject: [PATCH 43/89] Fragment shader using shader collection --- Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp | 2 +- Engine/Render/src/Render/OpenGL/GlShaders.cpp | 8 ++++---- Engine/Render/src/Render/OpenGL/GlShaders.hpp | 8 ++++---- Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp | 4 ++-- .../src/Render/OpenGL/Renderable/FragmentShader.hpp | 9 +++++++-- Engine/Scene/src/Scene/Shader/ShaderParameters.cpp | 9 ++++++--- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index 878de82..74e9189 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -30,7 +30,7 @@ class OpenGLRenderer : public Renderer { void updateFrameSize(std::pair size) override; void initialize(); - const OpenGLResources &getOpenGLResources() const; + const std::shared_ptr &getOpenGLResources() const; private: std::pair _frameSize; diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlShaders.cpp index 70e8c7c..9f73746 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.cpp @@ -206,20 +206,20 @@ GLint GlShaderProgram::getUniformLocation(const Scene::Material::Location &locat return -1; } -void GlShaderProgram::setUniform(Scene::Material::Location location, float scalar) const { +void GlShaderProgram::setUniform(const Scene::Material::Location &location, float scalar) const { glUniform1f(getUniformLocation(location), scalar); } -void GlShaderProgram::setUniform(Scene::Material::Location location, const glm::vec3 &vec3) const { +void GlShaderProgram::setUniform(const Scene::Material::Location &location, const glm::vec3 &vec3) const { glUniform3fv(getUniformLocation(location), 1, glm::value_ptr(vec3)); } // FIXME: Implement a real way to bind textures to the shader -void GlShaderProgram::setUniform(Scene::Material::Location location, const Texture &texture) const { +void GlShaderProgram::setUniform(const Scene::Material::Location &location, const Texture &texture) const { glUniform1i(getUniformLocation(location), texture.getGlTexture()); } -void GlShaderProgram::setUniform(Scene::Material::Location location, const glm::mat4 &mat4) const { +void GlShaderProgram::setUniform(const Scene::Material::Location &location, const glm::mat4 &mat4) const { glUniformMatrix4fv(getUniformLocation(location), 1, GL_FALSE, glm::value_ptr(mat4)); } diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.hpp b/Engine/Render/src/Render/OpenGL/GlShaders.hpp index e84594c..9fd108f 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.hpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.hpp @@ -85,10 +85,10 @@ class GlShaderProgram { GLint getUniformLocation(const std::string &name) const; GLint getUniformLocation(const Scene::Material::Location &location) const; - void setUniform(Scene::Material::Location location, float scalar) const; - void setUniform(Scene::Material::Location location, const glm::vec3 &vec3) const; - void setUniform(Scene::Material::Location location, const Texture &texture) const; - void setUniform(Scene::Material::Location location, const glm::mat4 &mat4) const; + void setUniform(const Scene::Material::Location &location, float scalar) const; + void setUniform(const Scene::Material::Location &location, const glm::vec3 &vec3) const; + void setUniform(const Scene::Material::Location &location, const Texture &texture) const; + void setUniform(const Scene::Material::Location &location, const glm::mat4 &mat4) const; private: GLuint _gl_program; diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index b5c7284..b956c01 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -73,8 +73,8 @@ void OpenGLRenderer::initialize() { _resources = std::make_shared(std::static_pointer_cast(shared_from_this())); } -const OpenGLResources &OpenGLRenderer::getOpenGLResources() const { - return *_resources; +const std::shared_ptr &OpenGLRenderer::getOpenGLResources() const { + return _resources; } diff --git a/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp b/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp index 0a28d0e..d198992 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp @@ -2,6 +2,7 @@ #pragma once +#include "../ShaderCollection.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Shader.hpp" @@ -10,15 +11,19 @@ namespace Stone::Render::OpenGL { class FragmentShader : public Scene::IRendererObject { public: FragmentShader(Scene::FragmentShader &fragmentShader, const std::shared_ptr &renderer) { - (void)fragmentShader; - (void)renderer; + _shaderCollection = std::make_shared(fragmentShader, renderer->getOpenGLResources()); } void render(Scene::RenderContext &context) override { (void)context; } + const std::shared_ptr &getShaderCollection() const { + return _shaderCollection; + } + private: + std::shared_ptr _shaderCollection; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp index 3361caf..73f0f52 100644 --- a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp +++ b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp @@ -14,9 +14,12 @@ void ShaderParameters::setParamWithName(const std::string &name, Type value) { using ParamSetter = std::function; #define __MAP_NAME_TO_PARAM(param) \ - {#param, [](ShaderParameters &matParams, Type value) { \ - matParams.param = value; \ - }}, + { \ + #param, [](ShaderParameters &matParams, Type value) { \ + matParams.param = value; \ + } \ + } \ + , const static std::unordered_map paramSetters = { FOR_EACH_SHADER_PARAMETERS(__MAP_NAME_TO_PARAM)}; From f83376efa337b0aace6ad2553d3679229827b74b Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 13 Nov 2024 23:46:01 +0100 Subject: [PATCH 44/89] opengl make material use shader collection --- Engine/Render/src/Render/OpenGL/GBuffer.hpp | 2 +- .../src/Render/OpenGL/OpenGLResources.cpp | 2 +- .../src/Render/OpenGL/RenderContext.hpp | 2 +- .../src/Render/OpenGL/Renderable/Material.cpp | 33 ++++++++++++++++ .../src/Render/OpenGL/Renderable/Material.hpp | 38 +++++++------------ .../src/Render/Vulkan/RenderContext.hpp | 2 +- 6 files changed, 50 insertions(+), 29 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/Material.cpp diff --git a/Engine/Render/src/Render/OpenGL/GBuffer.hpp b/Engine/Render/src/Render/OpenGL/GBuffer.hpp index 9534c49..7365453 100644 --- a/Engine/Render/src/Render/OpenGL/GBuffer.hpp +++ b/Engine/Render/src/Render/OpenGL/GBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright 2024 StoneEngine +// Copyright 2024 Stone-Engine #include diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index bb69e1b..b430e84 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -1,4 +1,4 @@ -// Copyright 2024 StoneEngine +// Copyright 2024 Stone-Engine #include "OpenGLResources.hpp" diff --git a/Engine/Render/src/Render/OpenGL/RenderContext.hpp b/Engine/Render/src/Render/OpenGL/RenderContext.hpp index 425deb5..509cd1e 100644 --- a/Engine/Render/src/Render/OpenGL/RenderContext.hpp +++ b/Engine/Render/src/Render/OpenGL/RenderContext.hpp @@ -1,4 +1,4 @@ -// Copyright 2024 StoneEngine +// Copyright 2024 Stone-Engine #pragma once diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp new file mode 100644 index 0000000..1ca18bd --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp @@ -0,0 +1,33 @@ +// Copyright 2024 Stone-Engine + +#include "Material.hpp" + +#include "FragmentShader.hpp" + +namespace Stone::Render::OpenGL { + +Material::Material(Scene::Material &material, const std::shared_ptr &renderer) : _material(material) { + if (_material.getFragmentShader() == nullptr) { + _shaderCollection = std::make_shared(material, renderer->getOpenGLResources()); + } else { + _shaderCollection = _material.getFragmentShader()->getRendererObject()->getShaderCollection(); + } +} + +void Material::render(Scene::RenderContext &context) { + (void)context; +} + +void Material::setUniforms(Scene::MeshType meshType) { + GlShaderProgram *program = _shaderCollection->getProgram(meshType); + + _material.forEachVectors([program](const auto &loc, glm::vec3 vec) { program->setUniform(loc, vec); }); + _material.forEachScalars([program](const auto &loc, float scalar) { program->setUniform(loc, scalar); }); +} + +const std::shared_ptr &Material::getShaderCollection() const { + return _shaderCollection; +} + + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp index 15fe8aa..c453b9e 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp @@ -3,42 +3,30 @@ #pragma once #include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Renderable/IMeshObject.hpp" #include "Scene/Renderable/Material.hpp" #include -#include -#include namespace Stone::Render::OpenGL { +class ShaderCollection; + class Material : public Scene::IRendererObject { public: - Material(Scene::Material &material, const std::shared_ptr &renderer) - : _material(material), _renderer(renderer) { - } - - ~Material() override { - if (_gl_meshProgram != 0) - glDeleteProgram(_gl_meshProgram); - if (_gl_skinMeshProgram != 0) - glDeleteProgram(_gl_skinMeshProgram); - if (_gl_instancedMeshProgram != 0) - glDeleteProgram(_gl_instancedMeshProgram); - } - - void render(Scene::RenderContext &context) override { - (void)context; - } + Material(Scene::Material &material, const std::shared_ptr &renderer); -private: - Scene::Material &_material; - std::weak_ptr _renderer; + ~Material() override = default; + + void render(Scene::RenderContext &context) override; - GLuint _gl_meshProgram = 0; - GLuint _gl_skinMeshProgram = 0; - GLuint _gl_instancedMeshProgram = 0; + void setUniforms(Scene::MeshType meshType); - GLuint _lastUsedProgram = 0; + const std::shared_ptr &getShaderCollection() const; + +private: + Scene::Material &_material; + std::shared_ptr _shaderCollection; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/Vulkan/RenderContext.hpp b/Engine/Render/src/Render/Vulkan/RenderContext.hpp index ec5f831..a3611d8 100644 --- a/Engine/Render/src/Render/Vulkan/RenderContext.hpp +++ b/Engine/Render/src/Render/Vulkan/RenderContext.hpp @@ -1,4 +1,4 @@ -// Copyright 2024 StoneEngine +// Copyright 2024 Stone-Engine #pragma once From 77d891687789a38be38b43a6220549647d75945b Mon Sep 17 00:00:00 2001 From: amasson Date: Thu, 14 Nov 2024 00:37:51 +0100 Subject: [PATCH 45/89] opengl mesh node pipeline --- .../src/Render/OpenGL/Renderable/MeshNode.cpp | 68 +++++++++++++++++++ .../src/Render/OpenGL/Renderable/MeshNode.hpp | 55 +++------------ 2 files changed, 76 insertions(+), 47 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp new file mode 100644 index 0000000..ada15b2 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp @@ -0,0 +1,68 @@ +// Copyright 2024 Stone-Engine + +#include "MeshNode.hpp" + +#include "../OpenGLResources.hpp" +#include "Material.hpp" +#include "Mesh.hpp" +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Renderable/Mesh.hpp" + +#include + +namespace Stone::Render::OpenGL { + +MeshNode::MeshNode(Scene::MeshNode &meshNode, const std::shared_ptr &renderer) + : _meshNode(meshNode), _material(nullptr), _shaderCollection(nullptr) { + + if (_meshNode.getMaterial() != nullptr) { + assert(_meshNode.getMaterial()->isDirty() == false); + _material = _meshNode.getMaterial()->getRendererObject().get(); + } else if (_meshNode.getMesh() != nullptr && _meshNode.getMesh()->getDefaultMaterial() != nullptr) { + assert(_meshNode.getMesh()->getDefaultMaterial()->isDirty() == false); + _material = _meshNode.getMesh()->getDefaultMaterial()->getRendererObject().get(); + } + assert(_material != nullptr); + + if (_material != nullptr) { + _shaderCollection = _material->getShaderCollection().get(); + } else { + _shaderCollection = renderer->getOpenGLResources()->getDefaultShaderCollection().get(); + } + assert(_shaderCollection != nullptr); + + _shaderCollection->makeMeshProgram(); +} + +void MeshNode::render(Scene::RenderContext &context) { + auto mesh = _meshNode.getMesh(); + if (mesh == nullptr) + return; + + auto rendererMesh = mesh->getRendererObject(); + if (rendererMesh == nullptr) { + return; + } + const VRAMMesh &vramMesh = rendererMesh->getVRAMMesh(); + + GlShaderProgram *program = _shaderCollection->getMeshProgram().get(); + program->use(); + + if (_material != nullptr) { + _material->setUniforms(Scene::MeshType::Standard); + } + + program->setUniform("model", context.mvp.modelMatrix); + program->setUniform("view", context.mvp.viewMatrix); + program->setUniform("projection", context.mvp.projMatrix); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + glBindVertexArray(vramMesh.elementsBuffer); + glDrawElements(GL_TRIANGLES, vramMesh.numIndices, GL_UNSIGNED_INT, nullptr); +} + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp index 294830b..57cbbfd 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp @@ -2,65 +2,26 @@ #pragma once -#include "../OpenGLResources.hpp" -#include "Material.hpp" -#include "Mesh.hpp" -#include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Node/MeshNode.hpp" -#include "Scene/Renderable/Mesh.hpp" - -#include namespace Stone::Render::OpenGL { +class Material; +class OpenGLRenderer; +class ShaderCollection; + class MeshNode : public Scene::IRendererObject { public: - MeshNode(Scene::MeshNode &meshNode, const std::shared_ptr &renderer) - : _meshNode(meshNode), _renderer(renderer) { - - std::shared_ptr usedMaterial = - meshNode.getMaterial() ? meshNode.getMaterial() - : meshNode.getMesh() != nullptr && meshNode.getMesh()->getDefaultMaterial() != nullptr - ? meshNode.getMesh()->getDefaultMaterial() - : nullptr; - } + MeshNode(Scene::MeshNode &meshNode, const std::shared_ptr &renderer); ~MeshNode() override = default; - void render(Scene::RenderContext &context) override { - auto mesh = _meshNode.getMesh(); - if (mesh == nullptr) - return; - - auto rendererMesh = mesh->getRendererObject(); - if (rendererMesh == nullptr) { - return; - } - const VRAMMesh &vramMesh = rendererMesh->getVRAMMesh(); - - std::shared_ptr sceneMaterial = _meshNode.getMaterial() ? _meshNode.getMaterial() - : mesh->getDefaultMaterial() ? mesh->getDefaultMaterial() - : nullptr; - - assert(sceneMaterial != nullptr); - assert(sceneMaterial->isDirty() == false); - - std::shared_ptr material = sceneMaterial->getRendererObject(); - - material->render(context); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - - glBindVertexArray(vramMesh.elementsBuffer); - glDrawElements(GL_TRIANGLES, vramMesh.numIndices, GL_UNSIGNED_INT, 0); - } + void render(Scene::RenderContext &context) override; private: Scene::MeshNode &_meshNode; - std::weak_ptr _renderer; + Material *_material; + ShaderCollection *_shaderCollection; }; } // namespace Stone::Render::OpenGL From 251b8dbaede7736477907e662ebd996095162f17 Mon Sep 17 00:00:00 2001 From: amasson Date: Fri, 15 Nov 2024 16:49:19 +0100 Subject: [PATCH 46/89] use children list #74 --- Engine/Scene/src/Scene/Node/Node.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Engine/Scene/src/Scene/Node/Node.cpp b/Engine/Scene/src/Scene/Node/Node.cpp index 61844fa..4edc00d 100644 --- a/Engine/Scene/src/Scene/Node/Node.cpp +++ b/Engine/Scene/src/Scene/Node/Node.cpp @@ -251,9 +251,8 @@ void Node::writeHierarchy(std::ostream &stream, bool colored, const std::string stream << _name << " [" << getClassName() << "] "; } stream << *this << std::endl; - std::list> children; - const auto last = children.back(); - for (auto &child : children) { + const auto last = _children.back(); + for (auto &child : _children) { if (child == last) { child->writeHierarchy(stream, colored, linePrefix + lastPrefix, "└─", " "); } else { From 1e2df6074e47ac0bf3b0e2d51b86e1905d71fad9 Mon Sep 17 00:00:00 2001 From: amasson Date: Fri, 15 Nov 2024 17:42:11 +0100 Subject: [PATCH 47/89] Use texture with program indices --- Engine/Render/src/Render/OpenGL/GlShaders.cpp | 13 +++++++----- Engine/Render/src/Render/OpenGL/GlShaders.hpp | 2 +- .../src/Render/OpenGL/Renderable/Material.cpp | 21 +++++++++++++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlShaders.cpp index 9f73746..a53bf11 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.cpp @@ -214,14 +214,17 @@ void GlShaderProgram::setUniform(const Scene::Material::Location &location, cons glUniform3fv(getUniformLocation(location), 1, glm::value_ptr(vec3)); } -// FIXME: Implement a real way to bind textures to the shader -void GlShaderProgram::setUniform(const Scene::Material::Location &location, const Texture &texture) const { - glUniform1i(getUniformLocation(location), texture.getGlTexture()); -} - void GlShaderProgram::setUniform(const Scene::Material::Location &location, const glm::mat4 &mat4) const { glUniformMatrix4fv(getUniformLocation(location), 1, GL_FALSE, glm::value_ptr(mat4)); } +void GlShaderProgram::setUniformTexture(const Scene::Material::Location &location, const Texture &texture, + int textureIndex) const { + assert(textureIndex >= 0 && textureIndex < 32); + glActiveTexture(GL_TEXTURE0 + textureIndex); + glBindTexture(GL_TEXTURE_2D, texture.getGlTexture()); + glUniform1i(getUniformLocation(location), texture.getGlTexture()); +} + } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.hpp b/Engine/Render/src/Render/OpenGL/GlShaders.hpp index 9fd108f..6e6f890 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.hpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.hpp @@ -87,8 +87,8 @@ class GlShaderProgram { void setUniform(const Scene::Material::Location &location, float scalar) const; void setUniform(const Scene::Material::Location &location, const glm::vec3 &vec3) const; - void setUniform(const Scene::Material::Location &location, const Texture &texture) const; void setUniform(const Scene::Material::Location &location, const glm::mat4 &mat4) const; + void setUniformTexture(const Scene::Material::Location &location, const Texture &texture, int textureIndex) const; private: GLuint _gl_program; diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp index 1ca18bd..a4b1ca1 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp @@ -12,6 +12,15 @@ Material::Material(Scene::Material &material, const std::shared_ptrgetRendererObject()->getShaderCollection(); } + +#ifndef NDEBUG + int textureCount = 0; + material.forEachTextures([&textureCount](auto, auto) { ++textureCount; }); + if (textureCount >= 32) { + // TODO: Use log module + std::cerr << "Material " << material.getId() << " has more than 32 textures" << std::endl; + } +#endif } void Material::render(Scene::RenderContext &context) { @@ -23,6 +32,18 @@ void Material::setUniforms(Scene::MeshType meshType) { _material.forEachVectors([program](const auto &loc, glm::vec3 vec) { program->setUniform(loc, vec); }); _material.forEachScalars([program](const auto &loc, float scalar) { program->setUniform(loc, scalar); }); + + int textureIndex = 0; + _material.forEachTextures( + [program, &textureIndex](const auto &loc, const std::shared_ptr &texture) { + if (textureIndex >= 32) + return; + + assert(texture->isDirty() == false); + auto rendererTexture = texture->getRendererObject(); + program->setUniformTexture(loc, *rendererTexture, textureIndex); + ++textureIndex; + }); } const std::shared_ptr &Material::getShaderCollection() const { From 7e4269998e5c0d00d8c3d8713594f6c4774a437c Mon Sep 17 00:00:00 2001 From: amasson Date: Thu, 28 Nov 2024 08:46:30 +0100 Subject: [PATCH 48/89] Fix glsl_generator json usage --- Engine/Scene/src/Scene/Node/Node.cpp | 1 - examples/glsl_generator/main.cpp | 16 +++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Engine/Scene/src/Scene/Node/Node.cpp b/Engine/Scene/src/Scene/Node/Node.cpp index 904991e..918429b 100644 --- a/Engine/Scene/src/Scene/Node/Node.cpp +++ b/Engine/Scene/src/Scene/Node/Node.cpp @@ -6,7 +6,6 @@ #include #include -#include namespace Stone::Scene { diff --git a/examples/glsl_generator/main.cpp b/examples/glsl_generator/main.cpp index d681b88..b32e409 100644 --- a/examples/glsl_generator/main.cpp +++ b/examples/glsl_generator/main.cpp @@ -19,10 +19,10 @@ static time_t getLastmodifiedTimeOfFile(const char *filename) { throw std::runtime_error("File does not exist"); } -Stone::Scene::ShaderParameters parseShaderParameters(const Stone::Json::Value &json) { +Stone::Scene::ShaderParameters parseShaderParameters(const Json::Value &json) { Stone::Scene::ShaderParameters params; - auto ¶ms_obj = json.get(); + auto ¶ms_obj = json.get(); for (auto [key, value] : params_obj) { Stone::Scene::ShaderParameters::Type type; @@ -56,8 +56,8 @@ std::string to_string(Stone::Scene::ShaderParameters::Type type) { void generateShaderOutput(const char *input_file, const char *output_file) { - Stone::Json::Value input_json; - Stone::Json::Value::parseFile(input_file, input_json); + Json::Value input_json; + Json::parseFile(input_file, input_json); std::ofstream output_stream(output_file, std::ios::out | std::ios::trunc); @@ -83,9 +83,15 @@ void generateShader() { } } +void printUsage() { + std::cout << "Usage: glsl_generator [-f]" << std::endl; +} + int main(int argc, const char *argv[]) { - if (argc < 3) + if (argc < 3) { + printUsage(); return 1; + } input = argv[1]; output = argv[2]; From d01d0765a1f660d12994b4806c338a25458733ee Mon Sep 17 00:00:00 2001 From: amasson Date: Fri, 29 Nov 2024 16:50:12 +0100 Subject: [PATCH 49/89] Move gbuffer textures as Texture --- Engine/Render/src/Render/OpenGL/GBuffer.hpp | 100 +++++++++++++----- .../src/Render/OpenGL/GlFramebuffer.hpp | 65 ++++++++++++ Engine/Render/src/Render/OpenGL/GlShaders.cpp | 2 +- .../src/Render/OpenGL/OpenGLRenderer.cpp | 11 +- .../src/Render/OpenGL/Renderable/Texture.hpp | 13 +++ 5 files changed, 161 insertions(+), 30 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/GlFramebuffer.hpp diff --git a/Engine/Render/src/Render/OpenGL/GBuffer.hpp b/Engine/Render/src/Render/OpenGL/GBuffer.hpp index 7365453..0cdd151 100644 --- a/Engine/Render/src/Render/OpenGL/GBuffer.hpp +++ b/Engine/Render/src/Render/OpenGL/GBuffer.hpp @@ -1,5 +1,11 @@ // Copyright 2024 Stone-Engine +#pragma once + +#include "GlFramebuffer.hpp" +#include "GlShaders.hpp" +#include "Renderable/Texture.hpp" + #include namespace Stone::Render::OpenGL { @@ -10,45 +16,85 @@ struct GBuffer { glGenFramebuffers(1, &gBuffer); glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); - glGenTextures(1, &gPosition); - glBindTexture(GL_TEXTURE_2D, gPosition); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0); - - glGenTextures(1, &gNormal); - glBindTexture(GL_TEXTURE_2D, gNormal); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormal, 0); - - glGenTextures(1, &gAlbedoSpec); - glBindTexture(GL_TEXTURE_2D, gAlbedoSpec); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gAlbedoSpec, 0); + gPosition = std::make_unique(width, height, GL_RGB16F, GL_RGB, GL_FLOAT, GL_CLAMP_TO_EDGE, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition->getGlTexture(), 0); + + gNormal = std::make_unique(width, height, GL_RGB16F, GL_RGB, GL_FLOAT, GL_CLAMP_TO_EDGE, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormal->getGlTexture(), 0); + + gAlbedoSpec = + std::make_unique(width, height, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GL_CLAMP_TO_EDGE, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gAlbedoSpec->getGlTexture(), 0); unsigned int attachments[3] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2}; glDrawBuffers(3, attachments); + + GlVertexShader vertexShader(R"(#version 400 core + +layout (location = 0) in vec2 position; +layout (location = 1) in vec2 uv; + +out vec2 fragUV; + +void main() { + gl_Position = vec4(position, 0.0, 1.0); + fragUV = uv; +} + +)"); + + GlFragmentShader fragmentShader(R"(#version 400 core + +in vec2 fragUV; + +uniform sampler2D u_position; +uniform sampler2D u_normal; +uniform sampler2D u_albedo_spec; + +out vec4 FragColor; + +void main() { + FragColor = vec4(fragUV, 1.0, 1.0); +} + +)"); + + program = std::make_shared(vertexShader, fragmentShader); + + frameMesh = std::make_shared(); } - ~GBuffer() { + virtual ~GBuffer() { glDeleteFramebuffers(1, &gBuffer); - glDeleteTextures(1, &gPosition); - glDeleteTextures(1, &gNormal); - glDeleteTextures(1, &gAlbedoSpec); + } + + void bind() { + glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); + } + + void render() { + program->use(); + + program->setUniformTexture("u_position", *gPosition, 0); + program->setUniformTexture("u_normal", *gNormal, 1); + program->setUniformTexture("u_albedo_spec", *gAlbedoSpec, 2); + + frameMesh->draw(); } unsigned int width; unsigned int height; GLuint gBuffer; - GLuint gPosition; - GLuint gNormal; - GLuint gAlbedoSpec; + + std::unique_ptr gPosition; + std::unique_ptr gNormal; + std::unique_ptr gAlbedoSpec; + + + std::shared_ptr frameMesh; + + std::shared_ptr program; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GlFramebuffer.hpp b/Engine/Render/src/Render/OpenGL/GlFramebuffer.hpp new file mode 100644 index 0000000..30f0bc6 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/GlFramebuffer.hpp @@ -0,0 +1,65 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include + +namespace Stone::Render::OpenGL { + +class GlFramebufferMesh { +public: + GlFramebufferMesh() { + float vertices[] = { + // positions // texture coords + 1.0f, 1.0f, 1.0f, 1.0f, // top right + 1.0f, -1.0f, 1.0f, 0.0f, // bottom right + -1.0f, -1.0f, 0.0f, 0.0f, // bottom left + -1.0f, 1.0f, 0.0f, 1.0f // top left + }; + + unsigned int indices[] = { + 0, 1, 3, // first triangle + 1, 2, 3 // second triangle + }; + + glGenVertexArrays(1, &vao); + glGenBuffers(1, &vbo); + glGenBuffers(1, &ebo); + + glBindVertexArray(vao); + + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + // position attribute + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)0); + glEnableVertexAttribArray(0); + // texture coord attribute + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)(2 * sizeof(float))); + glEnableVertexAttribArray(1); + + glBindVertexArray(0); + } + + virtual ~GlFramebufferMesh() { + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); + glDeleteBuffers(1, &ebo); + } + + void draw() { + glBindVertexArray(vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + } + +private: + GLuint vbo; + GLuint vao; + GLuint ebo; +}; + + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlShaders.cpp index a53bf11..26ec5cf 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.cpp @@ -96,7 +96,7 @@ void main() vs_out.wtangent = u_mat_normal * tangent; vs_out.wbitangent = u_mat_normal * bitangent; vs_out.uv = uv; -}; +} )shader"; diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index b956c01..e72d193 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -25,8 +25,8 @@ static void initializeOpenGL() { initialized = true; } -OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) : Renderer(), _frameSize(), _resources(nullptr) { - updateFrameSize(settings.frame_size); +OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) + : Renderer(), _frameSize(settings.frame_size), _resources(nullptr) { } OpenGLRenderer::~OpenGLRenderer() { @@ -56,7 +56,13 @@ void OpenGLRenderer::renderWorld(const std::shared_ptr &world) context.gBuffer = _gBuffer.get(); world->initializeRenderContext(context); + + _gBuffer->bind(); world->render(context); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + _gBuffer->render(); } void OpenGLRenderer::updateFrameSize(std::pair size) { @@ -68,6 +74,7 @@ void OpenGLRenderer::updateFrameSize(std::pair size) { void OpenGLRenderer::initialize() { initializeOpenGL(); + updateFrameSize(_frameSize); std::cout << "OpenGLRenderer created" << std::endl; std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; _resources = std::make_shared(std::static_pointer_cast(shared_from_this())); diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp index 0147b7e..5b935ac 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp @@ -48,6 +48,19 @@ class Texture : public Scene::IRendererObject { glBindTexture(GL_TEXTURE_2D, 0); } + Texture(GLsizei width, GLsizei height, GLint internalFormat, GLenum format, GLenum type, GLint wrap, GLint filter) { + glGenTextures(1, &_gl_texture); + if (_gl_texture == 0) { + std::runtime_error("Failed to create texture buffer."); + } + glBindTexture(GL_TEXTURE_2D, _gl_texture); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + } + ~Texture() override { if (_gl_texture != 0) { glDeleteTextures(1, &_gl_texture); From bd39baf969fbe7198591d31d864e747c66b11024 Mon Sep 17 00:00:00 2001 From: amasson Date: Thu, 16 Jan 2025 09:32:50 +0100 Subject: [PATCH 50/89] Fix framebuffer triangles --- Engine/Render/src/Render/OpenGL/GBuffer.hpp | 7 ++++++- Engine/Render/src/Render/OpenGL/GlFramebuffer.hpp | 12 ++++++------ Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp | 3 +-- .../Render/src/Render/OpenGL/Renderable/MeshNode.cpp | 6 +++--- Engine/Window/src/Window/Window.cpp | 2 +- examples/scop/main.cpp | 6 ++++-- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/GBuffer.hpp b/Engine/Render/src/Render/OpenGL/GBuffer.hpp index 0cdd151..e947888 100644 --- a/Engine/Render/src/Render/OpenGL/GBuffer.hpp +++ b/Engine/Render/src/Render/OpenGL/GBuffer.hpp @@ -43,6 +43,7 @@ void main() { )"); + // TODO: Write fragment shader using all lights and pbr GlFragmentShader fragmentShader(R"(#version 400 core in vec2 fragUV; @@ -54,7 +55,8 @@ uniform sampler2D u_albedo_spec; out vec4 FragColor; void main() { - FragColor = vec4(fragUV, 1.0, 1.0); + // FragColor = vec4(fragUV, 1.0, 1.0); + FragColor = vec4(vec3(texture(u_albedo_spec, fragUV)), 1.0); } )"); @@ -75,6 +77,9 @@ void main() { void render() { program->use(); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + program->setUniformTexture("u_position", *gPosition, 0); program->setUniformTexture("u_normal", *gNormal, 1); program->setUniformTexture("u_albedo_spec", *gAlbedoSpec, 2); diff --git a/Engine/Render/src/Render/OpenGL/GlFramebuffer.hpp b/Engine/Render/src/Render/OpenGL/GlFramebuffer.hpp index 30f0bc6..d0ef3d2 100644 --- a/Engine/Render/src/Render/OpenGL/GlFramebuffer.hpp +++ b/Engine/Render/src/Render/OpenGL/GlFramebuffer.hpp @@ -10,16 +10,16 @@ class GlFramebufferMesh { public: GlFramebufferMesh() { float vertices[] = { - // positions // texture coords - 1.0f, 1.0f, 1.0f, 1.0f, // top right - 1.0f, -1.0f, 1.0f, 0.0f, // bottom right + // pos | uv -1.0f, -1.0f, 0.0f, 0.0f, // bottom left - -1.0f, 1.0f, 0.0f, 1.0f // top left + 1.0f, -1.0f, 1.0f, 0.0f, // bottom right + -1.0f, 1.0f, 0.0f, 1.0f, // top left + 1.0f, 1.0f, 1.0f, 1.0f, // top right }; unsigned int indices[] = { - 0, 1, 3, // first triangle - 1, 2, 3 // second triangle + 0, 3, 2, // top left + 0, 1, 3 // bottom right }; glGenVertexArrays(1, &vao); diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index e72d193..5afbf77 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -47,6 +47,7 @@ void OpenGLRenderer::renderWorld(const std::shared_ptr &world) // Reset framebuffers + _gBuffer->bind(); glViewport(0, 0, static_cast(_frameSize.first), static_cast(_frameSize.second)); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -56,8 +57,6 @@ void OpenGLRenderer::renderWorld(const std::shared_ptr &world) context.gBuffer = _gBuffer.get(); world->initializeRenderContext(context); - - _gBuffer->bind(); world->render(context); glBindFramebuffer(GL_FRAMEBUFFER, 0); diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp index ada15b2..f043c0d 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp @@ -52,9 +52,9 @@ void MeshNode::render(Scene::RenderContext &context) { _material->setUniforms(Scene::MeshType::Standard); } - program->setUniform("model", context.mvp.modelMatrix); - program->setUniform("view", context.mvp.viewMatrix); - program->setUniform("projection", context.mvp.projMatrix); + program->setUniform("u_mat_model", context.mvp.modelMatrix); + program->setUniform("u_mat_view", context.mvp.viewMatrix); + program->setUniform("u_mat_projection", context.mvp.projMatrix); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); diff --git a/Engine/Window/src/Window/Window.cpp b/Engine/Window/src/Window/Window.cpp index 59dbba3..7214284 100644 --- a/Engine/Window/src/Window/Window.cpp +++ b/Engine/Window/src/Window/Window.cpp @@ -47,7 +47,7 @@ std::shared_ptr Window::getWorld() const { } void Window::_onMouseMoveCallback(double x, double y) { - std::cout << this << ":mouse move " << x << " " << y << std::endl; + // std::cout << this << ":mouse move " << x << " " << y << std::endl; } void Window::_onMouseButtonCallback(int button, int action, int mods) { diff --git a/examples/scop/main.cpp b/examples/scop/main.cpp index 468e16f..aae40ec 100644 --- a/examples/scop/main.cpp +++ b/examples/scop/main.cpp @@ -72,7 +72,8 @@ int main(int argc, char **argv) { }); // Create a MeshNode - auto meshNode = window->getWorld()->addChild(); + auto meshNode = std::make_shared(); + window->getWorld()->addChild(meshNode); meshNode->setMesh(mesh); // Create a Texture @@ -94,7 +95,8 @@ int main(int argc, char **argv) { // Create a second MeshNode with the same mesh auto meshRotatingNode = window->getWorld()->addChild(); meshRotatingNode->getTransform().setPosition({0.0f, 0.0f, 0.0f}); - auto secondMeshNode = meshRotatingNode->addChild(); + auto secondMeshNode = std::make_shared(); + meshRotatingNode->addChild(secondMeshNode); meshRotatingNode->setRotationSpeed({0.0f, 0.4f, 0.0f}); secondMeshNode->setMesh(mesh); From 3ac38d8294f094f14ab1dce24140e13034d93133 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 9 Apr 2025 10:16:06 +0200 Subject: [PATCH 51/89] OpenGLRenderer use forward or deferred rendering methods --- .../include/Render/OpenGL/OpenGLRenderer.hpp | 2 + .../Render/OpenGL/RendererSettings.hpp | 6 ++ Engine/Render/src/Render/OpenGL/GlShaders.cpp | 11 +++- Engine/Render/src/Render/OpenGL/GlShaders.hpp | 3 +- .../src/Render/OpenGL/OpenGLRenderer.cpp | 58 ++++++++++++++----- .../src/Render/OpenGL/OpenGLResources.cpp | 13 ++++- .../src/Render/OpenGL/OpenGLResources.hpp | 2 + .../src/Render/OpenGL/ShaderCollection.cpp | 23 ++++++++ .../src/Render/OpenGL/ShaderCollection.hpp | 19 +----- .../include/Scene/Shader/ShaderGenerator.hpp | 3 +- Engine/Window/src/Window/GlfwWindow.cpp | 1 + examples/glsl_generator/main.cpp | 16 ++++- 12 files changed, 117 insertions(+), 40 deletions(-) diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index 74e9189..fdad95e 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -30,10 +30,12 @@ class OpenGLRenderer : public Renderer { void updateFrameSize(std::pair size) override; void initialize(); + RenderingMethod getRenderingMethod() const; const std::shared_ptr &getOpenGLResources() const; private: std::pair _frameSize; + const RenderingMethod _method; std::shared_ptr _resources; std::unique_ptr _gBuffer; }; diff --git a/Engine/Render/include/Render/OpenGL/RendererSettings.hpp b/Engine/Render/include/Render/OpenGL/RendererSettings.hpp index 217b777..b669981 100644 --- a/Engine/Render/include/Render/OpenGL/RendererSettings.hpp +++ b/Engine/Render/include/Render/OpenGL/RendererSettings.hpp @@ -8,8 +8,14 @@ namespace Stone::Render::OpenGL { +enum class RenderingMethod { + Forward, + Deferred +}; + struct RendererSettings { std::pair frame_size = {}; + RenderingMethod rendering_method = RenderingMethod::Deferred; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlShaders.cpp index 26ec5cf..e7a0b3e 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.cpp @@ -149,10 +149,17 @@ std::unique_ptr GlVertexShader::makeStandardInstancedMeshShader( throw std::runtime_error("Not implemented."); } -std::unique_ptr GlFragmentShader::makeStandardShader(const Scene::ShaderParameters ¶ms) { +std::unique_ptr GlFragmentShader::makeStandardForwardShader(const Scene::ShaderParameters ¶ms) { std::stringstream source; Scene::ShaderGenerator generator; - generator.generateFragmentShader(params, source); + generator.generateForwardFragmentShader(params, source); + return std::make_unique(source.str().c_str()); +} + +std::unique_ptr GlFragmentShader::makeStandardDeferredShader(const Scene::ShaderParameters ¶ms) { + std::stringstream source; + Scene::ShaderGenerator generator; + generator.generateDeferredFragmentShader(params, source); return std::make_unique(source.str().c_str()); } diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.hpp b/Engine/Render/src/Render/OpenGL/GlShaders.hpp index 6e6f890..964dbb1 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.hpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.hpp @@ -69,7 +69,8 @@ class GlFragmentShader : public GlShaderBase { GlFragmentShader(const char *source) : GlShaderBase(source, GL_FRAGMENT_SHADER) { } - static std::unique_ptr makeStandardShader(const Scene::ShaderParameters ¶ms); + static std::unique_ptr makeStandardDeferredShader(const Scene::ShaderParameters ¶ms); + static std::unique_ptr makeStandardForwardShader(const Scene::ShaderParameters ¶ms); }; class GlShaderProgram { diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index 5afbf77..c9ba911 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -26,7 +26,7 @@ static void initializeOpenGL() { } OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) - : Renderer(), _frameSize(settings.frame_size), _resources(nullptr) { + : Renderer(), _frameSize(settings.frame_size), _method(settings.rendering_method), _resources(nullptr) { } OpenGLRenderer::~OpenGLRenderer() { @@ -45,30 +45,52 @@ void OpenGLRenderer::updateDataForWorld(const std::shared_ptr void OpenGLRenderer::renderWorld(const std::shared_ptr &world) { - // Reset framebuffers + switch (_method) { + case RenderingMethod::Deferred: + { + // Reset framebuffers - _gBuffer->bind(); - glViewport(0, 0, static_cast(_frameSize.first), static_cast(_frameSize.second)); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + _gBuffer->bind(); + glViewport(0, 0, static_cast(_frameSize.first), static_cast(_frameSize.second)); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - OpenGL::RenderContext context; - context.renderer = std::static_pointer_cast(shared_from_this()); - context.gBuffer = _gBuffer.get(); + OpenGL::RenderContext context; + context.renderer = std::static_pointer_cast(shared_from_this()); + context.gBuffer = _gBuffer.get(); - world->initializeRenderContext(context); - world->render(context); + world->initializeRenderContext(context); + world->render(context); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); - _gBuffer->render(); + _gBuffer->render(); + break; + } + case RenderingMethod::Forward: + { + OpenGL::RenderContext context; + context.renderer = std::static_pointer_cast(shared_from_this()); + + glViewport(0, 0, static_cast(_frameSize.first), static_cast(_frameSize.second)); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + world->initializeRenderContext(context); + world->render(context); + + break; + } + } } void OpenGLRenderer::updateFrameSize(std::pair size) { _frameSize = size; - if (_gBuffer) - _gBuffer.reset(); - _gBuffer = std::make_unique(_frameSize.first, _frameSize.second); + if (_method == RenderingMethod::Deferred) { + if (_gBuffer) + _gBuffer.reset(); + _gBuffer = std::make_unique(_frameSize.first, _frameSize.second); + } } void OpenGLRenderer::initialize() { @@ -79,6 +101,10 @@ void OpenGLRenderer::initialize() { _resources = std::make_shared(std::static_pointer_cast(shared_from_this())); } +RenderingMethod OpenGLRenderer::getRenderingMethod() const { + return _method; +} + const std::shared_ptr &OpenGLRenderer::getOpenGLResources() const { return _resources; } diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index b430e84..ac46e4d 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -42,9 +42,16 @@ GlVertexShader *OpenGLResources::getVertexShader(Scene::MeshType meshType) { const std::unique_ptr &OpenGLResources::getFragmentShader(Scene::ShaderParameters params) { + auto renderer = getRenderer().lock(); + assert(renderer != nullptr); auto it = _fragmentShaders.find(params); if (it == _fragmentShaders.end()) { - return (_fragmentShaders[params] = GlFragmentShader::makeStandardShader(params)); + switch (renderer->getRenderingMethod()) { + case RenderingMethod::Forward: + return (_fragmentShaders[params] = GlFragmentShader::makeStandardForwardShader(params)); + case RenderingMethod::Deferred: + return (_fragmentShaders[params] = GlFragmentShader::makeStandardDeferredShader(params)); + } } else { return it->second; } @@ -57,4 +64,8 @@ const std::unique_ptr &OpenGLResources::getDefaultShaderCollec return _defaultShaderCollection; } +const std::weak_ptr OpenGLResources::getRenderer() const { + return _renderer; +} + } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp index e5352f9..b08f89a 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp @@ -27,6 +27,8 @@ class OpenGLResources : std::enable_shared_from_this { const std::unique_ptr &getDefaultShaderCollection(); + const std::weak_ptr getRenderer() const; + private: std::weak_ptr _renderer; diff --git a/Engine/Render/src/Render/OpenGL/ShaderCollection.cpp b/Engine/Render/src/Render/OpenGL/ShaderCollection.cpp index ea40099..51fdbae 100644 --- a/Engine/Render/src/Render/OpenGL/ShaderCollection.cpp +++ b/Engine/Render/src/Render/OpenGL/ShaderCollection.cpp @@ -8,6 +8,29 @@ namespace Stone::Render::OpenGL { +ShaderCollection::ShaderCollection(const std::shared_ptr &resources) : _resources(resources) { + Scene::ShaderParameters params; + switch (resources->getRenderer().lock()->getRenderingMethod()) { + case RenderingMethod::Forward: _glFragmentShader = GlFragmentShader::makeStandardForwardShader(params); break; + case RenderingMethod::Deferred: _glFragmentShader = GlFragmentShader::makeStandardDeferredShader(params); break; + } +} + +ShaderCollection::ShaderCollection(Scene::FragmentShader &shader, const std::shared_ptr &resources) + : _resources(resources) { + _glFragmentShader = std::make_unique(shader); +} + +ShaderCollection::ShaderCollection(Scene::Material &material, const std::shared_ptr &resources) + : _resources(resources) { + Scene::ShaderParameters params; + params.setFromMaterial(material); + switch (resources->getRenderer().lock()->getRenderingMethod()) { + case RenderingMethod::Forward: _glFragmentShader = GlFragmentShader::makeStandardForwardShader(params); break; + case RenderingMethod::Deferred: _glFragmentShader = GlFragmentShader::makeStandardDeferredShader(params); break; + } +} + void ShaderCollection::makeMeshProgram() { if (_meshProgram != nullptr) return; diff --git a/Engine/Render/src/Render/OpenGL/ShaderCollection.hpp b/Engine/Render/src/Render/OpenGL/ShaderCollection.hpp index 9c9e791..09ed566 100644 --- a/Engine/Render/src/Render/OpenGL/ShaderCollection.hpp +++ b/Engine/Render/src/Render/OpenGL/ShaderCollection.hpp @@ -10,22 +10,9 @@ namespace Stone::Render::OpenGL { class ShaderCollection { public: - ShaderCollection(const std::shared_ptr &resources) : _resources(resources) { - Scene::ShaderParameters params; - _glFragmentShader = GlFragmentShader::makeStandardShader(params); - } - - ShaderCollection(Scene::FragmentShader &shader, const std::shared_ptr &resources) - : _resources(resources) { - _glFragmentShader = std::make_unique(shader); - } - - ShaderCollection(Scene::Material &material, const std::shared_ptr &Resources) - : _resources(Resources) { - Scene::ShaderParameters params; - params.setFromMaterial(material); - _glFragmentShader = GlFragmentShader::makeStandardShader(params); - } + ShaderCollection(const std::shared_ptr &resources); + ShaderCollection(Scene::FragmentShader &shader, const std::shared_ptr &resources); + ShaderCollection(Scene::Material &material, const std::shared_ptr &resources); void makeMeshProgram(); void makeSkinMeshProgram(); diff --git a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp index 705073d..e033067 100644 --- a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp +++ b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp @@ -14,7 +14,8 @@ class ShaderGenerator { ~ShaderGenerator() = default; - void generateFragmentShader(const ShaderParameters ¶ms, std::ostream &output); + void generateDeferredFragmentShader(const ShaderParameters ¶ms, std::ostream &output); + void generateForwardFragmentShader(const ShaderParameters ¶ms, std::ostream &output); }; } // namespace Stone::Scene diff --git a/Engine/Window/src/Window/GlfwWindow.cpp b/Engine/Window/src/Window/GlfwWindow.cpp index 9635cd8..f599dbf 100644 --- a/Engine/Window/src/Window/GlfwWindow.cpp +++ b/Engine/Window/src/Window/GlfwWindow.cpp @@ -81,6 +81,7 @@ GlfwWindow::GlfwWindow(const std::shared_ptr &app, const WindowSettings &se static_cast(frameBufferWidth), static_cast(frameBufferHeight), }; + rendererSettings.rendering_method = Render::OpenGL::RenderingMethod::Forward; auto renderer = std::make_shared(rendererSettings); renderer->initialize(); _renderer = renderer; diff --git a/examples/glsl_generator/main.cpp b/examples/glsl_generator/main.cpp index b32e409..eec844a 100644 --- a/examples/glsl_generator/main.cpp +++ b/examples/glsl_generator/main.cpp @@ -54,6 +54,8 @@ std::string to_string(Stone::Scene::ShaderParameters::Type type) { return ""; } +bool isForwardRender = false; + void generateShaderOutput(const char *input_file, const char *output_file) { Json::Value input_json; @@ -69,7 +71,10 @@ void generateShaderOutput(const char *input_file, const char *output_file) { FOR_EACH_SHADER_PARAMETERS(__PRINT_SHADER_PARAM) std::cout << "}" << std::endl; - generator.generateFragmentShader(params, output_stream); + if (isForwardRender) + generator.generateForwardFragmentShader(params, output_stream); + else + generator.generateDeferredFragmentShader(params, output_stream); } std::string input; @@ -84,7 +89,9 @@ void generateShader() { } void printUsage() { - std::cout << "Usage: glsl_generator [-f]" << std::endl; + std::cout << "Usage: glsl_generator [-fd]" << std::endl; + std::cout << "-f : Watch for file change" << std::endl; + std::cout << "-d : Generate forward rendering" << std::endl; } int main(int argc, const char *argv[]) { @@ -96,9 +103,12 @@ int main(int argc, const char *argv[]) { input = argv[1]; output = argv[2]; + if (argc >= 4 && std::string(argv[3]).find('d') != std::string::npos) + isForwardRender = true; + generateShader(); - if (argc >= 4 && std::string(argv[3]) == "-f") { + if (argc >= 4 && std::string(argv[3]).find('f') != std::string::npos) { while (true) { time_t last_modified = getLastmodifiedTimeOfFile(input.c_str()); while (last_modified == getLastmodifiedTimeOfFile(input.c_str())) { From 33701b061058927c623b435e3c98532b9a161172 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 9 Apr 2025 22:16:54 +0200 Subject: [PATCH 52/89] opengl renderer use program for uniforms --- Engine/Render/src/Render/OpenGL/GlShaders.cpp | 4 ++++ Engine/Render/src/Render/OpenGL/GlShaders.hpp | 1 + Engine/Render/src/Render/OpenGL/Renderable/Material.cpp | 1 + Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp | 2 +- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlShaders.cpp index e7a0b3e..a3a72c8 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.cpp @@ -213,6 +213,10 @@ GLint GlShaderProgram::getUniformLocation(const Scene::Material::Location &locat return -1; } +void GlShaderProgram::setUniform(const Scene::Material::Location &location, int integer) const { + glUniform1i(getUniformLocation(location), integer); +} + void GlShaderProgram::setUniform(const Scene::Material::Location &location, float scalar) const { glUniform1f(getUniformLocation(location), scalar); } diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.hpp b/Engine/Render/src/Render/OpenGL/GlShaders.hpp index 964dbb1..5979882 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.hpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.hpp @@ -86,6 +86,7 @@ class GlShaderProgram { GLint getUniformLocation(const std::string &name) const; GLint getUniformLocation(const Scene::Material::Location &location) const; + void setUniform(const Scene::Material::Location &location, int integer) const; void setUniform(const Scene::Material::Location &location, float scalar) const; void setUniform(const Scene::Material::Location &location, const glm::vec3 &vec3) const; void setUniform(const Scene::Material::Location &location, const glm::mat4 &mat4) const; diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp index a4b1ca1..84e6c0b 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp @@ -29,6 +29,7 @@ void Material::render(Scene::RenderContext &context) { void Material::setUniforms(Scene::MeshType meshType) { GlShaderProgram *program = _shaderCollection->getProgram(meshType); + program->use(); _material.forEachVectors([program](const auto &loc, glm::vec3 vec) { program->setUniform(loc, vec); }); _material.forEachScalars([program](const auto &loc, float scalar) { program->setUniform(loc, scalar); }); diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp index f043c0d..584f8eb 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp @@ -22,7 +22,6 @@ MeshNode::MeshNode(Scene::MeshNode &meshNode, const std::shared_ptrgetDefaultMaterial()->isDirty() == false); _material = _meshNode.getMesh()->getDefaultMaterial()->getRendererObject().get(); } - assert(_material != nullptr); if (_material != nullptr) { _shaderCollection = _material->getShaderCollection().get(); @@ -52,6 +51,7 @@ void MeshNode::render(Scene::RenderContext &context) { _material->setUniforms(Scene::MeshType::Standard); } + program->setUniform("u_lights_count", 0); program->setUniform("u_mat_model", context.mvp.modelMatrix); program->setUniform("u_mat_view", context.mvp.viewMatrix); program->setUniform("u_mat_projection", context.mvp.projMatrix); From 78bd95d8a1b7fe71392d3bf2787dc9ca6e6a6f43 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 9 Apr 2025 22:19:31 +0200 Subject: [PATCH 53/89] reimagine shader content pparams and generator --- .../Scene/include/Scene/Renderable/Shader.hpp | 4 +- .../include/Scene/Shader/ShaderGenerator.hpp | 3 +- .../include/Scene/Shader/ShaderParameters.hpp | 4 +- .../src/Scene/Shader/ShaderGenerator.cpp | 57 +++++++------------ .../src/Scene/Shader/ShaderParameters.cpp | 15 +++-- examples/glsl_generator/main.cpp | 12 +++- examples/glsl_generator/shader_params.json | 8 +-- 7 files changed, 48 insertions(+), 55 deletions(-) diff --git a/Engine/Scene/include/Scene/Renderable/Shader.hpp b/Engine/Scene/include/Scene/Renderable/Shader.hpp index fc8beb3..7d93315 100644 --- a/Engine/Scene/include/Scene/Renderable/Shader.hpp +++ b/Engine/Scene/include/Scene/Renderable/Shader.hpp @@ -87,8 +87,8 @@ class AShader : public Core::Object, public IRenderable { private: ContentType _contentType = ContentType::SourceCode; /** The type of the content. */ - std::string _content = "#version 400 core\n"; /** The content of the shader. */ - std::string _function = "main"; /** The function to call in the shader. */ + std::string _content = "void customShader() {}"; /** The content of the shader. */ + std::string _function = "customShader"; /** The function to call in the shader. */ std::unordered_map _locations = {}; /** The binding locations of the variables in the shader. */ int _maxLocation = -1; /** The cached maximum value from the locations. */ diff --git a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp index e033067..16d3f66 100644 --- a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp +++ b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp @@ -14,8 +14,7 @@ class ShaderGenerator { ~ShaderGenerator() = default; - void generateDeferredFragmentShader(const ShaderParameters ¶ms, std::ostream &output); - void generateForwardFragmentShader(const ShaderParameters ¶ms, std::ostream &output); + void generateFragmentShaderTemplate(const ShaderParameters ¶ms, std::ostream &output); }; } // namespace Stone::Scene diff --git a/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp b/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp index caec228..a2375e4 100644 --- a/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp +++ b/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp @@ -16,7 +16,9 @@ struct ShaderParameters { enum class Type : uint8_t { None = 0, Scalar, - Vector, + Vector2, + Vector3, + Vector4, Texture, }; diff --git a/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp b/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp index 81aa4ab..9953ec1 100644 --- a/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp +++ b/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp @@ -4,48 +4,35 @@ namespace Stone::Scene { +std::string to_glsl(ShaderParameters::Type type) { + switch (type) { + case ShaderParameters::Type::Scalar: return "float"; break; + case ShaderParameters::Type::Vector2: return "vec2"; break; + case ShaderParameters::Type::Vector3: return "vec3"; break; + case ShaderParameters::Type::Vector4: return "vec4"; break; + case ShaderParameters::Type::Texture: return "sampler2D"; break; + default: return ""; break; + } +} + +void ShaderGenerator::generateFragmentShaderTemplate(const ShaderParameters ¶ms, std::ostream &output) { + + output << "// Stone shader template" << std::endl; -void ShaderGenerator::generateFragmentShader(const ShaderParameters ¶ms, std::ostream &output) { - std::ostream &source = output; - - source << R"(#version 400 core - -in FRAG_DATA { - vec3 wposition; - vec2 uv; - vec3 wnormal; - vec3 wtangent; - vec3 wbitangent; -} fs_in; - -layout (location = 0) out vec3 gPosition; -layout (location = 1) out vec3 gNormal; -layout (location = 2) out vec4 gAlbedoSpec; - -)"; - - auto add_uniform_param = [&source](const char *name, ShaderParameters::Type type) { - if (type == ShaderParameters::Type::Texture) { - source << "uniform sampler2D " << name << ";" << std::endl; - } else if (type == ShaderParameters::Type::Vector) { - source << "uniform vec3 " << name << ";" << std::endl; - } else if (type == ShaderParameters::Type::Scalar) { - source << "uniform float " << name << ";" << std::endl; - } + auto add_uniform_param = [&output](const char *name, ShaderParameters::Type type) { + if (type != ShaderParameters::Type::None) + output << "// " << name << ": " << to_glsl(type) << std::endl; }; #define __ADD_UNIFORM_PARAM(PARAM) add_uniform_param(#PARAM, params.PARAM); FOR_EACH_SHADER_PARAMETERS(__ADD_UNIFORM_PARAM); + output << std::endl; - source << R"( -void main() { - gPosition = fs_in.wposition; - gNormal = normalize(fs_in.wnormal); - gAlbedoSpec = vec4(1.0, 0.0, 0.0, 1.0); + output << "void customShader() {" << std::endl; + output << " // diffuse = vec3(1, 0, 0);" << std::endl; + output << " // TODO: Implement shader generation logic here" << std::endl; + output << "}" << std::endl; } -)"; -} - } // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp index 73f0f52..4b830a5 100644 --- a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp +++ b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp @@ -14,14 +14,13 @@ void ShaderParameters::setParamWithName(const std::string &name, Type value) { using ParamSetter = std::function; #define __MAP_NAME_TO_PARAM(param) \ - { \ - #param, [](ShaderParameters &matParams, Type value) { \ - matParams.param = value; \ - } \ - } \ - , + {#param, [](ShaderParameters &matParams, Type value) { \ + matParams.param = value; \ + }}, + const static std::unordered_map paramSetters = { - FOR_EACH_SHADER_PARAMETERS(__MAP_NAME_TO_PARAM)}; + FOR_EACH_SHADER_PARAMETERS(__MAP_NAME_TO_PARAM) // + }; auto it = paramSetters.find(name); if (it != paramSetters.end()) { @@ -41,7 +40,7 @@ void ShaderParameters::setFromMaterial(const Material &material) { (void)value; if (std::holds_alternative(location)) { const std::string &name(std::get(location)); - setParamWithName(name, Type::Vector); + setParamWithName(name, Type::Vector3); } }); material.forEachTextures([this](const Material::Location &location, auto value) { diff --git a/examples/glsl_generator/main.cpp b/examples/glsl_generator/main.cpp index eec844a..1407b70 100644 --- a/examples/glsl_generator/main.cpp +++ b/examples/glsl_generator/main.cpp @@ -30,8 +30,12 @@ Stone::Scene::ShaderParameters parseShaderParameters(const Json::Value &json) { const std::string &type_str = value.get(); if (type_str == "scalar") type = Stone::Scene::ShaderParameters::Type::Scalar; - else if (type_str == "vector") - type = Stone::Scene::ShaderParameters::Type::Vector; + else if (type_str == "vector2") + type = Stone::Scene::ShaderParameters::Type::Vector2; + else if (type_str == "vector3") + type = Stone::Scene::ShaderParameters::Type::Vector3; + else if (type_str == "vector4") + type = Stone::Scene::ShaderParameters::Type::Vector4; else if (type_str == "texture") type = Stone::Scene::ShaderParameters::Type::Texture; else @@ -48,7 +52,9 @@ std::string to_string(Stone::Scene::ShaderParameters::Type type) { switch (type) { case Stone::Scene::ShaderParameters::Type::None: return "none"; case Stone::Scene::ShaderParameters::Type::Scalar: return "scalar"; - case Stone::Scene::ShaderParameters::Type::Vector: return "vector"; + case Stone::Scene::ShaderParameters::Type::Vector2: return "vector2"; + case Stone::Scene::ShaderParameters::Type::Vector3: return "vector3"; + case Stone::Scene::ShaderParameters::Type::Vector4: return "vector4"; case Stone::Scene::ShaderParameters::Type::Texture: return "texture"; } return ""; diff --git a/examples/glsl_generator/shader_params.json b/examples/glsl_generator/shader_params.json index 1af66a1..6ab58ff 100644 --- a/examples/glsl_generator/shader_params.json +++ b/examples/glsl_generator/shader_params.json @@ -2,12 +2,12 @@ "diffuse": "texture", "specular": "texture", "ambient": "scalar", - "emissive": "vector", + "emissive": "vector3", "shininess": "scalar", "opacity": "texture", "roughness": "scalar", - "metallic": "vector", - "normal": "vector", + "metallic": "vector3", + "normal": "vector3", "occlusion": "scalar", - "height": "vector" + "height": "vector3" } \ No newline at end of file From 08a5021ef6004e9b6267cc0fa4164804a39b5f88 Mon Sep 17 00:00:00 2001 From: amasson Date: Thu, 10 Apr 2025 00:24:57 +0200 Subject: [PATCH 54/89] opengl fragment shader code --- Engine/Render/src/Render/OpenGL/GlShaders.cpp | 17 +- .../src/Render/OpenGL/Renderable/Material.cpp | 1 + .../src/Render/OpenGL/Renderable/Mesh.hpp | 2 +- .../include/Scene/Shader/ShaderGenerator.hpp | 2 + .../include/Scene/Shader/ShaderParameters.hpp | 4 +- .../src/Scene/Shader/ShaderGenerator.cpp | 316 +++++++++++++++++- examples/glsl_generator/main.cpp | 47 ++- 7 files changed, 343 insertions(+), 46 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlShaders.cpp index a3a72c8..9b01f69 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.cpp @@ -9,6 +9,8 @@ namespace Stone::Render::OpenGL { +// MARK: Compilation + GLuint compileSource(const std::string &source, GLenum type) { GLuint shaderId = glCreateShader(type); if (shaderId == 0) { @@ -65,6 +67,8 @@ GLuint loadSpirv(const char *spirv_content, GLsizei spirv_length, GLenum type) { return shaderId; } +// MARK: Vertex + const char *basicVertexShaderSource = R"shader( #version 400 core @@ -149,20 +153,23 @@ std::unique_ptr GlVertexShader::makeStandardInstancedMeshShader( throw std::runtime_error("Not implemented."); } +// MARK: Fragment + std::unique_ptr GlFragmentShader::makeStandardForwardShader(const Scene::ShaderParameters ¶ms) { std::stringstream source; + Scene::ShaderGenerator generator; - generator.generateForwardFragmentShader(params, source); + generator.generateOpenGlForwardFragmentShader(params, source); + return std::make_unique(source.str().c_str()); } std::unique_ptr GlFragmentShader::makeStandardDeferredShader(const Scene::ShaderParameters ¶ms) { - std::stringstream source; - Scene::ShaderGenerator generator; - generator.generateDeferredFragmentShader(params, source); - return std::make_unique(source.str().c_str()); + (void)params; + throw std::runtime_error("deffered shader is not implemented."); } +// MARK: Program GlShaderProgram::GlShaderProgram(const GlVertexShader &vertexShader, const GlFragmentShader &fragmentShader) : _gl_program(0) { diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp index 84e6c0b..de0a570 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp @@ -29,6 +29,7 @@ void Material::render(Scene::RenderContext &context) { void Material::setUniforms(Scene::MeshType meshType) { GlShaderProgram *program = _shaderCollection->getProgram(meshType); + assert(program != nullptr); program->use(); _material.forEachVectors([program](const auto &loc, glm::vec3 vec) { program->setUniform(loc, vec); }); diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp index a6b0726..f47c640 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp @@ -25,7 +25,7 @@ struct VRAMMesh { glGenBuffers(1, &verticesBuffer); if (verticesBuffer == 0) { glDeleteVertexArrays(1, &elementsBuffer); - throw std::runtime_error("Failed to generate indices buffer"); + throw std::runtime_error("Failed to generate vertices buffer"); } glGenBuffers(1, &indicesBuffer); diff --git a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp index 16d3f66..cec9aab 100644 --- a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp +++ b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp @@ -15,6 +15,8 @@ class ShaderGenerator { ~ShaderGenerator() = default; void generateFragmentShaderTemplate(const ShaderParameters ¶ms, std::ostream &output); + + void generateOpenGlForwardFragmentShader(const ShaderParameters ¶ms, std::ostream &output); }; } // namespace Stone::Scene diff --git a/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp b/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp index a2375e4..38c3d84 100644 --- a/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp +++ b/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp @@ -24,10 +24,10 @@ struct ShaderParameters { union { struct { -#define __DECLARE_PARAM(param) Type param : 2; +#define __DECLARE_PARAM(param) Type param : 3; FOR_EACH_SHADER_PARAMETERS(__DECLARE_PARAM) }; - uint32_t data; // sizeof() should be greater or equal to the struct size + uint64_t data; // sizeof() should be greater or equal to the struct size }; bool _; diff --git a/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp b/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp index 9953ec1..4c3de04 100644 --- a/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp +++ b/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp @@ -4,22 +4,23 @@ namespace Stone::Scene { -std::string to_glsl(ShaderParameters::Type type) { - switch (type) { - case ShaderParameters::Type::Scalar: return "float"; break; - case ShaderParameters::Type::Vector2: return "vec2"; break; - case ShaderParameters::Type::Vector3: return "vec3"; break; - case ShaderParameters::Type::Vector4: return "vec4"; break; - case ShaderParameters::Type::Texture: return "sampler2D"; break; - default: return ""; break; - } -} - void ShaderGenerator::generateFragmentShaderTemplate(const ShaderParameters ¶ms, std::ostream &output) { output << "// Stone shader template" << std::endl; - auto add_uniform_param = [&output](const char *name, ShaderParameters::Type type) { + auto to_glsl = [](ShaderParameters::Type type) { + switch (type) { + case ShaderParameters::Type::None: return "void"; + case ShaderParameters::Type::Scalar: return "float"; + case ShaderParameters::Type::Vector2: return "vec2"; + case ShaderParameters::Type::Vector3: return "vec3"; + case ShaderParameters::Type::Vector4: return "vec4"; + case ShaderParameters::Type::Texture: return "sampler2D"; + default: return ""; + } + }; + + auto add_uniform_param = [&output, &to_glsl](const char *name, ShaderParameters::Type type) { if (type != ShaderParameters::Type::None) output << "// " << name << ": " << to_glsl(type) << std::endl; }; @@ -35,4 +36,295 @@ void ShaderGenerator::generateFragmentShaderTemplate(const ShaderParameters &par output << "}" << std::endl; } +void ShaderGenerator::generateOpenGlForwardFragmentShader(const ShaderParameters ¶ms, std::ostream &output) { + std::ostream &source(output); + + source << "#version 400 core" << std::endl; + + source << R"( +in FRAG_DATA { + vec3 wposition; + vec2 uv; + vec3 wnormal; + vec3 wtangent; + vec3 wbitangent; +} fs_in; +)"; + + source << R"( +struct Material { + vec3 diffuse; + vec3 specular; + float roughness; + float metalness; + vec3 occlusion; + float shininess; +}; +)"; + + // unused = 0; sunlight = 1; spotlight = 2; pointlight = 3; ambiantlight = 4; + // caster_index = -1 : no caster; + source << R"( +struct Light { + int type; + vec3 position; + vec3 color; + vec3 specular; + float intensity; + vec3 attenuation; + vec3 direction; + float angle; + float cone_attenuation; + int caster_index; +}; +)"; + + source << R"( +struct LightCaster { + mat4 vp; + sampler2D depth_map; +}; + +)"; + + source << "uniform Light u_lights[" << 16 << "];" << std::endl; + source << "uniform int u_lights_count;" << std::endl; + source << "uniform LightCaster u_light_casters[" << 4 << "];" << std::endl; + + source << R"( +uniform mat3 u_mat_normal; +uniform mat4 u_mat_projection; +uniform mat4 u_mat_view; +uniform mat4 u_mat_model; +uniform vec3 u_camera_position; + +)"; + + auto to_glsl = [](ShaderParameters::Type type) { + switch (type) { + case ShaderParameters::Type::None: return "void"; + case ShaderParameters::Type::Scalar: return "float"; + case ShaderParameters::Type::Vector2: return "vec2"; + case ShaderParameters::Type::Vector3: return "vec3"; + case ShaderParameters::Type::Vector4: return "vec4"; + case ShaderParameters::Type::Texture: return "sampler2D"; + default: return ""; + } + }; + + auto add_uniform_param = [&source, &to_glsl](const char *name, ShaderParameters::Type type) { + if (type != ShaderParameters::Type::None) + source << "uniform " << to_glsl(type) << ' ' << name << ";" << std::endl; + }; + +#define __ADD_UNIFORM_PARAM(PARAM) add_uniform_param(#PARAM, params.PARAM); + + FOR_EACH_SHADER_PARAMETERS(__ADD_UNIFORM_PARAM); + source << std::endl; + + source << "out vec4 FragColor;" << std::endl; + + source << R"( +float calculShadow(Light light) { + int caster_index = light.caster_index; + if (caster_index >= 0) { + vec4 fpos_light = u_light_casters[caster_index].vp * vec4(fs_in.wposition, 1.0); + vec3 proj_coords = fpos_light.xyz / fpos_light.w; + proj_coords = proj_coords * 0.5 + 0.5; + bool outOfLight = (proj_coords.x < 0 || proj_coords.x > 1 || proj_coords.y < 0 || proj_coords.y > 1); + if (outOfLight) + return 1.0; + float current_depth = proj_coords.z; + float bias = 0.00001; // max(0.05 * (1.0 - dot(normal_direction, -light.direction)), 0.005); + vec2 texel_size = 1.0 / textureSize(u_light_casters[caster_index].depth_map, 0); + float shadow = 0.0; + int total = 0; + for (int x = -2; x <= 2; x++) { + for (int y = -2; y <= 2; y++) { + float pcf_depth = texture(u_light_casters[caster_index].depth_map, proj_coords.xy + vec2(x, y) * texel_size).r; + shadow += current_depth - bias > pcf_depth ? 0.0 : 1.0; + total++; + } + } + return shadow / (total); + } + return 1.0; +} + +)"; + + source << R"( +vec3 calculDirectionalLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcamera_position) { + vec3 color = vec3(0); + float shadow = calculShadow(light); + if (shadow <= 0.0) return color; + float d = distance(light.position, fs_in.wposition); + float attenuation = 1.0 / (light.attenuation.x + light.attenuation.y * d + light.attenuation.z * d * d); + vec3 light_direction = normalize(-light.direction); + float diffuse_intensity = clamp(dot(light_direction, normal_direction), 0.0, 1.0); + color += light.color * fragMat.diffuse * diffuse_intensity * attenuation * shadow * fragMat.occlusion; + if (diffuse_intensity > 0) { + vec3 reflection = reflect(-light_direction, normal_direction); + vec3 halfway_direction = normalize(fcamera_position + light_direction); + float specular_intensity = pow(clamp(dot(normal_direction, halfway_direction), 0.0, 1.0), fragMat.shininess); + color += diffuse_intensity * light.specular * fragMat.specular * specular_intensity * shadow; + } + return color; +} + +)"; + + source << R"( +vec3 calculSpotLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcamera_position) { + vec3 color = vec3(0); + float shadow = calculShadow(light); + if (shadow <= 0.0) return color; + float d = distance(light.position, fs_in.wposition); + float attenuation = 1.0 / (light.attenuation.x + light.attenuation.y * d + light.attenuation.z * d * d); + vec3 light_direction = normalize(light.position - fs_in.wposition); + float cosangle = cos(light.angle); + float spot_result = dot(-light_direction, light.direction); + if (spot_result > cosangle) { + float cosat = cos(light.angle - light.cone_attenuation); + attenuation *= clamp((spot_result - cosangle) / (cosat - cosangle), 0.0, 1.0); + float diffuse_intensity = clamp(dot(light_direction, normal_direction), 0.0, 1.0); + color += light.color * fragMat.diffuse * diffuse_intensity * attenuation * shadow * fragMat.occlusion; + if (diffuse_intensity > 0) { + vec3 reflection = reflect(-light_direction, normal_direction); + vec3 halfway_direction = normalize(fcamera_position + light_direction); + float specular_intensity = pow(clamp(dot(normal_direction, halfway_direction), 0.0, 1.0), fragMat.shininess); + color += diffuse_intensity * light.specular * fragMat.specular * specular_intensity * shadow; + } + } + return color; +} + +)"; + + source << R"( +vec3 calculPointLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcamera_position) { + vec3 color = vec3(0); + float shadow = calculShadow(light); + if (shadow <= 0.0) return color; + float d = distance(light.position, fs_in.wposition); + float attenuation = 1.0 / (light.attenuation.x + light.attenuation.y * d + light.attenuation.z * d * d); + vec3 light_direction = normalize(light.position - fs_in.wposition); + float diffuse_intensity = clamp(dot(light_direction, normal_direction), 0.0, 1.0); + color += light.color * fragMat.diffuse * diffuse_intensity * attenuation * shadow * fragMat.occlusion; + if (diffuse_intensity > 0) { + vec3 reflection = reflect(-light_direction, normal_direction); + vec3 halfway_direction = normalize(fcamera_position + light_direction); + float specular_intensity = pow(clamp(dot(normal_direction, halfway_direction), 0.0, 1.0), fragMat.shininess); + color += diffuse_intensity * light.specular * fragMat.specular * specular_intensity * shadow; + } + return color; +} + +)"; + + source << R"( +vec3 calculAmbiantLight(Light light, Material fragMat) { + return fragMat.diffuse * light.color * light.intensity * fragMat.occlusion; +} +)"; + + // directional = 1; spotlight = 2; pointlight = 3; ambiantlight = 4; + source << R"( +vec3 calculLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcamera_position) { + switch (light.type) { + case 1: // directional + return calculDirectionalLight(light, fragMat, normal_direction, fcamera_position); + case 2: // spotlight + return calculSpotLight(light, fragMat, normal_direction, fcamera_position); + case 3: // pointlight + return calculPointLight(light, fragMat, normal_direction, fcamera_position); + case 4: // ambiant + return calculAmbiantLight(light, fragMat); + default: + return vec3(0); + } +} + +)"; + + + source << "void main() {" << std::endl; + // if ((texturebitmask & 128) != 0) { + // if (texture(texture_mask, (mask_transform * vec3(fs_in.uv, 1.0)).xy).a == 0.0) + // discard; + // } + source << " Material fragMat;" << std::endl; + + // TODO: Handle default values + const auto assign_to_vec = [&source](ShaderParameters::Type type, const std::string &name) { + switch (type) { + case ShaderParameters::Type::None: break; + case ShaderParameters::Type::Scalar: + source << " fragMat." << name << " = vec3(" << name << ", 0, 0);" << std::endl; + break; + case ShaderParameters::Type::Vector2: + source << " fragMat." << name << " = vec3(" << name << ", 0);" << std::endl; + break; + case ShaderParameters::Type::Vector3: + source << " fragMat." << name << " = " << name << ";" << std::endl; // + break; + case ShaderParameters::Type::Vector4: + source << " fragMat." << name << " = " << name << ".xyz;" << std::endl; + break; + case ShaderParameters::Type::Texture: + source << " fragMat." << name << " = texture(" << name << ", fs_in.uv).xyz;" << std::endl; + break; + } + }; + + const auto assign_to_float = [&source](ShaderParameters::Type type, const std::string &name, char x) { + switch (type) { + case ShaderParameters::Type::None: break; + case ShaderParameters::Type::Scalar: + source << " fragMat." << name << " = " << name << ";" << std::endl; // + break; + case ShaderParameters::Type::Vector2: + case ShaderParameters::Type::Vector3: + case ShaderParameters::Type::Vector4: + source << " fragMat." << name << " = " << name << "." << x << ";" << std::endl; + break; + case ShaderParameters::Type::Texture: + source << " fragMat." << name << " = texture(" << name << ", fs_in.uv)." << x << ";" << std::endl; + break; + } + }; + + assign_to_vec(params.diffuse, "diffuse"); + assign_to_vec(params.specular, "specular"); + assign_to_float(params.roughness, "roughness", 'x'); + assign_to_float(params.metallic, "metallic", 'x'); + assign_to_vec(params.occlusion, "occlusion"); + assign_to_float(params.shininess, "shininess", 'x'); + + + if (params.normal == ShaderParameters::Type::Texture) { + source << " vec3 normal_value = normalize(texture(normal, fs_in.uv).xyz * 2 - 1);" << std::endl; + } else { + source << " vec3 normal_value = vec3(0, 0, 1);" << std::endl; + } + + source << R"( + vec3 normal_direction = fs_in.wnormal * normal_value.z + + fs_in.wtangent * normal_value.x + + fs_in.wbitangent * normal_value.y; + normal_direction = normalize(normal_direction); + vec3 fcamera_position = normalize(u_camera_position - fs_in.wposition); + + vec3 color = vec3(0); + + // for (int i = 0; i < u_lights_count; i++) { + // color += calculLight(u_lights[i], fragMat, normal_direction, fcamera_position); + // } + color = vec3(1.0, 0.0, 0.0); + + FragColor = vec4(color, 1.0); +} +)"; +} + } // namespace Stone::Scene diff --git a/examples/glsl_generator/main.cpp b/examples/glsl_generator/main.cpp index 1407b70..c04474c 100644 --- a/examples/glsl_generator/main.cpp +++ b/examples/glsl_generator/main.cpp @@ -26,22 +26,24 @@ Stone::Scene::ShaderParameters parseShaderParameters(const Json::Value &json) { for (auto [key, value] : params_obj) { Stone::Scene::ShaderParameters::Type type; - if (value.is()) { - const std::string &type_str = value.get(); - if (type_str == "scalar") - type = Stone::Scene::ShaderParameters::Type::Scalar; - else if (type_str == "vector2") - type = Stone::Scene::ShaderParameters::Type::Vector2; - else if (type_str == "vector3") - type = Stone::Scene::ShaderParameters::Type::Vector3; - else if (type_str == "vector4") - type = Stone::Scene::ShaderParameters::Type::Vector4; - else if (type_str == "texture") - type = Stone::Scene::ShaderParameters::Type::Texture; - else - throw std::runtime_error("Invalid type " + type_str); - } else + + if (!value.is()) throw std::runtime_error("Invalid type for key " + key); + + const std::string &type_str = value.get(); + if (type_str == "scalar") + type = Stone::Scene::ShaderParameters::Type::Scalar; + else if (type_str == "vector2") + type = Stone::Scene::ShaderParameters::Type::Vector2; + else if (type_str == "vector3") + type = Stone::Scene::ShaderParameters::Type::Vector3; + else if (type_str == "vector4") + type = Stone::Scene::ShaderParameters::Type::Vector4; + else if (type_str == "texture") + type = Stone::Scene::ShaderParameters::Type::Texture; + else + throw std::runtime_error("Invalid type " + type_str); + params.setParamWithName(key, type); } @@ -60,8 +62,6 @@ std::string to_string(Stone::Scene::ShaderParameters::Type type) { return ""; } -bool isForwardRender = false; - void generateShaderOutput(const char *input_file, const char *output_file) { Json::Value input_json; @@ -77,10 +77,7 @@ void generateShaderOutput(const char *input_file, const char *output_file) { FOR_EACH_SHADER_PARAMETERS(__PRINT_SHADER_PARAM) std::cout << "}" << std::endl; - if (isForwardRender) - generator.generateForwardFragmentShader(params, output_stream); - else - generator.generateDeferredFragmentShader(params, output_stream); + generator.generateOpenGlForwardFragmentShader(params, output_stream); } std::string input; @@ -91,13 +88,14 @@ void generateShader() { generateShaderOutput(input.c_str(), output.c_str()); } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; + } catch (...) { + std::cerr << "Unknown error occurred" << std::endl; } } void printUsage() { - std::cout << "Usage: glsl_generator [-fd]" << std::endl; + std::cout << "Usage: glsl_generator [-f]" << std::endl; std::cout << "-f : Watch for file change" << std::endl; - std::cout << "-d : Generate forward rendering" << std::endl; } int main(int argc, const char *argv[]) { @@ -109,9 +107,6 @@ int main(int argc, const char *argv[]) { input = argv[1]; output = argv[2]; - if (argc >= 4 && std::string(argv[3]).find('d') != std::string::npos) - isForwardRender = true; - generateShader(); if (argc >= 4 && std::string(argv[3]).find('f') != std::string::npos) { From cd4b0958f4e7308aedce370bde85f5a459dcf0de Mon Sep 17 00:00:00 2001 From: amasson Date: Thu, 10 Apr 2025 09:29:29 +0200 Subject: [PATCH 55/89] make format command --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 471f7e6..2183174 100644 --- a/Makefile +++ b/Makefile @@ -50,4 +50,7 @@ ${ALL_EXAMPLES}: examples setup-tidy: @${CMAKE} --preset=setup-tidy -.PHONY: clean all test examples libs setup-tidy +format: + find Engine examples -name '*.cpp' -or -name '*.h' -or -name '*.hpp' | xargs clang-format -i -style=file + +.PHONY: clean all test examples libs setup-tidy format From b15c9969de12f35366a262f2838c8d50838fe561 Mon Sep 17 00:00:00 2001 From: amasson Date: Thu, 10 Apr 2025 09:46:31 +0200 Subject: [PATCH 56/89] silence eternal warning --- Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp index f5e7cad..9e1b508 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp @@ -84,12 +84,15 @@ void RendererObjectManager::updateStaticSkinMesh(const std::shared_ptr &shape) { + (void)shape; } void RendererObjectManager::updateTexture(const std::shared_ptr &texture) { + (void)texture; } void RendererObjectManager::updateFragmentShader(const std::shared_ptr &shader) { + (void)shader; } void RendererObjectManager::updateRendererObject(IRenderable &element, From 49e853fd537534978ca5f15c399f63477c4c5093 Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 13 Apr 2025 12:32:46 +0200 Subject: [PATCH 57/89] OpenGLRenderer fix resource creation --- Engine/Render/src/Render/OpenGL/OpenGLResources.cpp | 3 ++- Engine/Render/src/Render/OpenGL/OpenGLResources.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index ac46e4d..351da83 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -7,7 +7,8 @@ namespace Stone::Render::OpenGL { -OpenGLResources::OpenGLResources(const std::shared_ptr &renderer) : _renderer(renderer) { +OpenGLResources::OpenGLResources(const std::shared_ptr &renderer) + : std::enable_shared_from_this(), _renderer(renderer) { } const std::unique_ptr &OpenGLResources::getMeshVertexShader() { diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp index b08f89a..5702b42 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp @@ -12,7 +12,7 @@ class OpenGLRenderer; class OpenGLResources : std::enable_shared_from_this { public: - OpenGLResources() = default; + OpenGLResources() = delete; OpenGLResources(const std::shared_ptr &renderer); From 98ba4d96215bad290440549c26ee45c0537c0a79 Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 13 Apr 2025 12:35:28 +0200 Subject: [PATCH 58/89] shader generator use scene shader to generate --- Engine/Render/src/Render/OpenGL/GlShaders.cpp | 2 +- .../include/Scene/Shader/ShaderGenerator.hpp | 3 +- .../src/Scene/Shader/ShaderGenerator.cpp | 214 ++++++++++-------- examples/glsl_generator/main.cpp | 14 +- 4 files changed, 131 insertions(+), 102 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlShaders.cpp index 9b01f69..949d5fb 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlShaders.cpp @@ -159,7 +159,7 @@ std::unique_ptr GlFragmentShader::makeStandardForwardShader(co std::stringstream source; Scene::ShaderGenerator generator; - generator.generateOpenGlForwardFragmentShader(params, source); + generator.generateOpenGlForwardFragmentShader(params, nullptr, source); return std::make_unique(source.str().c_str()); } diff --git a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp index cec9aab..cef7cd4 100644 --- a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp +++ b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp @@ -16,7 +16,8 @@ class ShaderGenerator { void generateFragmentShaderTemplate(const ShaderParameters ¶ms, std::ostream &output); - void generateOpenGlForwardFragmentShader(const ShaderParameters ¶ms, std::ostream &output); + void generateOpenGlForwardFragmentShader(const ShaderParameters ¶ms, class FragmentShader *shader, + std::ostream &output); }; } // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp b/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp index 4c3de04..8b9f98a 100644 --- a/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp +++ b/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp @@ -2,6 +2,9 @@ #include "Scene/Shader/ShaderGenerator.hpp" +#include "Scene/Renderable/Shader.hpp" +#include "Utils/FileSystem.hpp" + namespace Stone::Scene { void ShaderGenerator::generateFragmentShaderTemplate(const ShaderParameters ¶ms, std::ostream &output) { @@ -30,13 +33,14 @@ void ShaderGenerator::generateFragmentShaderTemplate(const ShaderParameters &par FOR_EACH_SHADER_PARAMETERS(__ADD_UNIFORM_PARAM); output << std::endl; - output << "void customShader() {" << std::endl; - output << " // diffuse = vec3(1, 0, 0);" << std::endl; + output << "void customShader(inout Material material) {" << std::endl; + output << " material.diffuse = vec3(1, 0, 0);" << std::endl; output << " // TODO: Implement shader generation logic here" << std::endl; output << "}" << std::endl; } -void ShaderGenerator::generateOpenGlForwardFragmentShader(const ShaderParameters ¶ms, std::ostream &output) { +void ShaderGenerator::generateOpenGlForwardFragmentShader(const ShaderParameters ¶ms, FragmentShader *shader, + std::ostream &output) { std::ostream &source(output); source << "#version 400 core" << std::endl; @@ -53,12 +57,12 @@ in FRAG_DATA { source << R"( struct Material { - vec3 diffuse; - vec3 specular; - float roughness; - float metalness; - vec3 occlusion; - float shininess; + vec3 diffuse; + vec3 specular; + float roughness; + float metalness; + vec3 occlusion; + float shininess; }; )"; @@ -126,132 +130,143 @@ uniform vec3 u_camera_position; source << R"( float calculShadow(Light light) { - int caster_index = light.caster_index; - if (caster_index >= 0) { - vec4 fpos_light = u_light_casters[caster_index].vp * vec4(fs_in.wposition, 1.0); - vec3 proj_coords = fpos_light.xyz / fpos_light.w; - proj_coords = proj_coords * 0.5 + 0.5; - bool outOfLight = (proj_coords.x < 0 || proj_coords.x > 1 || proj_coords.y < 0 || proj_coords.y > 1); - if (outOfLight) - return 1.0; - float current_depth = proj_coords.z; - float bias = 0.00001; // max(0.05 * (1.0 - dot(normal_direction, -light.direction)), 0.005); - vec2 texel_size = 1.0 / textureSize(u_light_casters[caster_index].depth_map, 0); - float shadow = 0.0; - int total = 0; - for (int x = -2; x <= 2; x++) { - for (int y = -2; y <= 2; y++) { - float pcf_depth = texture(u_light_casters[caster_index].depth_map, proj_coords.xy + vec2(x, y) * texel_size).r; - shadow += current_depth - bias > pcf_depth ? 0.0 : 1.0; - total++; - } - } - return shadow / (total); - } - return 1.0; + int caster_index = light.caster_index; + if (caster_index >= 0) { + vec4 fpos_light = u_light_casters[caster_index].vp * vec4(fs_in.wposition, 1.0); + vec3 proj_coords = fpos_light.xyz / fpos_light.w; + proj_coords = proj_coords * 0.5 + 0.5; + bool outOfLight = (proj_coords.x < 0 || proj_coords.x > 1 || proj_coords.y < 0 || proj_coords.y > 1); + if (outOfLight) + return 1.0; + float current_depth = proj_coords.z; + float bias = 0.00001; // max(0.05 * (1.0 - dot(normal_direction, -light.direction)), 0.005); + vec2 texel_size = 1.0 / textureSize(u_light_casters[caster_index].depth_map, 0); + float shadow = 0.0; + int total = 0; + for (int x = -2; x <= 2; x++) { + for (int y = -2; y <= 2; y++) { + float pcf_depth = texture(u_light_casters[caster_index].depth_map, proj_coords.xy + vec2(x, y) * texel_size).r; + shadow += current_depth - bias > pcf_depth ? 0.0 : 1.0; + total++; + } + } + return shadow / (total); + } + return 1.0; } )"; source << R"( vec3 calculDirectionalLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcamera_position) { - vec3 color = vec3(0); - float shadow = calculShadow(light); - if (shadow <= 0.0) return color; - float d = distance(light.position, fs_in.wposition); - float attenuation = 1.0 / (light.attenuation.x + light.attenuation.y * d + light.attenuation.z * d * d); - vec3 light_direction = normalize(-light.direction); - float diffuse_intensity = clamp(dot(light_direction, normal_direction), 0.0, 1.0); - color += light.color * fragMat.diffuse * diffuse_intensity * attenuation * shadow * fragMat.occlusion; - if (diffuse_intensity > 0) { - vec3 reflection = reflect(-light_direction, normal_direction); - vec3 halfway_direction = normalize(fcamera_position + light_direction); - float specular_intensity = pow(clamp(dot(normal_direction, halfway_direction), 0.0, 1.0), fragMat.shininess); - color += diffuse_intensity * light.specular * fragMat.specular * specular_intensity * shadow; - } - return color; + vec3 color = vec3(0); + float shadow = calculShadow(light); + if (shadow <= 0.0) return color; + float d = distance(light.position, fs_in.wposition); + float attenuation = 1.0 / (light.attenuation.x + light.attenuation.y * d + light.attenuation.z * d * d); + vec3 light_direction = normalize(-light.direction); + float diffuse_intensity = clamp(dot(light_direction, normal_direction), 0.0, 1.0); + color += light.color * fragMat.diffuse * diffuse_intensity * attenuation * shadow * fragMat.occlusion; + if (diffuse_intensity > 0) { + vec3 reflection = reflect(-light_direction, normal_direction); + vec3 halfway_direction = normalize(fcamera_position + light_direction); + float specular_intensity = pow(clamp(dot(normal_direction, halfway_direction), 0.0, 1.0), fragMat.shininess); + color += diffuse_intensity * light.specular * fragMat.specular * specular_intensity * shadow; + } + return color; } )"; source << R"( vec3 calculSpotLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcamera_position) { - vec3 color = vec3(0); - float shadow = calculShadow(light); - if (shadow <= 0.0) return color; - float d = distance(light.position, fs_in.wposition); - float attenuation = 1.0 / (light.attenuation.x + light.attenuation.y * d + light.attenuation.z * d * d); - vec3 light_direction = normalize(light.position - fs_in.wposition); - float cosangle = cos(light.angle); - float spot_result = dot(-light_direction, light.direction); - if (spot_result > cosangle) { - float cosat = cos(light.angle - light.cone_attenuation); - attenuation *= clamp((spot_result - cosangle) / (cosat - cosangle), 0.0, 1.0); - float diffuse_intensity = clamp(dot(light_direction, normal_direction), 0.0, 1.0); - color += light.color * fragMat.diffuse * diffuse_intensity * attenuation * shadow * fragMat.occlusion; - if (diffuse_intensity > 0) { - vec3 reflection = reflect(-light_direction, normal_direction); - vec3 halfway_direction = normalize(fcamera_position + light_direction); - float specular_intensity = pow(clamp(dot(normal_direction, halfway_direction), 0.0, 1.0), fragMat.shininess); - color += diffuse_intensity * light.specular * fragMat.specular * specular_intensity * shadow; - } - } - return color; + vec3 color = vec3(0); + float shadow = calculShadow(light); + if (shadow <= 0.0) return color; + float d = distance(light.position, fs_in.wposition); + float attenuation = 1.0 / (light.attenuation.x + light.attenuation.y * d + light.attenuation.z * d * d); + vec3 light_direction = normalize(light.position - fs_in.wposition); + float cosangle = cos(light.angle); + float spot_result = dot(-light_direction, light.direction); + if (spot_result > cosangle) { + float cosat = cos(light.angle - light.cone_attenuation); + attenuation *= clamp((spot_result - cosangle) / (cosat - cosangle), 0.0, 1.0); + float diffuse_intensity = clamp(dot(light_direction, normal_direction), 0.0, 1.0); + color += light.color * fragMat.diffuse * diffuse_intensity * attenuation * shadow * fragMat.occlusion; + if (diffuse_intensity > 0) { + vec3 reflection = reflect(-light_direction, normal_direction); + vec3 halfway_direction = normalize(fcamera_position + light_direction); + float specular_intensity = pow(clamp(dot(normal_direction, halfway_direction), 0.0, 1.0), fragMat.shininess); + color += diffuse_intensity * light.specular * fragMat.specular * specular_intensity * shadow; + } + } + return color; } )"; source << R"( vec3 calculPointLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcamera_position) { - vec3 color = vec3(0); - float shadow = calculShadow(light); - if (shadow <= 0.0) return color; - float d = distance(light.position, fs_in.wposition); - float attenuation = 1.0 / (light.attenuation.x + light.attenuation.y * d + light.attenuation.z * d * d); - vec3 light_direction = normalize(light.position - fs_in.wposition); - float diffuse_intensity = clamp(dot(light_direction, normal_direction), 0.0, 1.0); - color += light.color * fragMat.diffuse * diffuse_intensity * attenuation * shadow * fragMat.occlusion; - if (diffuse_intensity > 0) { - vec3 reflection = reflect(-light_direction, normal_direction); - vec3 halfway_direction = normalize(fcamera_position + light_direction); - float specular_intensity = pow(clamp(dot(normal_direction, halfway_direction), 0.0, 1.0), fragMat.shininess); - color += diffuse_intensity * light.specular * fragMat.specular * specular_intensity * shadow; - } - return color; + vec3 color = vec3(0); + float shadow = calculShadow(light); + if (shadow <= 0.0) return color; + float d = distance(light.position, fs_in.wposition); + float attenuation = 1.0 / (light.attenuation.x + light.attenuation.y * d + light.attenuation.z * d * d); + vec3 light_direction = normalize(light.position - fs_in.wposition); + float diffuse_intensity = clamp(dot(light_direction, normal_direction), 0.0, 1.0); + color += light.color * fragMat.diffuse * diffuse_intensity * attenuation * shadow * fragMat.occlusion; + if (diffuse_intensity > 0) { + vec3 reflection = reflect(-light_direction, normal_direction); + vec3 halfway_direction = normalize(fcamera_position + light_direction); + float specular_intensity = pow(clamp(dot(normal_direction, halfway_direction), 0.0, 1.0), fragMat.shininess); + color += diffuse_intensity * light.specular * fragMat.specular * specular_intensity * shadow; + } + return color; } )"; source << R"( vec3 calculAmbiantLight(Light light, Material fragMat) { - return fragMat.diffuse * light.color * light.intensity * fragMat.occlusion; + return fragMat.diffuse * light.color * light.intensity * fragMat.occlusion; } )"; // directional = 1; spotlight = 2; pointlight = 3; ambiantlight = 4; source << R"( vec3 calculLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcamera_position) { - switch (light.type) { - case 1: // directional - return calculDirectionalLight(light, fragMat, normal_direction, fcamera_position); - case 2: // spotlight - return calculSpotLight(light, fragMat, normal_direction, fcamera_position); - case 3: // pointlight - return calculPointLight(light, fragMat, normal_direction, fcamera_position); - case 4: // ambiant - return calculAmbiantLight(light, fragMat); - default: - return vec3(0); - } + switch (light.type) { + case 1: // directional + return calculDirectionalLight(light, fragMat, normal_direction, fcamera_position); + case 2: // spotlight + return calculSpotLight(light, fragMat, normal_direction, fcamera_position); + case 3: // pointlight + return calculPointLight(light, fragMat, normal_direction, fcamera_position); + case 4: // ambiant + return calculAmbiantLight(light, fragMat); + default: + return vec3(0); + } } )"; + if (shader != nullptr) { + auto [contentType, content] = shader->getContent(); + + using ContentType = Scene::AShader::ContentType; + switch (contentType) { + case ContentType::SourceCode: source << content << std::endl; break; + case ContentType::SourceFile: source << Utils::readTextFile(content) << std::endl; break; + default: break; + } + } + source << "void main() {" << std::endl; // if ((texturebitmask & 128) != 0) { - // if (texture(texture_mask, (mask_transform * vec3(fs_in.uv, 1.0)).xy).a == 0.0) - // discard; + // if (texture(texture_mask, (mask_transform * vec3(fs_in.uv, 1.0)).xy).a == 0.0) + // discard; // } source << " Material fragMat;" << std::endl; @@ -301,6 +316,9 @@ vec3 calculLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcam assign_to_vec(params.occlusion, "occlusion"); assign_to_float(params.shininess, "shininess", 'x'); + if (shader) { + source << " " << shader->getFunction() << "(fragMat);" << std::endl; + } if (params.normal == ShaderParameters::Type::Texture) { source << " vec3 normal_value = normalize(texture(normal, fs_in.uv).xyz * 2 - 1);" << std::endl; diff --git a/examples/glsl_generator/main.cpp b/examples/glsl_generator/main.cpp index c04474c..1f55138 100644 --- a/examples/glsl_generator/main.cpp +++ b/examples/glsl_generator/main.cpp @@ -1,4 +1,5 @@ #include "config.h" +#include "Scene/Renderable/Shader.hpp" #include "Scene/Shader/ShaderGenerator.hpp" #include "Utils/FileSystem.hpp" #include "Utils/Json.hpp" @@ -66,18 +67,27 @@ void generateShaderOutput(const char *input_file, const char *output_file) { Json::Value input_json; Json::parseFile(input_file, input_json); + Json::Object &input_json_obj(input_json.get()); std::ofstream output_stream(output_file, std::ios::out | std::ios::trunc); + std::shared_ptr shader = nullptr; + if (input_json_obj.find("shader") != input_json_obj.end()) { + shader = std::make_shared(); + shader->setContent(Stone::Scene::AShader::ContentType::SourceCode, + input_json_obj["shader"].get()); + input_json_obj.erase("shader"); + } + Stone::Scene::ShaderParameters params = parseShaderParameters(input_json); Stone::Scene::ShaderGenerator generator; std::cout << "Generating shader: {" << std::endl; -#define __PRINT_SHADER_PARAM(param) std::cout << " -" << #param << " " << to_string(params.param) << std::endl; +#define __PRINT_SHADER_PARAM(param) std::cout << " " << #param << " " << to_string(params.param) << std::endl; FOR_EACH_SHADER_PARAMETERS(__PRINT_SHADER_PARAM) std::cout << "}" << std::endl; - generator.generateOpenGlForwardFragmentShader(params, output_stream); + generator.generateOpenGlForwardFragmentShader(params, shader.get(), output_stream); } std::string input; From b71e72f6b497c2846d45b0ee3233dc1557b7658d Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 13 Apr 2025 12:38:13 +0200 Subject: [PATCH 59/89] MeshNode get used material shortcut --- .../Render/src/Render/OpenGL/Renderable/MeshNode.cpp | 10 ++++------ Engine/Scene/include/Scene/Node/MeshNode.hpp | 2 ++ Engine/Scene/src/Scene/Node/MeshNode.cpp | 8 ++++++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp index 584f8eb..195c3af 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp @@ -15,12 +15,10 @@ namespace Stone::Render::OpenGL { MeshNode::MeshNode(Scene::MeshNode &meshNode, const std::shared_ptr &renderer) : _meshNode(meshNode), _material(nullptr), _shaderCollection(nullptr) { - if (_meshNode.getMaterial() != nullptr) { - assert(_meshNode.getMaterial()->isDirty() == false); - _material = _meshNode.getMaterial()->getRendererObject().get(); - } else if (_meshNode.getMesh() != nullptr && _meshNode.getMesh()->getDefaultMaterial() != nullptr) { - assert(_meshNode.getMesh()->getDefaultMaterial()->isDirty() == false); - _material = _meshNode.getMesh()->getDefaultMaterial()->getRendererObject().get(); + auto usedMaterial = _meshNode.getUsedMaterial(); + if (usedMaterial) { + assert(usedMaterial->isDirty() == false); + _material = usedMaterial->getRendererObject().get(); } if (_material != nullptr) { diff --git a/Engine/Scene/include/Scene/Node/MeshNode.hpp b/Engine/Scene/include/Scene/Node/MeshNode.hpp index 4c13783..617542c 100644 --- a/Engine/Scene/include/Scene/Node/MeshNode.hpp +++ b/Engine/Scene/include/Scene/Node/MeshNode.hpp @@ -26,6 +26,8 @@ class MeshNode : public RenderableNode { [[nodiscard]] std::shared_ptr getMaterial() const; void setMaterial(std::shared_ptr material); + [[nodiscard]] std::shared_ptr getUsedMaterial() const; + protected: std::shared_ptr _mesh; std::shared_ptr _material; diff --git a/Engine/Scene/src/Scene/Node/MeshNode.cpp b/Engine/Scene/src/Scene/Node/MeshNode.cpp index 97275e9..73f861a 100644 --- a/Engine/Scene/src/Scene/Node/MeshNode.cpp +++ b/Engine/Scene/src/Scene/Node/MeshNode.cpp @@ -37,6 +37,14 @@ void MeshNode::setMaterial(std::shared_ptr material) { markDirty(); } +std::shared_ptr MeshNode::getUsedMaterial() const { + if (_material) + return _material; + if (_mesh) + return _mesh->getDefaultMaterial(); + return nullptr; +} + const char *MeshNode::_termClassColor() const { return TERM_COLOR_BOLD TERM_COLOR_GREEN; } From bbc07a3674b682300e9e7f79d68f27df1ffadbee Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 13 Apr 2025 12:49:52 +0200 Subject: [PATCH 60/89] fix format --- Engine/Scene/src/Scene/Shader/ShaderParameters.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp index 4b830a5..f95cf6b 100644 --- a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp +++ b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp @@ -14,10 +14,13 @@ void ShaderParameters::setParamWithName(const std::string &name, Type value) { using ParamSetter = std::function; #define __MAP_NAME_TO_PARAM(param) \ - {#param, [](ShaderParameters &matParams, Type value) { \ - matParams.param = value; \ - }}, - + { \ + #param, [](ShaderParameters &matParams, Type value) { \ + matParams.param = value; \ + } \ + } \ + , + const static std::unordered_map paramSetters = { FOR_EACH_SHADER_PARAMETERS(__MAP_NAME_TO_PARAM) // }; From 3b2835dea83d05aecaec5e7eac3f13e0b8848f2b Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 13 Apr 2025 12:51:42 +0200 Subject: [PATCH 61/89] fix format --- Engine/Scene/src/Scene/Shader/ShaderParameters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp index f95cf6b..c4bad6a 100644 --- a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp +++ b/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp @@ -20,7 +20,7 @@ void ShaderParameters::setParamWithName(const std::string &name, Type value) { } \ } \ , - + const static std::unordered_map paramSetters = { FOR_EACH_SHADER_PARAMETERS(__MAP_NAME_TO_PARAM) // }; From a36f97cda787d36fcb6c949815c767b2947f991b Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 13 Apr 2025 20:01:45 +0200 Subject: [PATCH 62/89] OpenGLRenderer rename elements and resources --- .../include/Render/OpenGL/OpenGLRenderer.hpp | 4 +-- .../OpenGL/{ => GlElements}/GlFramebuffer.hpp | 0 .../{GBuffer.hpp => GlElements/GlGBuffer.hpp} | 8 ++--- .../OpenGL/{ => GlElements}/GlShaders.cpp | 0 .../OpenGL/{ => GlElements}/GlShaders.hpp | 2 +- .../ShaderPrograms.cpp} | 26 ++++++++-------- .../ShaderPrograms.hpp} | 8 ++--- .../src/Render/OpenGL/OpenGLRenderer.cpp | 3 +- .../src/Render/OpenGL/OpenGLResources.cpp | 31 ++++++++++--------- .../src/Render/OpenGL/OpenGLResources.hpp | 18 +++++++---- .../src/Render/OpenGL/RenderContext.hpp | 5 ++- .../OpenGL/Renderable/FragmentShader.hpp | 10 +++--- .../src/Render/OpenGL/Renderable/Material.cpp | 10 +++--- .../src/Render/OpenGL/Renderable/Material.hpp | 6 ++-- .../src/Render/OpenGL/Renderable/MeshNode.cpp | 12 +++---- .../src/Render/OpenGL/Renderable/MeshNode.hpp | 4 +-- 16 files changed, 77 insertions(+), 70 deletions(-) rename Engine/Render/src/Render/OpenGL/{ => GlElements}/GlFramebuffer.hpp (100%) rename Engine/Render/src/Render/OpenGL/{GBuffer.hpp => GlElements/GlGBuffer.hpp} (93%) rename Engine/Render/src/Render/OpenGL/{ => GlElements}/GlShaders.cpp (100%) rename Engine/Render/src/Render/OpenGL/{ => GlElements}/GlShaders.hpp (98%) rename Engine/Render/src/Render/OpenGL/{ShaderCollection.cpp => GlElements/ShaderPrograms.cpp} (72%) rename Engine/Render/src/Render/OpenGL/{ShaderCollection.hpp => GlElements/ShaderPrograms.hpp} (76%) diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index fdad95e..6a05f21 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -12,7 +12,7 @@ class WorldNode; namespace Stone::Render::OpenGL { class OpenGLResources; -struct GBuffer; +struct GlGBuffer; class OpenGLRenderer : public Renderer { public: @@ -37,7 +37,7 @@ class OpenGLRenderer : public Renderer { std::pair _frameSize; const RenderingMethod _method; std::shared_ptr _resources; - std::unique_ptr _gBuffer; + std::unique_ptr _gBuffer; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GlFramebuffer.hpp b/Engine/Render/src/Render/OpenGL/GlElements/GlFramebuffer.hpp similarity index 100% rename from Engine/Render/src/Render/OpenGL/GlFramebuffer.hpp rename to Engine/Render/src/Render/OpenGL/GlElements/GlFramebuffer.hpp diff --git a/Engine/Render/src/Render/OpenGL/GBuffer.hpp b/Engine/Render/src/Render/OpenGL/GlElements/GlGBuffer.hpp similarity index 93% rename from Engine/Render/src/Render/OpenGL/GBuffer.hpp rename to Engine/Render/src/Render/OpenGL/GlElements/GlGBuffer.hpp index e947888..7dc8b31 100644 --- a/Engine/Render/src/Render/OpenGL/GBuffer.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/GlGBuffer.hpp @@ -2,17 +2,17 @@ #pragma once +#include "../Renderable/Texture.hpp" #include "GlFramebuffer.hpp" #include "GlShaders.hpp" -#include "Renderable/Texture.hpp" #include namespace Stone::Render::OpenGL { -struct GBuffer { +struct GlGBuffer { - GBuffer(unsigned int width, unsigned int height) : width(width), height(height) { + GlGBuffer(unsigned int width, unsigned int height) : width(width), height(height) { glGenFramebuffers(1, &gBuffer); glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); @@ -66,7 +66,7 @@ void main() { frameMesh = std::make_shared(); } - virtual ~GBuffer() { + virtual ~GlGBuffer() { glDeleteFramebuffers(1, &gBuffer); } diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp similarity index 100% rename from Engine/Render/src/Render/OpenGL/GlShaders.cpp rename to Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp diff --git a/Engine/Render/src/Render/OpenGL/GlShaders.hpp b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp similarity index 98% rename from Engine/Render/src/Render/OpenGL/GlShaders.hpp rename to Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp index 5979882..e88b7ad 100644 --- a/Engine/Render/src/Render/OpenGL/GlShaders.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp @@ -2,7 +2,7 @@ #pragma once -#include "Renderable/Texture.hpp" +#include "../Renderable/Texture.hpp" #include "Scene/Renderable/Material.hpp" #include "Scene/Renderable/Shader.hpp" #include "Scene/Shader/ShaderParameters.hpp" diff --git a/Engine/Render/src/Render/OpenGL/ShaderCollection.cpp b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp similarity index 72% rename from Engine/Render/src/Render/OpenGL/ShaderCollection.cpp rename to Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp index 51fdbae..913aee5 100644 --- a/Engine/Render/src/Render/OpenGL/ShaderCollection.cpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp @@ -1,14 +1,14 @@ // Copyright 2024 Stone-Engine -#include "ShaderCollection.hpp" +#include "ShaderPrograms.hpp" +#include "../OpenGLResources.hpp" #include "GlShaders.hpp" -#include "OpenGLResources.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" namespace Stone::Render::OpenGL { -ShaderCollection::ShaderCollection(const std::shared_ptr &resources) : _resources(resources) { +ShaderPrograms::ShaderPrograms(const std::shared_ptr &resources) : _resources(resources) { Scene::ShaderParameters params; switch (resources->getRenderer().lock()->getRenderingMethod()) { case RenderingMethod::Forward: _glFragmentShader = GlFragmentShader::makeStandardForwardShader(params); break; @@ -16,12 +16,12 @@ ShaderCollection::ShaderCollection(const std::shared_ptr &resou } } -ShaderCollection::ShaderCollection(Scene::FragmentShader &shader, const std::shared_ptr &resources) +ShaderPrograms::ShaderPrograms(Scene::FragmentShader &shader, const std::shared_ptr &resources) : _resources(resources) { _glFragmentShader = std::make_unique(shader); } -ShaderCollection::ShaderCollection(Scene::Material &material, const std::shared_ptr &resources) +ShaderPrograms::ShaderPrograms(Scene::Material &material, const std::shared_ptr &resources) : _resources(resources) { Scene::ShaderParameters params; params.setFromMaterial(material); @@ -31,7 +31,7 @@ ShaderCollection::ShaderCollection(Scene::Material &material, const std::shared_ } } -void ShaderCollection::makeMeshProgram() { +void ShaderPrograms::makeMeshProgram() { if (_meshProgram != nullptr) return; @@ -43,7 +43,7 @@ void ShaderCollection::makeMeshProgram() { _meshProgram = std::make_unique(*vertexShader, *_glFragmentShader); } -void ShaderCollection::makeSkinMeshProgram() { +void ShaderPrograms::makeSkinMeshProgram() { if (_skinMeshProgram != nullptr) return; @@ -55,7 +55,7 @@ void ShaderCollection::makeSkinMeshProgram() { _skinMeshProgram = std::make_unique(*vertexShader, *_glFragmentShader); } -void ShaderCollection::makeInstancedMeshProgram() { +void ShaderPrograms::makeInstancedMeshProgram() { if (_instancedMeshProgram != nullptr) return; @@ -67,7 +67,7 @@ void ShaderCollection::makeInstancedMeshProgram() { _instancedMeshProgram = std::make_unique(*vertexShader, *_glFragmentShader); } -void ShaderCollection::makeProgram(Scene::MeshType meshType) { +void ShaderPrograms::makeProgram(Scene::MeshType meshType) { switch (meshType) { case Scene::MeshType::Standard: makeMeshProgram(); break; case Scene::MeshType::Skin: makeSkinMeshProgram(); break; @@ -75,19 +75,19 @@ void ShaderCollection::makeProgram(Scene::MeshType meshType) { } } -const std::unique_ptr &ShaderCollection::getMeshProgram() const { +const std::unique_ptr &ShaderPrograms::getMeshProgram() const { return _meshProgram; } -const std::unique_ptr &ShaderCollection::getSkinMeshProgram() const { +const std::unique_ptr &ShaderPrograms::getSkinMeshProgram() const { return _skinMeshProgram; } -const std::unique_ptr &ShaderCollection::getInstancedMeshProgram() const { +const std::unique_ptr &ShaderPrograms::getInstancedMeshProgram() const { return _instancedMeshProgram; } -GlShaderProgram *ShaderCollection::getProgram(Scene::MeshType meshType) const { +GlShaderProgram *ShaderPrograms::getProgram(Scene::MeshType meshType) const { switch (meshType) { case Scene::MeshType::Standard: return _meshProgram.get(); case Scene::MeshType::Skin: return _skinMeshProgram.get(); diff --git a/Engine/Render/src/Render/OpenGL/ShaderCollection.hpp b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp similarity index 76% rename from Engine/Render/src/Render/OpenGL/ShaderCollection.hpp rename to Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp index 09ed566..26db901 100644 --- a/Engine/Render/src/Render/OpenGL/ShaderCollection.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp @@ -8,11 +8,11 @@ namespace Stone::Render::OpenGL { -class ShaderCollection { +class ShaderPrograms { public: - ShaderCollection(const std::shared_ptr &resources); - ShaderCollection(Scene::FragmentShader &shader, const std::shared_ptr &resources); - ShaderCollection(Scene::Material &material, const std::shared_ptr &resources); + ShaderPrograms(const std::shared_ptr &resources); + ShaderPrograms(Scene::FragmentShader &shader, const std::shared_ptr &resources); + ShaderPrograms(Scene::Material &material, const std::shared_ptr &resources); void makeMeshProgram(); void makeSkinMeshProgram(); diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index c9ba911..db56911 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -3,6 +3,7 @@ #include "Render/OpenGL/OpenGLRenderer.hpp" +#include "GlElements/GlGBuffer.hpp" #include "OpenGLResources.hpp" #include "RenderContext.hpp" #include "RendererObjectManager.hpp" @@ -89,7 +90,7 @@ void OpenGLRenderer::updateFrameSize(std::pair size) { if (_method == RenderingMethod::Deferred) { if (_gBuffer) _gBuffer.reset(); - _gBuffer = std::make_unique(_frameSize.first, _frameSize.second); + _gBuffer = std::make_unique(_frameSize.first, _frameSize.second); } } diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index 351da83..f76179b 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -2,8 +2,8 @@ #include "OpenGLResources.hpp" +#include "GlElements/ShaderPrograms.hpp" #include "Scene/Renderable/Material.hpp" -#include "ShaderCollection.hpp" namespace Stone::Render::OpenGL { @@ -11,6 +11,12 @@ OpenGLResources::OpenGLResources(const std::shared_ptr &renderer : std::enable_shared_from_this(), _renderer(renderer) { } +const std::weak_ptr OpenGLResources::getRenderer() const { + return _renderer; +} + +// MARK: Vertex Shaders + const std::unique_ptr &OpenGLResources::getMeshVertexShader() { if (_meshVertexShader == nullptr) { _meshVertexShader = GlVertexShader::makeStandardMeshShader(); @@ -32,16 +38,15 @@ const std::unique_ptr &OpenGLResources::getInstancedMeshVertexSh return _instancedMeshVertexShader; } -GlVertexShader *OpenGLResources::getVertexShader(Scene::MeshType meshType) { +const std::unique_ptr &OpenGLResources::getVertexShader(Scene::MeshType meshType) { switch (meshType) { - case Scene::MeshType::Standard: return getMeshVertexShader().get(); - case Scene::MeshType::Skin: return getSkinMeshVertexShader().get(); - case Scene::MeshType::Instanced: return getInstancedMeshVertexShader().get(); - default: return nullptr; + case Scene::MeshType::Standard: return getMeshVertexShader(); + case Scene::MeshType::Skin: return getSkinMeshVertexShader(); + case Scene::MeshType::Instanced: return getInstancedMeshVertexShader(); } + assert(false); } - const std::unique_ptr &OpenGLResources::getFragmentShader(Scene::ShaderParameters params) { auto renderer = getRenderer().lock(); assert(renderer != nullptr); @@ -58,15 +63,11 @@ const std::unique_ptr &OpenGLResources::getFragmentShader(Scen } } -const std::unique_ptr &OpenGLResources::getDefaultShaderCollection() { - if (_defaultShaderCollection == nullptr) { - _defaultShaderCollection = std::make_unique(shared_from_this()); +const std::unique_ptr &OpenGLResources::getDefaultShaderPrograms() { + if (_defaultShaderPrograms == nullptr) { + _defaultShaderPrograms = std::make_unique(shared_from_this()); } - return _defaultShaderCollection; -} - -const std::weak_ptr OpenGLResources::getRenderer() const { - return _renderer; + return _defaultShaderPrograms; } } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp index 5702b42..8b07a92 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp @@ -2,9 +2,9 @@ #pragma once -#include "GlShaders.hpp" +#include "GlElements/GlShaders.hpp" +#include "GlElements/ShaderPrograms.hpp" #include "Scene/Shader/ShaderParameters.hpp" -#include "ShaderCollection.hpp" namespace Stone::Render::OpenGL { @@ -18,16 +18,22 @@ class OpenGLResources : std::enable_shared_from_this { virtual ~OpenGLResources() = default; + const std::weak_ptr getRenderer() const; + + // MARK: Vertex Shaders + const std::unique_ptr &getMeshVertexShader(); const std::unique_ptr &getSkinMeshVertexShader(); const std::unique_ptr &getInstancedMeshVertexShader(); - GlVertexShader *getVertexShader(Scene::MeshType meshType); + const std::unique_ptr &getVertexShader(Scene::MeshType meshType); + + // MARK: Fragment Shaders const std::unique_ptr &getFragmentShader(Scene::ShaderParameters params); - const std::unique_ptr &getDefaultShaderCollection(); + // MARK: Shader Programs - const std::weak_ptr getRenderer() const; + const std::unique_ptr &getDefaultShaderPrograms(); private: std::weak_ptr _renderer; @@ -38,7 +44,7 @@ class OpenGLResources : std::enable_shared_from_this { std::unordered_map> _fragmentShaders; - std::unique_ptr _defaultShaderCollection; + std::unique_ptr _defaultShaderPrograms; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/RenderContext.hpp b/Engine/Render/src/Render/OpenGL/RenderContext.hpp index 509cd1e..50f8113 100644 --- a/Engine/Render/src/Render/OpenGL/RenderContext.hpp +++ b/Engine/Render/src/Render/OpenGL/RenderContext.hpp @@ -2,17 +2,16 @@ #pragma once -#include "GBuffer.hpp" #include "Scene/Renderer/RenderContext.hpp" #include namespace Stone::Render::OpenGL { -class OpenGLRenderer; +struct GlGBuffer; struct RenderContext : public Scene::RenderContext { - GBuffer *gBuffer; + GlGBuffer *gBuffer; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp b/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp index d198992..6f94f50 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp @@ -2,7 +2,7 @@ #pragma once -#include "../ShaderCollection.hpp" +#include "../GlElements/ShaderPrograms.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Shader.hpp" @@ -11,19 +11,19 @@ namespace Stone::Render::OpenGL { class FragmentShader : public Scene::IRendererObject { public: FragmentShader(Scene::FragmentShader &fragmentShader, const std::shared_ptr &renderer) { - _shaderCollection = std::make_shared(fragmentShader, renderer->getOpenGLResources()); + _shaderPrograms = std::make_shared(fragmentShader, renderer->getOpenGLResources()); } void render(Scene::RenderContext &context) override { (void)context; } - const std::shared_ptr &getShaderCollection() const { - return _shaderCollection; + const std::shared_ptr &getShaderPrograms() const { + return _shaderPrograms; } private: - std::shared_ptr _shaderCollection; + std::shared_ptr _shaderPrograms; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp index de0a570..b0a5888 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp @@ -8,9 +8,9 @@ namespace Stone::Render::OpenGL { Material::Material(Scene::Material &material, const std::shared_ptr &renderer) : _material(material) { if (_material.getFragmentShader() == nullptr) { - _shaderCollection = std::make_shared(material, renderer->getOpenGLResources()); + _shaderPrograms = std::make_shared(material, renderer->getOpenGLResources()); } else { - _shaderCollection = _material.getFragmentShader()->getRendererObject()->getShaderCollection(); + _shaderPrograms = _material.getFragmentShader()->getRendererObject()->getShaderPrograms(); } #ifndef NDEBUG @@ -28,7 +28,7 @@ void Material::render(Scene::RenderContext &context) { } void Material::setUniforms(Scene::MeshType meshType) { - GlShaderProgram *program = _shaderCollection->getProgram(meshType); + GlShaderProgram *program = _shaderPrograms->getProgram(meshType); assert(program != nullptr); program->use(); @@ -48,8 +48,8 @@ void Material::setUniforms(Scene::MeshType meshType) { }); } -const std::shared_ptr &Material::getShaderCollection() const { - return _shaderCollection; +const std::shared_ptr &Material::getShaderPrograms() const { + return _shaderPrograms; } diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp index c453b9e..b3ce352 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp @@ -10,7 +10,7 @@ namespace Stone::Render::OpenGL { -class ShaderCollection; +class ShaderPrograms; class Material : public Scene::IRendererObject { public: @@ -22,11 +22,11 @@ class Material : public Scene::IRendererObject { void setUniforms(Scene::MeshType meshType); - const std::shared_ptr &getShaderCollection() const; + const std::shared_ptr &getShaderPrograms() const; private: Scene::Material &_material; - std::shared_ptr _shaderCollection; + std::shared_ptr _shaderPrograms; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp index 195c3af..4993fea 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp @@ -13,7 +13,7 @@ namespace Stone::Render::OpenGL { MeshNode::MeshNode(Scene::MeshNode &meshNode, const std::shared_ptr &renderer) - : _meshNode(meshNode), _material(nullptr), _shaderCollection(nullptr) { + : _meshNode(meshNode), _material(nullptr), _shaderPrograms(nullptr) { auto usedMaterial = _meshNode.getUsedMaterial(); if (usedMaterial) { @@ -22,13 +22,13 @@ MeshNode::MeshNode(Scene::MeshNode &meshNode, const std::shared_ptrgetShaderCollection().get(); + _shaderPrograms = _material->getShaderPrograms().get(); } else { - _shaderCollection = renderer->getOpenGLResources()->getDefaultShaderCollection().get(); + _shaderPrograms = renderer->getOpenGLResources()->getDefaultShaderPrograms().get(); } - assert(_shaderCollection != nullptr); + assert(_shaderPrograms != nullptr); - _shaderCollection->makeMeshProgram(); + _shaderPrograms->makeMeshProgram(); } void MeshNode::render(Scene::RenderContext &context) { @@ -42,7 +42,7 @@ void MeshNode::render(Scene::RenderContext &context) { } const VRAMMesh &vramMesh = rendererMesh->getVRAMMesh(); - GlShaderProgram *program = _shaderCollection->getMeshProgram().get(); + GlShaderProgram *program = _shaderPrograms->getMeshProgram().get(); program->use(); if (_material != nullptr) { diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp index 57cbbfd..0b6a65e 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp @@ -8,7 +8,7 @@ namespace Stone::Render::OpenGL { class Material; class OpenGLRenderer; -class ShaderCollection; +class ShaderPrograms; class MeshNode : public Scene::IRendererObject { public: @@ -21,7 +21,7 @@ class MeshNode : public Scene::IRendererObject { private: Scene::MeshNode &_meshNode; Material *_material; - ShaderCollection *_shaderCollection; + ShaderPrograms *_shaderPrograms; }; } // namespace Stone::Render::OpenGL From b2e82a2cc14867e6418fa9a6674e77b298419112 Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 13 Apr 2025 20:11:02 +0200 Subject: [PATCH 63/89] rename RendererObjectManager to RendererObjectFactory --- .../src/Render/OpenGL/OpenGLRenderer.cpp | 8 ++--- ...tManager.cpp => RendererObjectFactory.cpp} | 8 ++--- ...tManager.hpp => RendererObjectFactory.hpp} | 9 +++-- ...tManager.cpp => RendererObjectFactory.cpp} | 26 +++++++------- ...tManager.hpp => RendererObjectFactory.hpp} | 10 +++--- .../Vulkan/VulkanRenderer_ISceneRenderer.cpp | 8 ++--- Engine/Scene/include/Scene.hpp | 2 +- .../include/Scene/Renderable/IRenderable.hpp | 4 +-- ...tManager.hpp => RendererObjectFactory.hpp} | 8 ++--- .../Scene/src/Scene/Renderable/Material.cpp | 2 +- ...tManager.cpp => RendererObjectFactory.cpp} | 34 +++++++++---------- 11 files changed, 59 insertions(+), 60 deletions(-) rename Engine/Render/src/Render/OpenGL/{RendererObjectManager.cpp => RendererObjectFactory.cpp} (87%) rename Engine/Render/src/Render/OpenGL/{RendererObjectManager.hpp => RendererObjectFactory.hpp} (78%) rename Engine/Render/src/Render/Vulkan/{RendererObjectManager.cpp => RendererObjectFactory.cpp} (68%) rename Engine/Render/src/Render/Vulkan/{RendererObjectManager.hpp => RendererObjectFactory.hpp} (76%) rename Engine/Scene/include/Scene/Renderer/{RendererObjectManager.hpp => RendererObjectFactory.hpp} (96%) rename Engine/Scene/src/Scene/Renderer/{RendererObjectManager.cpp => RendererObjectFactory.cpp} (75%) diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index db56911..22c02c3 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -6,7 +6,7 @@ #include "GlElements/GlGBuffer.hpp" #include "OpenGLResources.hpp" #include "RenderContext.hpp" -#include "RendererObjectManager.hpp" +#include "RendererObjectFactory.hpp" #include "Scene/Node/WorldNode.hpp" #include @@ -35,11 +35,11 @@ OpenGLRenderer::~OpenGLRenderer() { } void OpenGLRenderer::updateDataForWorld(const std::shared_ptr &world) { - OpenGL::RendererObjectManager manager(std::static_pointer_cast(shared_from_this())); - world->traverseTopDown([&manager](const std::shared_ptr &node) { + OpenGL::RendererObjectFactory factory(std::static_pointer_cast(shared_from_this())); + world->traverseTopDown([&factory](const std::shared_ptr &node) { auto renderElement = std::dynamic_pointer_cast(node); if (renderElement && renderElement->isDirty()) { - manager.updateRenderable(node); + factory.updateRenderable(node); } }); } diff --git a/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp b/Engine/Render/src/Render/OpenGL/RendererObjectFactory.cpp similarity index 87% rename from Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp rename to Engine/Render/src/Render/OpenGL/RendererObjectFactory.cpp index 4aaee7a..08b8bc8 100644 --- a/Engine/Render/src/Render/OpenGL/RendererObjectManager.cpp +++ b/Engine/Render/src/Render/OpenGL/RendererObjectFactory.cpp @@ -1,6 +1,6 @@ // Copyright 2024 Stone-Engine -#include "RendererObjectManager.hpp" +#include "RendererObjectFactory.hpp" #include "Renderable/FragmentShader.hpp" #include "Renderable/InstancedMeshNode.hpp" @@ -13,8 +13,8 @@ #define UPDATE_RENDERER_OBJECT(RenderableClass, object) \ - void RendererObjectManager::update##RenderableClass(const std::shared_ptr &(object)) { \ - Scene::RendererObjectManager::update##RenderableClass((object)); \ + void RendererObjectFactory::update##RenderableClass(const std::shared_ptr &(object)) { \ + Scene::RendererObjectFactory::update##RenderableClass((object)); \ \ auto new##RenderableClass = std::make_shared(*(object), _renderer); \ updateRendererObject(*(object), new##RenderableClass); \ @@ -23,7 +23,7 @@ namespace Stone::Render::OpenGL { -RendererObjectManager::RendererObjectManager(std::shared_ptr renderer) +RendererObjectFactory::RendererObjectFactory(std::shared_ptr renderer) : _renderer(std::move(renderer)) { } diff --git a/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp b/Engine/Render/src/Render/OpenGL/RendererObjectFactory.hpp similarity index 78% rename from Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp rename to Engine/Render/src/Render/OpenGL/RendererObjectFactory.hpp index 64fbb70..ef12b98 100644 --- a/Engine/Render/src/Render/OpenGL/RendererObjectManager.hpp +++ b/Engine/Render/src/Render/OpenGL/RendererObjectFactory.hpp @@ -2,19 +2,18 @@ #pragma once -#include "Scene/Renderer/RendererObjectManager.hpp" +#include "Scene/Renderer/RendererObjectFactory.hpp" namespace Stone::Render::OpenGL { class OpenGLRenderer; -class RendererObjectManager : public Scene::RendererObjectManager { +class RendererObjectFactory : public Scene::RendererObjectFactory { public: - explicit RendererObjectManager(std::shared_ptr renderer); - RendererObjectManager(const RendererObjectManager &other) = default; + explicit RendererObjectFactory(std::shared_ptr renderer); - ~RendererObjectManager() override = default; + ~RendererObjectFactory() override = default; void updateMeshNode(const std::shared_ptr &meshNode) override; void updateInstancedMeshNode(const std::shared_ptr &instancedMeshNode) override; diff --git a/Engine/Render/src/Render/Vulkan/RendererObjectManager.cpp b/Engine/Render/src/Render/Vulkan/RendererObjectFactory.cpp similarity index 68% rename from Engine/Render/src/Render/Vulkan/RendererObjectManager.cpp rename to Engine/Render/src/Render/Vulkan/RendererObjectFactory.cpp index 0bfb97d..f7a8054 100644 --- a/Engine/Render/src/Render/Vulkan/RendererObjectManager.cpp +++ b/Engine/Render/src/Render/Vulkan/RendererObjectFactory.cpp @@ -1,6 +1,6 @@ // Copyright 2024 Stone-Engine -#include "RendererObjectManager.hpp" +#include "RendererObjectFactory.hpp" #include "Device.hpp" #include "Render/Vulkan/VulkanRenderer.hpp" @@ -17,12 +17,12 @@ namespace Stone::Render::Vulkan { -RendererObjectManager::RendererObjectManager(const std::shared_ptr &renderer) - : Scene::RendererObjectManager(), _renderer(renderer) { +RendererObjectFactory::RendererObjectFactory(const std::shared_ptr &renderer) + : Scene::RendererObjectFactory(), _renderer(renderer) { } -void RendererObjectManager::updateMeshNode(const std::shared_ptr &meshNode) { - Scene::RendererObjectManager::updateMeshNode(meshNode); +void RendererObjectFactory::updateMeshNode(const std::shared_ptr &meshNode) { + Scene::RendererObjectFactory::updateMeshNode(meshNode); if (meshNode->getRendererObject()) { return; @@ -32,8 +32,8 @@ void RendererObjectManager::updateMeshNode(const std::shared_ptr &material) { - Scene::RendererObjectManager::updateMaterial(material); +void RendererObjectFactory::updateMaterial(const std::shared_ptr &material) { + Scene::RendererObjectFactory::updateMaterial(material); if (material->getRendererObject()) { return; @@ -43,8 +43,8 @@ void RendererObjectManager::updateMaterial(const std::shared_ptr &mesh) { - Scene::RendererObjectManager::updateDynamicMesh(mesh); +void RendererObjectFactory::updateDynamicMesh(const std::shared_ptr &mesh) { + Scene::RendererObjectFactory::updateDynamicMesh(mesh); if (mesh->getRendererObject()) { return; @@ -54,8 +54,8 @@ void RendererObjectManager::updateDynamicMesh(const std::shared_ptr &texture) { - Scene::RendererObjectManager::updateTexture(texture); +void RendererObjectFactory::updateTexture(const std::shared_ptr &texture) { + Scene::RendererObjectFactory::updateTexture(texture); if (texture->getRendererObject()) { return; @@ -65,8 +65,8 @@ void RendererObjectManager::updateTexture(const std::shared_ptr updateRendererObject(*texture, newTexture); } -void RendererObjectManager::updateFragmentShader(const std::shared_ptr &shader) { - Scene::RendererObjectManager::updateFragmentShader(shader); +void RendererObjectFactory::updateFragmentShader(const std::shared_ptr &shader) { + Scene::RendererObjectFactory::updateFragmentShader(shader); if (shader->getRendererObject()) { return; diff --git a/Engine/Render/src/Render/Vulkan/RendererObjectManager.hpp b/Engine/Render/src/Render/Vulkan/RendererObjectFactory.hpp similarity index 76% rename from Engine/Render/src/Render/Vulkan/RendererObjectManager.hpp rename to Engine/Render/src/Render/Vulkan/RendererObjectFactory.hpp index 7cfdf5a..9bf35f5 100644 --- a/Engine/Render/src/Render/Vulkan/RendererObjectManager.hpp +++ b/Engine/Render/src/Render/Vulkan/RendererObjectFactory.hpp @@ -2,7 +2,7 @@ #pragma once -#include "Scene/Renderer/RendererObjectManager.hpp" +#include "Scene/Renderer/RendererObjectFactory.hpp" #include @@ -10,12 +10,12 @@ namespace Stone::Render::Vulkan { class VulkanRenderer; -class RendererObjectManager : public Scene::RendererObjectManager { +class RendererObjectFactory : public Scene::RendererObjectFactory { public: - RendererObjectManager(const std::shared_ptr &renderer); - RendererObjectManager(const RendererObjectManager &other) = default; - ~RendererObjectManager() override = default; + RendererObjectFactory(const std::shared_ptr &renderer); + RendererObjectFactory(const RendererObjectFactory &other) = default; + ~RendererObjectFactory() override = default; void updateMeshNode(const std::shared_ptr &meshNode) override; diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp index c185868..2431bce 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp @@ -4,7 +4,7 @@ #include "FramesRenderer.hpp" #include "Render/Vulkan/VulkanRenderer.hpp" #include "RenderContext.hpp" -#include "RendererObjectManager.hpp" +#include "RendererObjectFactory.hpp" #include "RenderPass.hpp" #include "Scene.hpp" #include "SwapChain.hpp" @@ -12,11 +12,11 @@ namespace Stone::Render::Vulkan { void VulkanRenderer::updateDataForWorld(const std::shared_ptr &world) { - RendererObjectManager manager(std::static_pointer_cast(shared_from_this())); - world->traverseTopDown([&manager](const std::shared_ptr &node) { + RendererObjectFactory factory(std::static_pointer_cast(shared_from_this())); + world->traverseTopDown([&factory](const std::shared_ptr &node) { auto renderElement = std::dynamic_pointer_cast(node); if (renderElement && renderElement->isDirty()) { - manager.updateRenderable(node); + factory.updateRenderable(node); } }); } diff --git a/Engine/Scene/include/Scene.hpp b/Engine/Scene/include/Scene.hpp index b4549c2..700acc4 100644 --- a/Engine/Scene/include/Scene.hpp +++ b/Engine/Scene/include/Scene.hpp @@ -19,6 +19,6 @@ #include "Scene/Renderable/Texture.hpp" #include "Scene/Renderer/ISceneRenderer.hpp" #include "Scene/Renderer/RenderContext.hpp" -#include "Scene/Renderer/RendererObjectManager.hpp" +#include "Scene/Renderer/RendererObjectFactory.hpp" #include "Scene/Transform.hpp" #include "Scene/Vertex.hpp" diff --git a/Engine/Scene/include/Scene/Renderable/IRenderable.hpp b/Engine/Scene/include/Scene/Renderable/IRenderable.hpp index f19f317..12cafc0 100644 --- a/Engine/Scene/include/Scene/Renderable/IRenderable.hpp +++ b/Engine/Scene/include/Scene/Renderable/IRenderable.hpp @@ -31,7 +31,7 @@ class IRendererObject { virtual void render(RenderContext &context) = 0; }; -class RendererObjectManager; +class RendererObjectFactory; /** * @brief Interface for renderable elements @@ -82,7 +82,7 @@ class IRenderable { } protected: - friend class RendererObjectManager; + friend class RendererObjectFactory; /** * @brief Set the renderer object diff --git a/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp b/Engine/Scene/include/Scene/Renderer/RendererObjectFactory.hpp similarity index 96% rename from Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp rename to Engine/Scene/include/Scene/Renderer/RendererObjectFactory.hpp index a55d1c0..113b631 100644 --- a/Engine/Scene/include/Scene/Renderer/RendererObjectManager.hpp +++ b/Engine/Scene/include/Scene/Renderer/RendererObjectFactory.hpp @@ -12,17 +12,17 @@ class Object; namespace Stone::Scene { /** - * @class RendererObjectManager + * @class RendererObjectFactory * @brief Provide basic overridable methods to manage the renderables objects elements in the scene. * * This class provides basic methods to update the renderer data of classes implementing the IRenderable interface. * It will store an instance of IRendererObject in the IRenderable::_rendererObject proprety. * Each IRenderable objects will use the appropriate method in this interface to update itself. */ -class RendererObjectManager { +class RendererObjectFactory { public: - RendererObjectManager() = default; - virtual ~RendererObjectManager() = default; + RendererObjectFactory() = default; + virtual ~RendererObjectFactory() = default; /** * Updates the renderable object with the given node. diff --git a/Engine/Scene/src/Scene/Renderable/Material.cpp b/Engine/Scene/src/Scene/Renderable/Material.cpp index 4f6524c..d46a843 100644 --- a/Engine/Scene/src/Scene/Renderable/Material.cpp +++ b/Engine/Scene/src/Scene/Renderable/Material.cpp @@ -3,7 +3,7 @@ #include "Scene/Renderable/Material.hpp" #include "Scene/Renderable/Texture.hpp" -#include "Scene/Renderer/RendererObjectManager.hpp" +#include "Scene/Renderer/RendererObjectFactory.hpp" #include "Utils/Glm.hpp" namespace Stone::Scene { diff --git a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp b/Engine/Scene/src/Scene/Renderer/RendererObjectFactory.cpp similarity index 75% rename from Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp rename to Engine/Scene/src/Scene/Renderer/RendererObjectFactory.cpp index 9e1b508..429a81e 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererObjectManager.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererObjectFactory.cpp @@ -1,17 +1,17 @@ // Copyright 2024 Stone-Engine -#include "Scene/Renderer/RendererObjectManager.hpp" +#include "Scene/Renderer/RendererObjectFactory.hpp" #include "Scene.hpp" namespace Stone::Scene { -using CastFunction = std::function &)>; +using CastFunction = std::function &)>; #define CASTED_FUNCTION_MAP_ENTRY(ClassName) \ {ClassName::StaticHashCode(), \ - [](RendererObjectManager &manager, const std::shared_ptr &renderable) { \ - manager.update##ClassName(std::static_pointer_cast(renderable)); \ + [](RendererObjectFactory &factory, const std::shared_ptr &renderable) { \ + factory.update##ClassName(std::static_pointer_cast(renderable)); \ }} const std::unordered_map updateCastedFunctions = { @@ -23,35 +23,35 @@ const std::unordered_map updateCastedFunctions = { CASTED_FUNCTION_MAP_ENTRY(FragmentShader), }; -void RendererObjectManager::updateRenderable(const std::shared_ptr &renderable) { +void RendererObjectFactory::updateRenderable(const std::shared_ptr &renderable) { auto it = updateCastedFunctions.find(renderable->getClassHashCode()); if (it != updateCastedFunctions.end()) { it->second(*this, renderable); } } -void RendererObjectManager::updateMeshNode(const std::shared_ptr &meshNode) { +void RendererObjectFactory::updateMeshNode(const std::shared_ptr &meshNode) { if (meshNode->getMaterial() && meshNode->getMaterial()->isDirty()) updateMaterial(meshNode->getMaterial()); if (meshNode->getMesh() && meshNode->getMesh()->isDirty()) updateRenderable(meshNode->getMesh()); } -void RendererObjectManager::updateInstancedMeshNode(const std::shared_ptr &instancedMeshNode) { +void RendererObjectFactory::updateInstancedMeshNode(const std::shared_ptr &instancedMeshNode) { if (instancedMeshNode->getMaterial() && instancedMeshNode->getMaterial()->isDirty()) updateMaterial(instancedMeshNode->getMaterial()); if (instancedMeshNode->getMesh() && instancedMeshNode->getMesh()->isDirty()) updateRenderable(instancedMeshNode->getMesh()); } -void RendererObjectManager::updateSkinMeshNode(const std::shared_ptr &skinMeshNode) { +void RendererObjectFactory::updateSkinMeshNode(const std::shared_ptr &skinMeshNode) { if (skinMeshNode->getMaterial() && skinMeshNode->getMaterial()->isDirty()) updateMaterial(skinMeshNode->getMaterial()); if (skinMeshNode->getSkinMesh() && skinMeshNode->getSkinMesh()->isDirty()) updateRenderable(skinMeshNode->getSkinMesh()); } -void RendererObjectManager::updateMaterial(const std::shared_ptr &material) { +void RendererObjectFactory::updateMaterial(const std::shared_ptr &material) { auto fragmentShader = material->getFragmentShader(); if (fragmentShader && fragmentShader->isDirty()) { updateFragmentShader(fragmentShader); @@ -63,39 +63,39 @@ void RendererObjectManager::updateMaterial(const std::shared_ptr &mate }); } -void RendererObjectManager::updateDynamicMesh(const std::shared_ptr &mesh) { +void RendererObjectFactory::updateDynamicMesh(const std::shared_ptr &mesh) { if (mesh->getDefaultMaterial() && mesh->getDefaultMaterial()->isDirty()) updateMaterial(mesh->getDefaultMaterial()); } -void RendererObjectManager::updateStaticMesh(const std::shared_ptr &mesh) { +void RendererObjectFactory::updateStaticMesh(const std::shared_ptr &mesh) { if (mesh->getDefaultMaterial() && mesh->getDefaultMaterial()->isDirty()) updateMaterial(mesh->getDefaultMaterial()); } -void RendererObjectManager::updateDynamicSkinMesh(const std::shared_ptr &skinmesh) { +void RendererObjectFactory::updateDynamicSkinMesh(const std::shared_ptr &skinmesh) { if (skinmesh->getDefaultMaterial() && skinmesh->getDefaultMaterial()->isDirty()) updateMaterial(skinmesh->getDefaultMaterial()); } -void RendererObjectManager::updateStaticSkinMesh(const std::shared_ptr &skinmesh) { +void RendererObjectFactory::updateStaticSkinMesh(const std::shared_ptr &skinmesh) { if (skinmesh->getDefaultMaterial() && skinmesh->getDefaultMaterial()->isDirty()) updateMaterial(skinmesh->getDefaultMaterial()); } -void RendererObjectManager::updateWireframeShape(const std::shared_ptr &shape) { +void RendererObjectFactory::updateWireframeShape(const std::shared_ptr &shape) { (void)shape; } -void RendererObjectManager::updateTexture(const std::shared_ptr &texture) { +void RendererObjectFactory::updateTexture(const std::shared_ptr &texture) { (void)texture; } -void RendererObjectManager::updateFragmentShader(const std::shared_ptr &shader) { +void RendererObjectFactory::updateFragmentShader(const std::shared_ptr &shader) { (void)shader; } -void RendererObjectManager::updateRendererObject(IRenderable &element, +void RendererObjectFactory::updateRendererObject(IRenderable &element, const std::shared_ptr &rendererObject) { element.setRendererObject(rendererObject); element.markUndirty(); From cb44c5ea6c68cff11473242c4c71b8972c434e61 Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 13 Apr 2025 21:43:02 +0200 Subject: [PATCH 64/89] RendererObjectFactory take responsibility of traversing node tree --- Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp | 2 +- Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp | 2 +- Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp | 9 ++------- .../src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp | 9 ++------- Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp | 2 +- .../include/Scene/Renderer/RendererObjectFactory.hpp | 7 +++++++ .../Scene/src/Scene/Renderer/RendererObjectFactory.cpp | 9 +++++++++ Engine/Window/src/Window/Window.cpp | 2 +- 8 files changed, 24 insertions(+), 18 deletions(-) diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index 6a05f21..4aad671 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -24,7 +24,7 @@ class OpenGLRenderer : public Renderer { /** Renderer */ - void updateDataForWorld(const std::shared_ptr &world) override; + void updateRenderablesInNode(const std::shared_ptr &rootNode) override; void renderWorld(const std::shared_ptr &world) override; void updateFrameSize(std::pair size) override; diff --git a/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp b/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp index a43fffa..ecb7eaf 100644 --- a/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp +++ b/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp @@ -27,7 +27,7 @@ class VulkanRenderer : public Renderer { /** Renderer */ - void updateDataForWorld(const std::shared_ptr &world) override; + void updateRenderablesInNode(const std::shared_ptr &rootNode) override; void renderWorld(const std::shared_ptr &world) override; void updateFrameSize(std::pair size) override; diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index 22c02c3..32e115c 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -34,14 +34,9 @@ OpenGLRenderer::~OpenGLRenderer() { std::cout << "OpenGLRenderer destroyed" << std::endl; } -void OpenGLRenderer::updateDataForWorld(const std::shared_ptr &world) { +void OpenGLRenderer::updateRenderablesInNode(const std::shared_ptr &rootNode) { OpenGL::RendererObjectFactory factory(std::static_pointer_cast(shared_from_this())); - world->traverseTopDown([&factory](const std::shared_ptr &node) { - auto renderElement = std::dynamic_pointer_cast(node); - if (renderElement && renderElement->isDirty()) { - factory.updateRenderable(node); - } - }); + factory.updateRenderablesInNode(rootNode); } void OpenGLRenderer::renderWorld(const std::shared_ptr &world) { diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp index 2431bce..1cf1e77 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderer_ISceneRenderer.cpp @@ -11,14 +11,9 @@ namespace Stone::Render::Vulkan { -void VulkanRenderer::updateDataForWorld(const std::shared_ptr &world) { +void VulkanRenderer::updateRenderablesInNode(const std::shared_ptr &rootNode) { RendererObjectFactory factory(std::static_pointer_cast(shared_from_this())); - world->traverseTopDown([&factory](const std::shared_ptr &node) { - auto renderElement = std::dynamic_pointer_cast(node); - if (renderElement && renderElement->isDirty()) { - factory.updateRenderable(node); - } - }); + factory.updateRenderablesInNode(rootNode); } void VulkanRenderer::renderWorld(const std::shared_ptr &world) { diff --git a/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp index 260bc92..ec32c19 100644 --- a/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp +++ b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp @@ -16,7 +16,7 @@ class ISceneRenderer { /** * @brief Request the renderer to update all rendering data in the world. */ - virtual void updateDataForWorld(const std::shared_ptr &world) = 0; + virtual void updateRenderablesInNode(const std::shared_ptr &rootNode) = 0; /** * @brief Request the renderer to render the world from the given world root node. diff --git a/Engine/Scene/include/Scene/Renderer/RendererObjectFactory.hpp b/Engine/Scene/include/Scene/Renderer/RendererObjectFactory.hpp index 113b631..775af98 100644 --- a/Engine/Scene/include/Scene/Renderer/RendererObjectFactory.hpp +++ b/Engine/Scene/include/Scene/Renderer/RendererObjectFactory.hpp @@ -24,6 +24,13 @@ class RendererObjectFactory { RendererObjectFactory() = default; virtual ~RendererObjectFactory() = default; + /** + * @brief Recursively updates the renderables in the given node. + * + * @param rootNode The root of the node graph that requires a renderable update + */ + virtual void updateRenderablesInNode(const std::shared_ptr &rootNode); + /** * Updates the renderable object with the given node. * diff --git a/Engine/Scene/src/Scene/Renderer/RendererObjectFactory.cpp b/Engine/Scene/src/Scene/Renderer/RendererObjectFactory.cpp index 429a81e..12c540e 100644 --- a/Engine/Scene/src/Scene/Renderer/RendererObjectFactory.cpp +++ b/Engine/Scene/src/Scene/Renderer/RendererObjectFactory.cpp @@ -23,6 +23,15 @@ const std::unordered_map updateCastedFunctions = { CASTED_FUNCTION_MAP_ENTRY(FragmentShader), }; +void RendererObjectFactory::updateRenderablesInNode(const std::shared_ptr &rootNode) { + rootNode->traverseTopDown([this](const std::shared_ptr &node) { + auto renderElement = std::dynamic_pointer_cast(node); + if (renderElement && renderElement->isDirty()) { + updateRenderable(node); + } + }); +} + void RendererObjectFactory::updateRenderable(const std::shared_ptr &renderable) { auto it = updateCastedFunctions.find(renderable->getClassHashCode()); if (it != updateCastedFunctions.end()) { diff --git a/Engine/Window/src/Window/Window.cpp b/Engine/Window/src/Window/Window.cpp index 7214284..0ee4b23 100644 --- a/Engine/Window/src/Window/Window.cpp +++ b/Engine/Window/src/Window/Window.cpp @@ -25,7 +25,7 @@ void Window::loopOnce() { [this](const std::shared_ptr &node) { node->update(static_cast(_deltaTime)); }); if (_renderer) { - _renderer->updateDataForWorld(_world); + _renderer->updateRenderablesInNode(_world); _renderer->renderWorld(_world); } } From 37be042febad9c6506289602d1b43dfa4b1ab13a Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 13 Apr 2025 21:48:02 +0200 Subject: [PATCH 65/89] shader code in shader params example --- .../Scene/include/Scene/Renderer/RendererObjectFactory.hpp | 2 +- examples/glsl_generator/shader_params.json | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Engine/Scene/include/Scene/Renderer/RendererObjectFactory.hpp b/Engine/Scene/include/Scene/Renderer/RendererObjectFactory.hpp index 775af98..7f37c83 100644 --- a/Engine/Scene/include/Scene/Renderer/RendererObjectFactory.hpp +++ b/Engine/Scene/include/Scene/Renderer/RendererObjectFactory.hpp @@ -26,7 +26,7 @@ class RendererObjectFactory { /** * @brief Recursively updates the renderables in the given node. - * + * * @param rootNode The root of the node graph that requires a renderable update */ virtual void updateRenderablesInNode(const std::shared_ptr &rootNode); diff --git a/examples/glsl_generator/shader_params.json b/examples/glsl_generator/shader_params.json index 6ab58ff..25ab05b 100644 --- a/examples/glsl_generator/shader_params.json +++ b/examples/glsl_generator/shader_params.json @@ -9,5 +9,10 @@ "metallic": "vector3", "normal": "vector3", "occlusion": "scalar", - "height": "vector3" + "height": "vector3", + "shader": " +void customShader(inout Material mat) { + mat.diffuse = vec3(1, 0, 0); +} +" } \ No newline at end of file From 1bfb8430b14be4d5dd837895de0993b1aa0d862b Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 13 Apr 2025 22:02:10 +0200 Subject: [PATCH 66/89] Move includes --- Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp | 3 --- Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp | 3 +++ Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index 4aad671..a289c20 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -5,9 +5,6 @@ #include "Render/OpenGL/RendererSettings.hpp" #include "Render/Renderer.hpp" -namespace Stone::Scene { -class WorldNode; -} namespace Stone::Render::OpenGL { diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp index 4e9e940..00898fb 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp @@ -7,6 +7,9 @@ #include "RenderPass.hpp" #include "SwapChain.hpp" +#include +#include + namespace Stone::Render::Vulkan { VulkanRenderer::VulkanRenderer(RendererSettings &settings) : Renderer() { diff --git a/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp index ec32c19..7c73f5d 100644 --- a/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp +++ b/Engine/Scene/include/Scene/Renderer/ISceneRenderer.hpp @@ -2,12 +2,13 @@ #pragma once -#include "SceneTypes.hpp" - #include namespace Stone::Scene { +class Node; +class WorldNode; + /** * @brief Interface for a scene renderer. */ From 5db6d601b0b67c4f7ff8c599cc66fd79ce308bd2 Mon Sep 17 00:00:00 2001 From: amasson Date: Mon, 14 Apr 2025 09:41:13 +0200 Subject: [PATCH 67/89] OpenGLRenderer move rendering logic into director --- .../include/Render/OpenGL/OpenGLRenderer.hpp | 19 ++-- .../Render/OpenGL/GlElements/GlGBuffer.hpp | 4 + .../OpenGL/GlElements/ShaderPrograms.cpp | 5 +- .../src/Render/OpenGL/OpenGLDirector.cpp | 85 ++++++++++++++++++ .../src/Render/OpenGL/OpenGLDirector.hpp | 47 ++++++++++ .../src/Render/OpenGL/OpenGLRenderer.cpp | 89 +++---------------- .../src/Render/OpenGL/OpenGLResources.cpp | 3 +- .../OpenGL/Renderable/FragmentShader.hpp | 2 +- .../src/Render/OpenGL/Renderable/Material.cpp | 2 +- .../src/Render/OpenGL/Renderable/MeshNode.cpp | 2 +- Engine/Window/src/Window/GlfwWindow.cpp | 4 +- 11 files changed, 165 insertions(+), 97 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/OpenGLDirector.cpp create mode 100644 Engine/Render/src/Render/OpenGL/OpenGLDirector.hpp diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index a289c20..e5d4ef7 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -8,16 +8,16 @@ namespace Stone::Render::OpenGL { +class OpenGLDirector; class OpenGLResources; -struct GlGBuffer; class OpenGLRenderer : public Renderer { public: - OpenGLRenderer() = delete; - explicit OpenGLRenderer(RendererSettings &settings); - OpenGLRenderer(const OpenGLRenderer &) = delete; + OpenGLRenderer() = default; - ~OpenGLRenderer() override; + ~OpenGLRenderer() override = default; + + void initialize(RendererSettings &settings); /** Renderer */ @@ -26,15 +26,12 @@ class OpenGLRenderer : public Renderer { void updateFrameSize(std::pair size) override; - void initialize(); - RenderingMethod getRenderingMethod() const; - const std::shared_ptr &getOpenGLResources() const; + const std::shared_ptr &getDirector() const; + const std::shared_ptr &getResources() const; private: - std::pair _frameSize; - const RenderingMethod _method; + std::shared_ptr _director; std::shared_ptr _resources; - std::unique_ptr _gBuffer; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GlElements/GlGBuffer.hpp b/Engine/Render/src/Render/OpenGL/GlElements/GlGBuffer.hpp index 7dc8b31..ca628d1 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/GlGBuffer.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/GlGBuffer.hpp @@ -74,6 +74,10 @@ void main() { glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); } + void unbind() { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + void render() { program->use(); diff --git a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp index 913aee5..1ac0157 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp @@ -2,6 +2,7 @@ #include "ShaderPrograms.hpp" +#include "../OpenGLDirector.hpp" #include "../OpenGLResources.hpp" #include "GlShaders.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" @@ -10,7 +11,7 @@ namespace Stone::Render::OpenGL { ShaderPrograms::ShaderPrograms(const std::shared_ptr &resources) : _resources(resources) { Scene::ShaderParameters params; - switch (resources->getRenderer().lock()->getRenderingMethod()) { + switch (resources->getRenderer().lock()->getDirector()->getRenderingMethod()) { case RenderingMethod::Forward: _glFragmentShader = GlFragmentShader::makeStandardForwardShader(params); break; case RenderingMethod::Deferred: _glFragmentShader = GlFragmentShader::makeStandardDeferredShader(params); break; } @@ -25,7 +26,7 @@ ShaderPrograms::ShaderPrograms(Scene::Material &material, const std::shared_ptr< : _resources(resources) { Scene::ShaderParameters params; params.setFromMaterial(material); - switch (resources->getRenderer().lock()->getRenderingMethod()) { + switch (resources->getRenderer().lock()->getDirector()->getRenderingMethod()) { case RenderingMethod::Forward: _glFragmentShader = GlFragmentShader::makeStandardForwardShader(params); break; case RenderingMethod::Deferred: _glFragmentShader = GlFragmentShader::makeStandardDeferredShader(params); break; } diff --git a/Engine/Render/src/Render/OpenGL/OpenGLDirector.cpp b/Engine/Render/src/Render/OpenGL/OpenGLDirector.cpp new file mode 100644 index 0000000..7984678 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/OpenGLDirector.cpp @@ -0,0 +1,85 @@ +// Copyright 2024 Stone-Engine + +#include "OpenGLDirector.hpp" + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Render/OpenGL/RenderContext.hpp" +#include "Scene/Node/WorldNode.hpp" + + +namespace Stone::Render::OpenGL { + +static void initializeOpenGL() { + static bool initialized = false; + if (initialized) + return; + + glewExperimental = true; + if (glewInit() != GLEW_OK) { + throw std::runtime_error("Failed to initialize GLEW"); + } + initialized = true; +} + +OpenGLDirector::OpenGLDirector(const std::shared_ptr &renderer, RenderingMethod method) + : _method(method), _frameSize(0, 0), _renderer(renderer), _gBuffer() { +} + +void OpenGLDirector::initialize(const std::pair &frameSize) { + initializeOpenGL(); + updateFrameSize(frameSize); + std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; +} + +void OpenGLDirector::renderWorld(const std::shared_ptr &world) { + switch (_method) { + case RenderingMethod::Forward: renderWorldForward(world); break; + case RenderingMethod::Deferred: renderWorldDeffered(world); break; + } +} + +void OpenGLDirector::updateFrameSize(const std::pair &frameSize) { + _frameSize = frameSize; + + if (_gBuffer) + _gBuffer.reset(); + + if (_method == RenderingMethod::Deferred) { + _gBuffer = std::make_unique(_frameSize.first, _frameSize.second); + } +} + +void OpenGLDirector::renderWorldForward(const std::shared_ptr &world) { + OpenGL::RenderContext context; + context.renderer = _renderer.lock(); + world->initializeRenderContext(context); + + _clearViewport(); + + world->render(context); +} + +void OpenGLDirector::renderWorldDeffered(const std::shared_ptr &world) { + OpenGL::RenderContext context; + context.renderer = _renderer.lock(); + context.gBuffer = _gBuffer.get(); + world->initializeRenderContext(context); + + _gBuffer->bind(); + _clearViewport(); + + world->render(context); + + _gBuffer->unbind(); + + _gBuffer->render(); +} + +void OpenGLDirector::_clearViewport() { + glViewport(0, 0, static_cast(_frameSize.first), static_cast(_frameSize.second)); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); +} + + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLDirector.hpp b/Engine/Render/src/Render/OpenGL/OpenGLDirector.hpp new file mode 100644 index 0000000..b9ddb47 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/OpenGLDirector.hpp @@ -0,0 +1,47 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "GlElements/GlGBuffer.hpp" +#include "Render/OpenGL/RendererSettings.hpp" + +namespace Stone::Scene { +class Node; +class WorldNode; +} // namespace Stone::Scene + +namespace Stone::Render::OpenGL { + +class OpenGLRenderer; +struct GlGBuffer; + +class OpenGLDirector { + +public: + OpenGLDirector(const std::shared_ptr &renderer, RenderingMethod method); + + virtual ~OpenGLDirector() = default; + + void initialize(const std::pair &frameSize); + + void updateFrameSize(const std::pair &frameSize); + + void renderWorld(const std::shared_ptr &world); + void renderWorldForward(const std::shared_ptr &world); + void renderWorldDeffered(const std::shared_ptr &world); + + [[nodiscard]] + RenderingMethod getRenderingMethod() const { + return _method; + } + +private: + void _clearViewport(); + + const RenderingMethod _method; + std::pair _frameSize; + std::weak_ptr _renderer; + std::unique_ptr _gBuffer; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index 32e115c..7f0c581 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -3,35 +3,18 @@ #include "Render/OpenGL/OpenGLRenderer.hpp" -#include "GlElements/GlGBuffer.hpp" +#include "OpenGLDirector.hpp" #include "OpenGLResources.hpp" -#include "RenderContext.hpp" #include "RendererObjectFactory.hpp" -#include "Scene/Node/WorldNode.hpp" - -#include namespace Stone::Render::OpenGL { -static void initializeOpenGL() { - static bool initialized = false; - if (initialized) - return; - - glewExperimental = true; - if (glewInit() != GLEW_OK) { - throw std::runtime_error("Failed to initialize GLEW"); - } - initialized = true; -} - -OpenGLRenderer::OpenGLRenderer(RendererSettings &settings) - : Renderer(), _frameSize(settings.frame_size), _method(settings.rendering_method), _resources(nullptr) { -} - -OpenGLRenderer::~OpenGLRenderer() { - std::cout << "OpenGLRenderer destroyed" << std::endl; +void OpenGLRenderer::initialize(RendererSettings &settings) { + const auto this_shared = std::static_pointer_cast(shared_from_this()); + _director = std::make_shared(this_shared, settings.rendering_method); + _resources = std::make_shared(this_shared); + _director->initialize(settings.frame_size); } void OpenGLRenderer::updateRenderablesInNode(const std::shared_ptr &rootNode) { @@ -40,68 +23,18 @@ void OpenGLRenderer::updateRenderablesInNode(const std::shared_ptr } void OpenGLRenderer::renderWorld(const std::shared_ptr &world) { - - switch (_method) { - case RenderingMethod::Deferred: - { - // Reset framebuffers - - _gBuffer->bind(); - glViewport(0, 0, static_cast(_frameSize.first), static_cast(_frameSize.second)); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - OpenGL::RenderContext context; - context.renderer = std::static_pointer_cast(shared_from_this()); - context.gBuffer = _gBuffer.get(); - - world->initializeRenderContext(context); - world->render(context); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - _gBuffer->render(); - break; - } - case RenderingMethod::Forward: - { - OpenGL::RenderContext context; - context.renderer = std::static_pointer_cast(shared_from_this()); - - glViewport(0, 0, static_cast(_frameSize.first), static_cast(_frameSize.second)); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - - world->initializeRenderContext(context); - world->render(context); - - break; - } - } + _director->renderWorld(world); } void OpenGLRenderer::updateFrameSize(std::pair size) { - _frameSize = size; - if (_method == RenderingMethod::Deferred) { - if (_gBuffer) - _gBuffer.reset(); - _gBuffer = std::make_unique(_frameSize.first, _frameSize.second); - } -} - -void OpenGLRenderer::initialize() { - initializeOpenGL(); - updateFrameSize(_frameSize); - std::cout << "OpenGLRenderer created" << std::endl; - std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; - _resources = std::make_shared(std::static_pointer_cast(shared_from_this())); + _director->updateFrameSize(size); } -RenderingMethod OpenGLRenderer::getRenderingMethod() const { - return _method; +const std::shared_ptr &OpenGLRenderer::getDirector() const { + return _director; } -const std::shared_ptr &OpenGLRenderer::getOpenGLResources() const { +const std::shared_ptr &OpenGLRenderer::getResources() const { return _resources; } diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index f76179b..619ebeb 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -3,6 +3,7 @@ #include "OpenGLResources.hpp" #include "GlElements/ShaderPrograms.hpp" +#include "OpenGLDirector.hpp" #include "Scene/Renderable/Material.hpp" namespace Stone::Render::OpenGL { @@ -52,7 +53,7 @@ const std::unique_ptr &OpenGLResources::getFragmentShader(Scen assert(renderer != nullptr); auto it = _fragmentShaders.find(params); if (it == _fragmentShaders.end()) { - switch (renderer->getRenderingMethod()) { + switch (renderer->getDirector()->getRenderingMethod()) { case RenderingMethod::Forward: return (_fragmentShaders[params] = GlFragmentShader::makeStandardForwardShader(params)); case RenderingMethod::Deferred: diff --git a/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp b/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp index 6f94f50..de4c889 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp @@ -11,7 +11,7 @@ namespace Stone::Render::OpenGL { class FragmentShader : public Scene::IRendererObject { public: FragmentShader(Scene::FragmentShader &fragmentShader, const std::shared_ptr &renderer) { - _shaderPrograms = std::make_shared(fragmentShader, renderer->getOpenGLResources()); + _shaderPrograms = std::make_shared(fragmentShader, renderer->getResources()); } void render(Scene::RenderContext &context) override { diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp index b0a5888..4ed41f1 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp @@ -8,7 +8,7 @@ namespace Stone::Render::OpenGL { Material::Material(Scene::Material &material, const std::shared_ptr &renderer) : _material(material) { if (_material.getFragmentShader() == nullptr) { - _shaderPrograms = std::make_shared(material, renderer->getOpenGLResources()); + _shaderPrograms = std::make_shared(material, renderer->getResources()); } else { _shaderPrograms = _material.getFragmentShader()->getRendererObject()->getShaderPrograms(); } diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp index 4993fea..2cd9af9 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp @@ -24,7 +24,7 @@ MeshNode::MeshNode(Scene::MeshNode &meshNode, const std::shared_ptrgetShaderPrograms().get(); } else { - _shaderPrograms = renderer->getOpenGLResources()->getDefaultShaderPrograms().get(); + _shaderPrograms = renderer->getResources()->getDefaultShaderPrograms().get(); } assert(_shaderPrograms != nullptr); diff --git a/Engine/Window/src/Window/GlfwWindow.cpp b/Engine/Window/src/Window/GlfwWindow.cpp index f599dbf..85643e6 100644 --- a/Engine/Window/src/Window/GlfwWindow.cpp +++ b/Engine/Window/src/Window/GlfwWindow.cpp @@ -82,8 +82,8 @@ GlfwWindow::GlfwWindow(const std::shared_ptr &app, const WindowSettings &se static_cast(frameBufferHeight), }; rendererSettings.rendering_method = Render::OpenGL::RenderingMethod::Forward; - auto renderer = std::make_shared(rendererSettings); - renderer->initialize(); + auto renderer = std::make_shared(); + renderer->initialize(rendererSettings); _renderer = renderer; #endif } From 09879a5072289f583abaf479f77425ee5ceb0313 Mon Sep 17 00:00:00 2001 From: amasson Date: Mon, 14 Apr 2025 09:42:42 +0200 Subject: [PATCH 68/89] Renderer updateFrameSize take const ref --- Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp | 2 +- Engine/Render/include/Render/Renderer.hpp | 2 +- Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp | 2 +- Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp | 2 +- Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp index e5d4ef7..628343a 100644 --- a/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp +++ b/Engine/Render/include/Render/OpenGL/OpenGLRenderer.hpp @@ -24,7 +24,7 @@ class OpenGLRenderer : public Renderer { void updateRenderablesInNode(const std::shared_ptr &rootNode) override; void renderWorld(const std::shared_ptr &world) override; - void updateFrameSize(std::pair size) override; + void updateFrameSize(const std::pair &size) override; const std::shared_ptr &getDirector() const; const std::shared_ptr &getResources() const; diff --git a/Engine/Render/include/Render/Renderer.hpp b/Engine/Render/include/Render/Renderer.hpp index 8e8f08a..4965f3e 100644 --- a/Engine/Render/include/Render/Renderer.hpp +++ b/Engine/Render/include/Render/Renderer.hpp @@ -15,7 +15,7 @@ class Renderer : public std::enable_shared_from_this, public Scene::IS virtual ~Renderer() = default; - virtual void updateFrameSize(std::pair size) = 0; + virtual void updateFrameSize(const std::pair &size) = 0; }; } // namespace Stone::Render diff --git a/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp b/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp index ecb7eaf..5c5f210 100644 --- a/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp +++ b/Engine/Render/include/Render/Vulkan/VulkanRenderer.hpp @@ -30,7 +30,7 @@ class VulkanRenderer : public Renderer { void updateRenderablesInNode(const std::shared_ptr &rootNode) override; void renderWorld(const std::shared_ptr &world) override; - void updateFrameSize(std::pair size) override; + void updateFrameSize(const std::pair &size) override; /** VulkanRenderer */ diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index 7f0c581..9da7e65 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -26,7 +26,7 @@ void OpenGLRenderer::renderWorld(const std::shared_ptr &world) _director->renderWorld(world); } -void OpenGLRenderer::updateFrameSize(std::pair size) { +void OpenGLRenderer::updateFrameSize(const std::pair &size) { _director->updateFrameSize(size); } diff --git a/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp b/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp index 00898fb..d4801f7 100644 --- a/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp +++ b/Engine/Render/src/Render/Vulkan/VulkanRenderer.cpp @@ -7,8 +7,8 @@ #include "RenderPass.hpp" #include "SwapChain.hpp" -#include #include +#include namespace Stone::Render::Vulkan { @@ -38,7 +38,7 @@ VulkanRenderer::~VulkanRenderer() { std::cout << "VulkanRenderer destroyed" << std::endl; } -void VulkanRenderer::updateFrameSize(std::pair size) { +void VulkanRenderer::updateFrameSize(const std::pair &size) { _recreateSwapChain(size); } From a4e8ad284bb76802e0683111a33292da5cc130f8 Mon Sep 17 00:00:00 2001 From: amasson Date: Mon, 14 Apr 2025 09:42:52 +0200 Subject: [PATCH 69/89] remove empty cpp files --- Engine/Render/src/Render/Renderer.cpp | 3 --- Engine/Scene/src/Scene/Renderer/RenderContext.cpp | 3 --- 2 files changed, 6 deletions(-) delete mode 100644 Engine/Render/src/Render/Renderer.cpp delete mode 100644 Engine/Scene/src/Scene/Renderer/RenderContext.cpp diff --git a/Engine/Render/src/Render/Renderer.cpp b/Engine/Render/src/Render/Renderer.cpp deleted file mode 100644 index b33b913..0000000 --- a/Engine/Render/src/Render/Renderer.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright 2024 Stone-Engine - -#include "Render/Renderer.hpp" diff --git a/Engine/Scene/src/Scene/Renderer/RenderContext.cpp b/Engine/Scene/src/Scene/Renderer/RenderContext.cpp deleted file mode 100644 index d97979f..0000000 --- a/Engine/Scene/src/Scene/Renderer/RenderContext.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright 2024 Stone-Engine - -#include "Scene/Renderer/RenderContext.hpp" From c2ed1d8b234bde4026b746e660a9fb8aaab67c25 Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 15 Apr 2025 19:52:58 +0200 Subject: [PATCH 70/89] Rename ShaderParameters to ShaderInputSignature --- .../Render/OpenGL/GlElements/GlShaders.cpp | 4 +- .../Render/OpenGL/GlElements/GlShaders.hpp | 6 +- .../OpenGL/GlElements/ShaderPrograms.cpp | 5 +- .../OpenGL/GlElements/ShaderPrograms.hpp | 2 +- .../src/Render/OpenGL/OpenGLResources.cpp | 13 +++- .../src/Render/OpenGL/OpenGLResources.hpp | 8 ++- .../include/Scene/Shader/ShaderGenerator.hpp | 6 +- ...arameters.hpp => ShaderInputSignature.hpp} | 10 +-- .../src/Scene/Shader/ShaderGenerator.cpp | 70 +++++++++---------- ...arameters.cpp => ShaderInputSignature.cpp} | 12 ++-- examples/glsl_generator/main.cpp | 32 ++++----- 11 files changed, 89 insertions(+), 79 deletions(-) rename Engine/Scene/include/Scene/Shader/{ShaderParameters.hpp => ShaderInputSignature.hpp} (81%) rename Engine/Scene/src/Scene/Shader/{ShaderParameters.cpp => ShaderInputSignature.cpp} (78%) diff --git a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp index 949d5fb..d7184de 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp @@ -155,7 +155,7 @@ std::unique_ptr GlVertexShader::makeStandardInstancedMeshShader( // MARK: Fragment -std::unique_ptr GlFragmentShader::makeStandardForwardShader(const Scene::ShaderParameters ¶ms) { +std::unique_ptr GlFragmentShader::makeStandardForwardShader(const Scene::ShaderInputSignature ¶ms) { std::stringstream source; Scene::ShaderGenerator generator; @@ -164,7 +164,7 @@ std::unique_ptr GlFragmentShader::makeStandardForwardShader(co return std::make_unique(source.str().c_str()); } -std::unique_ptr GlFragmentShader::makeStandardDeferredShader(const Scene::ShaderParameters ¶ms) { +std::unique_ptr GlFragmentShader::makeStandardDeferredShader(const Scene::ShaderInputSignature ¶ms) { (void)params; throw std::runtime_error("deffered shader is not implemented."); } diff --git a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp index e88b7ad..a654be3 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp @@ -5,7 +5,7 @@ #include "../Renderable/Texture.hpp" #include "Scene/Renderable/Material.hpp" #include "Scene/Renderable/Shader.hpp" -#include "Scene/Shader/ShaderParameters.hpp" +#include "Scene/Shader/ShaderInputSignature.hpp" #include "Utils/FileSystem.hpp" #include @@ -69,8 +69,8 @@ class GlFragmentShader : public GlShaderBase { GlFragmentShader(const char *source) : GlShaderBase(source, GL_FRAGMENT_SHADER) { } - static std::unique_ptr makeStandardDeferredShader(const Scene::ShaderParameters ¶ms); - static std::unique_ptr makeStandardForwardShader(const Scene::ShaderParameters ¶ms); + static std::unique_ptr makeStandardDeferredShader(const Scene::ShaderInputSignature ¶ms); + static std::unique_ptr makeStandardForwardShader(const Scene::ShaderInputSignature ¶ms); }; class GlShaderProgram { diff --git a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp index 1ac0157..a91574f 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp @@ -9,8 +9,7 @@ namespace Stone::Render::OpenGL { -ShaderPrograms::ShaderPrograms(const std::shared_ptr &resources) : _resources(resources) { - Scene::ShaderParameters params; +ShaderPrograms::ShaderPrograms(Scene::ShaderInputSignature params, const std::shared_ptr &resources) : _resources(resources) { switch (resources->getRenderer().lock()->getDirector()->getRenderingMethod()) { case RenderingMethod::Forward: _glFragmentShader = GlFragmentShader::makeStandardForwardShader(params); break; case RenderingMethod::Deferred: _glFragmentShader = GlFragmentShader::makeStandardDeferredShader(params); break; @@ -24,7 +23,7 @@ ShaderPrograms::ShaderPrograms(Scene::FragmentShader &shader, const std::shared_ ShaderPrograms::ShaderPrograms(Scene::Material &material, const std::shared_ptr &resources) : _resources(resources) { - Scene::ShaderParameters params; + Scene::ShaderInputSignature params; params.setFromMaterial(material); switch (resources->getRenderer().lock()->getDirector()->getRenderingMethod()) { case RenderingMethod::Forward: _glFragmentShader = GlFragmentShader::makeStandardForwardShader(params); break; diff --git a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp index 26db901..eb21f15 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp @@ -10,7 +10,7 @@ namespace Stone::Render::OpenGL { class ShaderPrograms { public: - ShaderPrograms(const std::shared_ptr &resources); + ShaderPrograms(Scene::ShaderInputSignature params, const std::shared_ptr &resources); ShaderPrograms(Scene::FragmentShader &shader, const std::shared_ptr &resources); ShaderPrograms(Scene::Material &material, const std::shared_ptr &resources); diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index 619ebeb..9e2b118 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -48,7 +48,7 @@ const std::unique_ptr &OpenGLResources::getVertexShader(Scene::M assert(false); } -const std::unique_ptr &OpenGLResources::getFragmentShader(Scene::ShaderParameters params) { +const std::unique_ptr &OpenGLResources::getFragmentShader(Scene::ShaderInputSignature params) { auto renderer = getRenderer().lock(); assert(renderer != nullptr); auto it = _fragmentShaders.find(params); @@ -66,9 +66,18 @@ const std::unique_ptr &OpenGLResources::getFragmentShader(Scen const std::unique_ptr &OpenGLResources::getDefaultShaderPrograms() { if (_defaultShaderPrograms == nullptr) { - _defaultShaderPrograms = std::make_unique(shared_from_this()); + _defaultShaderPrograms = std::make_unique(Scene::ShaderInputSignature(), shared_from_this()); } return _defaultShaderPrograms; } +const std::unique_ptr &OpenGLResources::getStandardShaderPrograms(Scene::ShaderInputSignature params) { + auto it = _standardsShaderPrograms.find(params); + if (it == _standardsShaderPrograms.end()) { + return (_standardsShaderPrograms[params] = std::make_unique(params, shared_from_this())); + } else { + return it->second; + } +} + } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp index 8b07a92..78e0ae2 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp @@ -4,7 +4,7 @@ #include "GlElements/GlShaders.hpp" #include "GlElements/ShaderPrograms.hpp" -#include "Scene/Shader/ShaderParameters.hpp" +#include "Scene/Shader/ShaderInputSignature.hpp" namespace Stone::Render::OpenGL { @@ -29,11 +29,12 @@ class OpenGLResources : std::enable_shared_from_this { // MARK: Fragment Shaders - const std::unique_ptr &getFragmentShader(Scene::ShaderParameters params); + const std::unique_ptr &getFragmentShader(Scene::ShaderInputSignature params); // MARK: Shader Programs const std::unique_ptr &getDefaultShaderPrograms(); + const std::unique_ptr &getStandardShaderPrograms(Scene::ShaderInputSignature params); private: std::weak_ptr _renderer; @@ -42,9 +43,10 @@ class OpenGLResources : std::enable_shared_from_this { std::unique_ptr _skinMeshVertexShader; std::unique_ptr _instancedMeshVertexShader; - std::unordered_map> _fragmentShaders; + std::unordered_map> _fragmentShaders; std::unique_ptr _defaultShaderPrograms; + std::unordered_map> _standardsShaderPrograms; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp index cef7cd4..ee65b78 100644 --- a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp +++ b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp @@ -2,7 +2,7 @@ #pragma once -#include "Scene/Shader/ShaderParameters.hpp" +#include "Scene/Shader/ShaderInputSignature.hpp" namespace Stone::Scene { @@ -14,9 +14,9 @@ class ShaderGenerator { ~ShaderGenerator() = default; - void generateFragmentShaderTemplate(const ShaderParameters ¶ms, std::ostream &output); + void generateFragmentShaderTemplate(const ShaderInputSignature ¶ms, std::ostream &output); - void generateOpenGlForwardFragmentShader(const ShaderParameters ¶ms, class FragmentShader *shader, + void generateOpenGlForwardFragmentShader(const ShaderInputSignature ¶ms, class FragmentShader *shader, std::ostream &output); }; diff --git a/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp b/Engine/Scene/include/Scene/Shader/ShaderInputSignature.hpp similarity index 81% rename from Engine/Scene/include/Scene/Shader/ShaderParameters.hpp rename to Engine/Scene/include/Scene/Shader/ShaderInputSignature.hpp index 38c3d84..2fd9909 100644 --- a/Engine/Scene/include/Scene/Shader/ShaderParameters.hpp +++ b/Engine/Scene/include/Scene/Shader/ShaderInputSignature.hpp @@ -11,7 +11,7 @@ namespace Stone::Scene { __WithParam(opacity) __WithParam(roughness) __WithParam(metallic) __WithParam(normal) __WithParam(occlusion) \ __WithParam(height) -struct ShaderParameters { +struct ShaderInputSignature { enum class Type : uint8_t { None = 0, @@ -32,13 +32,13 @@ struct ShaderParameters { bool _; #define __INITIALIZE_PARAM(param) param(Type::None), - ShaderParameters(); + ShaderInputSignature(); void setParamWithName(const std::string &name, Type value); void setFromMaterial(const Scene::Material &material); - bool operator==(const ShaderParameters &other) const { + bool operator==(const ShaderInputSignature &other) const { return data == other.data; } }; @@ -47,8 +47,8 @@ struct ShaderParameters { namespace std { template <> -struct hash { - std::size_t operator()(const Stone::Scene::ShaderParameters ¶ms) const noexcept { +struct hash { + std::size_t operator()(const Stone::Scene::ShaderInputSignature ¶ms) const noexcept { return std::hash()(params.data); } }; diff --git a/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp b/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp index 8b9f98a..a47db4d 100644 --- a/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp +++ b/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp @@ -7,24 +7,24 @@ namespace Stone::Scene { -void ShaderGenerator::generateFragmentShaderTemplate(const ShaderParameters ¶ms, std::ostream &output) { +void ShaderGenerator::generateFragmentShaderTemplate(const ShaderInputSignature ¶ms, std::ostream &output) { output << "// Stone shader template" << std::endl; - auto to_glsl = [](ShaderParameters::Type type) { + auto to_glsl = [](ShaderInputSignature::Type type) { switch (type) { - case ShaderParameters::Type::None: return "void"; - case ShaderParameters::Type::Scalar: return "float"; - case ShaderParameters::Type::Vector2: return "vec2"; - case ShaderParameters::Type::Vector3: return "vec3"; - case ShaderParameters::Type::Vector4: return "vec4"; - case ShaderParameters::Type::Texture: return "sampler2D"; + case ShaderInputSignature::Type::None: return "void"; + case ShaderInputSignature::Type::Scalar: return "float"; + case ShaderInputSignature::Type::Vector2: return "vec2"; + case ShaderInputSignature::Type::Vector3: return "vec3"; + case ShaderInputSignature::Type::Vector4: return "vec4"; + case ShaderInputSignature::Type::Texture: return "sampler2D"; default: return ""; } }; - auto add_uniform_param = [&output, &to_glsl](const char *name, ShaderParameters::Type type) { - if (type != ShaderParameters::Type::None) + auto add_uniform_param = [&output, &to_glsl](const char *name, ShaderInputSignature::Type type) { + if (type != ShaderInputSignature::Type::None) output << "// " << name << ": " << to_glsl(type) << std::endl; }; @@ -39,7 +39,7 @@ void ShaderGenerator::generateFragmentShaderTemplate(const ShaderParameters &par output << "}" << std::endl; } -void ShaderGenerator::generateOpenGlForwardFragmentShader(const ShaderParameters ¶ms, FragmentShader *shader, +void ShaderGenerator::generateOpenGlForwardFragmentShader(const ShaderInputSignature ¶ms, FragmentShader *shader, std::ostream &output) { std::ostream &source(output); @@ -104,20 +104,20 @@ uniform vec3 u_camera_position; )"; - auto to_glsl = [](ShaderParameters::Type type) { + auto to_glsl = [](ShaderInputSignature::Type type) { switch (type) { - case ShaderParameters::Type::None: return "void"; - case ShaderParameters::Type::Scalar: return "float"; - case ShaderParameters::Type::Vector2: return "vec2"; - case ShaderParameters::Type::Vector3: return "vec3"; - case ShaderParameters::Type::Vector4: return "vec4"; - case ShaderParameters::Type::Texture: return "sampler2D"; + case ShaderInputSignature::Type::None: return "void"; + case ShaderInputSignature::Type::Scalar: return "float"; + case ShaderInputSignature::Type::Vector2: return "vec2"; + case ShaderInputSignature::Type::Vector3: return "vec3"; + case ShaderInputSignature::Type::Vector4: return "vec4"; + case ShaderInputSignature::Type::Texture: return "sampler2D"; default: return ""; } }; - auto add_uniform_param = [&source, &to_glsl](const char *name, ShaderParameters::Type type) { - if (type != ShaderParameters::Type::None) + auto add_uniform_param = [&source, &to_glsl](const char *name, ShaderInputSignature::Type type) { + if (type != ShaderInputSignature::Type::None) source << "uniform " << to_glsl(type) << ' ' << name << ";" << std::endl; }; @@ -271,39 +271,39 @@ vec3 calculLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcam source << " Material fragMat;" << std::endl; // TODO: Handle default values - const auto assign_to_vec = [&source](ShaderParameters::Type type, const std::string &name) { + const auto assign_to_vec = [&source](ShaderInputSignature::Type type, const std::string &name) { switch (type) { - case ShaderParameters::Type::None: break; - case ShaderParameters::Type::Scalar: + case ShaderInputSignature::Type::None: break; + case ShaderInputSignature::Type::Scalar: source << " fragMat." << name << " = vec3(" << name << ", 0, 0);" << std::endl; break; - case ShaderParameters::Type::Vector2: + case ShaderInputSignature::Type::Vector2: source << " fragMat." << name << " = vec3(" << name << ", 0);" << std::endl; break; - case ShaderParameters::Type::Vector3: + case ShaderInputSignature::Type::Vector3: source << " fragMat." << name << " = " << name << ";" << std::endl; // break; - case ShaderParameters::Type::Vector4: + case ShaderInputSignature::Type::Vector4: source << " fragMat." << name << " = " << name << ".xyz;" << std::endl; break; - case ShaderParameters::Type::Texture: + case ShaderInputSignature::Type::Texture: source << " fragMat." << name << " = texture(" << name << ", fs_in.uv).xyz;" << std::endl; break; } }; - const auto assign_to_float = [&source](ShaderParameters::Type type, const std::string &name, char x) { + const auto assign_to_float = [&source](ShaderInputSignature::Type type, const std::string &name, char x) { switch (type) { - case ShaderParameters::Type::None: break; - case ShaderParameters::Type::Scalar: + case ShaderInputSignature::Type::None: break; + case ShaderInputSignature::Type::Scalar: source << " fragMat." << name << " = " << name << ";" << std::endl; // break; - case ShaderParameters::Type::Vector2: - case ShaderParameters::Type::Vector3: - case ShaderParameters::Type::Vector4: + case ShaderInputSignature::Type::Vector2: + case ShaderInputSignature::Type::Vector3: + case ShaderInputSignature::Type::Vector4: source << " fragMat." << name << " = " << name << "." << x << ";" << std::endl; break; - case ShaderParameters::Type::Texture: + case ShaderInputSignature::Type::Texture: source << " fragMat." << name << " = texture(" << name << ", fs_in.uv)." << x << ";" << std::endl; break; } @@ -320,7 +320,7 @@ vec3 calculLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcam source << " " << shader->getFunction() << "(fragMat);" << std::endl; } - if (params.normal == ShaderParameters::Type::Texture) { + if (params.normal == ShaderInputSignature::Type::Texture) { source << " vec3 normal_value = normalize(texture(normal, fs_in.uv).xyz * 2 - 1);" << std::endl; } else { source << " vec3 normal_value = vec3(0, 0, 1);" << std::endl; diff --git a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp b/Engine/Scene/src/Scene/Shader/ShaderInputSignature.cpp similarity index 78% rename from Engine/Scene/src/Scene/Shader/ShaderParameters.cpp rename to Engine/Scene/src/Scene/Shader/ShaderInputSignature.cpp index c4bad6a..73c40ce 100644 --- a/Engine/Scene/src/Scene/Shader/ShaderParameters.cpp +++ b/Engine/Scene/src/Scene/Shader/ShaderInputSignature.cpp @@ -1,21 +1,21 @@ // Copyright 2024 Stone-Engine -#include "Scene/Shader/ShaderParameters.hpp" +#include "Scene/Shader/ShaderInputSignature.hpp" #include "Scene/Renderable/Material.hpp" namespace Stone::Scene { #define __INITIALIZE_PARAM(param) param(Type::None), -ShaderParameters::ShaderParameters() : FOR_EACH_SHADER_PARAMETERS(__INITIALIZE_PARAM) _() { +ShaderInputSignature::ShaderInputSignature() : FOR_EACH_SHADER_PARAMETERS(__INITIALIZE_PARAM) _() { } -void ShaderParameters::setParamWithName(const std::string &name, Type value) { - using ParamSetter = std::function; +void ShaderInputSignature::setParamWithName(const std::string &name, Type value) { + using ParamSetter = std::function; #define __MAP_NAME_TO_PARAM(param) \ { \ - #param, [](ShaderParameters &matParams, Type value) { \ + #param, [](ShaderInputSignature &matParams, Type value) { \ matParams.param = value; \ } \ } \ @@ -31,7 +31,7 @@ void ShaderParameters::setParamWithName(const std::string &name, Type value) { } } -void ShaderParameters::setFromMaterial(const Material &material) { +void ShaderInputSignature::setFromMaterial(const Material &material) { material.forEachScalars([this](const Material::Location &location, float value) { (void)value; if (std::holds_alternative(location)) { diff --git a/examples/glsl_generator/main.cpp b/examples/glsl_generator/main.cpp index 1f55138..39da882 100644 --- a/examples/glsl_generator/main.cpp +++ b/examples/glsl_generator/main.cpp @@ -20,28 +20,28 @@ static time_t getLastmodifiedTimeOfFile(const char *filename) { throw std::runtime_error("File does not exist"); } -Stone::Scene::ShaderParameters parseShaderParameters(const Json::Value &json) { - Stone::Scene::ShaderParameters params; +Stone::Scene::ShaderInputSignature parseShaderInputSignature(const Json::Value &json) { + Stone::Scene::ShaderInputSignature params; auto ¶ms_obj = json.get(); for (auto [key, value] : params_obj) { - Stone::Scene::ShaderParameters::Type type; + Stone::Scene::ShaderInputSignature::Type type; if (!value.is()) throw std::runtime_error("Invalid type for key " + key); const std::string &type_str = value.get(); if (type_str == "scalar") - type = Stone::Scene::ShaderParameters::Type::Scalar; + type = Stone::Scene::ShaderInputSignature::Type::Scalar; else if (type_str == "vector2") - type = Stone::Scene::ShaderParameters::Type::Vector2; + type = Stone::Scene::ShaderInputSignature::Type::Vector2; else if (type_str == "vector3") - type = Stone::Scene::ShaderParameters::Type::Vector3; + type = Stone::Scene::ShaderInputSignature::Type::Vector3; else if (type_str == "vector4") - type = Stone::Scene::ShaderParameters::Type::Vector4; + type = Stone::Scene::ShaderInputSignature::Type::Vector4; else if (type_str == "texture") - type = Stone::Scene::ShaderParameters::Type::Texture; + type = Stone::Scene::ShaderInputSignature::Type::Texture; else throw std::runtime_error("Invalid type " + type_str); @@ -51,14 +51,14 @@ Stone::Scene::ShaderParameters parseShaderParameters(const Json::Value &json) { return params; } -std::string to_string(Stone::Scene::ShaderParameters::Type type) { +std::string to_string(Stone::Scene::ShaderInputSignature::Type type) { switch (type) { - case Stone::Scene::ShaderParameters::Type::None: return "none"; - case Stone::Scene::ShaderParameters::Type::Scalar: return "scalar"; - case Stone::Scene::ShaderParameters::Type::Vector2: return "vector2"; - case Stone::Scene::ShaderParameters::Type::Vector3: return "vector3"; - case Stone::Scene::ShaderParameters::Type::Vector4: return "vector4"; - case Stone::Scene::ShaderParameters::Type::Texture: return "texture"; + case Stone::Scene::ShaderInputSignature::Type::None: return "none"; + case Stone::Scene::ShaderInputSignature::Type::Scalar: return "scalar"; + case Stone::Scene::ShaderInputSignature::Type::Vector2: return "vector2"; + case Stone::Scene::ShaderInputSignature::Type::Vector3: return "vector3"; + case Stone::Scene::ShaderInputSignature::Type::Vector4: return "vector4"; + case Stone::Scene::ShaderInputSignature::Type::Texture: return "texture"; } return ""; } @@ -79,7 +79,7 @@ void generateShaderOutput(const char *input_file, const char *output_file) { input_json_obj.erase("shader"); } - Stone::Scene::ShaderParameters params = parseShaderParameters(input_json); + Stone::Scene::ShaderInputSignature params = parseShaderInputSignature(input_json); Stone::Scene::ShaderGenerator generator; std::cout << "Generating shader: {" << std::endl; From 0a0dd7427b067b08bb2e596e7b85ad0c82121b46 Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 15 Apr 2025 21:28:39 +0200 Subject: [PATCH 71/89] Move ShaderInputSignature to scene module as MaterialInputSignature and shader generator to render module --- .../Render/OpenGL/Shader/ShaderGenerator.hpp | 26 ++++++ .../Render/OpenGL/GlElements/GlShaders.cpp | 8 +- .../Render/OpenGL/GlElements/GlShaders.hpp | 5 +- .../OpenGL/GlElements/ShaderPrograms.cpp | 5 +- .../OpenGL/GlElements/ShaderPrograms.hpp | 3 +- .../src/Render/OpenGL/OpenGLResources.cpp | 6 +- .../src/Render/OpenGL/OpenGLResources.hpp | 10 +-- .../Render/OpenGL}/Shader/ShaderGenerator.cpp | 81 ++++++++++--------- .../include/Scene/Renderable/Material.hpp | 52 ++++++++++++ .../include/Scene/Shader/ShaderGenerator.hpp | 23 ------ .../Scene/Shader/ShaderInputSignature.hpp | 55 ------------- .../Scene/src/Scene/Renderable/Material.cpp | 54 +++++++++++++ .../src/Scene/Shader/ShaderInputSignature.cpp | 58 ------------- examples/glsl_generator/CMakeLists.txt | 2 +- examples/glsl_generator/main.cpp | 38 ++++----- 15 files changed, 212 insertions(+), 214 deletions(-) create mode 100644 Engine/Render/include/Render/OpenGL/Shader/ShaderGenerator.hpp rename Engine/{Scene/src/Scene => Render/src/Render/OpenGL}/Shader/ShaderGenerator.cpp (80%) delete mode 100644 Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp delete mode 100644 Engine/Scene/include/Scene/Shader/ShaderInputSignature.hpp delete mode 100644 Engine/Scene/src/Scene/Shader/ShaderInputSignature.cpp diff --git a/Engine/Render/include/Render/OpenGL/Shader/ShaderGenerator.hpp b/Engine/Render/include/Render/OpenGL/Shader/ShaderGenerator.hpp new file mode 100644 index 0000000..aec8af9 --- /dev/null +++ b/Engine/Render/include/Render/OpenGL/Shader/ShaderGenerator.hpp @@ -0,0 +1,26 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Scene/Renderable/Material.hpp" + +namespace Stone::Scene { +class FragmentShader; +} + +namespace Stone::Render::OpenGL { + +class ShaderGenerator { + + +public: + ShaderGenerator() = default; + + ~ShaderGenerator() = default; + + void generateFragmentShaderTemplate(const Scene::MaterialInputSignature ¶ms, std::ostream &output); + + void generateOpenGlForwardFragmentShader(const Scene::MaterialInputSignature ¶ms, const std::shared_ptr &shader, std::ostream &output); +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp index d7184de..d46a844 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp @@ -2,7 +2,7 @@ #include "GlShaders.hpp" -#include "Scene/Shader/ShaderGenerator.hpp" +#include "Render/OpenGL/Shader/ShaderGenerator.hpp" #include #include @@ -155,16 +155,16 @@ std::unique_ptr GlVertexShader::makeStandardInstancedMeshShader( // MARK: Fragment -std::unique_ptr GlFragmentShader::makeStandardForwardShader(const Scene::ShaderInputSignature ¶ms) { +std::unique_ptr GlFragmentShader::makeStandardForwardShader(const Scene::MaterialInputSignature ¶ms) { std::stringstream source; - Scene::ShaderGenerator generator; + Render::OpenGL::ShaderGenerator generator; generator.generateOpenGlForwardFragmentShader(params, nullptr, source); return std::make_unique(source.str().c_str()); } -std::unique_ptr GlFragmentShader::makeStandardDeferredShader(const Scene::ShaderInputSignature ¶ms) { +std::unique_ptr GlFragmentShader::makeStandardDeferredShader(const Scene::MaterialInputSignature ¶ms) { (void)params; throw std::runtime_error("deffered shader is not implemented."); } diff --git a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp index a654be3..9e1f614 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp @@ -5,7 +5,6 @@ #include "../Renderable/Texture.hpp" #include "Scene/Renderable/Material.hpp" #include "Scene/Renderable/Shader.hpp" -#include "Scene/Shader/ShaderInputSignature.hpp" #include "Utils/FileSystem.hpp" #include @@ -69,8 +68,8 @@ class GlFragmentShader : public GlShaderBase { GlFragmentShader(const char *source) : GlShaderBase(source, GL_FRAGMENT_SHADER) { } - static std::unique_ptr makeStandardDeferredShader(const Scene::ShaderInputSignature ¶ms); - static std::unique_ptr makeStandardForwardShader(const Scene::ShaderInputSignature ¶ms); + static std::unique_ptr makeStandardDeferredShader(const Scene::MaterialInputSignature ¶ms); + static std::unique_ptr makeStandardForwardShader(const Scene::MaterialInputSignature ¶ms); }; class GlShaderProgram { diff --git a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp index a91574f..8164e07 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp @@ -9,7 +9,7 @@ namespace Stone::Render::OpenGL { -ShaderPrograms::ShaderPrograms(Scene::ShaderInputSignature params, const std::shared_ptr &resources) : _resources(resources) { +ShaderPrograms::ShaderPrograms(Scene::MaterialInputSignature params, const std::shared_ptr &resources) : _resources(resources) { switch (resources->getRenderer().lock()->getDirector()->getRenderingMethod()) { case RenderingMethod::Forward: _glFragmentShader = GlFragmentShader::makeStandardForwardShader(params); break; case RenderingMethod::Deferred: _glFragmentShader = GlFragmentShader::makeStandardDeferredShader(params); break; @@ -23,8 +23,7 @@ ShaderPrograms::ShaderPrograms(Scene::FragmentShader &shader, const std::shared_ ShaderPrograms::ShaderPrograms(Scene::Material &material, const std::shared_ptr &resources) : _resources(resources) { - Scene::ShaderInputSignature params; - params.setFromMaterial(material); + Scene::MaterialInputSignature params(std::dynamic_pointer_cast(material.shared_from_this())); switch (resources->getRenderer().lock()->getDirector()->getRenderingMethod()) { case RenderingMethod::Forward: _glFragmentShader = GlFragmentShader::makeStandardForwardShader(params); break; case RenderingMethod::Deferred: _glFragmentShader = GlFragmentShader::makeStandardDeferredShader(params); break; diff --git a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp index eb21f15..2630bce 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp @@ -5,12 +5,13 @@ #include "GlShaders.hpp" #include "Scene/Renderable/Material.hpp" #include "Scene/Renderable/Shader.hpp" +#include "Scene/Renderable/IMeshObject.hpp" namespace Stone::Render::OpenGL { class ShaderPrograms { public: - ShaderPrograms(Scene::ShaderInputSignature params, const std::shared_ptr &resources); + ShaderPrograms(Scene::MaterialInputSignature params, const std::shared_ptr &resources); ShaderPrograms(Scene::FragmentShader &shader, const std::shared_ptr &resources); ShaderPrograms(Scene::Material &material, const std::shared_ptr &resources); diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index 9e2b118..33d6278 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -48,7 +48,7 @@ const std::unique_ptr &OpenGLResources::getVertexShader(Scene::M assert(false); } -const std::unique_ptr &OpenGLResources::getFragmentShader(Scene::ShaderInputSignature params) { +const std::unique_ptr &OpenGLResources::getFragmentShader(Scene::MaterialInputSignature params) { auto renderer = getRenderer().lock(); assert(renderer != nullptr); auto it = _fragmentShaders.find(params); @@ -66,12 +66,12 @@ const std::unique_ptr &OpenGLResources::getFragmentShader(Scen const std::unique_ptr &OpenGLResources::getDefaultShaderPrograms() { if (_defaultShaderPrograms == nullptr) { - _defaultShaderPrograms = std::make_unique(Scene::ShaderInputSignature(), shared_from_this()); + _defaultShaderPrograms = std::make_unique(Scene::MaterialInputSignature(), shared_from_this()); } return _defaultShaderPrograms; } -const std::unique_ptr &OpenGLResources::getStandardShaderPrograms(Scene::ShaderInputSignature params) { +const std::unique_ptr &OpenGLResources::getStandardShaderPrograms(Scene::MaterialInputSignature params) { auto it = _standardsShaderPrograms.find(params); if (it == _standardsShaderPrograms.end()) { return (_standardsShaderPrograms[params] = std::make_unique(params, shared_from_this())); diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp index 78e0ae2..6d9ea04 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp @@ -4,7 +4,7 @@ #include "GlElements/GlShaders.hpp" #include "GlElements/ShaderPrograms.hpp" -#include "Scene/Shader/ShaderInputSignature.hpp" +#include "Scene/Renderable/Material.hpp" namespace Stone::Render::OpenGL { @@ -29,12 +29,12 @@ class OpenGLResources : std::enable_shared_from_this { // MARK: Fragment Shaders - const std::unique_ptr &getFragmentShader(Scene::ShaderInputSignature params); + const std::unique_ptr &getFragmentShader(Scene::MaterialInputSignature params); // MARK: Shader Programs const std::unique_ptr &getDefaultShaderPrograms(); - const std::unique_ptr &getStandardShaderPrograms(Scene::ShaderInputSignature params); + const std::unique_ptr &getStandardShaderPrograms(Scene::MaterialInputSignature params); private: std::weak_ptr _renderer; @@ -43,10 +43,10 @@ class OpenGLResources : std::enable_shared_from_this { std::unique_ptr _skinMeshVertexShader; std::unique_ptr _instancedMeshVertexShader; - std::unordered_map> _fragmentShaders; + std::unordered_map> _fragmentShaders; std::unique_ptr _defaultShaderPrograms; - std::unordered_map> _standardsShaderPrograms; + std::unordered_map> _standardsShaderPrograms; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp b/Engine/Render/src/Render/OpenGL/Shader/ShaderGenerator.cpp similarity index 80% rename from Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp rename to Engine/Render/src/Render/OpenGL/Shader/ShaderGenerator.cpp index a47db4d..2498ca8 100644 --- a/Engine/Scene/src/Scene/Shader/ShaderGenerator.cpp +++ b/Engine/Render/src/Render/OpenGL/Shader/ShaderGenerator.cpp @@ -1,30 +1,31 @@ // Copyright 2024 Stone-Engine -#include "Scene/Shader/ShaderGenerator.hpp" +#include "Render/OpenGL/Shader/ShaderGenerator.hpp" #include "Scene/Renderable/Shader.hpp" #include "Utils/FileSystem.hpp" -namespace Stone::Scene { +namespace Stone::Render::OpenGL { -void ShaderGenerator::generateFragmentShaderTemplate(const ShaderInputSignature ¶ms, std::ostream &output) { +void ShaderGenerator::generateFragmentShaderTemplate(const Scene::MaterialInputSignature ¶ms, + std::ostream &output) { output << "// Stone shader template" << std::endl; - auto to_glsl = [](ShaderInputSignature::Type type) { + auto to_glsl = [](Scene::MaterialInputSignature::Type type) { switch (type) { - case ShaderInputSignature::Type::None: return "void"; - case ShaderInputSignature::Type::Scalar: return "float"; - case ShaderInputSignature::Type::Vector2: return "vec2"; - case ShaderInputSignature::Type::Vector3: return "vec3"; - case ShaderInputSignature::Type::Vector4: return "vec4"; - case ShaderInputSignature::Type::Texture: return "sampler2D"; + case Scene::MaterialInputSignature::Type::None: return "void"; + case Scene::MaterialInputSignature::Type::Scalar: return "float"; + case Scene::MaterialInputSignature::Type::Vector2: return "vec2"; + case Scene::MaterialInputSignature::Type::Vector3: return "vec3"; + case Scene::MaterialInputSignature::Type::Vector4: return "vec4"; + case Scene::MaterialInputSignature::Type::Texture: return "sampler2D"; default: return ""; } }; - auto add_uniform_param = [&output, &to_glsl](const char *name, ShaderInputSignature::Type type) { - if (type != ShaderInputSignature::Type::None) + auto add_uniform_param = [&output, &to_glsl](const char *name, Scene::MaterialInputSignature::Type type) { + if (type != Scene::MaterialInputSignature::Type::None) output << "// " << name << ": " << to_glsl(type) << std::endl; }; @@ -39,8 +40,10 @@ void ShaderGenerator::generateFragmentShaderTemplate(const ShaderInputSignature output << "}" << std::endl; } -void ShaderGenerator::generateOpenGlForwardFragmentShader(const ShaderInputSignature ¶ms, FragmentShader *shader, +void ShaderGenerator::generateOpenGlForwardFragmentShader(const Scene::MaterialInputSignature& params, + const std::shared_ptr &shader, std::ostream &output) { + std::ostream &source(output); source << "#version 400 core" << std::endl; @@ -104,20 +107,20 @@ uniform vec3 u_camera_position; )"; - auto to_glsl = [](ShaderInputSignature::Type type) { + auto to_glsl = [](Scene::MaterialInputSignature::Type type) { switch (type) { - case ShaderInputSignature::Type::None: return "void"; - case ShaderInputSignature::Type::Scalar: return "float"; - case ShaderInputSignature::Type::Vector2: return "vec2"; - case ShaderInputSignature::Type::Vector3: return "vec3"; - case ShaderInputSignature::Type::Vector4: return "vec4"; - case ShaderInputSignature::Type::Texture: return "sampler2D"; + case Scene::MaterialInputSignature::Type::None: return "void"; + case Scene::MaterialInputSignature::Type::Scalar: return "float"; + case Scene::MaterialInputSignature::Type::Vector2: return "vec2"; + case Scene::MaterialInputSignature::Type::Vector3: return "vec3"; + case Scene::MaterialInputSignature::Type::Vector4: return "vec4"; + case Scene::MaterialInputSignature::Type::Texture: return "sampler2D"; default: return ""; } }; - auto add_uniform_param = [&source, &to_glsl](const char *name, ShaderInputSignature::Type type) { - if (type != ShaderInputSignature::Type::None) + auto add_uniform_param = [&source, &to_glsl](const char *name, Scene::MaterialInputSignature::Type type) { + if (type != Scene::MaterialInputSignature::Type::None) source << "uniform " << to_glsl(type) << ' ' << name << ";" << std::endl; }; @@ -251,7 +254,7 @@ vec3 calculLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcam )"; - if (shader != nullptr) { + if (shader) { auto [contentType, content] = shader->getContent(); using ContentType = Scene::AShader::ContentType; @@ -271,39 +274,39 @@ vec3 calculLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcam source << " Material fragMat;" << std::endl; // TODO: Handle default values - const auto assign_to_vec = [&source](ShaderInputSignature::Type type, const std::string &name) { + const auto assign_to_vec = [&source](Scene::MaterialInputSignature::Type type, const std::string &name) { switch (type) { - case ShaderInputSignature::Type::None: break; - case ShaderInputSignature::Type::Scalar: + case Scene::MaterialInputSignature::Type::None: break; + case Scene::MaterialInputSignature::Type::Scalar: source << " fragMat." << name << " = vec3(" << name << ", 0, 0);" << std::endl; break; - case ShaderInputSignature::Type::Vector2: + case Scene::MaterialInputSignature::Type::Vector2: source << " fragMat." << name << " = vec3(" << name << ", 0);" << std::endl; break; - case ShaderInputSignature::Type::Vector3: + case Scene::MaterialInputSignature::Type::Vector3: source << " fragMat." << name << " = " << name << ";" << std::endl; // break; - case ShaderInputSignature::Type::Vector4: + case Scene::MaterialInputSignature::Type::Vector4: source << " fragMat." << name << " = " << name << ".xyz;" << std::endl; break; - case ShaderInputSignature::Type::Texture: + case Scene::MaterialInputSignature::Type::Texture: source << " fragMat." << name << " = texture(" << name << ", fs_in.uv).xyz;" << std::endl; break; } }; - const auto assign_to_float = [&source](ShaderInputSignature::Type type, const std::string &name, char x) { + const auto assign_to_float = [&source](Scene::MaterialInputSignature::Type type, const std::string &name, char x) { switch (type) { - case ShaderInputSignature::Type::None: break; - case ShaderInputSignature::Type::Scalar: + case Scene::MaterialInputSignature::Type::None: break; + case Scene::MaterialInputSignature::Type::Scalar: source << " fragMat." << name << " = " << name << ";" << std::endl; // break; - case ShaderInputSignature::Type::Vector2: - case ShaderInputSignature::Type::Vector3: - case ShaderInputSignature::Type::Vector4: + case Scene::MaterialInputSignature::Type::Vector2: + case Scene::MaterialInputSignature::Type::Vector3: + case Scene::MaterialInputSignature::Type::Vector4: source << " fragMat." << name << " = " << name << "." << x << ";" << std::endl; break; - case ShaderInputSignature::Type::Texture: + case Scene::MaterialInputSignature::Type::Texture: source << " fragMat." << name << " = texture(" << name << ", fs_in.uv)." << x << ";" << std::endl; break; } @@ -320,7 +323,7 @@ vec3 calculLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcam source << " " << shader->getFunction() << "(fragMat);" << std::endl; } - if (params.normal == ShaderInputSignature::Type::Texture) { + if (params.normal == Scene::MaterialInputSignature::Type::Texture) { source << " vec3 normal_value = normalize(texture(normal, fs_in.uv).xyz * 2 - 1);" << std::endl; } else { source << " vec3 normal_value = vec3(0, 0, 1);" << std::endl; @@ -345,4 +348,4 @@ vec3 calculLight(Light light, Material fragMat, vec3 normal_direction, vec3 fcam )"; } -} // namespace Stone::Scene +} // namespace Stone::Render::OpenGL diff --git a/Engine/Scene/include/Scene/Renderable/Material.hpp b/Engine/Scene/include/Scene/Renderable/Material.hpp index e577948..7181f63 100644 --- a/Engine/Scene/include/Scene/Renderable/Material.hpp +++ b/Engine/Scene/include/Scene/Renderable/Material.hpp @@ -134,4 +134,56 @@ class Material : public Core::Object, public IRenderable { std::string location_to_string(const Material::Location &location); Material::Location string_to_location(const std::string &str); + +#define FOR_EACH_SHADER_PARAMETERS(__WithParam) \ + __WithParam(diffuse) __WithParam(specular) __WithParam(ambient) __WithParam(emissive) __WithParam(shininess) \ + __WithParam(opacity) __WithParam(roughness) __WithParam(metallic) __WithParam(normal) __WithParam(occlusion) \ + __WithParam(height) + +struct MaterialInputSignature { + + enum class Type : uint8_t { + None = 0, + Scalar, + Vector2, + Vector3, + Vector4, + Texture, + }; + + union { + struct { +#define __DECLARE_PARAM(param) Type param : 3; + FOR_EACH_SHADER_PARAMETERS(__DECLARE_PARAM) +#undef __DECLARE_PARAM + }; + uint64_t data; // sizeof() should be greater or equal to the struct size + }; + bool _; + + MaterialInputSignature(); + MaterialInputSignature(const MaterialInputSignature &other) = default; + MaterialInputSignature &operator=(const MaterialInputSignature &other) = default; + + MaterialInputSignature(const std::shared_ptr &material); + + void setParamWithName(const std::string &name, Type value); + + void setFromMaterial(const std::shared_ptr &material); + + bool operator==(const MaterialInputSignature &other) const { + return data == other.data; + } +}; + + } // namespace Stone::Scene + +namespace std { +template <> +struct hash { + std::size_t operator()(const Stone::Scene::MaterialInputSignature ¶ms) const noexcept { + return std::hash()(params.data); + } +}; +} // namespace std diff --git a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp b/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp deleted file mode 100644 index ee65b78..0000000 --- a/Engine/Scene/include/Scene/Shader/ShaderGenerator.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2024 Stone-Engine - -#pragma once - -#include "Scene/Shader/ShaderInputSignature.hpp" - -namespace Stone::Scene { - -class ShaderGenerator { - - -public: - ShaderGenerator() = default; - - ~ShaderGenerator() = default; - - void generateFragmentShaderTemplate(const ShaderInputSignature ¶ms, std::ostream &output); - - void generateOpenGlForwardFragmentShader(const ShaderInputSignature ¶ms, class FragmentShader *shader, - std::ostream &output); -}; - -} // namespace Stone::Scene diff --git a/Engine/Scene/include/Scene/Shader/ShaderInputSignature.hpp b/Engine/Scene/include/Scene/Shader/ShaderInputSignature.hpp deleted file mode 100644 index 2fd9909..0000000 --- a/Engine/Scene/include/Scene/Shader/ShaderInputSignature.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2024 Stone-Engine - -#pragma once - -#include "Scene/Renderable/IMeshObject.hpp" - -namespace Stone::Scene { - -#define FOR_EACH_SHADER_PARAMETERS(__WithParam) \ - __WithParam(diffuse) __WithParam(specular) __WithParam(ambient) __WithParam(emissive) __WithParam(shininess) \ - __WithParam(opacity) __WithParam(roughness) __WithParam(metallic) __WithParam(normal) __WithParam(occlusion) \ - __WithParam(height) - -struct ShaderInputSignature { - - enum class Type : uint8_t { - None = 0, - Scalar, - Vector2, - Vector3, - Vector4, - Texture, - }; - - union { - struct { -#define __DECLARE_PARAM(param) Type param : 3; - FOR_EACH_SHADER_PARAMETERS(__DECLARE_PARAM) - }; - uint64_t data; // sizeof() should be greater or equal to the struct size - }; - bool _; - -#define __INITIALIZE_PARAM(param) param(Type::None), - ShaderInputSignature(); - - void setParamWithName(const std::string &name, Type value); - - void setFromMaterial(const Scene::Material &material); - - bool operator==(const ShaderInputSignature &other) const { - return data == other.data; - } -}; - -} // namespace Stone::Scene - -namespace std { -template <> -struct hash { - std::size_t operator()(const Stone::Scene::ShaderInputSignature ¶ms) const noexcept { - return std::hash()(params.data); - } -}; -} // namespace std diff --git a/Engine/Scene/src/Scene/Renderable/Material.cpp b/Engine/Scene/src/Scene/Renderable/Material.cpp index d46a843..1c5e78a 100644 --- a/Engine/Scene/src/Scene/Renderable/Material.cpp +++ b/Engine/Scene/src/Scene/Renderable/Material.cpp @@ -109,4 +109,58 @@ Material::Location string_to_location(const std::string &str) { return str; } +#define __INITIALIZE_PARAM(param) param(Type::None), +MaterialInputSignature::MaterialInputSignature() : FOR_EACH_SHADER_PARAMETERS(__INITIALIZE_PARAM) _() { +} + +MaterialInputSignature::MaterialInputSignature(const std::shared_ptr &material) : MaterialInputSignature() { + setFromMaterial(material); +} + +void MaterialInputSignature::setParamWithName(const std::string &name, Type value) { + using ParamSetter = std::function; + +#define __MAP_NAME_TO_PARAM(param) \ + {#param, [](MaterialInputSignature &matParams, Type value) { \ + matParams.param = value; \ + }}, + + const static std::unordered_map paramSetters = { + FOR_EACH_SHADER_PARAMETERS(__MAP_NAME_TO_PARAM) // + }; + + auto it = paramSetters.find(name); + if (it != paramSetters.end()) { + it->second(*this, value); + } +} + +void MaterialInputSignature::setFromMaterial(const std::shared_ptr &material) { + if (material == nullptr) { + return; + } + + material->forEachScalars([this](const Material::Location &location, float value) { + (void)value; + if (std::holds_alternative(location)) { + const std::string &name(std::get(location)); + setParamWithName(name, Type::Scalar); + } + }); + material->forEachVectors([this](const Material::Location &location, glm::vec3 value) { + (void)value; + if (std::holds_alternative(location)) { + const std::string &name(std::get(location)); + setParamWithName(name, Type::Vector3); + } + }); + material->forEachTextures([this](const Material::Location &location, auto value) { + (void)value; + if (std::holds_alternative(location)) { + const std::string &name(std::get(location)); + setParamWithName(name, Type::Texture); + } + }); +} + } // namespace Stone::Scene diff --git a/Engine/Scene/src/Scene/Shader/ShaderInputSignature.cpp b/Engine/Scene/src/Scene/Shader/ShaderInputSignature.cpp deleted file mode 100644 index 73c40ce..0000000 --- a/Engine/Scene/src/Scene/Shader/ShaderInputSignature.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2024 Stone-Engine - -#include "Scene/Shader/ShaderInputSignature.hpp" - -#include "Scene/Renderable/Material.hpp" - -namespace Stone::Scene { - -#define __INITIALIZE_PARAM(param) param(Type::None), -ShaderInputSignature::ShaderInputSignature() : FOR_EACH_SHADER_PARAMETERS(__INITIALIZE_PARAM) _() { -} - -void ShaderInputSignature::setParamWithName(const std::string &name, Type value) { - using ParamSetter = std::function; - -#define __MAP_NAME_TO_PARAM(param) \ - { \ - #param, [](ShaderInputSignature &matParams, Type value) { \ - matParams.param = value; \ - } \ - } \ - , - - const static std::unordered_map paramSetters = { - FOR_EACH_SHADER_PARAMETERS(__MAP_NAME_TO_PARAM) // - }; - - auto it = paramSetters.find(name); - if (it != paramSetters.end()) { - it->second(*this, value); - } -} - -void ShaderInputSignature::setFromMaterial(const Material &material) { - material.forEachScalars([this](const Material::Location &location, float value) { - (void)value; - if (std::holds_alternative(location)) { - const std::string &name(std::get(location)); - setParamWithName(name, Type::Scalar); - } - }); - material.forEachVectors([this](const Material::Location &location, glm::vec3 value) { - (void)value; - if (std::holds_alternative(location)) { - const std::string &name(std::get(location)); - setParamWithName(name, Type::Vector3); - } - }); - material.forEachTextures([this](const Material::Location &location, auto value) { - (void)value; - if (std::holds_alternative(location)) { - const std::string &name(std::get(location)); - setParamWithName(name, Type::Texture); - } - }); -} - -} // namespace Stone::Scene diff --git a/examples/glsl_generator/CMakeLists.txt b/examples/glsl_generator/CMakeLists.txt index 28af4ac..03835fa 100644 --- a/examples/glsl_generator/CMakeLists.txt +++ b/examples/glsl_generator/CMakeLists.txt @@ -2,4 +2,4 @@ set(NAME glsl_generator) add_executable(${NAME} EXCLUDE_FROM_ALL main.cpp) target_include_directories(${NAME} PRIVATE ${PROJECT_BINARY_DIR}/include) -target_link_libraries(${NAME} PRIVATE scene) +target_link_libraries(${NAME} PRIVATE scene render) diff --git a/examples/glsl_generator/main.cpp b/examples/glsl_generator/main.cpp index 39da882..416d556 100644 --- a/examples/glsl_generator/main.cpp +++ b/examples/glsl_generator/main.cpp @@ -1,6 +1,6 @@ #include "config.h" #include "Scene/Renderable/Shader.hpp" -#include "Scene/Shader/ShaderGenerator.hpp" +#include "Render/OpenGL/Shader/ShaderGenerator.hpp" #include "Utils/FileSystem.hpp" #include "Utils/Json.hpp" @@ -20,28 +20,28 @@ static time_t getLastmodifiedTimeOfFile(const char *filename) { throw std::runtime_error("File does not exist"); } -Stone::Scene::ShaderInputSignature parseShaderInputSignature(const Json::Value &json) { - Stone::Scene::ShaderInputSignature params; +Stone::Scene::MaterialInputSignature parseMaterialInputSignature(const Json::Value &json) { + Stone::Scene::MaterialInputSignature params; auto ¶ms_obj = json.get(); for (auto [key, value] : params_obj) { - Stone::Scene::ShaderInputSignature::Type type; + Stone::Scene::MaterialInputSignature::Type type; if (!value.is()) throw std::runtime_error("Invalid type for key " + key); const std::string &type_str = value.get(); if (type_str == "scalar") - type = Stone::Scene::ShaderInputSignature::Type::Scalar; + type = Stone::Scene::MaterialInputSignature::Type::Scalar; else if (type_str == "vector2") - type = Stone::Scene::ShaderInputSignature::Type::Vector2; + type = Stone::Scene::MaterialInputSignature::Type::Vector2; else if (type_str == "vector3") - type = Stone::Scene::ShaderInputSignature::Type::Vector3; + type = Stone::Scene::MaterialInputSignature::Type::Vector3; else if (type_str == "vector4") - type = Stone::Scene::ShaderInputSignature::Type::Vector4; + type = Stone::Scene::MaterialInputSignature::Type::Vector4; else if (type_str == "texture") - type = Stone::Scene::ShaderInputSignature::Type::Texture; + type = Stone::Scene::MaterialInputSignature::Type::Texture; else throw std::runtime_error("Invalid type " + type_str); @@ -51,14 +51,14 @@ Stone::Scene::ShaderInputSignature parseShaderInputSignature(const Json::Value & return params; } -std::string to_string(Stone::Scene::ShaderInputSignature::Type type) { +std::string to_string(Stone::Scene::MaterialInputSignature::Type type) { switch (type) { - case Stone::Scene::ShaderInputSignature::Type::None: return "none"; - case Stone::Scene::ShaderInputSignature::Type::Scalar: return "scalar"; - case Stone::Scene::ShaderInputSignature::Type::Vector2: return "vector2"; - case Stone::Scene::ShaderInputSignature::Type::Vector3: return "vector3"; - case Stone::Scene::ShaderInputSignature::Type::Vector4: return "vector4"; - case Stone::Scene::ShaderInputSignature::Type::Texture: return "texture"; + case Stone::Scene::MaterialInputSignature::Type::None: return "none"; + case Stone::Scene::MaterialInputSignature::Type::Scalar: return "scalar"; + case Stone::Scene::MaterialInputSignature::Type::Vector2: return "vector2"; + case Stone::Scene::MaterialInputSignature::Type::Vector3: return "vector3"; + case Stone::Scene::MaterialInputSignature::Type::Vector4: return "vector4"; + case Stone::Scene::MaterialInputSignature::Type::Texture: return "texture"; } return ""; } @@ -79,15 +79,15 @@ void generateShaderOutput(const char *input_file, const char *output_file) { input_json_obj.erase("shader"); } - Stone::Scene::ShaderInputSignature params = parseShaderInputSignature(input_json); + Stone::Scene::MaterialInputSignature params = parseMaterialInputSignature(input_json); - Stone::Scene::ShaderGenerator generator; + Stone::Render::OpenGL::ShaderGenerator generator; std::cout << "Generating shader: {" << std::endl; #define __PRINT_SHADER_PARAM(param) std::cout << " " << #param << " " << to_string(params.param) << std::endl; FOR_EACH_SHADER_PARAMETERS(__PRINT_SHADER_PARAM) std::cout << "}" << std::endl; - generator.generateOpenGlForwardFragmentShader(params, shader.get(), output_stream); + generator.generateOpenGlForwardFragmentShader(params, shader, output_stream); } std::string input; From addf5ec5a712b2e4c4dea4c94fc6f69157c7737c Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 15 Apr 2025 21:29:35 +0200 Subject: [PATCH 72/89] fix format --- .../Render/include/Render/OpenGL/Shader/ShaderGenerator.hpp | 4 +++- Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp | 6 ++++-- .../Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp | 3 ++- .../Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp | 2 +- Engine/Render/src/Render/OpenGL/OpenGLResources.cpp | 3 ++- Engine/Render/src/Render/OpenGL/Shader/ShaderGenerator.cpp | 2 +- examples/glsl_generator/main.cpp | 2 +- 7 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Engine/Render/include/Render/OpenGL/Shader/ShaderGenerator.hpp b/Engine/Render/include/Render/OpenGL/Shader/ShaderGenerator.hpp index aec8af9..4c89cab 100644 --- a/Engine/Render/include/Render/OpenGL/Shader/ShaderGenerator.hpp +++ b/Engine/Render/include/Render/OpenGL/Shader/ShaderGenerator.hpp @@ -20,7 +20,9 @@ class ShaderGenerator { void generateFragmentShaderTemplate(const Scene::MaterialInputSignature ¶ms, std::ostream &output); - void generateOpenGlForwardFragmentShader(const Scene::MaterialInputSignature ¶ms, const std::shared_ptr &shader, std::ostream &output); + void generateOpenGlForwardFragmentShader(const Scene::MaterialInputSignature ¶ms, + const std::shared_ptr &shader, + std::ostream &output); }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp index d46a844..2293495 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp @@ -155,7 +155,8 @@ std::unique_ptr GlVertexShader::makeStandardInstancedMeshShader( // MARK: Fragment -std::unique_ptr GlFragmentShader::makeStandardForwardShader(const Scene::MaterialInputSignature ¶ms) { +std::unique_ptr +GlFragmentShader::makeStandardForwardShader(const Scene::MaterialInputSignature ¶ms) { std::stringstream source; Render::OpenGL::ShaderGenerator generator; @@ -164,7 +165,8 @@ std::unique_ptr GlFragmentShader::makeStandardForwardShader(co return std::make_unique(source.str().c_str()); } -std::unique_ptr GlFragmentShader::makeStandardDeferredShader(const Scene::MaterialInputSignature ¶ms) { +std::unique_ptr +GlFragmentShader::makeStandardDeferredShader(const Scene::MaterialInputSignature ¶ms) { (void)params; throw std::runtime_error("deffered shader is not implemented."); } diff --git a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp index 8164e07..b75c435 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.cpp @@ -9,7 +9,8 @@ namespace Stone::Render::OpenGL { -ShaderPrograms::ShaderPrograms(Scene::MaterialInputSignature params, const std::shared_ptr &resources) : _resources(resources) { +ShaderPrograms::ShaderPrograms(Scene::MaterialInputSignature params, const std::shared_ptr &resources) + : _resources(resources) { switch (resources->getRenderer().lock()->getDirector()->getRenderingMethod()) { case RenderingMethod::Forward: _glFragmentShader = GlFragmentShader::makeStandardForwardShader(params); break; case RenderingMethod::Deferred: _glFragmentShader = GlFragmentShader::makeStandardDeferredShader(params); break; diff --git a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp index 2630bce..3ed581f 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp @@ -3,9 +3,9 @@ #pragma once #include "GlShaders.hpp" +#include "Scene/Renderable/IMeshObject.hpp" #include "Scene/Renderable/Material.hpp" #include "Scene/Renderable/Shader.hpp" -#include "Scene/Renderable/IMeshObject.hpp" namespace Stone::Render::OpenGL { diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index 33d6278..eb8dbc3 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -71,7 +71,8 @@ const std::unique_ptr &OpenGLResources::getDefaultShaderPrograms return _defaultShaderPrograms; } -const std::unique_ptr &OpenGLResources::getStandardShaderPrograms(Scene::MaterialInputSignature params) { +const std::unique_ptr & +OpenGLResources::getStandardShaderPrograms(Scene::MaterialInputSignature params) { auto it = _standardsShaderPrograms.find(params); if (it == _standardsShaderPrograms.end()) { return (_standardsShaderPrograms[params] = std::make_unique(params, shared_from_this())); diff --git a/Engine/Render/src/Render/OpenGL/Shader/ShaderGenerator.cpp b/Engine/Render/src/Render/OpenGL/Shader/ShaderGenerator.cpp index 2498ca8..32c2d8f 100644 --- a/Engine/Render/src/Render/OpenGL/Shader/ShaderGenerator.cpp +++ b/Engine/Render/src/Render/OpenGL/Shader/ShaderGenerator.cpp @@ -40,7 +40,7 @@ void ShaderGenerator::generateFragmentShaderTemplate(const Scene::MaterialInputS output << "}" << std::endl; } -void ShaderGenerator::generateOpenGlForwardFragmentShader(const Scene::MaterialInputSignature& params, +void ShaderGenerator::generateOpenGlForwardFragmentShader(const Scene::MaterialInputSignature ¶ms, const std::shared_ptr &shader, std::ostream &output) { diff --git a/examples/glsl_generator/main.cpp b/examples/glsl_generator/main.cpp index 416d556..b9ac3a2 100644 --- a/examples/glsl_generator/main.cpp +++ b/examples/glsl_generator/main.cpp @@ -1,6 +1,6 @@ #include "config.h" -#include "Scene/Renderable/Shader.hpp" #include "Render/OpenGL/Shader/ShaderGenerator.hpp" +#include "Scene/Renderable/Shader.hpp" #include "Utils/FileSystem.hpp" #include "Utils/Json.hpp" From a516346b91fb74ef4b79765d75f75197d53b186a Mon Sep 17 00:00:00 2001 From: amasson Date: Tue, 15 Apr 2025 21:30:34 +0200 Subject: [PATCH 73/89] fix format --- Engine/Scene/src/Scene/Renderable/Material.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Engine/Scene/src/Scene/Renderable/Material.cpp b/Engine/Scene/src/Scene/Renderable/Material.cpp index 1c5e78a..8f35b89 100644 --- a/Engine/Scene/src/Scene/Renderable/Material.cpp +++ b/Engine/Scene/src/Scene/Renderable/Material.cpp @@ -121,9 +121,12 @@ void MaterialInputSignature::setParamWithName(const std::string &name, Type valu using ParamSetter = std::function; #define __MAP_NAME_TO_PARAM(param) \ - {#param, [](MaterialInputSignature &matParams, Type value) { \ - matParams.param = value; \ - }}, + { \ + #param, [](MaterialInputSignature &matParams, Type value) { \ + matParams.param = value; \ + } \ + } \ + , const static std::unordered_map paramSetters = { FOR_EACH_SHADER_PARAMETERS(__MAP_NAME_TO_PARAM) // From ac2ebbf87688bd527243c0bf6219f93e9b982809 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 16 Apr 2025 09:43:23 +0200 Subject: [PATCH 74/89] fix format --- Engine/Scene/src/Scene/Renderable/Material.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/Scene/src/Scene/Renderable/Material.cpp b/Engine/Scene/src/Scene/Renderable/Material.cpp index 8f35b89..e8390d0 100644 --- a/Engine/Scene/src/Scene/Renderable/Material.cpp +++ b/Engine/Scene/src/Scene/Renderable/Material.cpp @@ -124,7 +124,7 @@ void MaterialInputSignature::setParamWithName(const std::string &name, Type valu { \ #param, [](MaterialInputSignature &matParams, Type value) { \ matParams.param = value; \ - } \ + } \ } \ , From ca0739ebbfd3f821e29eb7d95907fb192bb975c5 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 16 Apr 2025 18:53:32 +0200 Subject: [PATCH 75/89] Cannot create empty slots --- Engine/Utils/include/Utils/SigSlot.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Engine/Utils/include/Utils/SigSlot.hpp b/Engine/Utils/include/Utils/SigSlot.hpp index b9065ef..c4e4654 100644 --- a/Engine/Utils/include/Utils/SigSlot.hpp +++ b/Engine/Utils/include/Utils/SigSlot.hpp @@ -23,6 +23,7 @@ struct Signal; template struct Slot { + Slot() = delete; Slot(const Slot &) = delete; Slot &operator=(const Slot &) = delete; From 84ddbfd927bfd3321ffc974e8ea3c81e765b0988 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 16 Apr 2025 20:42:58 +0200 Subject: [PATCH 76/89] OpenGLRenderer use shared ptr in private properties --- .../Render/src/Render/OpenGL/OpenGLRenderer.cpp | 2 +- .../Render/src/Render/OpenGL/OpenGLResources.cpp | 11 ++--------- .../Render/src/Render/OpenGL/OpenGLResources.hpp | 8 +++----- .../src/Render/OpenGL/Renderable/Material.cpp | 7 ++++++- .../src/Render/OpenGL/Renderable/MeshNode.cpp | 16 ++++++++-------- .../src/Render/OpenGL/Renderable/MeshNode.hpp | 5 +++-- 6 files changed, 23 insertions(+), 26 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp index 9da7e65..8a25894 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLRenderer.cpp @@ -12,8 +12,8 @@ namespace Stone::Render::OpenGL { void OpenGLRenderer::initialize(RendererSettings &settings) { const auto this_shared = std::static_pointer_cast(shared_from_this()); - _director = std::make_shared(this_shared, settings.rendering_method); _resources = std::make_shared(this_shared); + _director = std::make_shared(this_shared, settings.rendering_method); _director->initialize(settings.frame_size); } diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index eb8dbc3..5192ffc 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -64,18 +64,11 @@ const std::unique_ptr &OpenGLResources::getFragmentShader(Scen } } -const std::unique_ptr &OpenGLResources::getDefaultShaderPrograms() { - if (_defaultShaderPrograms == nullptr) { - _defaultShaderPrograms = std::make_unique(Scene::MaterialInputSignature(), shared_from_this()); - } - return _defaultShaderPrograms; -} - -const std::unique_ptr & +const std::shared_ptr & OpenGLResources::getStandardShaderPrograms(Scene::MaterialInputSignature params) { auto it = _standardsShaderPrograms.find(params); if (it == _standardsShaderPrograms.end()) { - return (_standardsShaderPrograms[params] = std::make_unique(params, shared_from_this())); + return (_standardsShaderPrograms[params] = std::make_shared(params, shared_from_this())); } else { return it->second; } diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp index 6d9ea04..485ed18 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp @@ -10,7 +10,7 @@ namespace Stone::Render::OpenGL { class OpenGLRenderer; -class OpenGLResources : std::enable_shared_from_this { +class OpenGLResources : public std::enable_shared_from_this { public: OpenGLResources() = delete; @@ -33,8 +33,7 @@ class OpenGLResources : std::enable_shared_from_this { // MARK: Shader Programs - const std::unique_ptr &getDefaultShaderPrograms(); - const std::unique_ptr &getStandardShaderPrograms(Scene::MaterialInputSignature params); + const std::shared_ptr &getStandardShaderPrograms(Scene::MaterialInputSignature params); private: std::weak_ptr _renderer; @@ -45,8 +44,7 @@ class OpenGLResources : std::enable_shared_from_this { std::unordered_map> _fragmentShaders; - std::unique_ptr _defaultShaderPrograms; - std::unordered_map> _standardsShaderPrograms; + std::unordered_map> _standardsShaderPrograms; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp index 4ed41f1..700d3c3 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp @@ -3,15 +3,20 @@ #include "Material.hpp" #include "FragmentShader.hpp" +#include "../OpenGLResources.hpp" namespace Stone::Render::OpenGL { Material::Material(Scene::Material &material, const std::shared_ptr &renderer) : _material(material) { + assert(renderer); + assert(renderer->getResources()); if (_material.getFragmentShader() == nullptr) { - _shaderPrograms = std::make_shared(material, renderer->getResources()); + Scene::MaterialInputSignature inputs(std::dynamic_pointer_cast(material.shared_from_this())); + _shaderPrograms = renderer->getResources()->getStandardShaderPrograms(inputs); } else { _shaderPrograms = _material.getFragmentShader()->getRendererObject()->getShaderPrograms(); } + assert(_shaderPrograms); #ifndef NDEBUG int textureCount = 0; diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp index 2cd9af9..f9e12f3 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp @@ -13,20 +13,20 @@ namespace Stone::Render::OpenGL { MeshNode::MeshNode(Scene::MeshNode &meshNode, const std::shared_ptr &renderer) - : _meshNode(meshNode), _material(nullptr), _shaderPrograms(nullptr) { + : _meshNode(meshNode), _renderer(renderer), _material(nullptr), _shaderPrograms(nullptr) { auto usedMaterial = _meshNode.getUsedMaterial(); if (usedMaterial) { assert(usedMaterial->isDirty() == false); - _material = usedMaterial->getRendererObject().get(); + _material = usedMaterial->getRendererObject(); } - if (_material != nullptr) { - _shaderPrograms = _material->getShaderPrograms().get(); + if (_material) { + _shaderPrograms = _material->getShaderPrograms(); } else { - _shaderPrograms = renderer->getResources()->getDefaultShaderPrograms().get(); + _shaderPrograms = renderer->getResources()->getStandardShaderPrograms(Scene::MaterialInputSignature(nullptr)); } - assert(_shaderPrograms != nullptr); + assert(_shaderPrograms); _shaderPrograms->makeMeshProgram(); } @@ -45,7 +45,7 @@ void MeshNode::render(Scene::RenderContext &context) { GlShaderProgram *program = _shaderPrograms->getMeshProgram().get(); program->use(); - if (_material != nullptr) { + if (_material) { _material->setUniforms(Scene::MeshType::Standard); } @@ -60,7 +60,7 @@ void MeshNode::render(Scene::RenderContext &context) { glCullFace(GL_BACK); glBindVertexArray(vramMesh.elementsBuffer); - glDrawElements(GL_TRIANGLES, vramMesh.numIndices, GL_UNSIGNED_INT, nullptr); + glDrawElements(GL_TRIANGLES, vramMesh.numIndices, GL_UNSIGNED_INT, NULL); } } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp index 0b6a65e..c020609 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp @@ -20,8 +20,9 @@ class MeshNode : public Scene::IRendererObject { private: Scene::MeshNode &_meshNode; - Material *_material; - ShaderPrograms *_shaderPrograms; + std::weak_ptr _renderer; + std::shared_ptr _material; + std::shared_ptr _shaderPrograms; }; } // namespace Stone::Render::OpenGL From d21d34ecb0b2ff52a68ed1fe50584545c3b44439 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 16 Apr 2025 20:47:23 +0200 Subject: [PATCH 77/89] Move vram mesh to gl elements --- .../src/Render/OpenGL/GlElements/VramMesh.hpp | 85 +++++++++++++++++++ .../src/Render/OpenGL/Renderable/Mesh.hpp | 75 +--------------- 2 files changed, 86 insertions(+), 74 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp diff --git a/Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp b/Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp new file mode 100644 index 0000000..04aadd1 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp @@ -0,0 +1,85 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "Scene/Renderable/Mesh.hpp" + +#include + +namespace Stone::Render::OpenGL { + +struct VRAMMesh { + + VRAMMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) { + (void)renderer; + if (mesh == nullptr) { + return; + } + + glGenVertexArrays(1, &elementsBuffer); + if (elementsBuffer == 0) { + throw std::runtime_error("Failed to generate vertex array buffer"); + } + + glGenBuffers(1, &verticesBuffer); + if (verticesBuffer == 0) { + glDeleteVertexArrays(1, &elementsBuffer); + throw std::runtime_error("Failed to generate vertices buffer"); + } + + glGenBuffers(1, &indicesBuffer); + if (indicesBuffer == 0) { + glDeleteBuffers(1, &verticesBuffer); + glDeleteVertexArrays(1, &elementsBuffer); + throw std::runtime_error("Failed to generate indices buffer"); + } + + glBindVertexArray(elementsBuffer); + + glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer); + glBufferData(GL_ARRAY_BUFFER, mesh->getVertices().size() * sizeof(Scene::Vertex), mesh->getVertices().data(), + GL_STATIC_DRAW); + + numIndices = mesh->getIndices().size(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(uint32_t), mesh->getIndices().data(), GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), + (void *)offsetof(Scene::Vertex, position)); + + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), (void *)offsetof(Scene::Vertex, normal)); + + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), + (void *)offsetof(Scene::Vertex, tangent)); + + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), + (void *)offsetof(Scene::Vertex, bitangent)); + + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), (void *)offsetof(Scene::Vertex, uv)); + } + + ~VRAMMesh() { + if (verticesBuffer != 0) { + glDeleteBuffers(1, &verticesBuffer); + } + if (indicesBuffer != 0) { + glDeleteBuffers(1, &indicesBuffer); + } + if (elementsBuffer != 0) { + glDeleteVertexArrays(1, &elementsBuffer); + } + } + + GLuint verticesBuffer = 0; + GLuint indicesBuffer = 0; + GLuint elementsBuffer = 0; + GLsizei numIndices = 0; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp index f47c640..681a938 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp @@ -5,83 +5,10 @@ #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Mesh.hpp" -#include +#include "../GlElements/VramMesh.hpp" namespace Stone::Render::OpenGL { -struct VRAMMesh { - - VRAMMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) { - (void)renderer; - if (mesh == nullptr) { - return; - } - - glGenVertexArrays(1, &elementsBuffer); - if (elementsBuffer == 0) { - throw std::runtime_error("Failed to generate vertex array buffer"); - } - - glGenBuffers(1, &verticesBuffer); - if (verticesBuffer == 0) { - glDeleteVertexArrays(1, &elementsBuffer); - throw std::runtime_error("Failed to generate vertices buffer"); - } - - glGenBuffers(1, &indicesBuffer); - if (indicesBuffer == 0) { - glDeleteBuffers(1, &verticesBuffer); - glDeleteVertexArrays(1, &elementsBuffer); - throw std::runtime_error("Failed to generate indices buffer"); - } - - glBindVertexArray(elementsBuffer); - - glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer); - glBufferData(GL_ARRAY_BUFFER, mesh->getVertices().size() * sizeof(Scene::Vertex), mesh->getVertices().data(), - GL_STATIC_DRAW); - - numIndices = mesh->getIndices().size(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(uint32_t), mesh->getIndices().data(), GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), - (void *)offsetof(Scene::Vertex, position)); - - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), (void *)offsetof(Scene::Vertex, normal)); - - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), - (void *)offsetof(Scene::Vertex, tangent)); - - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), - (void *)offsetof(Scene::Vertex, bitangent)); - - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), (void *)offsetof(Scene::Vertex, uv)); - } - - ~VRAMMesh() { - if (verticesBuffer != 0) { - glDeleteBuffers(1, &verticesBuffer); - } - if (indicesBuffer != 0) { - glDeleteBuffers(1, &indicesBuffer); - } - if (elementsBuffer != 0) { - glDeleteVertexArrays(1, &elementsBuffer); - } - } - - GLuint verticesBuffer = 0; - GLuint indicesBuffer = 0; - GLuint elementsBuffer = 0; - GLsizei numIndices = 0; -}; - class RendererMesh : public Scene::IRendererObject { public: From d2bd9a09b9becdec273490c1f1f3b4d64e426060 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 16 Apr 2025 20:48:13 +0200 Subject: [PATCH 78/89] fix format --- Engine/Render/src/Render/OpenGL/Renderable/Material.cpp | 2 +- Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp index 700d3c3..5ece0eb 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp @@ -2,8 +2,8 @@ #include "Material.hpp" -#include "FragmentShader.hpp" #include "../OpenGLResources.hpp" +#include "FragmentShader.hpp" namespace Stone::Render::OpenGL { diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp index 681a938..886074a 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp @@ -2,11 +2,10 @@ #pragma once +#include "../GlElements/VramMesh.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Mesh.hpp" -#include "../GlElements/VramMesh.hpp" - namespace Stone::Render::OpenGL { class RendererMesh : public Scene::IRendererObject { From ec8ec33e7e090321b04f3feea56d71dab9367a3d Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 16 Apr 2025 22:57:38 +0200 Subject: [PATCH 79/89] OpenGLRenderer refactor all renderer objects --- .../OpenGL/GlElements/ShaderPrograms.hpp | 2 + .../Render/OpenGL/GlElements/VRAMSkinMesh.hpp | 20 ++++++ .../src/Render/OpenGL/GlElements/VramMesh.hpp | 4 +- .../src/Render/OpenGL/OpenGLResources.cpp | 1 + .../OpenGL/Renderable/FragmentShader.hpp | 9 +-- .../Renderable/IOpenGLRendererObject.hpp | 22 +++++++ .../OpenGL/Renderable/InstancedMeshNode.hpp | 12 ++-- .../src/Render/OpenGL/Renderable/Material.cpp | 7 +-- .../src/Render/OpenGL/Renderable/Material.hpp | 8 +-- .../src/Render/OpenGL/Renderable/Mesh.hpp | 29 ++++----- .../src/Render/OpenGL/Renderable/MeshNode.cpp | 3 +- .../src/Render/OpenGL/Renderable/MeshNode.hpp | 5 +- .../src/Render/OpenGL/Renderable/SkinMesh.hpp | 45 +++++++++----- .../Render/OpenGL/Renderable/SkinMeshNode.hpp | 12 ++-- .../src/Render/OpenGL/Renderable/Texture.cpp | 52 ++++++++++++++++ .../src/Render/OpenGL/Renderable/Texture.hpp | 62 ++----------------- 16 files changed, 165 insertions(+), 128 deletions(-) create mode 100644 Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp create mode 100644 Engine/Render/src/Render/OpenGL/Renderable/IOpenGLRendererObject.hpp diff --git a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp index 3ed581f..c402e62 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/ShaderPrograms.hpp @@ -9,6 +9,8 @@ namespace Stone::Render::OpenGL { +class OpenGLResources; + class ShaderPrograms { public: ShaderPrograms(Scene::MaterialInputSignature params, const std::shared_ptr &resources); diff --git a/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp b/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp new file mode 100644 index 0000000..885048e --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp @@ -0,0 +1,20 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Scene/Renderable/SkinMesh.hpp" + +#include + +namespace Stone::Render::OpenGL { + +struct VRAMSkinMesh { + + VRAMSkinMesh(const std::shared_ptr &skinMesh) { + } + + ~VRAMSkinMesh() { + } +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp b/Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp index 04aadd1..815e44f 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp @@ -2,7 +2,6 @@ #pragma once -#include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Mesh.hpp" #include @@ -11,8 +10,7 @@ namespace Stone::Render::OpenGL { struct VRAMMesh { - VRAMMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) { - (void)renderer; + VRAMMesh(const std::shared_ptr &mesh) { if (mesh == nullptr) { return; } diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index 5192ffc..b8d77f1 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -4,6 +4,7 @@ #include "GlElements/ShaderPrograms.hpp" #include "OpenGLDirector.hpp" +#include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Material.hpp" namespace Stone::Render::OpenGL { diff --git a/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp b/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp index de4c889..b666d74 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/FragmentShader.hpp @@ -3,19 +3,20 @@ #pragma once #include "../GlElements/ShaderPrograms.hpp" +#include "IOpenGLRendererObject.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Shader.hpp" namespace Stone::Render::OpenGL { -class FragmentShader : public Scene::IRendererObject { +class FragmentShader : public IOpenGLRendererObject { public: - FragmentShader(Scene::FragmentShader &fragmentShader, const std::shared_ptr &renderer) { + FragmentShader(Scene::FragmentShader &fragmentShader, const std::shared_ptr &renderer) + : IOpenGLRendererObject(renderer) { _shaderPrograms = std::make_shared(fragmentShader, renderer->getResources()); } - void render(Scene::RenderContext &context) override { - (void)context; + void render(Scene::RenderContext &) override { } const std::shared_ptr &getShaderPrograms() const { diff --git a/Engine/Render/src/Render/OpenGL/Renderable/IOpenGLRendererObject.hpp b/Engine/Render/src/Render/OpenGL/Renderable/IOpenGLRendererObject.hpp new file mode 100644 index 0000000..f459272 --- /dev/null +++ b/Engine/Render/src/Render/OpenGL/Renderable/IOpenGLRendererObject.hpp @@ -0,0 +1,22 @@ +// Copyright 2024 Stone-Engine + +#pragma once + +#include "Scene/Renderable/IRenderable.hpp" + +namespace Stone::Render::OpenGL { + +class OpenGLRenderer; + +class IOpenGLRendererObject : public Scene::IRendererObject { +public: + IOpenGLRendererObject(const std::shared_ptr &renderer) : _renderer(renderer) { + } + + ~IOpenGLRendererObject() override = default; + +protected: + std::weak_ptr _renderer; +}; + +} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp index 285e605..8c872fc 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/InstancedMeshNode.hpp @@ -2,29 +2,25 @@ #pragma once -#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "IOpenGLRendererObject.hpp" #include "Scene/Node/InstancedMeshNode.hpp" -#include - namespace Stone::Render::OpenGL { -class InstancedMeshNode : public Scene::IRendererObject { +class InstancedMeshNode : public IOpenGLRendererObject { public: InstancedMeshNode(Scene::InstancedMeshNode &instancedMeshNode, const std::shared_ptr &renderer) - : _instancedMeshNode(instancedMeshNode), _renderer(renderer) { + : IOpenGLRendererObject(renderer), _instancedMeshNode(instancedMeshNode) { } ~InstancedMeshNode() override { } - void render(Scene::RenderContext &context) override { - (void)context; + void render(Scene::RenderContext &) override { } private: Scene::InstancedMeshNode &_instancedMeshNode; - std::weak_ptr _renderer; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp index 5ece0eb..2713d0c 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.cpp @@ -7,7 +7,8 @@ namespace Stone::Render::OpenGL { -Material::Material(Scene::Material &material, const std::shared_ptr &renderer) : _material(material) { +Material::Material(Scene::Material &material, const std::shared_ptr &renderer) + : IOpenGLRendererObject(renderer), _material(material) { assert(renderer); assert(renderer->getResources()); if (_material.getFragmentShader() == nullptr) { @@ -28,10 +29,6 @@ Material::Material(Scene::Material &material, const std::shared_ptrgetProgram(meshType); assert(program != nullptr); diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp index b3ce352..5423855 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Material.hpp @@ -2,23 +2,23 @@ #pragma once -#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "IOpenGLRendererObject.hpp" #include "Scene/Renderable/IMeshObject.hpp" #include "Scene/Renderable/Material.hpp" -#include namespace Stone::Render::OpenGL { class ShaderPrograms; -class Material : public Scene::IRendererObject { +class Material : public IOpenGLRendererObject { public: Material(Scene::Material &material, const std::shared_ptr &renderer); ~Material() override = default; - void render(Scene::RenderContext &context) override; + void render(Scene::RenderContext &) override { + } void setUniforms(Scene::MeshType meshType); diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp index 886074a..4964ac5 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp @@ -2,21 +2,21 @@ #pragma once -#include "../GlElements/VramMesh.hpp" +#include "../GlElements/VRAMMesh.hpp" +#include "IOpenGLRendererObject.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Mesh.hpp" namespace Stone::Render::OpenGL { -class RendererMesh : public Scene::IRendererObject { +class RendererMesh : public IOpenGLRendererObject { public: RendererMesh(const std::shared_ptr &mesh, const std::shared_ptr &renderer) - : _vramMesh(mesh, renderer) { + : IOpenGLRendererObject(renderer), _vramMesh(mesh) { } - ~RendererMesh() override { - } + ~RendererMesh() override = default; const VRAMMesh &getVRAMMesh() const { return _vramMesh; @@ -30,38 +30,31 @@ class RendererMesh : public Scene::IRendererObject { class DynamicMesh : public RendererMesh { public: DynamicMesh(Scene::DynamicMesh &mesh, const std::shared_ptr &renderer) - : RendererMesh(std::static_pointer_cast(mesh.shared_from_this()), renderer), _mesh(mesh), - _renderer(renderer) { + : RendererMesh(std::static_pointer_cast(mesh.shared_from_this()), renderer), _mesh(mesh) { } - ~DynamicMesh() override { - } + ~DynamicMesh() override = default; - void render(Scene::RenderContext &context) override { - (void)context; + void render(Scene::RenderContext &) override { } private: Scene::DynamicMesh &_mesh; - std::weak_ptr _renderer; }; class StaticMesh : public RendererMesh { public: StaticMesh(Scene::StaticMesh &mesh, const std::shared_ptr &renderer) - : RendererMesh(mesh.getSourceMesh(), renderer), _mesh(mesh), _renderer(renderer) { + : RendererMesh(mesh.getSourceMesh(), renderer), _mesh(mesh) { } - ~StaticMesh() override { - } + ~StaticMesh() override = default; - void render(Scene::RenderContext &context) override { - (void)context; + void render(Scene::RenderContext &) override { } private: Scene::StaticMesh &_mesh; - std::weak_ptr _renderer; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp index f9e12f3..14d351a 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp @@ -8,12 +8,11 @@ #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Mesh.hpp" -#include namespace Stone::Render::OpenGL { MeshNode::MeshNode(Scene::MeshNode &meshNode, const std::shared_ptr &renderer) - : _meshNode(meshNode), _renderer(renderer), _material(nullptr), _shaderPrograms(nullptr) { + : IOpenGLRendererObject(renderer), _meshNode(meshNode), _material(nullptr), _shaderPrograms(nullptr) { auto usedMaterial = _meshNode.getUsedMaterial(); if (usedMaterial) { diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp index c020609..f6a01f8 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.hpp @@ -2,15 +2,15 @@ #pragma once +#include "IOpenGLRendererObject.hpp" #include "Scene/Node/MeshNode.hpp" namespace Stone::Render::OpenGL { class Material; -class OpenGLRenderer; class ShaderPrograms; -class MeshNode : public Scene::IRendererObject { +class MeshNode : public IOpenGLRendererObject { public: MeshNode(Scene::MeshNode &meshNode, const std::shared_ptr &renderer); @@ -20,7 +20,6 @@ class MeshNode : public Scene::IRendererObject { private: Scene::MeshNode &_meshNode; - std::weak_ptr _renderer; std::shared_ptr _material; std::shared_ptr _shaderPrograms; }; diff --git a/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp index 45856ac..f47aa93 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp @@ -2,47 +2,58 @@ #pragma once -#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "../GlElements/VRAMSkinMesh.hpp" +#include "IOpenGLRendererObject.hpp" #include "Scene/Renderable/SkinMesh.hpp" -#include - namespace Stone::Render::OpenGL { -class DynamicSkinMesh : public Scene::IRendererObject { +class RendererSkinMesh : public IOpenGLRendererObject { public: - DynamicSkinMesh(Scene::DynamicSkinMesh &skinMesh, const std::shared_ptr &renderer) - : _skinMesh(skinMesh), _renderer(renderer) { + RendererSkinMesh(const std::shared_ptr &skinMesh, + const std::shared_ptr &renderer) + : IOpenGLRendererObject(renderer), _vramMesh(skinMesh) { + } + + ~RendererSkinMesh() override = default; + + const VRAMSkinMesh &getVRAMSkinMesh() const { + return _vramMesh; } - ~DynamicSkinMesh() override { +private: + VRAMSkinMesh _vramMesh; +}; + +class DynamicSkinMesh : public RendererSkinMesh { +public: + DynamicSkinMesh(Scene::DynamicSkinMesh &skinMesh, const std::shared_ptr &renderer) + : RendererSkinMesh(std::static_pointer_cast(skinMesh.shared_from_this()), renderer), + _skinMesh(skinMesh) { } - void render(Scene::RenderContext &context) override { - (void)context; + ~DynamicSkinMesh() override = default; + + void render(Scene::RenderContext &) override { } private: Scene::DynamicSkinMesh &_skinMesh; - std::weak_ptr _renderer; }; -class StaticSkinMesh : public Scene::IRendererObject { +class StaticSkinMesh : public RendererSkinMesh { public: StaticSkinMesh(Scene::StaticSkinMesh &skinMesh, const std::shared_ptr &renderer) - : _skinMesh(skinMesh), _renderer(renderer) { + : RendererSkinMesh(skinMesh.getSourceMesh(), renderer), _skinMesh(skinMesh) { } - ~StaticSkinMesh() override { - } + ~StaticSkinMesh() override = default; - void render(Scene::RenderContext &context) override { - (void)context; + void render(Scene::RenderContext &) override { } private: Scene::StaticSkinMesh &_skinMesh; - std::weak_ptr _renderer; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp b/Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp index ea89dbd..34274ce 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/SkinMeshNode.hpp @@ -2,21 +2,18 @@ #pragma once -#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "IOpenGLRendererObject.hpp" #include "Scene/Node/SkinMeshNode.hpp" -#include - namespace Stone::Render::OpenGL { -class SkinMeshNode : public Scene::IRendererObject { +class SkinMeshNode : public IOpenGLRendererObject { public: SkinMeshNode(Scene::SkinMeshNode &skinMeshNode, const std::shared_ptr &renderer) - : _skinMeshNode(skinMeshNode), _renderer(renderer) { + : IOpenGLRendererObject(renderer), _skinMeshNode(skinMeshNode) { } - ~SkinMeshNode() override { - } + ~SkinMeshNode() override = default; void render(Scene::RenderContext &context) override { (void)context; @@ -24,7 +21,6 @@ class SkinMeshNode : public Scene::IRendererObject { private: Scene::SkinMeshNode &_skinMeshNode; - std::weak_ptr _renderer; }; } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp index 6676ec2..b09b8fe 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp @@ -2,6 +2,9 @@ #include "Texture.hpp" +#include "Core/Image/ImageData.hpp" +#include "Core/Image/ImageSource.hpp" + namespace Stone::Render::OpenGL { GLuint convert(Core::Image::Channel channel) { @@ -33,4 +36,53 @@ GLuint convert(Scene::TextureWrap wrap) { } } +Texture::Texture(Scene::Texture &texture, const std::shared_ptr &renderer) + : IOpenGLRendererObject(renderer), _gl_texture(0) { + std::shared_ptr imageSource = texture.getImage(); + if (imageSource == nullptr) { + return; + } + + imageSource->loadData(); + std::shared_ptr imageData = imageSource->getLoadedImage(); + + GLuint format = convert(imageData->getChannels()); + glGenTextures(1, &_gl_texture); + if (_gl_texture == 0) { + std::runtime_error("Failed to create texture buffer."); + } + glBindTexture(GL_TEXTURE_2D, _gl_texture); + glTexImage2D(GL_TEXTURE_2D, 0, format, imageData->getSize().x, imageData->getSize().y, 0, format, GL_UNSIGNED_BYTE, + imageData->getData()); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, convert(texture.getWrap())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, convert(texture.getWrap())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert(texture.getMinFilter(), true)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert(texture.getMagFilter(), false)); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); +} + +Texture::Texture(GLsizei width, GLsizei height, GLint internalFormat, GLenum format, GLenum type, GLint wrap, + GLint filter) + : IOpenGLRendererObject(nullptr), _gl_texture(0) { + glGenTextures(1, &_gl_texture); + if (_gl_texture == 0) { + std::runtime_error("Failed to create texture buffer."); + } + glBindTexture(GL_TEXTURE_2D, _gl_texture); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); +} + +Texture::~Texture() { + if (_gl_texture != 0) { + glDeleteTextures(1, &_gl_texture); + } +} + + } // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp index 5b935ac..c94e4ca 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.hpp @@ -2,73 +2,23 @@ #pragma once -#include "Core/Image/ImageData.hpp" -#include "Core/Image/ImageSource.hpp" -#include "Render/OpenGL/OpenGLRenderer.hpp" +#include "IOpenGLRendererObject.hpp" #include "Scene/Renderable/Texture.hpp" #include namespace Stone::Render::OpenGL { -GLuint convert(Core::Image::Channel channel); -GLuint convert(Scene::TextureFilter filter, bool mipmap); - -GLuint convert(Scene::TextureWrap wrap); - - -class Texture : public Scene::IRendererObject { +class Texture : public IOpenGLRendererObject { public: - Texture(Scene::Texture &texture, const std::shared_ptr &renderer) : _gl_texture(0) { - (void)renderer; - - std::shared_ptr imageSource = texture.getImage(); - if (imageSource == nullptr) { - return; - } - - imageSource->loadData(); - std::shared_ptr imageData = imageSource->getLoadedImage(); + Texture(Scene::Texture &texture, const std::shared_ptr &renderer); - GLuint format = convert(imageData->getChannels()); - glGenTextures(1, &_gl_texture); - if (_gl_texture == 0) { - std::runtime_error("Failed to create texture buffer."); - } - glBindTexture(GL_TEXTURE_2D, _gl_texture); - glTexImage2D(GL_TEXTURE_2D, 0, format, imageData->getSize().x, imageData->getSize().y, 0, format, - GL_UNSIGNED_BYTE, imageData->getData()); + Texture(GLsizei width, GLsizei height, GLint internalFormat, GLenum format, GLenum type, GLint wrap, GLint filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, convert(texture.getWrap())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, convert(texture.getWrap())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert(texture.getMinFilter(), true)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert(texture.getMagFilter(), false)); - glGenerateMipmap(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); - } - - Texture(GLsizei width, GLsizei height, GLint internalFormat, GLenum format, GLenum type, GLint wrap, GLint filter) { - glGenTextures(1, &_gl_texture); - if (_gl_texture == 0) { - std::runtime_error("Failed to create texture buffer."); - } - glBindTexture(GL_TEXTURE_2D, _gl_texture); - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); - } - - ~Texture() override { - if (_gl_texture != 0) { - glDeleteTextures(1, &_gl_texture); - } - } + ~Texture() override; - void render(Scene::RenderContext &context) override { - (void)context; + void render(Scene::RenderContext &) override { } GLuint getGlTexture() const { From 67c78409922aac38ff34373536190bb8c803826a Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 16 Apr 2025 23:17:43 +0200 Subject: [PATCH 80/89] OpenGLRenderer fill VRAMSkinMesh --- .../Render/OpenGL/GlElements/VRAMSkinMesh.hpp | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp b/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp index 885048e..391af46 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp @@ -11,10 +11,85 @@ namespace Stone::Render::OpenGL { struct VRAMSkinMesh { VRAMSkinMesh(const std::shared_ptr &skinMesh) { + if (skinMesh == nullptr) { + return; + } + + glGenVertexArrays(1, &elementsBuffer); + if (elementsBuffer == 0) { + throw std::runtime_error("Failed to generate vertex array buffer"); + } + + glGenBuffers(1, &verticesBuffer); + if (verticesBuffer == 0) { + glDeleteVertexArrays(1, &elementsBuffer); + throw std::runtime_error("Failed to generate vertices buffer"); + } + + glGenBuffers(1, &indicesBuffer); + if (indicesBuffer == 0) { + glDeleteVertexArrays(1, &elementsBuffer); + glDeleteBuffers(1, &verticesBuffer); + throw std::runtime_error("Failed to generate indices buffer"); + } + + glBindVertexArray(elementsBuffer); + + glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer); + glBufferData(GL_ARRAY_BUFFER, skinMesh->getVertices().size() * sizeof(Scene::WeightVertex), + skinMesh->getVertices().data(), GL_STATIC_DRAW); + + numIndices = skinMesh->getIndices().size(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(uint32_t), skinMesh->getIndices().data(), + GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)offsetof(Scene::WeightVertex, position)); + + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)offsetof(Scene::WeightVertex, normal)); + + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)offsetof(Scene::WeightVertex, tangent)); + + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)offsetof(Scene::WeightVertex, bitangent)); + + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)offsetof(Scene::WeightVertex, uv)); + + glEnableVertexAttribArray(5); + glVertexAttribIPointer( + 5, 4, GL_INT, sizeof(Scene::WeightVertex), + (void *)reinterpret_cast(&reinterpret_cast(0)->weights)); + + glEnableVertexAttribArray(6); + glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)reinterpret_cast(&reinterpret_cast(0)->ids)); } ~VRAMSkinMesh() { + if (verticesBuffer != 0) { + glDeleteBuffers(1, &verticesBuffer); + } + if (indicesBuffer != 0) { + glDeleteBuffers(1, &indicesBuffer); + } + if (elementsBuffer != 0) { + glDeleteVertexArrays(1, &elementsBuffer); + } } + + GLuint verticesBuffer = 0; + GLuint indicesBuffer = 0; + GLuint elementsBuffer = 0; + GLsizei numIndices = 0; }; } // namespace Stone::Render::OpenGL From aa81b358b53b369a708f514c2004e32eacb3659c Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 16 Apr 2025 23:39:09 +0200 Subject: [PATCH 81/89] clang tidy --- .../src/Render/OpenGL/GlElements/GlShaders.cpp | 4 ++-- .../src/Render/OpenGL/OpenGLResources.cpp | 17 ++++++++--------- .../src/Render/OpenGL/OpenGLResources.hpp | 2 +- .../src/Render/OpenGL/Renderable/Texture.cpp | 16 ++++++++-------- Engine/Scene/src/Scene/Renderable/Material.cpp | 6 +++--- 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp index 2293495..8f4daf5 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp @@ -214,7 +214,7 @@ GLint GlShaderProgram::getUniformLocation(const std::string &name) const { GLint GlShaderProgram::getUniformLocation(const Scene::Material::Location &location) const { if (std::holds_alternative(location)) { - const std::string &name(std::get(location)); + const auto &name(std::get(location)); return getUniformLocation(name); } else if (std::holds_alternative(location)) { return std::get(location); @@ -243,7 +243,7 @@ void GlShaderProgram::setUniformTexture(const Scene::Material::Location &locatio assert(textureIndex >= 0 && textureIndex < 32); glActiveTexture(GL_TEXTURE0 + textureIndex); glBindTexture(GL_TEXTURE_2D, texture.getGlTexture()); - glUniform1i(getUniformLocation(location), texture.getGlTexture()); + glUniform1i(getUniformLocation(location), (GLint)texture.getGlTexture()); } diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp index b8d77f1..44a47f3 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.cpp @@ -13,7 +13,7 @@ OpenGLResources::OpenGLResources(const std::shared_ptr &renderer : std::enable_shared_from_this(), _renderer(renderer) { } -const std::weak_ptr OpenGLResources::getRenderer() const { +const std::weak_ptr &OpenGLResources::getRenderer() const { return _renderer; } @@ -53,16 +53,15 @@ const std::unique_ptr &OpenGLResources::getFragmentShader(Scen auto renderer = getRenderer().lock(); assert(renderer != nullptr); auto it = _fragmentShaders.find(params); - if (it == _fragmentShaders.end()) { - switch (renderer->getDirector()->getRenderingMethod()) { - case RenderingMethod::Forward: - return (_fragmentShaders[params] = GlFragmentShader::makeStandardForwardShader(params)); - case RenderingMethod::Deferred: - return (_fragmentShaders[params] = GlFragmentShader::makeStandardDeferredShader(params)); - } - } else { + if (it != _fragmentShaders.end()) { return it->second; } + switch (renderer->getDirector()->getRenderingMethod()) { + case RenderingMethod::Deferred: + return (_fragmentShaders[params] = GlFragmentShader::makeStandardDeferredShader(params)); + case RenderingMethod::Forward: + return (_fragmentShaders[params] = GlFragmentShader::makeStandardForwardShader(params)); + } } const std::shared_ptr & diff --git a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp index 485ed18..9669fe3 100644 --- a/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp +++ b/Engine/Render/src/Render/OpenGL/OpenGLResources.hpp @@ -18,7 +18,7 @@ class OpenGLResources : public std::enable_shared_from_this { virtual ~OpenGLResources() = default; - const std::weak_ptr getRenderer() const; + const std::weak_ptr &getRenderer() const; // MARK: Vertex Shaders diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp index b09b8fe..70754ae 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp @@ -7,38 +7,38 @@ namespace Stone::Render::OpenGL { -GLuint convert(Core::Image::Channel channel) { +GLint convert(Core::Image::Channel channel) { switch (channel) { case Core::Image::Channel::GREY: return GL_RED; case Core::Image::Channel::DUAL: return GL_RG; case Core::Image::Channel::RGB: return GL_RGB; case Core::Image::Channel::RGBA: return GL_RGBA; - default: return GL_RGBA; } + return GL_RGBA; } -GLuint convert(Scene::TextureFilter filter, bool mipmap) { +GLint convert(Scene::TextureFilter filter, bool mipmap) { switch (filter) { case Scene::TextureFilter::Nearest: return mipmap ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; case Scene::TextureFilter::Linear: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; case Scene::TextureFilter::Cubic: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; - default: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; } + return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; } -GLuint convert(Scene::TextureWrap wrap) { +GLint convert(Scene::TextureWrap wrap) { switch (wrap) { case Scene::TextureWrap::Repeat: return GL_REPEAT; case Scene::TextureWrap::MirroredRepeat: return GL_MIRRORED_REPEAT; case Scene::TextureWrap::ClampToEdge: return GL_CLAMP_TO_EDGE; case Scene::TextureWrap::ClampToBorder: return GL_CLAMP_TO_BORDER; - default: return GL_REPEAT; } + return GL_REPEAT; } Texture::Texture(Scene::Texture &texture, const std::shared_ptr &renderer) : IOpenGLRendererObject(renderer), _gl_texture(0) { - std::shared_ptr imageSource = texture.getImage(); + const auto &imageSource = texture.getImage(); if (imageSource == nullptr) { return; } @@ -46,12 +46,12 @@ Texture::Texture(Scene::Texture &texture, const std::shared_ptr imageSource->loadData(); std::shared_ptr imageData = imageSource->getLoadedImage(); - GLuint format = convert(imageData->getChannels()); glGenTextures(1, &_gl_texture); if (_gl_texture == 0) { std::runtime_error("Failed to create texture buffer."); } glBindTexture(GL_TEXTURE_2D, _gl_texture); + GLint format = convert(imageData->getChannels()); glTexImage2D(GL_TEXTURE_2D, 0, format, imageData->getSize().x, imageData->getSize().y, 0, format, GL_UNSIGNED_BYTE, imageData->getData()); diff --git a/Engine/Scene/src/Scene/Renderable/Material.cpp b/Engine/Scene/src/Scene/Renderable/Material.cpp index e8390d0..edd3e77 100644 --- a/Engine/Scene/src/Scene/Renderable/Material.cpp +++ b/Engine/Scene/src/Scene/Renderable/Material.cpp @@ -146,21 +146,21 @@ void MaterialInputSignature::setFromMaterial(const std::shared_ptr &ma material->forEachScalars([this](const Material::Location &location, float value) { (void)value; if (std::holds_alternative(location)) { - const std::string &name(std::get(location)); + const auto &name(std::get(location)); setParamWithName(name, Type::Scalar); } }); material->forEachVectors([this](const Material::Location &location, glm::vec3 value) { (void)value; if (std::holds_alternative(location)) { - const std::string &name(std::get(location)); + const auto &name(std::get(location)); setParamWithName(name, Type::Vector3); } }); material->forEachTextures([this](const Material::Location &location, auto value) { (void)value; if (std::holds_alternative(location)) { - const std::string &name(std::get(location)); + const auto &name(std::get(location)); setParamWithName(name, Type::Texture); } }); From 0c44f86edb0489b85a608448837774de367b5d69 Mon Sep 17 00:00:00 2001 From: amasson Date: Wed, 16 Apr 2025 23:57:04 +0200 Subject: [PATCH 82/89] OpenGLRenderer fix layout offset --- .../src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp | 10 +++++----- Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp b/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp index 391af46..10e360d 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp @@ -46,23 +46,23 @@ struct VRAMSkinMesh { glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)offsetof(Scene::WeightVertex, position)); + (void *)offsetof(Scene::Vertex, position)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)offsetof(Scene::WeightVertex, normal)); + (void *)offsetof(Scene::Vertex, normal)); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)offsetof(Scene::WeightVertex, tangent)); + (void *)offsetof(Scene::Vertex, tangent)); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)offsetof(Scene::WeightVertex, bitangent)); + (void *)offsetof(Scene::Vertex, bitangent)); glEnableVertexAttribArray(4); glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)offsetof(Scene::WeightVertex, uv)); + (void *)offsetof(Scene::Vertex, uv)); glEnableVertexAttribArray(5); glVertexAttribIPointer( diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp b/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp index 70754ae..cbba8ce 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Texture.cpp @@ -20,7 +20,7 @@ GLint convert(Core::Image::Channel channel) { GLint convert(Scene::TextureFilter filter, bool mipmap) { switch (filter) { case Scene::TextureFilter::Nearest: return mipmap ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; - case Scene::TextureFilter::Linear: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; + case Scene::TextureFilter::Linear: case Scene::TextureFilter::Cubic: return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; } return mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; From 856ce0a099bf242ebb9ec5c3a7bac48cfa02d84e Mon Sep 17 00:00:00 2001 From: amasson Date: Thu, 17 Apr 2025 00:05:38 +0200 Subject: [PATCH 83/89] OpenGLRenderer put vrammesh into renderer object file --- .../Render/OpenGL/GlElements/VRAMSkinMesh.hpp | 95 ------------------- .../src/Render/OpenGL/GlElements/VramMesh.hpp | 83 ---------------- .../src/Render/OpenGL/Renderable/Mesh.hpp | 75 ++++++++++++++- .../src/Render/OpenGL/Renderable/SkinMesh.hpp | 87 ++++++++++++++++- 4 files changed, 160 insertions(+), 180 deletions(-) delete mode 100644 Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp delete mode 100644 Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp diff --git a/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp b/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp deleted file mode 100644 index 10e360d..0000000 --- a/Engine/Render/src/Render/OpenGL/GlElements/VRAMSkinMesh.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2024 Stone-Engine - -#pragma once - -#include "Scene/Renderable/SkinMesh.hpp" - -#include - -namespace Stone::Render::OpenGL { - -struct VRAMSkinMesh { - - VRAMSkinMesh(const std::shared_ptr &skinMesh) { - if (skinMesh == nullptr) { - return; - } - - glGenVertexArrays(1, &elementsBuffer); - if (elementsBuffer == 0) { - throw std::runtime_error("Failed to generate vertex array buffer"); - } - - glGenBuffers(1, &verticesBuffer); - if (verticesBuffer == 0) { - glDeleteVertexArrays(1, &elementsBuffer); - throw std::runtime_error("Failed to generate vertices buffer"); - } - - glGenBuffers(1, &indicesBuffer); - if (indicesBuffer == 0) { - glDeleteVertexArrays(1, &elementsBuffer); - glDeleteBuffers(1, &verticesBuffer); - throw std::runtime_error("Failed to generate indices buffer"); - } - - glBindVertexArray(elementsBuffer); - - glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer); - glBufferData(GL_ARRAY_BUFFER, skinMesh->getVertices().size() * sizeof(Scene::WeightVertex), - skinMesh->getVertices().data(), GL_STATIC_DRAW); - - numIndices = skinMesh->getIndices().size(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(uint32_t), skinMesh->getIndices().data(), - GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)offsetof(Scene::Vertex, position)); - - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)offsetof(Scene::Vertex, normal)); - - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)offsetof(Scene::Vertex, tangent)); - - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)offsetof(Scene::Vertex, bitangent)); - - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)offsetof(Scene::Vertex, uv)); - - glEnableVertexAttribArray(5); - glVertexAttribIPointer( - 5, 4, GL_INT, sizeof(Scene::WeightVertex), - (void *)reinterpret_cast(&reinterpret_cast(0)->weights)); - - glEnableVertexAttribArray(6); - glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)reinterpret_cast(&reinterpret_cast(0)->ids)); - } - - ~VRAMSkinMesh() { - if (verticesBuffer != 0) { - glDeleteBuffers(1, &verticesBuffer); - } - if (indicesBuffer != 0) { - glDeleteBuffers(1, &indicesBuffer); - } - if (elementsBuffer != 0) { - glDeleteVertexArrays(1, &elementsBuffer); - } - } - - GLuint verticesBuffer = 0; - GLuint indicesBuffer = 0; - GLuint elementsBuffer = 0; - GLsizei numIndices = 0; -}; - -} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp b/Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp deleted file mode 100644 index 815e44f..0000000 --- a/Engine/Render/src/Render/OpenGL/GlElements/VramMesh.hpp +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2024 Stone-Engine - -#pragma once - -#include "Scene/Renderable/Mesh.hpp" - -#include - -namespace Stone::Render::OpenGL { - -struct VRAMMesh { - - VRAMMesh(const std::shared_ptr &mesh) { - if (mesh == nullptr) { - return; - } - - glGenVertexArrays(1, &elementsBuffer); - if (elementsBuffer == 0) { - throw std::runtime_error("Failed to generate vertex array buffer"); - } - - glGenBuffers(1, &verticesBuffer); - if (verticesBuffer == 0) { - glDeleteVertexArrays(1, &elementsBuffer); - throw std::runtime_error("Failed to generate vertices buffer"); - } - - glGenBuffers(1, &indicesBuffer); - if (indicesBuffer == 0) { - glDeleteBuffers(1, &verticesBuffer); - glDeleteVertexArrays(1, &elementsBuffer); - throw std::runtime_error("Failed to generate indices buffer"); - } - - glBindVertexArray(elementsBuffer); - - glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer); - glBufferData(GL_ARRAY_BUFFER, mesh->getVertices().size() * sizeof(Scene::Vertex), mesh->getVertices().data(), - GL_STATIC_DRAW); - - numIndices = mesh->getIndices().size(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(uint32_t), mesh->getIndices().data(), GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), - (void *)offsetof(Scene::Vertex, position)); - - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), (void *)offsetof(Scene::Vertex, normal)); - - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), - (void *)offsetof(Scene::Vertex, tangent)); - - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), - (void *)offsetof(Scene::Vertex, bitangent)); - - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), (void *)offsetof(Scene::Vertex, uv)); - } - - ~VRAMMesh() { - if (verticesBuffer != 0) { - glDeleteBuffers(1, &verticesBuffer); - } - if (indicesBuffer != 0) { - glDeleteBuffers(1, &indicesBuffer); - } - if (elementsBuffer != 0) { - glDeleteVertexArrays(1, &elementsBuffer); - } - } - - GLuint verticesBuffer = 0; - GLuint indicesBuffer = 0; - GLuint elementsBuffer = 0; - GLsizei numIndices = 0; -}; - -} // namespace Stone::Render::OpenGL diff --git a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp index 4964ac5..9c8025d 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/Mesh.hpp @@ -2,13 +2,86 @@ #pragma once -#include "../GlElements/VRAMMesh.hpp" #include "IOpenGLRendererObject.hpp" #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Mesh.hpp" +#include + namespace Stone::Render::OpenGL { +struct VRAMMesh { + + VRAMMesh(const std::shared_ptr &mesh) { + if (mesh == nullptr) { + return; + } + + glGenVertexArrays(1, &elementsBuffer); + if (elementsBuffer == 0) { + throw std::runtime_error("Failed to generate vertex array buffer"); + } + + glGenBuffers(1, &verticesBuffer); + if (verticesBuffer == 0) { + glDeleteVertexArrays(1, &elementsBuffer); + throw std::runtime_error("Failed to generate vertices buffer"); + } + + glGenBuffers(1, &indicesBuffer); + if (indicesBuffer == 0) { + glDeleteBuffers(1, &verticesBuffer); + glDeleteVertexArrays(1, &elementsBuffer); + throw std::runtime_error("Failed to generate indices buffer"); + } + + glBindVertexArray(elementsBuffer); + + glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer); + glBufferData(GL_ARRAY_BUFFER, mesh->getVertices().size() * sizeof(Scene::Vertex), mesh->getVertices().data(), + GL_STATIC_DRAW); + + numIndices = mesh->getIndices().size(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(uint32_t), mesh->getIndices().data(), GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), + (void *)offsetof(Scene::Vertex, position)); + + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), (void *)offsetof(Scene::Vertex, normal)); + + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), + (void *)offsetof(Scene::Vertex, tangent)); + + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), + (void *)offsetof(Scene::Vertex, bitangent)); + + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Scene::Vertex), (void *)offsetof(Scene::Vertex, uv)); + } + + ~VRAMMesh() { + if (verticesBuffer != 0) { + glDeleteBuffers(1, &verticesBuffer); + } + if (indicesBuffer != 0) { + glDeleteBuffers(1, &indicesBuffer); + } + if (elementsBuffer != 0) { + glDeleteVertexArrays(1, &elementsBuffer); + } + } + + GLuint verticesBuffer = 0; + GLuint indicesBuffer = 0; + GLuint elementsBuffer = 0; + GLsizei numIndices = 0; +}; + class RendererMesh : public IOpenGLRendererObject { public: diff --git a/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp index f47aa93..f5f4c74 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp @@ -2,12 +2,97 @@ #pragma once -#include "../GlElements/VRAMSkinMesh.hpp" #include "IOpenGLRendererObject.hpp" #include "Scene/Renderable/SkinMesh.hpp" +#include + namespace Stone::Render::OpenGL { +struct VRAMSkinMesh { + + VRAMSkinMesh(const std::shared_ptr &skinMesh) { + if (skinMesh == nullptr) { + return; + } + + glGenVertexArrays(1, &elementsBuffer); + if (elementsBuffer == 0) { + throw std::runtime_error("Failed to generate vertex array buffer"); + } + + glGenBuffers(1, &verticesBuffer); + if (verticesBuffer == 0) { + glDeleteVertexArrays(1, &elementsBuffer); + throw std::runtime_error("Failed to generate vertices buffer"); + } + + glGenBuffers(1, &indicesBuffer); + if (indicesBuffer == 0) { + glDeleteVertexArrays(1, &elementsBuffer); + glDeleteBuffers(1, &verticesBuffer); + throw std::runtime_error("Failed to generate indices buffer"); + } + + glBindVertexArray(elementsBuffer); + + glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer); + glBufferData(GL_ARRAY_BUFFER, skinMesh->getVertices().size() * sizeof(Scene::WeightVertex), + skinMesh->getVertices().data(), GL_STATIC_DRAW); + + numIndices = skinMesh->getIndices().size(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(uint32_t), skinMesh->getIndices().data(), + GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)offsetof(Scene::Vertex, position)); + + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)offsetof(Scene::Vertex, normal)); + + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)offsetof(Scene::Vertex, tangent)); + + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)offsetof(Scene::Vertex, bitangent)); + + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)offsetof(Scene::Vertex, uv)); + + glEnableVertexAttribArray(5); + glVertexAttribIPointer( + 5, 4, GL_INT, sizeof(Scene::WeightVertex), + (void *)reinterpret_cast(&reinterpret_cast(0)->weights)); + + glEnableVertexAttribArray(6); + glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)reinterpret_cast(&reinterpret_cast(0)->ids)); + } + + ~VRAMSkinMesh() { + if (verticesBuffer != 0) { + glDeleteBuffers(1, &verticesBuffer); + } + if (indicesBuffer != 0) { + glDeleteBuffers(1, &indicesBuffer); + } + if (elementsBuffer != 0) { + glDeleteVertexArrays(1, &elementsBuffer); + } + } + + GLuint verticesBuffer = 0; + GLuint indicesBuffer = 0; + GLuint elementsBuffer = 0; + GLsizei numIndices = 0; +}; + class RendererSkinMesh : public IOpenGLRendererObject { public: RendererSkinMesh(const std::shared_ptr &skinMesh, From 0df98bc1d4383202446df4971f04ced1e2d67592 Mon Sep 17 00:00:00 2001 From: amasson Date: Thu, 17 Apr 2025 00:28:37 +0200 Subject: [PATCH 84/89] fix skin mesh order --- .../Render/src/Render/OpenGL/Renderable/SkinMesh.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp index f5f4c74..03c5f12 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp @@ -66,13 +66,13 @@ struct VRAMSkinMesh { (void *)offsetof(Scene::Vertex, uv)); glEnableVertexAttribArray(5); - glVertexAttribIPointer( - 5, 4, GL_INT, sizeof(Scene::WeightVertex), - (void *)reinterpret_cast(&reinterpret_cast(0)->weights)); + glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)reinterpret_cast(&reinterpret_cast(0)->weights)); glEnableVertexAttribArray(6); - glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)reinterpret_cast(&reinterpret_cast(0)->ids)); + glVertexAttribIPointer( + 6, 4, GL_INT, sizeof(Scene::WeightVertex), + (void *)reinterpret_cast(&reinterpret_cast(0)->ids)); } ~VRAMSkinMesh() { From a98b91a1cc67e1d983893003790b0d040cc245a7 Mon Sep 17 00:00:00 2001 From: amasson Date: Thu, 17 Apr 2025 00:29:55 +0200 Subject: [PATCH 85/89] fix format --- .../Render/src/Render/OpenGL/Renderable/SkinMesh.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp index 03c5f12..9295026 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/SkinMesh.hpp @@ -66,13 +66,13 @@ struct VRAMSkinMesh { (void *)offsetof(Scene::Vertex, uv)); glEnableVertexAttribArray(5); - glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), - (void *)reinterpret_cast(&reinterpret_cast(0)->weights)); + glVertexAttribPointer( + 5, 4, GL_FLOAT, GL_FALSE, sizeof(Scene::WeightVertex), + (void *)reinterpret_cast(&reinterpret_cast(0)->weights)); glEnableVertexAttribArray(6); - glVertexAttribIPointer( - 6, 4, GL_INT, sizeof(Scene::WeightVertex), - (void *)reinterpret_cast(&reinterpret_cast(0)->ids)); + glVertexAttribIPointer(6, 4, GL_INT, sizeof(Scene::WeightVertex), + (void *)reinterpret_cast(&reinterpret_cast(0)->ids)); } ~VRAMSkinMesh() { From 3f574cc6fafcf9498d828f34cc0a49e953e899fd Mon Sep 17 00:00:00 2001 From: amasson Date: Sat, 19 Apr 2025 23:55:51 +0200 Subject: [PATCH 86/89] OpenGLRenderer send normal matrix to pipeline --- Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp | 4 ++++ Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp | 1 + Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp | 3 +++ 3 files changed, 8 insertions(+) diff --git a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp index 8f4daf5..ac7d1a1 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.cpp @@ -234,6 +234,10 @@ void GlShaderProgram::setUniform(const Scene::Material::Location &location, cons glUniform3fv(getUniformLocation(location), 1, glm::value_ptr(vec3)); } +void GlShaderProgram::setUniform(const Scene::Material::Location &location, const glm::mat3 &mat3) const { + glUniformMatrix3fv(getUniformLocation(location), 1, GL_FALSE, glm::value_ptr(mat3)); +} + void GlShaderProgram::setUniform(const Scene::Material::Location &location, const glm::mat4 &mat4) const { glUniformMatrix4fv(getUniformLocation(location), 1, GL_FALSE, glm::value_ptr(mat4)); } diff --git a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp index 9e1f614..15cd4bf 100644 --- a/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp +++ b/Engine/Render/src/Render/OpenGL/GlElements/GlShaders.hpp @@ -88,6 +88,7 @@ class GlShaderProgram { void setUniform(const Scene::Material::Location &location, int integer) const; void setUniform(const Scene::Material::Location &location, float scalar) const; void setUniform(const Scene::Material::Location &location, const glm::vec3 &vec3) const; + void setUniform(const Scene::Material::Location &location, const glm::mat3 &mat3) const; void setUniform(const Scene::Material::Location &location, const glm::mat4 &mat4) const; void setUniformTexture(const Scene::Material::Location &location, const Texture &texture, int textureIndex) const; diff --git a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp index 14d351a..1c94cbb 100644 --- a/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp +++ b/Engine/Render/src/Render/OpenGL/Renderable/MeshNode.cpp @@ -8,6 +8,8 @@ #include "Render/OpenGL/OpenGLRenderer.hpp" #include "Scene/Renderable/Mesh.hpp" +#include + namespace Stone::Render::OpenGL { @@ -52,6 +54,7 @@ void MeshNode::render(Scene::RenderContext &context) { program->setUniform("u_mat_model", context.mvp.modelMatrix); program->setUniform("u_mat_view", context.mvp.viewMatrix); program->setUniform("u_mat_projection", context.mvp.projMatrix); + program->setUniform("u_mat_normal", glm::inverseTranspose(glm::mat3(context.mvp.modelMatrix))); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); From b725c33c44a84eb12d68ebade8663a22f3e5e2d1 Mon Sep 17 00:00:00 2001 From: amasson Date: Sat, 19 Apr 2025 23:56:30 +0200 Subject: [PATCH 87/89] custom fragment shader take inout Material --- Engine/Scene/include/Scene/Renderable/Shader.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Engine/Scene/include/Scene/Renderable/Shader.hpp b/Engine/Scene/include/Scene/Renderable/Shader.hpp index 7d93315..d06f4fa 100644 --- a/Engine/Scene/include/Scene/Renderable/Shader.hpp +++ b/Engine/Scene/include/Scene/Renderable/Shader.hpp @@ -86,9 +86,9 @@ class AShader : public Core::Object, public IRenderable { void setLocation(const std::string &name, int location); private: - ContentType _contentType = ContentType::SourceCode; /** The type of the content. */ - std::string _content = "void customShader() {}"; /** The content of the shader. */ - std::string _function = "customShader"; /** The function to call in the shader. */ + ContentType _contentType = ContentType::SourceCode; /** The type of the content. */ + std::string _content = "void customShader(inout Material fragMat) {}"; /** The content of the shader. */ + std::string _function = "customShader"; /** The function to call in the shader. */ std::unordered_map _locations = {}; /** The binding locations of the variables in the shader. */ int _maxLocation = -1; /** The cached maximum value from the locations. */ From 89d0cebd1b3f84eb2c744235aab9854cad834dc0 Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 27 Apr 2025 09:42:53 +0200 Subject: [PATCH 88/89] reorganize scop --- examples/scop/CMakeLists.txt | 2 +- examples/scop/RotatingNode.cpp | 4 + examples/scop/RotatingNode.hpp | 23 +++++ examples/scop/ScopEnv.hpp | 53 ++++++++++++ examples/scop/ScopSceneController.hpp | 100 ++++++++++++++++++++++ examples/scop/main.cpp | 119 ++------------------------ 6 files changed, 186 insertions(+), 115 deletions(-) create mode 100644 examples/scop/RotatingNode.cpp create mode 100644 examples/scop/RotatingNode.hpp create mode 100644 examples/scop/ScopEnv.hpp create mode 100644 examples/scop/ScopSceneController.hpp diff --git a/examples/scop/CMakeLists.txt b/examples/scop/CMakeLists.txt index 74e5ab3..f825f41 100644 --- a/examples/scop/CMakeLists.txt +++ b/examples/scop/CMakeLists.txt @@ -1,6 +1,6 @@ set(NAME scop) -add_executable(${NAME} EXCLUDE_FROM_ALL main.cpp) +add_executable(${NAME} EXCLUDE_FROM_ALL main.cpp RotatingNode.cpp) target_include_directories(${NAME} PRIVATE ${PROJECT_BINARY_DIR}/include) target_link_libraries(${NAME} PRIVATE scene diff --git a/examples/scop/RotatingNode.cpp b/examples/scop/RotatingNode.cpp new file mode 100644 index 0000000..974d083 --- /dev/null +++ b/examples/scop/RotatingNode.cpp @@ -0,0 +1,4 @@ + +#include "RotatingNode.hpp" + +STONE_NODE_IMPLEMENTATION(RotatingNode) diff --git a/examples/scop/RotatingNode.hpp b/examples/scop/RotatingNode.hpp new file mode 100644 index 0000000..c78536f --- /dev/null +++ b/examples/scop/RotatingNode.hpp @@ -0,0 +1,23 @@ + +#pragma once + +#include "Scene/Node/PivotNode.hpp" + +class RotatingNode : public Stone::Scene::PivotNode { + STONE_NODE(RotatingNode) + +public: + RotatingNode(const std::string &name = "rotating_node") : PivotNode(name) { + } + + void update(float deltaTime) override { + getTransform().rotate(deltaTime * rotationSpeeds); + } + + void setRotationSpeed(glm::vec3 speeds) { + rotationSpeeds = speeds; + } + +private: + glm::vec3 rotationSpeeds = {0.0f, 0.4f, 0.0f}; +}; diff --git a/examples/scop/ScopEnv.hpp b/examples/scop/ScopEnv.hpp new file mode 100644 index 0000000..75ef800 --- /dev/null +++ b/examples/scop/ScopEnv.hpp @@ -0,0 +1,53 @@ + +#pragma once + +#include "ScopSceneController.hpp" +#include "Window.hpp" + +#include + +namespace Scop { + +class Env { +public: + Env(std::optional path = std::nullopt) { + std::cout << "Starting in directory " << std::filesystem::current_path() << std::endl; + + app = std::make_shared(); + + _makeWindow(); + _makeSceneController(); + + if (path) + sceneController->loadAsset(*path); + } + + int run() { + return app->run(); + } + + ~Env() { + std::cout << "Bye!" << std::endl; + } + +private: + void _makeWindow() { + Stone::Window::WindowSettings win_settings; + win_settings.title = "Scop"; + win_settings.width = 1280; + win_settings.height = 720; + win_settings.resizable = true; + + window = app->createWindow(win_settings); + } + + void _makeSceneController() { + sceneController = std::make_shared(window->getWorld()); + } + + std::shared_ptr app; + std::shared_ptr window; + std::shared_ptr sceneController; +}; + +} // namespace Scop diff --git a/examples/scop/ScopSceneController.hpp b/examples/scop/ScopSceneController.hpp new file mode 100644 index 0000000..c60b44c --- /dev/null +++ b/examples/scop/ScopSceneController.hpp @@ -0,0 +1,100 @@ + +#pragma once + +#include "Core/Assets/Bundle.hpp" +#include "Core/Image/ImageSource.hpp" +#include "RotatingNode.hpp" +#include "Scene.hpp" +#include "Scene/Assets/AssetResource.hpp" +#include "Scene/Node/WorldNode.hpp" + +namespace Scop { + +class SceneController { +public: + SceneController(std::shared_ptr world) : world(world) { + assetsBundle = std::make_shared(); + + // Generate a Mesh + auto mesh = makePlaneMesh(); + + // Create a MeshNode + auto meshNode = std::make_shared(); + world->addChild(meshNode); + meshNode->setMesh(mesh); + + // Create a Texture + auto stone_texture = std::make_shared(); + auto stone_image_source = assetsBundle->loadResource( + "docs/img/stone-engine.png", Stone::Core::Image::Channel::RGBA); + stone_texture->setImage(stone_image_source); + + // Create a Material using the texture + auto stone_material = std::make_shared(); + stone_material->setTextureParameter("diffuse", stone_texture); + meshNode->setMaterial(stone_material); + + // Create a shader from a file + // auto stone_shader = std::make_shared("shaders/frag.spv"); + // stone_shader->setLocation("diffuse", 1); + // stone_material->setFragmentShader(stone_shader); + + // Create a second MeshNode with the same mesh + auto meshRotatingNode = world->addChild(); + meshRotatingNode->getTransform().setPosition({0.0f, 0.0f, 0.0f}); + auto secondMeshNode = std::make_shared(); + meshRotatingNode->addChild(secondMeshNode); + meshRotatingNode->setRotationSpeed({0.0f, 0.4f, 0.0f}); + secondMeshNode->setMesh(mesh); + + // Create a blue material that takes no texture as everything is in the shader code + // auto blueShader = std::make_shared("shaders/frag-blue.glsl"); + // auto blueMaterial = std::make_shared(); + // blueMaterial->setFragmentShader(blueShader); + // secondMeshNode->setMaterial(stone_material /* blueMaterial */); + + // Create a camera moving around the scene + auto cameraRotator = world->addChild(); + auto cameraNode = cameraRotator->addChild(); + cameraNode->getTransform().setPosition({0.0f, 3.0f, 3.0f}); + cameraNode->getTransform().rotate({-0.6f, 0.0f, 0.0f}); + world->setActiveCamera(cameraNode); + } + + void loadAsset(std::string path) { + // Load the asset from the given path + assetsBundle = std::make_shared(); + auto asset = assetsBundle->loadResource(path); + auto node = asset->getRootNode(); + world->addChild(node); + std::cout << asset->getMetadatas() << std::endl; + node->writeHierarchy(std::cout); + } + +private: + + std::shared_ptr makePlaneMesh() { + auto mesh = std::make_shared(); + mesh->withElementsRef([](auto vertices, auto indices) { + indices = {0, 1, 2, 0, 2, 3}; + vertices.emplace_back(); + vertices.back().position = {-0.5f, -0.5f, 0.0f}; + vertices.back().uv = {0.0f, 0.0f}; + vertices.emplace_back(); + vertices.back().position = {0.5f, -0.5f, 0.0f}; + vertices.back().uv = {1.0f, 0.0f}; + vertices.emplace_back(); + vertices.back().position = {0.5f, 0.5f, 0.0f}; + vertices.back().uv = {1.0f, 1.0f}; + vertices.emplace_back(); + vertices.back().position = {-0.5f, 0.5f, 0.0f}; + vertices.back().uv = {0.0f, 1.0f}; + }); + return mesh; + } + + std::shared_ptr world; + std::shared_ptr assetsBundle; +}; + +} // namespace Scop diff --git a/examples/scop/main.cpp b/examples/scop/main.cpp index aae40ec..541c317 100644 --- a/examples/scop/main.cpp +++ b/examples/scop/main.cpp @@ -4,130 +4,21 @@ #include #endif -#include "Core/Assets/Bundle.hpp" -#include "Core/Image/ImageSource.hpp" -#include "Scene.hpp" -#include "Scene/Assets/AssetResource.hpp" -#include "Window.hpp" - -#include - -class RotatingNode : public Stone::Scene::PivotNode { - STONE_NODE(RotatingNode) - -public: - RotatingNode(const std::string &name = "rotating_node") : PivotNode(name) { - } - - void update(float deltaTime) override { - getTransform().rotate(deltaTime * rotationSpeeds); - } - - void setRotationSpeed(glm::vec3 speeds) { - rotationSpeeds = speeds; - } - -private: - glm::vec3 rotationSpeeds = {0.0f, 0.4f, 0.0f}; -}; - -STONE_NODE_IMPLEMENTATION(RotatingNode) +#include "ScopEnv.hpp" int main(int argc, char **argv) { #ifdef _WIN32 SetConsoleOutputCP(CP_UTF8); #endif - std::cout << "Starting in directory " << std::filesystem::current_path() << std::endl; - int retCode; { - // Create an App - auto app = std::make_shared(); - - // Create a Window - Stone::Window::WindowSettings win_settings; - win_settings.title = "Scop"; - auto window = app->createWindow(win_settings); - - // Create the assets bundle - auto assetsBundle = std::make_shared(); - - // Generate a Mesh - auto mesh = std::make_shared(); - mesh->withElementsRef([](auto vertices, auto indices) { - indices = {0, 1, 2, 0, 2, 3}; - vertices.emplace_back(); - vertices.back().position = {-0.5f, -0.5f, 0.0f}; - vertices.back().uv = {0.0f, 0.0f}; - vertices.emplace_back(); - vertices.back().position = {0.5f, -0.5f, 0.0f}; - vertices.back().uv = {1.0f, 0.0f}; - vertices.emplace_back(); - vertices.back().position = {0.5f, 0.5f, 0.0f}; - vertices.back().uv = {1.0f, 1.0f}; - vertices.emplace_back(); - vertices.back().position = {-0.5f, 0.5f, 0.0f}; - vertices.back().uv = {0.0f, 1.0f}; - }); - - // Create a MeshNode - auto meshNode = std::make_shared(); - window->getWorld()->addChild(meshNode); - meshNode->setMesh(mesh); - - // Create a Texture - auto stone_texture = std::make_shared(); - auto stone_image_source = assetsBundle->loadResource( - "docs/img/stone-engine.png", Stone::Core::Image::Channel::RGBA); - stone_texture->setImage(stone_image_source); - - // Create a Material using the texture - auto stone_material = std::make_shared(); - stone_material->setTextureParameter("diffuse", stone_texture); - meshNode->setMaterial(stone_material); - - // Create a shader from a file - // auto stone_shader = std::make_shared("shaders/frag.spv"); - // stone_shader->setLocation("diffuse", 1); - // stone_material->setFragmentShader(stone_shader); - - // Create a second MeshNode with the same mesh - auto meshRotatingNode = window->getWorld()->addChild(); - meshRotatingNode->getTransform().setPosition({0.0f, 0.0f, 0.0f}); - auto secondMeshNode = std::make_shared(); - meshRotatingNode->addChild(secondMeshNode); - meshRotatingNode->setRotationSpeed({0.0f, 0.4f, 0.0f}); - secondMeshNode->setMesh(mesh); - - // Create a blue material that takes no texture as everything is in the shader code - // auto blueShader = std::make_shared("shaders/frag-blue.glsl"); - // auto blueMaterial = std::make_shared(); - // blueMaterial->setFragmentShader(blueShader); - secondMeshNode->setMaterial(stone_material /* blueMaterial */); - - // Create a camera moving around the scene - auto cameraRotator = window->getWorld()->addChild(); - auto cameraNode = cameraRotator->addChild(); - cameraNode->getTransform().setPosition({0.0f, 3.0f, 3.0f}); - cameraNode->getTransform().rotate({-0.6f, 0.0f, 0.0f}); - window->getWorld()->setActiveCamera(cameraNode); - - // Load a node from a file - if (argc > 1) { - auto asset = assetsBundle->loadResource(argv[1]); - auto node = asset->getRootNode(); - window->getWorld()->addChild(node); - std::cout << asset->getMetadatas() << std::endl; - node->writeHierarchy(std::cout); - } - - // Run the App - retCode = app->run(); + std::optional path = std::nullopt; + if (argc >= 2) + path = std::string(argv[1]); + retCode = Scop::Env(path).run(); } - std::cout << "Bye!" << std::endl; - #if STONE_ENGINE_USE_SYSTEM_PAUSE system("pause"); #endif From f96c003a2c873069201515525cbe9655e1a8ce6d Mon Sep 17 00:00:00 2001 From: amasson Date: Sun, 27 Apr 2025 09:43:38 +0200 Subject: [PATCH 89/89] fix format --- examples/scop/ScopSceneController.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/scop/ScopSceneController.hpp b/examples/scop/ScopSceneController.hpp index c60b44c..b401752 100644 --- a/examples/scop/ScopSceneController.hpp +++ b/examples/scop/ScopSceneController.hpp @@ -72,7 +72,6 @@ class SceneController { } private: - std::shared_ptr makePlaneMesh() { auto mesh = std::make_shared(); mesh->withElementsRef([](auto vertices, auto indices) {