From 136677c456769575781f78837501ff866354f8ce Mon Sep 17 00:00:00 2001 From: ternaryop8479 Date: Mon, 9 Feb 2026 18:32:13 +0800 Subject: [PATCH] Initial structure. --- CMakeLists.txt | 243 - all_headers.md | 4336 ------------------ examples/00_phase1_test/CMakeLists.txt | 4 - examples/00_phase1_test/main.cpp | 188 - examples/01_hello_triangle/CMakeLists.txt | 2 - examples/01_phase2_test/CMakeLists.txt | 10 - examples/01_phase2_test/main.cpp | 326 -- examples/02_cornell_box/CMakeLists.txt | 2 - examples/02_phase3_test/CMakeLists.txt | 18 - examples/02_phase3_test/main.cpp | 478 -- examples/02_visual_test/CMakeLists.txt | 10 - examples/02_visual_test/main.cpp | 329 -- examples/03_material_showcase/CMakeLists.txt | 2 - examples/03_phase4_test/CMakeLists.txt | 10 - examples/03_phase4_test/main.cpp | 410 -- examples/04_phase5_test/CMakeLists.txt | 7 - examples/04_phase5_test/main.cpp | 282 -- examples/04performance_test/CMakeLists.txt | 2 - examples/CMakeLists.txt | 16 - files.md | 1933 -------- include/are/acceleration/bvh.h | 135 - include/are/acceleration/bvh_builder.h | 94 - include/are/acceleration/bvh_node.h | 52 - include/are/are.h | 77 - include/are/core/config.h | 104 - include/are/core/logger.h | 79 - include/are/core/profiler.h | 122 - include/are/core/types.h | 75 - include/are/geometry/aabb.h | 133 - include/are/geometry/transform.h | 120 - include/are/geometry/triangle.h | 89 - include/are/geometry/vertex.h | 110 - include/are/platform/gl_context.h | 90 - include/are/platform/window.h | 84 - include/are/rasterizer/gbuffer.h | 118 - include/are/rasterizer/rasterizer.h | 73 - include/are/rasterizer/shader_program.h | 60 - include/are/raytracer/compute_raytracer.h | 69 - include/are/raytracer/cpu_raytracer.h | 103 - include/are/raytracer/hit_record.h | 48 - include/are/raytracer/ray.h | 55 - include/are/raytracer/raytracer.h | 75 - include/are/renderer/geometry_cache.h | 63 - include/are/renderer/render_context.h | 51 - include/are/renderer/render_stats.h | 66 - include/are/renderer/renderer.h | 122 - include/are/scene/camera.h | 108 - include/are/scene/directional_light.h | 49 - include/are/scene/light.h | 83 - include/are/scene/material.h | 107 - include/are/scene/mesh.h | 108 - include/are/scene/point_light.h | 71 - include/are/scene/scene_manager.h | 99 - include/are/scene/spot_light.h | 77 - include/are/texture/sampler.h | 52 - include/are/texture/texture.h | 149 - include/are/texture/texture_manager.h | 101 - include/are/utils/file_utils.h | 104 - include/are/utils/image_io.h | 103 - include/are/utils/math_utils.h | 127 - include/are/utils/random.h | 119 - new_conversation.md | 854 ---- phase3.md | 605 --- phase4.md | 270 -- phase5.md | 310 -- request2.md | 322 -- shaders/gbuffer/gbuffer.frag | 26 - shaders/gbuffer/gbuffer.vert | 29 - src/acceleration/bvh.cpp | 512 --- src/acceleration/bvh_builder.cpp | 198 - src/acceleration/bvh_node.cpp | 13 - src/are.cpp | 44 - src/core/config.cpp | 123 - src/core/logger.cpp | 164 - src/core/profiler.cpp | 182 - src/core/types.cpp | 15 - src/geometry/aabb.cpp | 130 - src/geometry/transform.cpp | 171 - src/geometry/triangle.cpp | 145 - src/geometry/vertex.cpp | 48 - src/platform/gl_context.cpp | 165 - src/platform/window.cpp | 180 - src/rasterizer/gbuffer.cpp | 255 - src/rasterizer/rasterizer.cpp | 197 - src/rasterizer/shader_program.cpp | 255 - src/raytracer/cpu_raytracer.cpp | 334 -- src/raytracer/hit_record.cpp | 32 - src/raytracer/ray.cpp | 41 - src/raytracer/raytracer.cpp | 18 - src/renderer/geometry_cache.cpp | 85 - src/scene/camera.cpp | 200 - src/scene/directional_light.cpp | 59 - src/scene/light.cpp | 35 - src/scene/material.cpp | 81 - src/scene/mesh.cpp | 202 - src/scene/point_light.cpp | 97 - src/scene/scene_manager.cpp | 303 -- src/scene/spot_light.cpp | 152 - src/utils/file_utils.cpp | 228 - src/utils/image_io.cpp | 181 - src/utils/math_utils.cpp | 79 - src/utils/random.cpp | 102 - write.sh | 54 - 103 files changed, 19828 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 all_headers.md delete mode 100644 examples/00_phase1_test/CMakeLists.txt delete mode 100644 examples/00_phase1_test/main.cpp delete mode 100644 examples/01_hello_triangle/CMakeLists.txt delete mode 100644 examples/01_phase2_test/CMakeLists.txt delete mode 100644 examples/01_phase2_test/main.cpp delete mode 100644 examples/02_cornell_box/CMakeLists.txt delete mode 100644 examples/02_phase3_test/CMakeLists.txt delete mode 100644 examples/02_phase3_test/main.cpp delete mode 100644 examples/02_visual_test/CMakeLists.txt delete mode 100644 examples/02_visual_test/main.cpp delete mode 100644 examples/03_material_showcase/CMakeLists.txt delete mode 100644 examples/03_phase4_test/CMakeLists.txt delete mode 100644 examples/03_phase4_test/main.cpp delete mode 100644 examples/04_phase5_test/CMakeLists.txt delete mode 100644 examples/04_phase5_test/main.cpp delete mode 100644 examples/04performance_test/CMakeLists.txt delete mode 100644 examples/CMakeLists.txt delete mode 100644 files.md delete mode 100644 include/are/acceleration/bvh.h delete mode 100644 include/are/acceleration/bvh_builder.h delete mode 100644 include/are/acceleration/bvh_node.h delete mode 100644 include/are/are.h delete mode 100644 include/are/core/config.h delete mode 100644 include/are/core/logger.h delete mode 100644 include/are/core/profiler.h delete mode 100644 include/are/core/types.h delete mode 100644 include/are/geometry/aabb.h delete mode 100644 include/are/geometry/transform.h delete mode 100644 include/are/geometry/triangle.h delete mode 100644 include/are/geometry/vertex.h delete mode 100644 include/are/platform/gl_context.h delete mode 100644 include/are/platform/window.h delete mode 100644 include/are/rasterizer/gbuffer.h delete mode 100644 include/are/rasterizer/rasterizer.h delete mode 100644 include/are/rasterizer/shader_program.h delete mode 100644 include/are/raytracer/compute_raytracer.h delete mode 100644 include/are/raytracer/cpu_raytracer.h delete mode 100644 include/are/raytracer/hit_record.h delete mode 100644 include/are/raytracer/ray.h delete mode 100644 include/are/raytracer/raytracer.h delete mode 100644 include/are/renderer/geometry_cache.h delete mode 100644 include/are/renderer/render_context.h delete mode 100644 include/are/renderer/render_stats.h delete mode 100644 include/are/renderer/renderer.h delete mode 100644 include/are/scene/camera.h delete mode 100644 include/are/scene/directional_light.h delete mode 100644 include/are/scene/light.h delete mode 100644 include/are/scene/material.h delete mode 100644 include/are/scene/mesh.h delete mode 100644 include/are/scene/point_light.h delete mode 100644 include/are/scene/scene_manager.h delete mode 100644 include/are/scene/spot_light.h delete mode 100644 include/are/texture/sampler.h delete mode 100644 include/are/texture/texture.h delete mode 100644 include/are/texture/texture_manager.h delete mode 100644 include/are/utils/file_utils.h delete mode 100644 include/are/utils/image_io.h delete mode 100644 include/are/utils/math_utils.h delete mode 100644 include/are/utils/random.h delete mode 100644 new_conversation.md delete mode 100644 phase3.md delete mode 100644 phase4.md delete mode 100644 phase5.md delete mode 100644 request2.md delete mode 100644 shaders/gbuffer/gbuffer.frag delete mode 100644 shaders/gbuffer/gbuffer.vert delete mode 100644 src/acceleration/bvh.cpp delete mode 100644 src/acceleration/bvh_builder.cpp delete mode 100644 src/acceleration/bvh_node.cpp delete mode 100644 src/are.cpp delete mode 100644 src/core/config.cpp delete mode 100644 src/core/logger.cpp delete mode 100644 src/core/profiler.cpp delete mode 100644 src/core/types.cpp delete mode 100644 src/geometry/aabb.cpp delete mode 100644 src/geometry/transform.cpp delete mode 100644 src/geometry/triangle.cpp delete mode 100644 src/geometry/vertex.cpp delete mode 100644 src/platform/gl_context.cpp delete mode 100644 src/platform/window.cpp delete mode 100644 src/rasterizer/gbuffer.cpp delete mode 100644 src/rasterizer/rasterizer.cpp delete mode 100644 src/rasterizer/shader_program.cpp delete mode 100644 src/raytracer/cpu_raytracer.cpp delete mode 100644 src/raytracer/hit_record.cpp delete mode 100644 src/raytracer/ray.cpp delete mode 100644 src/raytracer/raytracer.cpp delete mode 100644 src/renderer/geometry_cache.cpp delete mode 100644 src/scene/camera.cpp delete mode 100644 src/scene/directional_light.cpp delete mode 100644 src/scene/light.cpp delete mode 100644 src/scene/material.cpp delete mode 100644 src/scene/mesh.cpp delete mode 100644 src/scene/point_light.cpp delete mode 100644 src/scene/scene_manager.cpp delete mode 100644 src/scene/spot_light.cpp delete mode 100644 src/utils/file_utils.cpp delete mode 100644 src/utils/image_io.cpp delete mode 100644 src/utils/math_utils.cpp delete mode 100644 src/utils/random.cpp delete mode 100644 write.sh diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index d2600df..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,243 +0,0 @@ -cmake_minimum_required(VERSION 3.15) -project(AuroraRenderingEngine VERSION 0.1.0 LANGUAGES CXX C) - -# Set C++ standard -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - -# Set C standard for GLAD -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED ON) - -# Build options -option(ARE_BUILD_SHARED "Build shared library" OFF) -option(ARE_BUILD_EXAMPLES "Build example programs" ON) -option(ARE_ENABLE_PROFILING "Enable performance profiling" ON) -option(ARE_ENABLE_DEBUG_VIS "Enable debug visualization" ON) - -# Set output directories -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) - -# Compiler flags -if(MSVC) - add_compile_options(/W4) - add_compile_definitions(_CRT_SECURE_NO_WARNINGS) - # Disable specific warnings that are too strict - add_compile_options(/wd4100) # unreferenced formal parameter -else() - add_compile_options(-Wall -Wextra -pedantic) - # Disable specific warnings - add_compile_options(-Wno-unused-parameter) -endif() - -# Find required packages -find_package(OpenGL REQUIRED) -find_package(glfw3 REQUIRED) -find_package(glm REQUIRED) - -# Try to find spdlog (system installation) -find_package(spdlog QUIET) - -if(NOT spdlog_FOUND) - message(STATUS "spdlog not found in system, using local version") - # Use local spdlog - set(SPDLOG_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/lib/spdlog/include") - if(NOT EXISTS ${SPDLOG_INCLUDE_DIR}) - message(FATAL_ERROR "spdlog not found. Please install spdlog or place it in lib/spdlog/") - endif() - add_library(spdlog INTERFACE) - target_include_directories(spdlog INTERFACE ${SPDLOG_INCLUDE_DIR}) - # spdlog compile definitions - target_compile_definitions(spdlog INTERFACE SPDLOG_COMPILED_LIB) -endif() - -# Find OpenMP (optional) -find_package(OpenMP) -if(OpenMP_CXX_FOUND) - set(ARE_USE_OPENMP ON) - add_compile_definitions(ARE_USE_OPENMP) - message(STATUS "OpenMP found and enabled") -else() - message(STATUS "OpenMP not found, multithreading will use std::thread") -endif() - -# GLAD library path -set(GLAD_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/lib/glad") -set(GLAD_SOURCE_DIR "${CMAKE_SOURCE_DIR}/lib/glad") - -if(NOT EXISTS ${GLAD_INCLUDE_DIR}) - message(FATAL_ERROR "GLAD include directory not found: ${GLAD_INCLUDE_DIR}") -endif() - -if(NOT EXISTS ${GLAD_SOURCE_DIR}) - message(FATAL_ERROR "GLAD source directory not found: ${GLAD_SOURCE_DIR}") -endif() - -# STB library path -set(STB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/lib/stb") - -if(NOT EXISTS ${STB_INCLUDE_DIR}) - message(FATAL_ERROR "STB include directory not found: ${STB_INCLUDE_DIR}") -endif() - -# Collect all source files from src/ -file(GLOB_RECURSE ARE_SOURCES - "${CMAKE_SOURCE_DIR}/src/*.cpp" - "${CMAKE_SOURCE_DIR}/src/*.c" -) - -# Collect all GLAD source files -file(GLOB GLAD_SOURCES - "${GLAD_SOURCE_DIR}/*.c" -) - -# Add GLAD sources to ARE sources -list(APPEND ARE_SOURCES ${GLAD_SOURCES}) - -# Collect all header files -file(GLOB_RECURSE ARE_HEADERS - "${CMAKE_SOURCE_DIR}/include/*.h" - "${CMAKE_SOURCE_DIR}/include/*.hpp" -) - -# Create library -if(ARE_BUILD_SHARED) - add_library(are SHARED ${ARE_SOURCES} ${ARE_HEADERS}) - target_compile_definitions(are PRIVATE ARE_BUILD_SHARED) - message(STATUS "Building shared library") -else() - add_library(are STATIC ${ARE_SOURCES} ${ARE_HEADERS}) - message(STATUS "Building static library") -endif() - -# Set target properties -set_target_properties(are PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR} - PUBLIC_HEADER "${ARE_HEADERS}" -) - -# Include directories -target_include_directories(are - PUBLIC - $ - $ - PRIVATE - ${CMAKE_SOURCE_DIR}/src - ${GLAD_INCLUDE_DIR} - ${STB_INCLUDE_DIR} -) - -# Link libraries -target_link_libraries(are - PUBLIC - OpenGL::GL - glfw - glm::glm -) - -# Link spdlog -if(spdlog_FOUND) - target_link_libraries(are PUBLIC spdlog::spdlog) -else() - target_link_libraries(are PUBLIC spdlog) - target_include_directories(are PRIVATE ${SPDLOG_INCLUDE_DIR}) -endif() - -# Link OpenMP if available -if(OpenMP_CXX_FOUND) - target_link_libraries(are PUBLIC OpenMP::OpenMP_CXX) -endif() - -# Platform-specific libraries -if(UNIX AND NOT APPLE) - target_link_libraries(are PUBLIC dl pthread) -endif() - -# Compile definitions -if(ARE_ENABLE_PROFILING) - target_compile_definitions(are PUBLIC ARE_ENABLE_PROFILING) - message(STATUS "Profiling enabled") -endif() - -if(ARE_ENABLE_DEBUG_VIS) - target_compile_definitions(are PUBLIC ARE_ENABLE_DEBUG_VIS) - message(STATUS "Debug visualization enabled") -endif() - -# Build examples -if(ARE_BUILD_EXAMPLES) - # Define helper function for creating examples - function(add_are_example EXAMPLE_NAME) - add_executable(${EXAMPLE_NAME} ${ARGN}) - target_link_libraries(${EXAMPLE_NAME} PRIVATE are) - set_target_properties(${EXAMPLE_NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin - ) - endfunction() - - # Add example subdirectories - add_subdirectory(examples/00_phase1_test) - add_subdirectory(examples/01_phase2_test) - add_subdirectory(examples/02_visual_test) - add_subdirectory(examples/02_phase3_test) - add_subdirectory(examples/03_phase4_test) - add_subdirectory(examples/04_phase5_test) - - message(STATUS "Examples will be built") -endif() - -# Installation rules -install(TARGETS are - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin - PUBLIC_HEADER DESTINATION include/are -) - -install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/are - DESTINATION include - FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp" -) - -install(DIRECTORY ${CMAKE_SOURCE_DIR}/shaders - DESTINATION share/are/shaders -) - -# Print configuration summary -message(STATUS "") -message(STATUS "========================================") -message(STATUS "Aurora Rendering Engine Configuration") -message(STATUS "========================================") -message(STATUS " Version: ${PROJECT_VERSION}") -message(STATUS " Build type: ${CMAKE_BUILD_TYPE}") -message(STATUS " Library type: ${ARE_BUILD_SHARED}") -message(STATUS " C++ standard: ${CMAKE_CXX_STANDARD}") -message(STATUS " Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") -message(STATUS "") -message(STATUS "Features:") -message(STATUS " OpenMP support: ${ARE_USE_OPENMP}") -message(STATUS " Build examples: ${ARE_BUILD_EXAMPLES}") -message(STATUS " Enable profiling: ${ARE_ENABLE_PROFILING}") -message(STATUS " Enable debug vis: ${ARE_ENABLE_DEBUG_VIS}") -message(STATUS "") -message(STATUS "Dependencies:") -message(STATUS " OpenGL: ${OPENGL_LIBRARIES}") -message(STATUS " GLFW: Found") -message(STATUS " GLM: Found") -if(spdlog_FOUND) - message(STATUS " spdlog: Found (system)") -else() - message(STATUS " spdlog: Found (local)") -endif() -message(STATUS " GLAD: ${GLAD_INCLUDE_DIR}") -message(STATUS " STB: ${STB_INCLUDE_DIR}") -message(STATUS "") -message(STATUS "Output directories:") -message(STATUS " Executables: ${CMAKE_BINARY_DIR}/bin") -message(STATUS " Libraries: ${CMAKE_BINARY_DIR}/lib") -message(STATUS "========================================") -message(STATUS "") diff --git a/all_headers.md b/all_headers.md deleted file mode 100644 index 60bcb6c..0000000 --- a/all_headers.md +++ /dev/null @@ -1,4336 +0,0 @@ -我其实已经实现了所有头文件了,包括所有模块的所有接口以及使用方法都在里面,所以让我直接给你所有头文件的完整源码吧: - -### 文件:include/are/are.h - -```cpp -/** - * @file are.h - * @brief Aurora Rendering Engine - Main header file - * - * This header includes all public interfaces of the Aurora Rendering Engine. - * Users only need to include this single header to access all functionality. - * - * @author Ternary_Operator - * @version 1.0 - */ - -#ifndef ARE_INCLUDE_ARE_H -#define ARE_INCLUDE_ARE_H - -// Core modules -#include -#include -#include -#include - -// Platform modules -#include -#include - -// Geometry modules -#include -#include -#include -#include - -// Scene modules -#include -#include -#include -#include -#include -#include -#include -#include - -// Acceleration modules -#include - -// Renderer modules -#include -#include - -// Utility modules -#include -#include - -/** - * @namespace are - * @brief Main namespace for Aurora Rendering Engine - */ -namespace are { - -/** - * @brief Get the version string of the engine - * @return Version string in format "major.minor.patch" - */ -const char* get_version(); - -/** - * @brief Initialize the Aurora Rendering Engine - * @return true if initialization succeeded, false otherwise - */ -bool initialize(); - -/** - * @brief Shutdown the Aurora Rendering Engine - */ -void shutdown(); - -} // namespace are - -#endif // ARE_INCLUDE_ARE_H -``` - -### 文件:include/are/core/types.h - -```cpp -/** - * @file types.h - * @brief Basic type definitions and constants - */ - -#ifndef ARE_INCLUDE_CORE_TYPES_H -#define ARE_INCLUDE_CORE_TYPES_H - -#include -#include - -namespace are { - -// Floating point precision -using Real = float; - -// Common vector types -using Vec2 = glm::vec2; -using Vec3 = glm::vec3; -using Vec4 = glm::vec4; - -using Vec2i = glm::ivec2; -using Vec3i = glm::ivec3; -using Vec4i = glm::ivec4; - -// Matrix types -using Mat3 = glm::mat3; -using Mat4 = glm::mat4; - -// Color type (RGBA) -using Color = Vec4; - -// Handle types for resource management -using MeshHandle = uint32_t; -using MaterialHandle = uint32_t; -using LightHandle = uint32_t; -using TextureHandle = uint32_t; - -// Invalid handle constant -constexpr uint32_t are_invalid_handle = 0xFFFFFFFF; - -// Mathematical constants -constexpr Real are_pi = 3.14159265358979323846f; -constexpr Real are_two_pi = 6.28318530717958647692f; -constexpr Real are_inv_pi = 0.31830988618379067154f; -constexpr Real are_inv_two_pi = 0.15915494309189533577f; -constexpr Real are_epsilon = 1e-6f; - -// Ray tracing backend types -enum class RayTracingBackend { - ARE_RT_BACKEND_CPU, - ARE_RT_BACKEND_COMPUTE_SHADER -}; - -// Tone mapping operators -enum class ToneMappingOperator { - ARE_TONEMAP_NONE, - ARE_TONEMAP_REINHARD, - ARE_TONEMAP_ACES -}; - -// G-Buffer visualization modes -enum class GBufferVisualizationMode { - ARE_GBUFFER_VIS_NONE, - ARE_GBUFFER_VIS_POSITION, - ARE_GBUFFER_VIS_NORMAL, - ARE_GBUFFER_VIS_ALBEDO, - ARE_GBUFFER_VIS_METALLIC, - ARE_GBUFFER_VIS_ROUGHNESS, - ARE_GBUFFER_VIS_DEPTH -}; - -} // namespace are - -#endif // ARE_INCLUDE_CORE_TYPES_H -``` - -### 文件:include/are/core/config.h - -```cpp -/** - * @file config.h - * @brief Configuration system for the rendering engine - */ - -#ifndef ARE_INCLUDE_CORE_CONFIG_H -#define ARE_INCLUDE_CORE_CONFIG_H - -#include -#include - -namespace are { - -/** - * @struct WindowConfig - * @brief Configuration for window creation - */ -struct WindowConfig { - int width = 1280; ///< Window width in pixels - int height = 720; ///< Window height in pixels - std::string title = "Aurora Rendering Engine"; ///< Window title - bool resizable = true; ///< Whether window is resizable - bool vsync = true; ///< Enable vertical synchronization - int samples = 1; ///< MSAA samples (1 = disabled) -}; - -/** - * @struct RayTracingConfig - * @brief Configuration for ray tracing - */ -struct RayTracingConfig { - RayTracingBackend backend = RayTracingBackend::ARE_RT_BACKEND_COMPUTE_SHADER; - int spp = 64; ///< Samples per pixel - int max_depth = 8; ///< Maximum ray bounce depth - bool enable_gi = true; ///< Enable global illumination - bool enable_ao = true; ///< Enable ambient occlusion - bool enable_soft_shadows = false; ///< Enable soft shadows - int ao_samples = 16; ///< AO sample count - Real ao_radius = 1.0f; ///< AO sampling radius -}; - -/** - * @struct RenderConfig - * @brief General rendering configuration - */ -struct RenderConfig { - ToneMappingOperator tonemap_op = ToneMappingOperator::ARE_TONEMAP_ACES; - Real exposure = 1.0f; ///< Exposure value for tone mapping - bool use_hdr = true; ///< Use HDR rendering pipeline - GBufferVisualizationMode gbuffer_vis_mode = GBufferVisualizationMode::ARE_GBUFFER_VIS_NONE; -}; - -/** - * @struct PerformanceConfig - * @brief Performance-related configuration - */ -struct PerformanceConfig { - int num_threads = 0; ///< Number of threads (0 = auto-detect) - bool enable_bvh_multithreading = true; ///< Use multithreading for BVH construction - bool enable_profiling = false; ///< Enable performance profiling -}; - -/** - * @struct PathConfig - * @brief File path configuration - */ -struct PathConfig { - std::string shader_dir = "shaders/"; ///< Directory containing shader files - std::string texture_dir = "textures/"; ///< Default texture directory - std::string output_dir = "output/"; ///< Default output directory -}; - -/** - * @class AreConfig - * @brief Main configuration class for Aurora Rendering Engine - */ -class AreConfig { -public: - WindowConfig window; ///< Window configuration - RayTracingConfig ray_tracing; ///< Ray tracing configuration - RenderConfig render; ///< Rendering configuration - PerformanceConfig performance; ///< Performance configuration - PathConfig paths; ///< Path configuration - - /** - * @brief Constructor with default values - */ - AreConfig() = default; - - /** - * @brief Validate configuration values - * @return true if configuration is valid, false otherwise - */ - bool validate() const; - - /** - * @brief Print configuration to console - */ - void print() const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_CORE_CONFIG_H -``` - -### 文件:include/are/core/logger.h - -```cpp -/** - * @file logger.h - * @brief Logging system for the rendering engine - */ - -#ifndef ARE_INCLUDE_CORE_LOGGER_H -#define ARE_INCLUDE_CORE_LOGGER_H - -#include -#include - -namespace are { - -/** - * @enum LogLevel - * @brief Logging severity levels - */ -enum class LogLevel { - ARE_LOG_TRACE, - ARE_LOG_DEBUG, - ARE_LOG_INFO, - ARE_LOG_WARN, - ARE_LOG_ERROR, - ARE_LOG_CRITICAL -}; - -/** - * @class Logger - * @brief Thread-safe logging system - * - * This class provides a simple interface for logging messages with different - * severity levels. It wraps spdlog for actual logging functionality. - */ -class Logger { -public: - /** - * @brief Initialize the logging system - * @param min_level Minimum log level to display - */ - static void init(LogLevel min_level = LogLevel::ARE_LOG_INFO); - - /** - * @brief Shutdown the logging system - */ - static void shutdown(); - - /** - * @brief Log a message with file/function/line information - * @param level Log severity level - * @param file Source file name - * @param func Function name - * @param line Line number - * @param message Log message - */ - static void log(LogLevel level, const char* file, const char* func, - int line, const std::string& message); - - /** - * @brief Set minimum log level - * @param level Minimum log level to display - */ - static void set_level(LogLevel level); - -private: - static std::shared_ptr logger_impl_; ///< Internal logger implementation - static bool initialized_; ///< Initialization flag -}; - -} // namespace are - -// Logging macros -#define ARE_LOG_TRACE(msg) are::Logger::log(are::LogLevel::ARE_LOG_TRACE, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_DEBUG(msg) are::Logger::log(are::LogLevel::ARE_LOG_DEBUG, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_INFO(msg) are::Logger::log(are::LogLevel::ARE_LOG_INFO, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_WARN(msg) are::Logger::log(are::LogLevel::ARE_LOG_WARN, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_ERROR(msg) are::Logger::log(are::LogLevel::ARE_LOG_ERROR, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_CRITICAL(msg) are::Logger::log(are::LogLevel::ARE_LOG_CRITICAL, __FILE__, __func__, __LINE__, msg) - -#endif // ARE_INCLUDE_CORE_LOGGER_H -``` - -### 文件:include/are/core/profiler.h - -```cpp -/** - * @file profiler.h - * @brief Performance profiling utilities - */ - -#ifndef ARE_INCLUDE_CORE_PROFILER_H -#define ARE_INCLUDE_CORE_PROFILER_H - -#include -#include -#include -#include - -namespace are { - -/** - * @struct ProfileResult - * @brief Result of a profiling measurement - */ -struct ProfileResult { - std::string name_; ///< Profile section name - double duration_ms_; ///< Duration in milliseconds - uint64_t call_count_; ///< Number of times called - double avg_duration_ms_; ///< Average duration per call -}; - -/** - * @class Profiler - * @brief Simple performance profiler - * - * This class provides basic timing functionality for performance analysis. - * It is only active when ARE_ENABLE_PROFILING is defined. - */ -class Profiler { -public: - /** - * @brief Initialize the profiler - */ - static void init(); - - /** - * @brief Shutdown the profiler and print results - */ - static void shutdown(); - - /** - * @brief Begin a profiling section - * @param name Section name - */ - static void begin(const std::string& name); - - /** - * @brief End a profiling section - * @param name Section name - */ - static void end(const std::string& name); - - /** - * @brief Get profiling results - * @return Map of section names to profile results - */ - static const std::unordered_map& get_results(); - - /** - * @brief Reset all profiling data - */ - static void reset(); - - /** - * @brief Print profiling results to console - */ - static void print_results(); - -private: - struct SectionData { - std::chrono::high_resolution_clock::time_point start_time_; - double total_duration_ms_ = 0.0; - uint64_t call_count_ = 0; - }; - - static std::unordered_map sections_; - static std::unordered_map results_; - static bool enabled_; -}; - -/** - * @class ScopedProfiler - * @brief RAII-style profiler for automatic timing - */ -class ScopedProfiler { -public: - /** - * @brief Constructor - begins profiling - * @param name Section name - */ - explicit ScopedProfiler(const std::string& name); - - /** - * @brief Destructor - ends profiling - */ - ~ScopedProfiler(); - -private: - std::string name_; -}; - -} // namespace are - -// Profiling macros -#ifdef ARE_ENABLE_PROFILING - #define ARE_PROFILE_BEGIN(name) are::Profiler::begin(name) - #define ARE_PROFILE_END(name) are::Profiler::end(name) - #define ARE_PROFILE_SCOPE(name) are::ScopedProfiler are_profiler_##__LINE__(name) - #define ARE_PROFILE_FUNCTION() ARE_PROFILE_SCOPE(__func__) -#else - #define ARE_PROFILE_BEGIN(name) ((void)0) - #define ARE_PROFILE_END(name) ((void)0) - #define ARE_PROFILE_SCOPE(name) ((void)0) - #define ARE_PROFILE_FUNCTION() ((void)0) -#endif - -#endif // ARE_INCLUDE_CORE_PROFILER_H -``` - -### 文件:include/are/geometry/vertex.h - -```cpp -/** - * @file vertex.h - * @brief Vertex data structure definition - */ - -#ifndef ARE_INCLUDE_GEOMETRY_VERTEX_H -#define ARE_INCLUDE_GEOMETRY_VERTEX_H - -#include - -namespace are { - -/** - * @struct Vertex - * @brief Standard vertex structure for mesh data - * - * Contains position, normal, texture coordinates, and tangent information - * for PBR rendering pipeline. - */ -struct Vertex { - Vec3 position_;///< Vertex position in object space - Vec3 normal_; ///< Vertex normal (normalized) - Vec2 texcoord_; ///< Texture coordinates (UV) - Vec3 tangent_; ///< Tangent vector for normal mapping - - Vertex() = default; - - /** - * @brief Construct vertex with position only - * @param pos Position - */ - explicit Vertex(const Vec3& pos); - - /** - * @brief Construct vertex with position and normal - * @param pos Position - * @param norm Normal - */ - Vertex(const Vec3& pos, const Vec3& norm); - - /** - * @brief Construct vertex with position, normal, and texcoord - * @param pos Position - * @param norm Normal - * @param uv Texture coordinates - */ - Vertex(const Vec3& pos, const Vec3& norm, const Vec2& uv); - - /** - * @brief Construct vertex with all attributes - * @param pos Position - * @param norm Normal - * @param uv Texture coordinates - * @param tan Tangent - */ - Vertex(const Vec3& pos, const Vec3& norm, const Vec2& uv, const Vec3& tan); - - /** - * @brief Interpolate between two vertices - * @param a First vertex - * @param b Second vertex - * @param t Interpolation factor [0, 1] - * @return Interpolated vertex - */ - static Vertex lerp(const Vertex& a, const Vertex& b, Real t); -}; - -/** - * @brief Get vertex attribute stride for OpenGL - * @return Size of Vertex structure in bytes - */ -constexpr size_t get_vertex_stride() { - return sizeof(Vertex); -} - -/** - * @brief Get offset of position attribute - * @return Offset in bytes - */ -constexpr size_t get_position_offset() { - return offsetof(Vertex, position_); -} - -/** - * @brief Get offset of normal attribute - * @return Offset in bytes - */ -constexpr size_t get_normal_offset() { - return offsetof(Vertex, normal_); -} - -/** - * @brief Get offset of texcoord attribute - * @return Offset in bytes - */ -constexpr size_t get_texcoord_offset() { - return offsetof(Vertex, texcoord_); -} - -/** - * @brief Get offset of tangent attribute - * @return Offset in bytes - */ -constexpr size_t get_tangent_offset() { - return offsetof(Vertex, tangent_); -} - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_VERTEX_H -``` - -### 文件:include/are/geometry/aabb.h - -```cpp -/** - * @file aabb.h - * @brief Axis-Aligned Bounding Box implementation - */ - -#ifndef ARE_INCLUDE_GEOMETRY_AABB_H -#define ARE_INCLUDE_GEOMETRY_AABB_H - -#include - -namespace are { - -// Forward declaration -struct Ray; - -/** - * @class AABB - * @brief Axis-Aligned Bounding Box for spatial queries - * - * Used for BVH construction and ray intersection acceleration. - */ -class AABB { -public: - Vec3 min_; ///< Minimum corner - Vec3 max_; ///< Maximum corner - - /** - * @brief Default constructor - creates invalid AABB - */ - AABB(); - - /** - * @brief Construct AABB from min and max corners - * @param min Minimum corner - * @param max Maximum corner - */ - AABB(const Vec3& min, const Vec3& max); - - /** - * @brief Construct AABB containing a single point - * @param point Point to contain - */ - explicit AABB(const Vec3& point); - - /** - * @brief Check if AABB is valid (min <= max) - * @return true if valid - */ - bool is_valid() const; - - /** - * @brief Get center of AABB - * @return Center point - */ - Vec3 center() const; - - /** - * @brief Get size (extent) of AABB - * @return Size vector - */ - Vec3 size() const; - - /** - * @brief Get surface area of AABB - * @return Surface area - */ - Real surface_area() const; - - /** - * @brief Get volume of AABB - * @return Volume - */ - Real volume() const; - - /** - * @brief Get longest axis index (0=x, 1=y, 2=z) - * @return Axis index - */ - int longest_axis() const; - - /** - * @brief Expand AABB to include a point - * @param point Point to include - */ - void expand(const Vec3& point); - - /** - * @brief Expand AABB to include another AABB - * @param other AABB to include - */ - void expand(const AABB& other); - - /** - * @brief Check if AABB contains a point - * @param point Point to check - * @return true if point is inside AABB - */ - bool contains(const Vec3& point) const; - - /** - * @brief Check if AABB intersects another AABB - * @param other AABB to check - * @return true if AABBs intersect - */ - bool intersects(const AABB& other) const; - - /** - * @brief Ray-AABB intersection test - * @param ray Ray to test - * @param t_min Minimum t value (output) - * @param t_max Maximum t value (output) - * @return true if ray intersects AABB - */ - bool intersect_ray(const Ray& ray, Real& t_min, Real& t_max) const; - - /** - * @brief Merge two AABBs - * @param a First AABB - * @param b Second AABB - * @return Merged AABB containing both - */ - static AABB merge(const AABB& a, const AABB& b); - - /** - * @brief Create invalid AABB (for initialization) - * @return Invalid AABB - */ - static AABB invalid(); -}; - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_AABB_H -``` - -### 文件:include/are/geometry/triangle.h - -```cpp -/** - * @file triangle.h - * @brief Triangle primitive definition - */ - -#ifndef ARE_INCLUDE_GEOMETRY_TRIANGLE_H -#define ARE_INCLUDE_GEOMETRY_TRIANGLE_H - -#include -#include -#include - -namespace are { - -// Forward declaration -struct Ray; -struct HitRecord; - -/** - * @struct Triangle - * @brief Triangle primitive for ray tracing - * - * Stores three vertices and provides intersection testing. - */ -struct Triangle { - Vertex v0_; ///< First vertex - Vertex v1_; ///< Second vertex - Vertex v2_; ///< Third vertex - MaterialHandle material_; ///< Material handle - - /** - * @brief Default constructor - */ - Triangle(); - - /** - * @brief Construct triangle from three vertices - * @param v0 First vertex - * @param v1 Second vertex - * @param v2 Third vertex - * @param material Material handle - */ - Triangle(const Vertex& v0, const Vertex& v1, const Vertex& v2, - MaterialHandle material = are_invalid_handle); - - /** - * @brief Get triangle centroid - * @return Centroid position - */ - Vec3 centroid() const; - - /** - * @brief Get triangle normal (geometric normal) - * @return Normal vector (normalized) - */ - Vec3 normal() const; - - /** - * @brief Get triangle area - * @return Area - */ - Real area() const; - - /** - * @brief Compute axis-aligned bounding box - * @return AABB containing the triangle - */ - AABB compute_aabb() const; - - /** - * @brief Ray-triangle intersection test (Möller-Trumbore algorithm) - * @param ray Ray to test - * @param hit Output hit record - * @return true if intersection occurred - */ - bool intersect(const Ray& ray, HitRecord& hit) const; - - /** - * @brief Fast ray-triangle intersection test (no hit record) - * @param ray Ray to test - * @param t_max Maximum t value - * @return true if intersection occurred - */ - bool intersect_fast(const Ray& ray, Real t_max) const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_TRIANGLE_H -``` - -### 文件:include/are/geometry/transform.h - -```cpp -/** - * @file transform.h - * @brief Transformation matrix utilities - */ - -#ifndef ARE_INCLUDE_GEOMETRY_TRANSFORM_H -#define ARE_INCLUDE_GEOMETRY_TRANSFORM_H - -#include - -namespace are { - -/** - * @class Transform - * @brief 3D transformation (position, rotation, scale) - * - * Provides convenient interface for building transformation matrices. - */ -class Transform { -public: - /** - * @brief Default constructor (identity transform) - */ - Transform(); - - /** - * @brief Construct from position, rotation, and scale - * @param position Translation - * @param rotation Rotation (Euler angles in radians) - * @param scale Scale factors - */ - Transform(const Vec3& position, const Vec3& rotation, const Vec3& scale); - - // Setters - void set_position(const Vec3& position); - void set_rotation(const Vec3& rotation); - void set_scale(const Vec3& scale); - void set_scale(Real uniform_scale); - - // Getters - const Vec3& get_position() const { return position_; } - const Vec3& get_rotation() const { return rotation_; } - const Vec3& get_scale() const { return scale_; } - - // Matrix operations - Mat4 get_matrix() const; - Mat4 get_inverse_matrix() const; - Mat3 get_normal_matrix() const; - - /** - * @brief Transform a point - * @param point Point to transform - * @return Transformed point - */ - Vec3 transform_point(const Vec3& point) const; - - /** - * @brief Transform a direction (ignores translation) - * @param direction Direction to transform - * @return Transformed direction - */ - Vec3 transform_direction(const Vec3& direction) const; - - /** - * @brief Transform a normal (uses inverse transpose) - * @param normal Normal to transform - * @return Transformed normal - */ - Vec3 transform_normal(const Vec3& normal) const; - - /** - * @brief Combine two transforms - * @param other Other transform - * @return Combined transform - */ - Transform operator*(const Transform& other) const; - - /** - * @brief Create identity transform - * @return Identity transform - */ - static Transform identity(); - - /** - * @brief Create translation transform - * @param translation Translation vector - * @return Translation transform - */ - static Transform translate(const Vec3& translation); - - /** - * @brief Create rotation transform - * @param rotation Rotation (Euler angles in radians) - * @return Rotation transform - */ - static Transform rotate(const Vec3& rotation); - - /** - * @brief Create scale transform - * @param scale Scale factors - * @return Scale transform - */ - static Transform scale(const Vec3& scale); - -private: - void mark_dirty(); - void update_matrix() const; - - Vec3 position_; ///< Translation - Vec3 rotation_; ///< Rotation (Euler angles) - Vec3 scale_; ///< Scale factors - - mutable Mat4 matrix_; ///< Cached transformation matrix - mutable Mat4 inverse_matrix_; ///< Cached inverse matrix - mutable bool dirty_; ///< Matrix needs update -}; - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_TRANSFORM_H -``` - -### 文件:include/are/scene/camera.h - -```cpp -/** - * @file camera.h - * @brief Camera class for view and projection management - */ - -#ifndef ARE_INCLUDE_SCENE_CAMERA_H -#define ARE_INCLUDE_SCENE_CAMERA_H - -#include - -namespace are { - -/** - * @class Camera - * @brief Perspective camera for rendering - * - * Manages view and projection matrices, and provides ray generation - * for ray tracing. - */ -class Camera { -public: - /** - * @brief Default constructor - */ - Camera(); - - /** - * @brief Construct camera with position and target - * @param position Camera position - * @param target Look-at target - * @param up Up vector - */ - Camera(const Vec3& position, const Vec3& target, const Vec3& up = Vec3(0, 1, 0)); - - // Position and orientation setters - void set_position(const Vec3& position); - void set_target(const Vec3& target); - void set_up(const Vec3& up); - void look_at(const Vec3& position, const Vec3& target, const Vec3& up = Vec3(0, 1, 0)); - - // Projection setters - void set_fov(Real fov_degrees); - void set_aspect_ratio(Real aspect); - void set_near_plane(Real near); - void set_far_plane(Real far); - void set_perspective(Real fov_degrees, Real aspect, Real near, Real far); - - // Getters - const Vec3& get_position() const { return position_; } - const Vec3& get_target() const { return target_; } - const Vec3& get_up() const { return up_; } - Real get_fov() const { return fov_; } - Real get_aspect_ratio() const { return aspect_ratio_; } - Real get_near_plane() const { return near_plane_; } - Real get_far_plane() const { return far_plane_; } - - // Direction vectors - Vec3 get_forward() const; - Vec3 get_right() const; - - // Matrix getters - const Mat4& get_view_matrix() const; - const Mat4& get_projection_matrix() const; - Mat4 get_view_projection_matrix() const; - - /** - * @brief Generate ray for given pixel coordinates - * @param u Normalized x coordinate [0, 1] - * @param v Normalized y coordinate [0, 1] - * @param origin Output ray origin - * @param direction Output ray direction (normalized) - */ - void generate_ray(Real u, Real v, Vec3& origin, Vec3& direction) const; - - /** - * @brief Check if camera parameters have changed - * @return true if matrices need recalculation - */ - bool is_dirty() const { return dirty_; } - - /** - * @brief Mark camera as clean after matrix update - */ - void clear_dirty() { dirty_ = false; } - -private: - void update_view_matrix() const; - void update_projection_matrix() const; - - Vec3 position_; ///< Camera position - Vec3 target_; ///< Look-at target - Vec3 up_; ///< Up vector - - Real fov_; ///< Field of view in degrees - Real aspect_ratio_; ///< Aspect ratio (width/height) - Real near_plane_; ///< Near clipping plane - Real far_plane_; ///< Far clipping plane - - mutable Mat4 view_matrix_; ///< Cached view matrix - mutable Mat4 projection_matrix_; ///< Cached projection matrix - mutable bool view_dirty_; ///< View matrix needs update - mutable bool projection_dirty_; ///< Projection matrix needs update - bool dirty_; ///< Any parameter changed -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_CAMERA_H -``` - -### 文件:include/are/scene/material.h - -```cpp -/** - * @file material.h - * @brief PBR material definition - */ - -#ifndef ARE_INCLUDE_SCENE_MATERIAL_H -#define ARE_INCLUDE_SCENE_MATERIAL_H - -#include -#include - -namespace are { - -/** - * @class Material - * @brief Physically-based rendering material - * - * Supports standard PBR workflow with metallic-roughness model. - */ -class Material { -public: - /** - * @brief Default constructor - creates default white material - */ - Material(); - - // Albedo (base color) - void set_albedo(const Vec3& albedo); - void set_albedo_map(const std::string& path); - const Vec3& get_albedo() const { return albedo_; } - const std::string& get_albedo_map() const { return albedo_map_; } - bool has_albedo_map() const { return !albedo_map_.empty(); } - - // Metallic - void set_metallic(Real metallic); - void set_metallic_map(const std::string& path); - Real get_metallic() const { return metallic_; } - const std::string& get_metallic_map() const { return metallic_map_; } - bool has_metallic_map() const { return !metallic_map_.empty(); } - - // Roughness - void set_roughness(Real roughness); - void set_roughness_map(const std::string& path); - Real get_roughness() const { return roughness_; } - const std::string& get_roughness_map() const { return roughness_map_; } - bool has_roughness_map() const { return !roughness_map_.empty(); } - - // Normal map - void set_normal_map(const std::string& path); - const std::string& get_normal_map() const { return normal_map_; } - bool has_normal_map() const { return !normal_map_.empty(); } - - // Ambient occlusion - void set_ao_map(const std::string& path); - const std::string& get_ao_map() const { return ao_map_; } - bool has_ao_map() const { return !ao_map_.empty(); } - - // Emissive - void set_emissive(const Vec3& emissive); - void set_emissive_map(const std::string& path); - const Vec3& get_emissive() const { return emissive_; } - const std::string& get_emissive_map() const { return emissive_map_; } - bool has_emissive_map() const { return !emissive_map_.empty(); } - bool is_emissive() const; - - // Texture handles (set by TextureManager) - void set_albedo_texture_handle(TextureHandle handle) { albedo_tex_handle_ = handle; } - void set_metallic_texture_handle(TextureHandle handle) { metallic_tex_handle_ = handle; } - void set_roughness_texture_handle(TextureHandle handle) { roughness_tex_handle_ = handle; } - void set_normal_texture_handle(TextureHandle handle) { normal_tex_handle_ = handle; } - void set_ao_texture_handle(TextureHandle handle) { ao_tex_handle_ = handle; } - void set_emissive_texture_handle(TextureHandle handle) { emissive_tex_handle_ = handle; } - - TextureHandle get_albedo_texture_handle() const { return albedo_tex_handle_; } - TextureHandle get_metallic_texture_handle() const { return metallic_tex_handle_; } - TextureHandle get_roughness_texture_handle() const { return roughness_tex_handle_; } - TextureHandle get_normal_texture_handle() const { return normal_tex_handle_; } - TextureHandle get_ao_texture_handle() const { return ao_tex_handle_; } - TextureHandle get_emissive_texture_handle() const { return emissive_tex_handle_; } - -private: - // Base values - Vec3 albedo_;///< Base color (RGB) - Real metallic_; ///< Metallic factor [0, 1] - Real roughness_; ///< Roughness factor [0, 1] - Vec3 emissive_; ///< Emissive color (RGB) - - // Texture paths - std::string albedo_map_; - std::string metallic_map_; - std::string roughness_map_; - std::string normal_map_; - std::string ao_map_; - std::string emissive_map_; - - // Texture handles (GPU resources) - TextureHandle albedo_tex_handle_; - TextureHandle metallic_tex_handle_; - TextureHandle roughness_tex_handle_; - TextureHandle normal_tex_handle_; - TextureHandle ao_tex_handle_; - TextureHandle emissive_tex_handle_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_MATERIAL_H -``` - -### 文件:include/are/scene/mesh.h - -```cpp -/** - * @file mesh.h - * @brief Mesh class for geometry storage - */ - -#ifndef ARE_INCLUDE_SCENE_MESH_H -#define ARE_INCLUDE_SCENE_MESH_H - -#include -#include -#include -#include - -namespace are { - -/** - * @class Mesh - * @brief Triangle mesh container - * - * Stores vertex and index data for a triangle mesh. - * Supports automatic AABB computation. - */ -class Mesh { -public: - /** - * @brief Default constructor - creates empty mesh - */ - Mesh(); - - /** - * @brief Construct mesh from vertex and index data - * @param vertices Vertex array - * @param indices Index array (triangles) - * @param material_id Material handle - */ - Mesh(const std::vector& vertices, - const std::vector& indices, - MaterialHandle material_id = are_invalid_handle); - - /** - * @brief Construct mesh from raw arrays - * @param vertices Vertex array pointer - * @param vertex_count Number of vertices - * @param indices Index array pointer - * @param index_count Number of indices - * @param material_id Material handle - */ - Mesh(const Vertex* vertices, size_t vertex_count, - const uint32_t* indices, size_t index_count, - MaterialHandle material_id = are_invalid_handle); - - // Data setters - void set_vertices(const std::vector& vertices); - void set_indices(const std::vector& indices); - void set_material(MaterialHandle material_id); - - // Data getters - const std::vector& get_vertices() const { return vertices_; } - const std::vector& get_indices() const { return indices_; } - MaterialHandle get_material() const { return material_id_; } - - // Geometry queries - size_t get_vertex_count() const { return vertices_.size(); } - size_t get_index_count() const { return indices_.size(); } - size_t get_triangle_count() const { return indices_.size() / 3; } - bool is_empty() const { return vertices_.empty() || indices_.empty(); } - - // AABB - const AABB& get_aabb() const { return aabb_; } - void compute_aabb(); - - /** - * @brief Compute tangent vectors for normal mapping - */ - void compute_tangents();/** - * @brief Get triangle vertices by index - * @param triangle_index Triangle index - * @param v0 Output first vertex - * @param v1 Output second vertex - * @param v2 Output third vertex - * @return true if triangle exists - */ - bool get_triangle(size_t triangle_index, Vertex& v0, Vertex& v1, Vertex& v2) const; - - // GPU resource handles (set by Renderer) - void set_vao(uint32_t vao) { vao_ = vao; } - void set_vbo(uint32_t vbo) { vbo_ = vbo; } - void set_ebo(uint32_t ebo) { ebo_ = ebo; } - uint32_t get_vao() const { return vao_; } - uint32_t get_vbo() const { return vbo_; } - uint32_t get_ebo() const { return ebo_; } - bool has_gpu_resources() const { return vao_ != 0; } - -private: - std::vector vertices_; ///< Vertex data - std::vector indices_; ///< Index data (triangles) - MaterialHandle material_id_; ///< Associated material - AABB aabb_; ///< Bounding box - - // GPU resources - uint32_t vao_; ///< Vertex Array Object - uint32_t vbo_; ///< Vertex Buffer Object - uint32_t ebo_; ///< Element Buffer Object -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_MESH_H -``` - -### 文件:include/are/scene/light.h - -```cpp -/** - * @file light.h - * @brief Base light class and common light utilities - */ - -#ifndef ARE_INCLUDE_SCENE_LIGHT_H -#define ARE_INCLUDE_SCENE_LIGHT_H - -#include - -namespace are { - -/** - * @enum LightType - * @brief Types of light sources - */ -enum class LightType { - ARE_LIGHT_DIRECTIONAL, - ARE_LIGHT_POINT, - ARE_LIGHT_SPOT -}; - -/** - * @struct LightData - * @brief Packed light data for GPU transfer - * - * This structure is designed to be efficiently transferred to GPU - * via SSBO or UBO. - */ -struct LightData { - Vec4 position_type_; ///< xyz: position, w: light type - Vec4 direction_range_; ///< xyz: direction, w: range - Vec4 color_intensity_; ///< xyz: color, w: intensity - Vec4 params_; ///< Light-specific parameters -}; - -/** - * @class Light - * @brief Base class for all light types - */ -class Light { -public: - /** - * @brief Constructor - * @param type Light type - */ - explicit Light(LightType type); - - virtual ~Light() = default; - - // Common properties - void set_color(const Vec3& color); - void set_intensity(Real intensity); - void set_cast_shadows(bool cast); - - const Vec3& get_color() const { return color_; } - Real get_intensity() const { return intensity_; } - bool get_cast_shadows() const { return cast_shadows_; } - LightType get_type() const { return type_; } - - /** - * @brief Pack light data for GPU transfer - * @return Packed light data - */ - virtual LightData pack() const = 0; - - /** - * @brief Check if light affects a point - * @param point World position - * @return true if light can affect the point - */ - virtual bool affects_point(const Vec3& point) const = 0; - -protected: - LightType type_; ///< Light type - Vec3 color_; ///< Light color (RGB) - Real intensity_; ///< Light intensity - bool cast_shadows_; ///< Whether light casts shadows -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_LIGHT_H -``` - -### 文件:include/are/scene/directional_light.h - -```cpp -/** - * @file directional_light.h - * @brief Directional light implementation - */ - -#ifndef ARE_INCLUDE_SCENE_DIRECTIONAL_LIGHT_H -#define ARE_INCLUDE_SCENE_DIRECTIONAL_LIGHT_H - -#include - -namespace are { - -/** - * @class DirectionalLight - * @brief Directional light source (sun-like) - * - * Represents an infinitely distant light source with parallel rays. - */ -class DirectionalLight : public Light { -public: - /** - * @brief Default constructor - */ - DirectionalLight(); - - /** - * @brief Construct with direction and color - * @param direction Light direction (will be normalized) - * @param color Light color - * @param intensity Light intensity - */ - DirectionalLight(const Vec3& direction, const Vec3& color = Vec3(1.0f), - Real intensity = 1.0f); - - // Direction - void set_direction(const Vec3& direction); - const Vec3& get_direction() const { return direction_; } - - // Light interface - LightData pack() const override; - bool affects_point(const Vec3& point) const override; - -private: - Vec3 direction_; ///< Light direction (normalized) -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_DIRECTIONAL_LIGHT_H -``` - -### 文件:include/are/scene/point_light.h - -```cpp -/** - * @file point_light.h - * @brief Point light implementation - */ - -#ifndef ARE_INCLUDE_SCENE_POINT_LIGHT_H -#define ARE_INCLUDE_SCENE_POINT_LIGHT_H - -#include - -namespace are { - -/** - * @class PointLight - * @brief Point light source - * - * Emits light equally in all directions from a single point. - */ -class PointLight : public Light { -public: - /** - * @brief Default constructor - */ - PointLight(); - - /** - * @brief Construct with position and color - * @param position Light position - * @param color Light color - * @param intensity Light intensity - * @param range Light range (attenuation distance) - */ - PointLight(const Vec3& position, const Vec3& color = Vec3(1.0f), - Real intensity = 1.0f, Real range = 10.0f); - - // Position - void set_position(const Vec3& position); - const Vec3& get_position() const { return position_; } - - // Range (attenuation) - void set_range(Real range); - Real get_range() const { return range_; } - - // Attenuation parameters - void set_attenuation(Real constant, Real linear, Real quadratic); - Real get_constant_attenuation() const { return attenuation_constant_; } - Real get_linear_attenuation() const { return attenuation_linear_; } - Real get_quadratic_attenuation() const { return attenuation_quadratic_; } - - /** - * @brief Calculate attenuation at given distance - * @param distance Distance from light - * @return Attenuation factor [0, 1] - */ - Real calculate_attenuation(Real distance) const; - - // Light interface - LightData pack() const override; - bool affects_point(const Vec3& point) const override; - -private: - Vec3 position_; ///< Light position - Real range_; ///< Light range - Real attenuation_constant_; ///< Constant attenuation factor - Real attenuation_linear_; ///< Linear attenuation factor - Real attenuation_quadratic_; ///< Quadratic attenuation factor -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_POINT_LIGHT_H -``` - -### 文件:include/are/scene/spot_light.h - -```cpp -/** - * @file spot_light.h - * @brief Spot light implementation - */ - -#ifndef ARE_INCLUDE_SCENE_SPOT_LIGHT_H -#define ARE_INCLUDE_SCENE_SPOT_LIGHT_H - -#include - -namespace are { - -/** - * @class SpotLight - * @brief Spot light source - * - * Emits light in a cone from a single point. - */ -class SpotLight : public Light { -public: - /** - * @brief Default constructor - */ - SpotLight(); - - /** - * @brief Construct with position, direction, and angles - * @param position Light position - * @param direction Light direction - * @param inner_angle Inner cone angle in degrees - * @param outer_angle Outer cone angle in degrees - * @param color Light color - * @param intensity Light intensity - */ - SpotLight(const Vec3& position, const Vec3& direction,Real inner_angle, Real outer_angle, - const Vec3& color = Vec3(1.0f), Real intensity = 1.0f); - - // Position and direction - void set_position(const Vec3& position); - void set_direction(const Vec3& direction); - const Vec3& get_position() const { return position_; } - const Vec3& get_direction() const { return direction_; } - - // Cone angles (in degrees) - void set_inner_angle(Real angle); - void set_outer_angle(Real angle); - Real get_inner_angle() const { return inner_angle_; } - Real get_outer_angle() const { return outer_angle_; } - - // Range - void set_range(Real range); - Real get_range() const { return range_; } - - /** - * @brief Calculate spotlight intensity at given direction - * @param to_point Direction from light to point (normalized) - * @return Spotlight factor [0, 1] - */ - Real calculate_spot_factor(const Vec3& to_point) const; - - // Light interface - LightData pack() const override; - bool affects_point(const Vec3& point) const override; - -private: - Vec3 position_; ///< Light position - Vec3 direction_; ///< Light direction (normalized) - Real inner_angle_; ///< Inner cone angle (degrees) - Real outer_angle_; ///< Outer cone angle (degrees) - Real range_; ///< Light range - Real cos_inner_; ///< Cosine of inner angle (cache - Real cos_outer_; ///< Cosine of outer angle (cached) -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_SPOT_LIGHT_H -``` - -### 文件:include/are/scene/scene_manager.h - -```cpp -/** - * @file scene_manager.h - * @brief Scene data management - */ - -#ifndef ARE_INCLUDE_SCENE_SCENE_MANAGER_H -#define ARE_INCLUDE_SCENE_SCENE_MANAGER_H - -#include -#include -#include -#include -#include -#include -#include - -namespace are { - -/** - * @class SceneManager - * @brief Manages all scene objects (meshes, materials, lights) - * - * Provides handle-based access to scene resources and tracks - * scene modifications for BVH rebuilding. - */ -class SceneManager { -public: - /** - * @brief Constructor - */ - SceneManager(); - - /** - * @brief Destructor - */ - ~SceneManager(); - - // Mesh management - MeshHandle add_mesh(const Mesh& mesh); - void remove_mesh(MeshHandle handle); - void update_mesh(MeshHandle handle, const Mesh& mesh); - Mesh* get_mesh(MeshHandle handle); - const Mesh* get_mesh(MeshHandle handle) const; - const std::vector& get_all_meshes() const { return meshes_; } - - // Material management - MaterialHandle add_material(const Material& material); - void remove_material(MaterialHandle handle); - void update_material(MaterialHandle handle, const Material& material); - Material* get_material(MaterialHandle handle); - const Material* get_material(MaterialHandle handle) const; - const std::vector& get_all_materials() const { return materials_; } - - // Light management - LightHandle add_light(const std::shared_ptr& light); - void remove_light(LightHandle handle); - std::shared_ptr get_light(LightHandle handle); - const std::vector>& get_all_lights() const { return lights_; } - - // Scene queries - size_t get_mesh_count() const { return meshes_.size(); } - size_t get_material_count() const { return materials_.size(); } - size_t get_light_count() const { return lights_.size(); } - size_t get_total_triangle_count() const; - - // Scene state - bool is_dirty() const { return dirty_; } - void mark_dirty() { dirty_ = true; } - void clear_dirty() { dirty_ = false; } - - /** - * @brief Clear all scene data - */ - void clear(); - - /** - * @brief Validate all handles and remove invalid entries - */ - void compact(); - -private: - std::vector meshes_; ///< Mesh storage - std::vector materials_; ///< Material storage - std::vector> lights_; ///< Light storage - - std::unordered_map mesh_handle_map_; - std::unordered_map material_handle_map_; - std::unordered_map light_handle_map_; - - MeshHandle next_mesh_handle_; - MaterialHandle next_material_handle_; - LightHandle next_light_handle_; - - bool dirty_; ///< Scene modified flag -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_SCENE_MANAGER_H -``` - -### 文件:include/are/renderer/renderer.h - -```cpp -/** - * @file renderer.h - * @brief Main renderer interface - */ - -#ifndef ARE_INCLUDE_RENDERER_RENDERER_H -#define ARE_INCLUDE_RENDERER_RENDERER_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace are { - -// Forward declarations -class Window; -class SceneManager; -class Rasterizer; -class RayTracer; -class TextureManager; - -/** - * @class Renderer - * @brief Main rendering interface for Aurora Rendering Engine - * - * This class provides the primary API for rendering scenes using - * hybrid rasterization and ray tracing techniques. - */ -class Renderer { -public: - /** - * @brief Constructor - * @param config Rendering configuration - */ - explicit Renderer(const AreConfig& config); - - /** - * @brief Destructor - */ - ~Renderer(); - - // Configuration - void set_config(const AreConfig& config); - const AreConfig& get_config() const; - - // Camera management - void set_camera(const Camera& camera); - Camera& get_camera(); - const Camera& get_camera() const; - - // Scene management - MeshHandle add_mesh(const Mesh& mesh); - MaterialHandle add_material(const Material& material); - LightHandle add_light(const std::shared_ptr& light); - - void remove_mesh(MeshHandle handle); - void remove_material(MaterialHandle handle); - void remove_light(LightHandle handle); - - void update_mesh(MeshHandle handle, const Mesh& mesh); - void update_material(MaterialHandle handle, const Material& material); - - void clear_scene(); - - // Ray tracing backend control - void set_ray_tracing_backend(RayTracingBackend backend); - RayTracingBackend get_ray_tracing_backend() const; - - // Rendering - void begin_frame(); - void render(); - void end_frame(); - void present(); - - // Frame capture - void capture_frame_ldr(uint8_t** pixels, int* width, int* height); - void capture_frame_hdr(float** pixels, int* width, int* height); - void save_frame(const std::string& filename, const uint8_t* pixels, - int width, int height); - - // Window control - bool should_close() const; - void set_should_close(bool should_close); - - // Statistics - const RenderStats& get_stats() const; - void reset_stats(); - - // Debug visualization - void set_gbuffer_visualization_mode(GBufferVisualizationMode mode); - GBufferVisualizationMode get_gbuffer_visualization_mode() const; - -private: - void initialize_subsystems(); - void shutdown_subsystems(); - void rebuild_bvh_if_needed(); - void check_scene_dirty(); - - AreConfig config_; ///< Current configuration - - std::unique_ptr window_; ///< Window management - std::unique_ptr scene_manager_; ///< Scene data management - std::unique_ptr rasterizer_; ///< Rasterization pipeline - std::unique_ptr raytracer_; ///< Ray tracing pipeline - std::unique_ptr texture_manager_; ///< Texture management - - Camera camera_; ///< Active camera - RenderStats stats_; ///< Rendering statistics - - bool scene_dirty_; ///< Scene needs BVH rebuild - bool initialized_; ///< Initialization flag -}; - -} // namespace are - -#endif // ARE_INCLUDE_RENDERER_RENDERER_H -``` - -### 文件:include/are/renderer/render_stats.h - -```cpp -/** - * @file render_stats.h - * @brief Rendering statistics tracking - */ - -#ifndef ARE_INCLUDE_RENDERER_RENDER_STATS_H -#define ARE_INCLUDE_RENDERER_RENDER_STATS_H - -#include -#include - -namespace are { - -/** - * @struct RenderStats - * @brief Statistics for rendering performance analysis - */ -struct RenderStats { - // Frame timing - double frame_time_ms_; ///< Total frame time in milliseconds - double rasterization_time_ms_; ///< Rasterization time - double ray_tracing_time_ms_; ///< Ray tracing time - double bvh_build_time_ms_; ///< BVH construction time - double present_time_ms_; ///< Present/swap time - - // Scene statistics - uint32_t mesh_count_; ///< Number of meshes - uint32_t triangle_count_; ///< Total triangle count - uint32_t light_count_; ///< Number of lights - uint32_t material_count_; ///< Number of materials - - // Ray tracing statistics - uint64_t primary_rays_; ///< Number of primary rays - uint64_t secondary_rays_; ///< Number of secondary rays - uint64_t shadow_rays_; ///< Number of shadow rays - uint64_t bvh_traversals_; ///< BVH traversal count - uint64_t triangle_tests_; ///< Triangle intersection tests - - // Memory statistics - size_t vertex_memory_bytes_; ///< Vertex buffer memory - size_t index_memory_bytes_; ///< Index buffer memory - size_t texture_memory_bytes_; ///< Texture memory - size_t bvh_memory_bytes_; ///< BVH memory - - // FPS - double fps_; ///< Frames per second - - /** - * @brief Reset all statistics to zero - */ - void reset(); - - /** - * @brief Print statistics to console - */ - void print() const; - - /** - * @brief Update FPS based on frame time - */ - void update_fps(); -}; - -} // namespace are - -#endif // ARE_INCLUDE_RENDERER_RENDER_STATS_H -``` - -### 文件:include/are/renderer/render_context.h - -```cpp -/** - * @file render_context.h - * @brief Rendering context and state management - */ - -#ifndef ARE_INCLUDE_RENDERER_RENDER_CONTEXT_H -#define ARE_INCLUDE_RENDERER_RENDER_CONTEXT_H - -#include -#include - -namespace are { - -/** - * @struct RenderContext - * @brief Rendering context information - * - * Contains current rendering state and frame information. - */ -struct RenderContext { - int frame_number_; ///< Current frame number - double time_; ///< Total elapsed time in seconds - double delta_time_; ///< Time since last frame - - int viewport_width_; ///< Viewport width - int viewport_height_; ///< Viewport height - - RayTracingBackend current_backend_; ///< Current ray tracing backend - bool scene_dirty_; ///< Scene needs BVH rebuild - bool camera_moved_; ///< Camera moved this frame - - /** - * @brief Constructor - */ - RenderContext(); - - /** - * @brief Reset context - */ - void reset(); - - /** - * @brief Update frame timing - * @param current_time Current time in seconds - */ - void update_timing(double current_time); -}; - -} // namespace are - -#endif // ARE_INCLUDE_RENDERER_RENDER_CONTEXT_H -``` - -### 文件:include/are/raytracer/ray.h - -```cpp -/** - * @file ray.h - * @brief Ray structure for ray tracing - */ - -#ifndef ARE_INCLUDE_RAYTRACER_RAY_H -#define ARE_INCLUDE_RAYTRACER_RAY_H - -#include - -namespace are { - -/** - * @struct Ray - * @brief Ray representation for ray tracing - */ -struct Ray { - Vec3 origin_; ///< Ray origin - Vec3 direction_; ///< Ray direction (normalized) - Real t_min_; ///< Minimum t value - Real t_max_; ///< Maximum t value - - /** - * @brief Default constructor - */ - Ray(); - - /** - * @brief Construct ray with origin and direction - * @param origin Ray origin - * @param direction Ray direction (will be normalized) - * @param t_min Minimum t value - * @param t_max Maximum t value - */ - Ray(const Vec3& origin, const Vec3& direction, - Real t_min = are_epsilon, Real t_max = 1e30f); - - /** - * @brief Evaluate ray at parameter t - * @param t Parameter value - * @return Point on ray - */ - Vec3 at(Real t) const; - - /** - * @brief Check if t is within valid range - * @param t Parameter value - * @return true if t is valid - */ - bool is_valid_t(Real t) const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_RAY_H -``` - -### 文件:include/are/raytracer/hit_record.h - -```cpp -/** - * @file hit_record.h - * @brief Ray-surface intersection record - */ - -#ifndef ARE_INCLUDE_RAYTRACER_HIT_RECORD_H -#define ARE_INCLUDE_RAYTRACER_HIT_RECORD_H - -#include - -namespace are { - -/** - * @struct HitRecord - * @brief Information about ray-surface intersection - */ -struct HitRecord { - Vec3 position_; ///< Hit position in world space - Vec3 normal_; ///< Surface normal at hit point - Vec2 texcoord_; ///< Texture coordinates at hit point - Vec3 tangent_; ///< Tangent vector at hit point - Real t_; ///< Ray parameter at hit point - MaterialHandle material_; ///< Material at hit point - uint32_t triangle_index_; ///< Triangle index that was hit - bool front_face_; ///< Whether ray hit front face - - /** - * @brief Default constructor - */ - HitRecord(); - - /** - * @brief Set face normal based on ray direction - * @param ray_direction Ray direction - * @param outward_normal Outward-facing normal - */ - void set_face_normal(const Vec3& ray_direction, const Vec3& outward_normal); - - /** - * @brief Check if hit record is valid - * @return true if hit occurred - */ - bool is_valid() const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_HIT_RECORD_H -``` - -### 文件:include/are/raytracer/raytracer.h - -```cpp -/** - * @file raytracer.h - * @brief Ray tracing interface - */ - -#ifndef ARE_INCLUDE_RAYTRACER_RAYTRACER_H -#define ARE_INCLUDE_RAYTRACER_RAYTRACER_H - -#include -#include - -namespace are { - -// Forward declarations -class SceneManager; -class Camera; -class GBuffer; -class BVH; - -/** - * @class RayTracer - * @brief Abstract ray tracing interface - * - * Base class for CPU and GPU ray tracing implementations. - */ -class RayTracer { -public: - /** - * @brief Constructor - * @param config Ray tracing configuration - */ - explicit RayTracer(const RayTracingConfig& config); - - /** - * @brief Virtual destructor - */ - virtual ~RayTracer() = default; - - /** - * @brief Render scene using ray tracing - * @param scene Scene manager - * @param camera Camera - * @param gbuffer G-Buffer (optional, for hybrid rendering) - * @param output Output texture ID - */ - virtual void render(const SceneManager& scene, - const Camera& camera, - const GBuffer* gbuffer, - uint32_t output_texture) = 0; - - /** - * @brief Update BVH - * @param bvh BVH reference - */ - virtual void update_bvh(const BVH& bvh) = 0; - - /** - * @brief Set configuration - * @param config New configuration - */ - virtual void set_config(const RayTracingConfig& config); - - /** - * @brief Get configuration - * @return Current configuration - */ - const RayTracingConfig& get_config() const { return config_; } - -protected: - RayTracingConfig config_; ///< Ray tracing configuration -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_RAYTRACER_H -``` - -### 文件:include/are/raytracer/cpu_raytracer.h - -```cpp -/** - * @file cpu_raytracer.h - * @brief CPU-based ray tracing implementation - */ - -#ifndef ARE_INCLUDE_RAYTRACER_CPU_RAYTRACER_H -#define ARE_INCLUDE_RAYTRACER_CPU_RAYTRACER_H - -#include -#include -#include -#include - -namespace are { - -/** - * @class CPURayTracer - * @brief CPU-based ray tracing implementation - * - * Uses multithreading for parallel ray tracing on CPU. - */ -class CPURayTracer : public RayTracer { -public: - /** - * @brief Constructor - * @param config Ray tracing configuration - */ - explicit CPURayTracer(const RayTracingConfig& config); - - /** - * @brief Destructor - */ - ~CPURayTracer() override; - - /** - * @brief Render scene using CPU ray tracing - * @param scene Scene manager - * @param camera Camera - * @param gbuffer G-Buffer (optional) - * @param output Output texture ID - */ - void render(const SceneManager& scene, - const Camera& camera, - const GBuffer* gbuffer, - uint32_t output_texture) override; - - /** - * @brief Update BVH - * @param bvh BVH reference - */ - void update_bvh(const BVH& bvh) override; - -private: - /** - * @brief Trace a single ray - * @param ray Ray to trace - * @param depth Current recursion depth - * @return Ray color - */ - Vec3 trace_ray(const Ray& ray, int depth); - - /** - * @brief Shade hit point - * @param hit Hit record - * @param ray Incident ray - * @param depth Current recursion depth - * @return Shaded color - */ - Vec3 shade(const HitRecord& hit, const Ray& ray, int depth); - - /** - * @brief Compute direct lighting - * @param hit Hit record - * @return Direct lighting contribution - */ - Vec3 compute_direct_lighting(const HitRecord& hit); - - /** - * @brief Compute ambient occlusion - * @param hit Hit record - * @return AO factor [0, 1] - */ - Real compute_ambient_occlusion(const HitRecord& hit); - - /** - * @brief Check shadow ray - * @param origin Shadow ray origin - * @param direction Shadow ray direction - * @param max_distance Maximum distance - * @return true if in shadow - */ - bool is_in_shadow(const Vec3& origin, const Vec3& direction, Real max_distance); - - const BVH* bvh_; ///< BVH reference - const SceneManager* scene_; ///< Scene reference - std::vector framebuffer_; ///< CPU framebuffer (HDR) - int width_; ///< Framebuffer width - int height_; ///< Framebuffer height -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_CPU_RAYTRACER_H -``` - -### 文件:include/are/raytracer/compute_raytracer.h - -```cpp -/** - * @file compute_raytracer.h - * @brief GPU compute shader ray tracing implementation - */ - -#ifndef ARE_INCLUDE_RAYTRACER_COMPUTE_RAYTRACER_H -#define ARE_INCLUDE_RAYTRACER_COMPUTE_RAYTRACER_H - -#include -#include - -namespace are { - -// Forward declarations -class ShaderProgram; - -/** - * @class ComputeRayTracer - * @brief GPU-based ray tracing using compute shaders - */ -class ComputeRayTracer : public RayTracer { -public: - /** - * @brief Constructor - * @param config Ray tracing configuration - */ - explicit ComputeRayTracer(const RayTracingConfig& config); - - /** - * @brief Destructor - */ - ~ComputeRayTracer() override; - - /** - * @brief Render scene using compute shader ray tracing - * @param scene Scene manager - * @param camera Camera - * @param gbuffer G-Buffer (optional) - * @param output Output texture ID - */ - void render(const SceneManager& scene, - const Camera& camera, - const GBuffer* gbuffer, - uint32_t output_texture) override; - - /** - * @brief Update BVH - * @param bvh BVH reference - */ - void update_bvh(const BVH& bvh) override; - -private: - void initialize_compute_shader(const std::string& shader_dir); - void upload_scene_data(const SceneManager& scene); - void upload_bvh_data(const BVH& bvh); - void upload_camera_data(const Camera& camera); - - std::unique_ptr compute_shader_; ///< Ray tracing compute shader - - // GPU buffers (SSBOs) - uint32_t bvh_buffer_; ///< BVH nodes buffer - uint32_t triangle_buffer_; ///< Triangle data buffer - uint32_t material_buffer_; ///< Material data buffer - uint32_t light_buffer_; ///< Light data buffer - - bool buffers_initialized_; ///< Buffer initialization flag -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_COMPUTE_RAYTRACER_H -``` - -### 文件:include/are/utils/image_io.h - -```cpp -/** - * @file image_io.h - * @brief Image loading and saving utilities - */ - -#ifndef ARE_INCLUDE_UTILS_IMAGE_IO_H -#define ARE_INCLUDE_UTILS_IMAGE_IO_H - -#include -#include -#include - -namespace are { - -/** - * @enum ImageFormat - * @brief Supported image formats - */ -enum class ImageFormat { - ARE_IMAGE_FORMAT_PPM, - ARE_IMAGE_FORMAT_BMP, - ARE_IMAGE_FORMAT_PNG, - ARE_IMAGE_FORMAT_JPG -}; - -/** - * @struct ImageData - * @brief Container for image data - */ -struct ImageData { - int width_; ///< Image width - int height_; ///< Image height - int channels_; ///< Number of channels (3=RGB, 4=RGBA) - std::vector data_; ///< Pixel data (row-major) - - /** - * @brief Check if image data is valid - * @return true if valid - */ - bool is_valid() const; - - /** - * @brief Get pixel at (x, y) - * @param x X coordinate - * @param y Y coordinate - * @return Pointer to pixel data (RGB or RGBA) - */ - const uint8_t* get_pixel(int x, int y) const; - - /** - * @brief Set pixel at (x, y) - * @param x X coordinate - * @param y Y coordinate - * @param r Red channel - * @param g Green channel - * @param b Blue channel - * @param a Alpha channel (optional) - */ - void set_pixel(int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255); -}; - -/** - * @brief Load image from file - * @param filename Image file path - * @param flip_vertically Whether to flip image vertically - * @return Image data (empty if failed) - */ -ImageData load_image(const std::string& filename, bool flip_vertically = false); - -/** - * @brief Save image to file - * @param filename Output file path - * @param data Image data - * @param format Output format (auto-detected from extension if not specified) - * @return true if save succeeded - */ -bool save_image(const std::string& filename, const ImageData& data, - ImageFormat format = ImageFormat::ARE_IMAGE_FORMAT_PNG); - -/** - * @brief Save raw pixel data to file - * @param filename Output file path - * @param pixels Pixel data pointer - * @param width Image width - * @param height Image height - * @param channels Number of channels - * @param format Output format - * @return true if save succeeded - */ -bool save_image(const std::string& filename, const uint8_t* pixels, - int width, int height, int channels, - ImageFormat format = ImageFormat::ARE_IMAGE_FORMAT_PNG); - -/** - * @brief Detect image format from file extension - * @param filename File path - * @return Detected format - */ -ImageFormat detect_format(const std::string& filename); - -} // namespace are - -#endif // ARE_INCLUDE_UTILS_IMAGE_IO_H -``` - -### 文件:include/are/utils/math_utils.h - -```cpp -/** - * @file math_utils.h - * @brief Mathematical utility functions - */ - -#ifndef ARE_INCLUDE_UTILS_MATH_UTILS_H -#define ARE_INCLUDE_UTILS_MATH_UTILS_H - -#include -#include - -namespace are { - -/** - * @brief Clamp value to range [min, max] - * @param value Value to clamp - * @param min Minimum value - * @param max Maximum value - * @return Clamped value - */ -template -inline T clamp(T value, T min, T max) { - return std::max(min, std::min(value, max)); -} - -/** - * @brief Linear interpolation - * @param a Start value - * @param b End value - * @param t Interpolation factor [0, 1] - * @return Interpolated value - */ -template -inline T lerp(T a, T b, Real t) { - return a + (b - a) * t; -} - -/** - * @brief Convert degrees to radians - * @param degrees Angle in degrees - * @return Angle in radians - */ -inline Real degrees_to_radians(Real degrees) { - return degrees * are_pi / 180.0f; -} - -/** - * @brief Convert radians to degrees - * @param radians Angle in radians - * @return Angle in degrees - */ -inline Real radians_to_degrees(Real radians) { - return radians * 180.0f / are_pi; -} - -/** - * @brief Check if two floating point values are approximately equal - * @param a First value - * @param b Second value - * @param epsilon Tolerance - * @return true if approximately equal - */ -inline bool approx_equal(Real a, Real b, Real epsilon = are_epsilon) { - return std::abs(a - b) < epsilon; -} - -/** - * @brief Compute barycentric coordinates - * @param p Point - * @param a Triangle vertex A - * @param b Triangle vertex B - * @param c Triangle vertex C - * @param u Output barycentric coordinate u - * @param v Output barycentric coordinate v - * @param w Output barycentric coordinate w - */ -void compute_barycentric(const Vec3& p, const Vec3& a, const Vec3& b, const Vec3& c, - Real& u, Real& v, Real& w); - -/** - * @brief Reflect vector around normal - * @param incident Incident vector - * @param normal Surface normal (normalized) - * @return Reflected vector - */ -Vec3 reflect(const Vec3& incident, const Vec3& normal); - -/** - * @brief Refract vector through surface - * @param incident Incident vector (normalized) - * @param normal Surface normal (normalized) - * @param eta Ratio of refractive indices - * @param refracted Output refracted vector - * @return true if refraction occurred (false for total internal reflection) - */ -bool refract(const Vec3& incident, const Vec3& normal, Real eta, Vec3& refracted); - -/** - * @brief Compute Fresnel reflectance (Schlick approximation) - * @param cos_theta Cosine of angle between view and normal - * @param f0 Reflectance at normal incidence - * @return Fresnel reflectance - */ -Real fresnel_schlick(Real cos_theta, Real f0); - -/** - * @brief Create orthonormal basis from normal - * @param normal Normal vector (normalized) - * @param tangent Output tangent vector - * @param bitangent Output bitangent vector - */ -void create_orthonormal_basis(const Vec3& normal, Vec3& tangent, Vec3& bitangent); - -/** - * @brief Transform direction from tangent space to world space - * @param tangent_dir Direction in tangent space - * @param normal Surface normal - * @param tangent Surface tangent - * @param bitangent Surface bitangent - * @return Direction in world space - */ -Vec3 tangent_to_world(const Vec3& tangent_dir, const Vec3& normal, - const Vec3& tangent, const Vec3& bitangent); - -} // namespace are - -#endif // ARE_INCLUDE_UTILS_MATH_UTILS_H -``` - -### 文件:include/are/utils/random.h - -```cpp -/** - * @file random.h - * @brief Random number generation utilities - */ - -#ifndef ARE_INCLUDE_UTILS_RANDOM_H -#define ARE_INCLUDE_UTILS_RANDOM_H - -#include -#include - -namespace are { - -/** - * @class RandomGenerator - * @brief Thread-safe random number generator - * - * Uses PCG (Permuted Congruential Generator) for high-quality random numbers. - */ -class RandomGenerator { -public: - /** - * @brief Constructor with optional seed - * @param seed Random seed (0 = use random device) - */ - explicit RandomGenerator(uint64_t seed = 0); - - /** - * @brief Generate random float in [0, 1) - * @return Random float - */ - Real random_float(); - - /** - * @brief Generate random float in [min, max) - * @param min Minimum value - * @param max Maximum value - * @return Random float - */ - Real random_float(Real min, Real max); - - /** - * @brief Generate random integer in [min, max] - * @param min Minimum value - * @param max Maximum value - * @return Random integer - */ - int random_int(int min, int max); - - /** - * @brief Generate random point in unit disk - * @return Random point (z = 0) - */ - Vec3 random_in_unit_disk(); - - /** - * @brief Generate random point in unit sphere - * @return Random point - */ - Vec3 random_in_unit_sphere(); - - /** - * @brief Generate random unit vector - * @return Random unit vector - */ - Vec3 random_unit_vector(); - - /** - * @brief Generate random vector in hemisphere - * @param normal Hemisphere normal - * @return Random vector in hemisphere - */ - Vec3 random_in_hemisphere(const Vec3 &normal); - - /** - * @brief Generate random cosine-weighted direction - * @param normal Surface normal - * @return Random direction (cosine-weighted) - */ - Vec3 random_cosine_direction(const Vec3 &normal); - - /** - * @brief Set seed for reproducible results - * @param seed Random seed - */ - void set_seed(uint64_t seed); - -private: - std::mt19937_64 rng_; ///< Random number generator - std::uniform_real_distribution dist_; ///< Uniform distribution [0, 1) -}; - -/** - * @brief Get thread-local random generator - * @return Reference to thread-local generator - */ -RandomGenerator &get_thread_random(); - -/** - * @brief Generate random float in [0, 1) using thread-local generator - * @return Random float - */ -inline Real random_float() { - return get_thread_random().random_float(); -} - -/** - * @brief Generate random float in [min, max) using thread-local generator - * @param min Minimum value - * @param max Maximum value - * @return Random float - */ -inline Real random_float(Real min, Real max) { - return get_thread_random().random_float(min, max); -} - -} // namespace are - -#endif // ARE_INCLUDE_UTILS_RANDOM_H -``` - -### 文件:include/are/utils/file_utils.h - -```cpp -/** - * @file file_utils.h - * @brief File system utilities - */ - -#ifndef ARE_INCLUDE_UTILS_FILE_UTILS_H -#define ARE_INCLUDE_UTILS_FILE_UTILS_H - -#include -#include -#include - -namespace are { - -/** - * @brief Read entire file into string - * @param filepath File path - * @return File contents (empty if failed) - */ -std::string read_file_to_string(const std::string& filepath); - -/** - * @brief Read entire file into byte array - * @param filepath File path - * @return File contents (empty if failed) - */ -std::vector read_file_to_bytes(const std::string& filepath); - -/** - * @brief Write string to file - * @param filepath File path - * @param content Content to write - * @return true if write succeeded - */ -bool write_string_to_file(const std::string& filepath, const std::string& content); - -/** - * @brief Write bytes to file - * @param filepath File path - * @param data Data pointer - * @param size Data size in bytes - * @return true if write succeeded - */ -bool write_bytes_to_file(const std::string& filepath, const void* data, size_t size); - -/** - * @brief Check if file exists - * @param filepath File path - * @return true if file exists - */ -bool file_exists(const std::string& filepath); - -/** - * @brief Check if path is directory - * @param path Directory path - * @return true if directory exists - */ -bool is_directory(const std::string& path); - -/** - * @brief Create directory (including parent directories) - * @param path Directory path - * @return true if creation succeeded - */ -bool create_directory(const std::string& path); - -/** - * @brief Get file extension - * @param filepath File path - * @return Extension (lowercase, without dot) - */ -std::string get_file_extension(const std::string& filepath); - -/** - * @brief Get filename from path - * @param filepath File path - * @return Filename (without directory) - */ -std::string get_filename(const std::string& filepath); - -/** - * @brief Get directory from path - * @param filepath File path - * @return Directory path - */ -std::string get_directory(const std::string& filepath); - -/** - * @brief Join path components - * @param parts Path components - * @return Joined path - */ -std::string join_path(const std::vector& parts); - -/** - * @brief Normalize path (resolve .. and .) - * @param path Path to normalize - * @return Normalized path - */ -std::string normalize_path(const std::string& path); - -} // namespace are - -#endif // ARE_INCLUDE_UTILS_FILE_UTILS_H -``` - -### 文件:include/are/platform/window.h - -```cpp -/** - * @file window.h - * @brief Window management using GLFW - */ - -#ifndef ARE_INCLUDE_PLATFORM_WINDOW_H -#define ARE_INCLUDE_PLATFORM_WINDOW_H - -#include -#include -#include - -// Forward declare GLFW types to avoid including GLFW in header -struct GLFWwindow; - -namespace are { - -/** - * @class Window - * @brief GLFW window wrapper - * - * Manages window creation, input handling, and OpenGL context. - */ -class Window { -public: - /** - * @brief Constructor - * @param config Window configuration - */ - explicit Window(const WindowConfig& config); - - /** - * @brief Destructor - */ - ~Window(); - - // Window control - bool should_close() const; - void set_should_close(bool should_close); - void swap_buffers(); - void poll_events(); - - // Window properties - int get_width() const; - int get_height() const; - Real get_aspect_ratio() const; - const std::string& get_title() const; - - void set_title(const std::string& title); - void set_size(int width, int height); - - // Framebuffer size (may differ from window size on high-DPI displays) - void get_framebuffer_size(int& width, int& height) const; - - // VSync control - void set_vsync(bool enabled); - bool get_vsync() const; - - // Input queries (basic support) - bool is_key_pressed(int key) const; - bool is_mouse_button_pressed(int button) const; - void get_cursor_pos(double& x, double& y) const; - - // Internal - GLFWwindow* get_native_window() const { return window_; } - -private: - void initialize_glfw(); - void create_window(); - void setup_callbacks(); - - static void framebuffer_size_callback(GLFWwindow* window, int width, int height); - static void error_callback(int error, const char* description); - - GLFWwindow* window_; ///< GLFW window handle - WindowConfig config_; ///< Window configuration - bool vsync_enabled_; ///< VSync state - - static int instance_count_; ///< Number of Window instances -}; - -} // namespace are - -#endif // ARE_INCLUDE_PLATFORM_WINDOW_H -``` - -### 文件:include/are/platform/gl_context.h - -```cpp -/** - * @file gl_context.h - * @brief OpenGL context management - */ - -#ifndef ARE_INCLUDE_PLATFORM_GL_CONTEXT_H -#define ARE_INCLUDE_PLATFORM_GL_CONTEXT_H - -#include -#include - -namespace are { - -/** - * @class GLContext - * @brief OpenGL context initialization and management - * - * Handles GLAD initialization and provides OpenGL utility functions. - */ -class GLContext { -public: - /** - * @brief Initialize OpenGL context (load function pointers) - * @return true if initialization succeeded - */ - static bool initialize(); - - /** - * @brief Check if context is initialized - * @return true if initialized - */ - static bool is_initialized(); - - /** - * @brief Get OpenGL version string - * @return Version string - */ - static std::string get_version(); - - /** - * @brief Get OpenGL renderer string - * @return Renderer string - */ - static std::string get_renderer(); - - /** - * @brief Get OpenGL vendor string - * @return Vendor string - */ - static std::string get_vendor(); - - /** - * @brief Check if OpenGL extension is supported - * @param extension Extension name - * @return true if supported - */ - static bool is_extension_supported(const std::string& extension); - - /** - * @brief Print OpenGL information to console - */ - static void print_info(); - - /** - * @brief Check for OpenGL errors - * @param file Source file - * @param line Line number - * @return true if error occurred - */ - static bool check_error(const char* file, int line); - - /** - * @brief Clear all OpenGL errors - */ - static void clear_errors(); - -private: - static bool initialized_; ///< Initialization flag -}; - -} // namespace are - -// OpenGL error checking macro -#ifdef ARE_ENABLE_DEBUG_VIS - #define ARE_GL_CHECK() are::GLContext::check_error(__FILE__, __LINE__) -#else - #define ARE_GL_CHECK() ((void)0) -#endif - -#endif // ARE_INCLUDE_PLATFORM_GL_CONTEXT_H -``` - -### 文件:include/are/acceleration/bvh_node.h - -```cpp -/** - * @file bvh_node.h - * @brief BVH node structure - */ - -#ifndef ARE_INCLUDE_ACCELERATION_BVH_NODE_H -#define ARE_INCLUDE_ACCELERATION_BVH_NODE_H - -#include -#include - -namespace are { - -/** - * @struct BVHNode - * @brief Node in Bounding Volume Hierarchy - * - * Uses a compact representation for efficient GPU transfer. - */ -struct BVHNode { - AABB bounds_; ///< Node bounding box - - union { - uint32_t left_child_; ///< Left child index (internal node) - uint32_t first_primitive_; ///< First primitive index (leaf node) - }; - - union { - uint32_t right_child_; ///< Right child index (internal node) - uint32_t primitive_count_; ///< Number of primitives (leaf node) - }; - - /** - * @brief Check if node is a leaf - * @return true if leaf node - */ - bool is_leaf() const { - return primitive_count_ > 0; - } - - /** - * @brief Get node surface area (for SAH) - * @return Surface area - */ - Real surface_area() const { - return bounds_.surface_area(); - } -}; - -} // namespace are - -#endif // ARE_INCLUDE_ACCELERATION_BVH_NODE_H -``` - -### 文件:include/are/acceleration/bvh_builder.h - -```cpp -/** - * @file bvh_builder.h - * @brief BVH construction algorithms - */ - -#ifndef ARE_INCLUDE_ACCELERATION_BVH_BUILDER_H -#define ARE_INCLUDE_ACCELERATION_BVH_BUILDER_H - -#include -#include -#include -#include - -namespace are { - -/** - * @enum BVHSplitMethod - * @brief BVH splitting strategies - */ -enum class BVHSplitMethod { - ARE_BVH_SPLIT_MIDDLE, ///< Split at midpoint - ARE_BVH_SPLIT_SAH ///< Surface Area Heuristic -}; - -/** - * @struct BVHBuildConfig - * @brief Configuration for BVH construction - */ -struct BVHBuildConfig { - BVHSplitMethod split_method_ = BVHSplitMethod::ARE_BVH_SPLIT_SAH; - int max_leaf_size_ = 4; ///< Maximum triangles per leaf - int max_depth_ = 64; ///< Maximum tree depth - bool use_multithreading_ = true; ///< Use parallel construction -}; - -/** - * @class BVHBuilder - * @brief Constructs BVH from triangle list - */ -class BVHBuilder { -public: - /** - * @brief Constructor - * @param config Build configuration - */ - explicit BVHBuilder(const BVHBuildConfig& config = BVHBuildConfig()); - - /** - * @brief Build BVH from triangles - * @param triangles Triangle list - * @param nodes Output node list - * @param primitive_indices Output primitive index list - * @return Root node index - */ - uint32_t build(const std::vector& triangles, - std::vector& nodes, - std::vector& primitive_indices); - - /** - * @brief Get build statistics - * @param node_count Output node count - * @param leaf_count Output leaf count - * @param max_depth Output maximum depth reached - */ - void get_stats(size_t& node_count, size_t& leaf_count, int& max_depth) const; - -private: - struct BuildEntry { - uint32_t parent_; - uint32_t start_; - uint32_t end_; - int depth_; - }; - - uint32_t build_recursive(const std::vector& triangles, - std::vector& nodes, - std::vector& primitive_indices, - uint32_t start, uint32_t end, int depth); - - int find_best_split_axis(const std::vector& triangles, - const std::vector& indices, - uint32_t start, uint32_t end); - - Real compute_sah_cost(const AABB& bounds, uint32_t count); - - BVHBuildConfig config_; - size_t node_count_; - size_t leaf_count_; - int max_depth_reached_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_ACCELERATION_BVH_BUILDER_H -``` - -### 文件:include/are/acceleration/bvh.h - -```cpp -/** - * @file bvh.h - * @brief BVH interface and traversal - */ - -#ifndef ARE_INCLUDE_ACCELERATION_BVH_H -#define ARE_INCLUDE_ACCELERATION_BVH_H - -#include -#include -#include -#include -#include -#include -#include - -namespace are { - -/** - * @class BVH - * @brief Bounding Volume Hierarchy for ray tracing acceleration - */ -class BVH { -public: - /** - * @brief Constructor - */ - BVH(); - - /** - * @brief Destructor - */ - ~BVH(); - - /** - * @brief Build BVH from triangle list - * @param triangles Triangle list - * @param config Build configuration - * @return true if build succeeded - */ - bool build(const std::vector& triangles, - const BVHBuildConfig& config = BVHBuildConfig()); - - /** - * @brief Traverse BVH and find closest intersection - * @param ray Ray to trace - * @param hit Output hit record - * @return true if intersection found - */ - bool intersect(const Ray& ray, HitRecord& hit) const; - - /** - * @brief Fast occlusion test (any hit) - * @param ray Ray to trace - * @param t_max Maximum t value - * @return true if any intersection found - */ - bool intersect_any(const Ray& ray, Real t_max) const; - - /** - * @brief Check if BVH is built - * @return true if built - */ - bool is_built() const { return !nodes_.empty(); } - - /** - * @brief Get BVH nodes (for GPU upload) - * @return Node array - */ - const std::vector& get_nodes() const { return nodes_; } - - /** - * @brief Get primitive indices - * @return Index array - */ - const std::vector& get_primitive_indices() const { - return primitive_indices_; - } - - /** - * @brief Get triangles - * @return Triangle array - */ - const std::vector& get_triangles() const { return triangles_; } - - /** - * @brief Get memory usage in bytes - * @return Memory usage - */ - size_t get_memory_usage() const; - - /** - * @brief Clear BVH data - */ - void clear(); - -private: - // Recursive traversal (kept for reference) - bool intersect_recursive(uint32_t node_index, const Ray& ray, HitRecord& hit) const; - bool intersect_any_recursive(uint32_t node_index, const Ray& ray, Real t_max) const; - - // Optimized iterative traversal - bool intersect_iterative(const Ray& ray, HitRecord& hit) const; - bool intersect_any_iterative(const Ray& ray, Real t_max) const; - - // Fast intersection helpers - inline bool intersect_aabb_fast(const AABB& bounds, const Ray& ray, - const Vec3& inv_dir, Real t_max, - Real& t_min_out, Real& t_max_out) const; - inline bool intersect_triangle_fast(const Triangle& triangle, const Ray& ray, - Real t_max, HitRecord& hit) const; - - std::vector nodes_; ///< BVH nodes - std::vector primitive_indices_; ///< Primitive index array - std::vector triangles_; ///< Triangle data - uint32_t root_index_; ///< Root node index -}; - -} // namespace are - -#endif // ARE_INCLUDE_ACCELERATION_BVH_H -``` - -### 文件:include/are/rasterizer/rasterizer.h - -```cpp -/** - * @file rasterizer.h - * @brief Rasterization pipeline for G-Buffer generation - */ - -#ifndef ARE_INCLUDE_RASTERIZER_RASTERIZER_H -#define ARE_INCLUDE_RASTERIZER_RASTERIZER_H - -#include -#include -#include - -namespace are { - -// Forward declarations -class GBuffer; -class ShaderProgram; -class SceneManager; -class Camera; -class Mesh; - -/** - * @class Rasterizer - * @brief OpenGL rasterization pipeline - * - * Renders scene geometry to G-Buffer using traditional rasterization. - */ -class Rasterizer { -public: - /** - * @brief Constructor - * @param width Framebuffer width - * @param height Framebuffer height - */ - Rasterizer(int width, int height); - - /** - * @brief Destructor - */ - ~Rasterizer(); - - /** - * @brief Resize framebuffer - * @param width New width - * @param height New height - */ - void resize(int width, int height); - - /** - * @brief Render scene to G-Buffer - * @param scene Scene manager - * @param camera Camera - */ - void render_gbuffer(const SceneManager& scene, const Camera& camera); - - /** - * @brief Get G-Buffer - * @return G-Buffer reference - */ - GBuffer& get_gbuffer(); - const GBuffer& get_gbuffer() const; - - /** - * @brief Upload mesh data to GPU - * @param mesh Mesh to upload - */ - void upload_mesh(Mesh& mesh); - - /** - * @brief Delete mesh GPU resources - * @param mesh Mesh to delete - */ - void delete_mesh(Mesh& mesh); - -private: - void initialize_shaders(const std::string& shader_dir); - void setup_mesh_buffers(Mesh& mesh); - - std::unique_ptr gbuffer_; ///< G-Buffer - std::unique_ptr gbuffer_shader_; ///< G-Buffer shader - - int width_; ///< Framebuffer width - int height_; ///< Framebuffer height -}; - -} // namespace are - -#endif // ARE_INCLUDE_RASTERIZER_RASTERIZER_H -``` - -### 文件:include/are/rasterizer/shader_program.h - -```cpp -/** - * @file shader_program.h - * @brief OpenGL shader program wrapper - */ - -#ifndef ARE_INCLUDE_RASTERIZER_SHADER_PROGRAM_H -#define ARE_INCLUDE_RASTERIZER_SHADER_PROGRAM_H - -#include -#include -#include - -namespace are { - -/** - * @enum ShaderType - * @brief Shader stage types - */ -enum class ShaderType { - ARE_SHADER_VERTEX, - ARE_SHADER_FRAGMENT, - ARE_SHADER_COMPUTE -}; - -/** - * @class ShaderProgram - * @brief OpenGL shader program management - */ -class ShaderProgram { -public: - /** - * @brief Constructor - */ - ShaderProgram(); - - /** - * @brief Destructor - */ - ~ShaderProgram(); - - /** - * @brief Load and compile shader from file - * @param type Shader type - * @param filepath Shader file path - * @return true if compilation succeeded - */ - bool load_shader(ShaderType type, const std::string& filepath); - - /** - * @brief Compile shader from source string - * @param type Shader type - * @param source Shader source code - * @return true if compilation succeeded - */ - bool compile_shader(ShaderType type, const std::string& source); - - /** - * @brief Link shader program - * @return true if linking succeeded - */ - bool link(); - - /** - * @brief Use this shader program - */ - void use() const; - - /** - * @brief Check if program is valid - * @return true if valid - */ - bool is_valid() const { return program_ != 0 && linked_; } - - /** - * @brief Get OpenGL program ID - * @return Program ID - */ - uint32_t get_program() const { return program_; } - - // Uniform setters - void set_uniform(const std::string& name, int value); - void set_uniform(const std::string& name, float value); - void set_uniform(const std::string& name, const Vec2& value); - void set_uniform(const std::string& name, const Vec3& value); - void set_uniform(const std::string& name, const Vec4& value); - void set_uniform(const std::string& name, const Mat3& value); - void set_uniform(const std::string& name, const Mat4& value); - - /** - * @brief Get uniform location (cached) - * @param name Uniform name - * @return Uniform location (-1 if not found) - */ - int get_uniform_location(const std::string& name); - -private: - bool check_compile_errors(uint32_t shader, ShaderType type); - bool check_link_errors(); - - uint32_t program_; ///< OpenGL program ID - uint32_t vertex_shader_; ///< Vertex shader ID - uint32_t fragment_shader_; ///< Fragment shader ID - uint32_t compute_shader_; ///< Compute shader ID - - bool linked_; ///< Link status - std::unordered_map uniform_cache_; ///< Uniform location cache -}; - -} // namespace are - -#endif // ARE_INCLUDE_RASTERIZER_SHADER_PROGRAM_H -``` - -### 文件:include/are/rasterizer/gbuffer.h - -```cpp -/** - * @file gbuffer.h - * @brief G-Buffer management for deferred rendering - */ - -#ifndef ARE_INCLUDE_RASTERIZER_GBUFFER_H -#define ARE_INCLUDE_RASTERIZER_GBUFFER_H - -#include -#include - -namespace are { - -/** - * @class GBuffer - * @brief G-Buffer for deferred rendering - * - * Contains multiple render targets for position, normal, albedo, etc. - */ -class GBuffer { -public: - /** - * @brief Constructor - * @param width Buffer width - * @param height Buffer height - */ - GBuffer(int width, int height); - - /** - * @brief Destructor - */ - ~GBuffer(); - - /** - * @brief Resize G-Buffer - * @param width New width - * @param height New height - */ - void resize(int width, int height); - - /** - * @brief Bind G-Buffer for rendering - */ - void bind(); - - /** - * @brief Unbind G-Buffer - */ - void unbind(); - - /** - * @brief Clear all buffers - */ - void clear(); - - /** - * @brief Bind texture for reading - * @param index Texture index (0=position, 1=normal, 2=albedo, etc.) - * @param texture_unit Texture unit to bind to - */ - void bind_texture(int index, int texture_unit); - - // Texture getters - uint32_t get_position_texture() const { return position_texture_; } - uint32_t get_normal_texture() const { return normal_texture_; } - uint32_t get_albedo_texture() const { return albedo_texture_; } - uint32_t get_material_texture() const { return material_texture_; } - uint32_t get_depth_texture() const { return depth_texture_; } - - // Dimensions - int get_width() const { return width_; } - int get_height() const { return height_; } - - /** - * @brief Read pixel data from G-Buffer - * @param index Buffer index - * @param data Output data pointer - */ - void read_pixels(int index, void* data); - -private: - void create_textures(); - void delete_textures(); - void create_framebuffer(); - - uint32_t fbo_; ///< Framebuffer object - uint32_t rbo_depth_; ///< Depth renderbuffer - - // G-Buffer textures - uint32_t position_texture_; ///< World position (RGB16F) - uint32_t normal_texture_; ///< World normal (RGB16F) - uint32_t albedo_texture_; ///< Albedo + Metallic (RGBA8) - uint32_t material_texture_; ///< Roughness + AO (RG8) - uint32_t depth_texture_; ///< Depth (R32F) - - int width_; ///< Buffer width - int height_; ///< Buffer height -}; - -} // namespace are - -#endif // ARE_INCLUDE_RASTERIZER_GBUFFER_H -``` - -### 文件:include/are/texture/texture.h - -```cpp -/** - * @file texture.h - * @brief Texture resource management - */ - -#ifndef ARE_INCLUDE_TEXTURE_TEXTURE_H -#define ARE_INCLUDE_TEXTURE_TEXTURE_H - -#include -#include - -namespace are { - -/** - * @enum TextureFormat - * @brief Texture internal formats - */ -enum class TextureFormat { - ARE_TEXTURE_R8, - ARE_TEXTURE_RG8, - ARE_TEXTURE_RGB8, - ARE_TEXTURE_RGBA8, - ARE_TEXTURE_R16F, - ARE_TEXTURE_RG16F, - ARE_TEXTURE_RGB16F, - ARE_TEXTURE_RGBA16F, - ARE_TEXTURE_R32F, - ARE_TEXTURE_RG32F, - ARE_TEXTURE_RGB32F, - ARE_TEXTURE_RGBA32F -}; - -/** - * @enum TextureFilter - * @brief Texture filtering modes - */ -enum class TextureFilter { - ARE_TEXTURE_FILTER_NEAREST, - ARE_TEXTURE_FILTER_LINEAR, - ARE_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST, - ARE_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST, - ARE_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR, - ARE_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR -}; - -/** - * @enum TextureWrap - * @brief Texture wrapping modes - */ -enum class TextureWrap { - ARE_TEXTURE_WRAP_REPEAT, - ARE_TEXTURE_WRAP_CLAMP_TO_EDGE, - ARE_TEXTURE_WRAP_CLAMP_TO_BORDER, - ARE_TEXTURE_WRAP_MIRRORED_REPEAT -}; - -/** - * @class Texture - * @brief OpenGL texture wrapper - */ -class Texture { -public: - /** - * @brief Constructor - */ - Texture(); - - /** - * @brief Destructor - */ - ~Texture(); - - /** - * @brief Load texture from file - * @param filepath Image file path - * @param format Desired texture format - * @param generate_mipmaps Generate mipmaps - * @return true if load succeeded - */ - bool load_from_file(const std::string& filepath, - TextureFormat format = TextureFormat::ARE_TEXTURE_RGBA8, - bool generate_mipmaps = true); - - /** - * @brief Create texture from raw data - * @param width Texture width - * @param height Texture height - * @param format Texture format - * @param data Pixel data - * @param generate_mipmaps Generate mipmaps - * @return true if creation succeeded - */ - bool create_from_data(int width, int height, - TextureFormat format, - const void* data, - bool generate_mipmaps = true); - - /** - * @brief Bind texture to texture unit - * @param unit Texture unit (0-31) - */ - void bind(int unit = 0) const; - - /** - * @brief Unbind texture - */ - void unbind() const; - - /** - * @brief Set texture filtering - * @param min_filter Minification filter - * @param mag_filter Magnification filter - */ - void set_filter(TextureFilter min_filter, TextureFilter mag_filter); - - /** - * @brief Set texture wrapping - * @param wrap_s S-axis wrapping - * @param wrap_t T-axis wrapping - */ - void set_wrap(TextureWrap wrap_s, TextureWrap wrap_t); - - /** - * @brief Generate mipmaps - */ - void generate_mipmaps(); - - // Getters - uint32_t get_id() const { return texture_id_; } - int get_width() const { return width_; } - int get_height() const { return height_; } - TextureFormat get_format() const { return format_; } - bool is_valid() const { return texture_id_ != 0; } - - /** - * @brief Delete texture - */ - void destroy(); - -private: - uint32_t texture_id_; ///< OpenGL texture ID - int width_; ///< Texture width - int height_; ///< Texture height - TextureFormat format_; ///< Texture format -}; - -} // namespace are - -#endif // ARE_INCLUDE_TEXTURE_TEXTURE_H -``` - -### 文件:include/are/texture/texture_manager.h - -```cpp -/** - * @file texture_manager.h - * @brief Texture resource management and caching - */ - -#ifndef ARE_INCLUDE_TEXTURE_TEXTURE_MANAGER_H -#define ARE_INCLUDE_TEXTURE_TEXTURE_MANAGER_H - -#include -#include -#include -#include -#include - -namespace are { - -/** - * @class TextureManager - * @brief Manages texture loading and caching - * - * Automatically handles texture deduplication and lifetime management. - */ -class TextureManager { -public: - /** - * @brief Constructor - */ - TextureManager(); - - /** - * @brief Destructor - */ - ~TextureManager(); - - /** - * @brief Load texture from file (with caching) - * @param filepath Texture file path - * @param format Desired texture format - * @param generate_mipmaps Generate mipmaps - * @return Texture handle (are_invalid_handle if failed) - */ - TextureHandle load_texture(const std::string& filepath, - TextureFormat format = TextureFormat::ARE_TEXTURE_RGBA8, - bool generate_mipmaps = true); - - /** - * @brief Create texture from raw data - * @param name Texture name (for caching) - * @param width Texture width - * @param height Texture height - * @param format Texture format - * @param data Pixel data - * @param generate_mipmaps Generate mipmaps - * @return Texture handle - */ - TextureHandle create_texture(const std::string& name, - int width, int height, - TextureFormat format, - const void* data, - bool generate_mipmaps = true); - - /** - * @brief Get texture by handle - * @param handle Texture handle - * @return Texture pointer (nullptr if not found) - */ - Texture* get_texture(TextureHandle handle); - const Texture* get_texture(TextureHandle handle) const; - - /** - * @brief Unload texture - * @param handle Texture handle - */ - void unload_texture(TextureHandle handle); - - /** - * @brief Clear all textures - */ - void clear(); - - /** - * @brief Get total texture memory usage - * @return Memory usage in bytes - */ - size_t get_memory_usage() const; - - /** - * @brief Get number of loaded textures - * @return Texture count - */ - size_t get_texture_count() const { return textures_.size(); } - -private: - std::unordered_map path_to_handle_; - std::unordered_map> textures_; - TextureHandle next_handle_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_TEXTURE_TEXTURE_MANAGER_H -``` - -### 文件:include/are/texture/sampler.h - -```cpp -/** - * @file sampler.h - * @brief Texture sampling utilities - */ - -#ifndef ARE_INCLUDE_TEXTURE_SAMPLER_H -#define ARE_INCLUDE_TEXTURE_SAMPLER_H - -#include - -namespace are { - -// Forward declaration -class Texture; -class TextureWrap; - -/** - * @class Sampler - * @brief Texture sampling utilities for CPU ray tracing - * - * Provides bilinear filtering and wrapping modes for CPU-side texture access. - */ -class Sampler { -public: - /** - * @brief Sample texture at UV coordinates - * @param texture Texture to sample - * @param uv UV coordinates - * @return Sampled color (RGBA) - */ - static Vec4 sample(const Texture& texture, const Vec2& uv); - - /** - * @brief Sample texture with bilinear filtering - * @param texture Texture to sample - * @param uv UV coordinates - * @return Sampled color (RGBA) - */ - static Vec4 sample_bilinear(const Texture& texture, const Vec2& uv); - - /** - * @brief Sample texture at nearest pixel - * @param texture Texture to sample - * @param uv UV coordinates - * @return Sampled color (RGBA) - */ - static Vec4 sample_nearest(const Texture& texture, const Vec2& uv); - -private: - static Vec2 apply_wrap(const Vec2& uv, TextureWrap wrap); -}; - -} // namespace are - -#endif // ARE_INCLUDE_TEXTURE_SAMPLER_H -``` - -接下来我再给你一个项目中的.cpp文件,让你熟悉错误处理和日志输出等信息: -### 文件:src/utils/image_io.cpp -```cpp -/** - * @file image_io.cpp - * @brief Implementation of image I/O utilities - */ - -#include -#include -#include -#include -#include -#include - -#define STB_IMAGE_IMPLEMENTATION -#include - -#define STB_IMAGE_WRITE_IMPLEMENTATION -#include - -namespace are { - -bool ImageData::is_valid() const { - return width_ > 0 && height_ > 0 && channels_ > 0 && !data_.empty(); -} - -const uint8_t* ImageData::get_pixel(int x, int y) const { - if (x < 0 || x >= width_ || y < 0 || y >= height_) { - return nullptr; - } - - size_t index = (y * width_ + x) * channels_; - return &data_[index]; -} - -void ImageData::set_pixel(int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - if (x < 0 || x >= width_ || y < 0 || y >= height_) { - return; - } - - size_t index = (y * width_ + x) * channels_; - - data_[index + 0] = r; - data_[index + 1] = g; - data_[index + 2] = b; - - if (channels_ == 4) { - data_[index + 3] = a; - } -} - -ImageData load_image(const std::string& filename, bool flip_vertically) { - ImageData image; - - // Set flip flag - stbi_set_flip_vertically_on_load(flip_vertically ? 1 : 0); - - // Load image - int width, height, channels; - unsigned char* data = stbi_load(filename.c_str(), &width, &height, &channels, 0); - - if (!data) { - ARE_LOG_ERROR("Failed to load image: " + filename + " - " + stbi_failure_reason()); - return image; - } - - // Copy data to ImageData - image.width_ = width; - image.height_ = height; - image.channels_ = channels; - - size_t data_size = width * height * channels; - image.data_.resize(data_size); - std::memcpy(image.data_.data(), data, data_size); - - // Free stb_image data - stbi_image_free(data); - - ARE_LOG_INFO("Loaded image: " + filename + " (" + - std::to_string(width) + "x" + std::to_string(height) + - ", " + std::to_string(channels) + " channels)"); - - return image; -} - -ImageFormat detect_format(const std::string& filename) { - std::string ext; - size_t dot_pos = filename.find_last_of('.'); - - if (dot_pos != std::string::npos) { - ext = filename.substr(dot_pos + 1); - - // Convert to lowercase - std::transform(ext.begin(), ext.end(), ext.begin(), - [](unsigned char c) { return std::tolower(c); }); - } - - if (ext == "ppm") return ImageFormat::ARE_IMAGE_FORMAT_PPM; - if (ext == "bmp") return ImageFormat::ARE_IMAGE_FORMAT_BMP; - if (ext == "png") return ImageFormat::ARE_IMAGE_FORMAT_PNG; - if (ext == "jpg" || ext == "jpeg") return ImageFormat::ARE_IMAGE_FORMAT_JPG; - - // Default to PNG - return ImageFormat::ARE_IMAGE_FORMAT_PNG; -} - -bool save_image(const std::string& filename, const ImageData& data, ImageFormat format) { - if (!data.is_valid()) { - ARE_LOG_ERROR("Cannot save invalid image data"); - return false; - } - - // Auto-detect format if not specified - if (format == ImageFormat::ARE_IMAGE_FORMAT_PNG) { - format = detect_format(filename); - } - - int result = 0; - - switch (format) { - case ImageFormat::ARE_IMAGE_FORMAT_PPM: { - // Write PPM manually (stb doesn't support it) - std::ofstream file(filename, std::ios::binary); - if (!file.is_open()) { - ARE_LOG_ERROR("Failed to open file for writing: " + filename); - return false; - } - - file << "P6\n" << data.width_ << " " << data.height_ << "\n255\n"; - - for (int i = 0; i < data.width_ * data.height_; ++i) { - int idx = i * data.channels_; - file.put(data.data_[idx + 0]); // R - file.put(data.data_[idx + 1]); // G - file.put(data.data_[idx + 2]); // B - } - - file.close(); - result = 1; - break; - } - - case ImageFormat::ARE_IMAGE_FORMAT_BMP: - result = stbi_write_bmp(filename.c_str(), data.width_, data.height_, - data.channels_, data.data_.data()); - break; - - case ImageFormat::ARE_IMAGE_FORMAT_PNG: - result = stbi_write_png(filename.c_str(), data.width_, data.height_, - data.channels_, data.data_.data(), - data.width_ * data.channels_); - break; - - case ImageFormat::ARE_IMAGE_FORMAT_JPG: - result = stbi_write_jpg(filename.c_str(), data.width_, data.height_, - data.channels_, data.data_.data(), 90); - break; - } - - if (result == 0) { - ARE_LOG_ERROR("Failed to save image: " + filename); - return false; - } - - ARE_LOG_INFO("Saved image: " + filename); - return true; -} - -bool save_image(const std::string& filename, const uint8_t* pixels, - int width, int height, int channels, ImageFormat format) { - ImageData data; - data.width_ = width; - data.height_ = height; - data.channels_ = channels; - - size_t data_size = width * height * channels; - data.data_.resize(data_size); - std::memcpy(data.data_.data(), pixels, data_size); - - return save_image(filename, data, format); -} - -} // namespace are -``` -哦对了,这是我们现在的CMakeLists.txt,你可以在编写完这个模块之后编写cornell_box的测试代码和独属于Phase 5的测试代码(在CPU光追效率太低的时候使用): -```CMakeLists.txt -cmake_minimum_required(VERSION 3.15) -project(AuroraRenderingEngine VERSION 0.1.0 LANGUAGES CXX C) - -# Set C++ standard -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - -# Set C standard for GLAD -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED ON) - -# Build options -option(ARE_BUILD_SHARED "Build shared library" OFF) -option(ARE_BUILD_EXAMPLES "Build example programs" ON) -option(ARE_ENABLE_PROFILING "Enable performance profiling" ON) -option(ARE_ENABLE_DEBUG_VIS "Enable debug visualization" ON) - -# Set output directories -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) - -# Compiler flags -if(MSVC) - add_compile_options(/W4) - add_compile_definitions(_CRT_SECURE_NO_WARNINGS) - # Disable specific warnings that are too strict - add_compile_options(/wd4100) # unreferenced formal parameter -else() - add_compile_options(-Wall -Wextra -pedantic) - # Disable specific warnings - add_compile_options(-Wno-unused-parameter) -endif() - -# Find required packages -find_package(OpenGL REQUIRED) -find_package(glfw3 REQUIRED) -find_package(glm REQUIRED) - -# Try to find spdlog (system installation) -find_package(spdlog QUIET) - -if(NOT spdlog_FOUND) - message(STATUS "spdlog not found in system, using local version") - # Use local spdlog - set(SPDLOG_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/lib/spdlog/include") - if(NOT EXISTS ${SPDLOG_INCLUDE_DIR}) - message(FATAL_ERROR "spdlog not found. Please install spdlog or place it in lib/spdlog/") - endif() - add_library(spdlog INTERFACE) - target_include_directories(spdlog INTERFACE ${SPDLOG_INCLUDE_DIR}) - # spdlog compile definitions - target_compile_definitions(spdlog INTERFACE SPDLOG_COMPILED_LIB) -endif() - -# Find OpenMP (optional) -find_package(OpenMP) -if(OpenMP_CXX_FOUND) - set(ARE_USE_OPENMP ON) - add_compile_definitions(ARE_USE_OPENMP) - message(STATUS "OpenMP found and enabled") -else() - message(STATUS "OpenMP not found, multithreading will use std::thread") -endif() - -# GLAD library path -set(GLAD_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/lib/glad") -set(GLAD_SOURCE_DIR "${CMAKE_SOURCE_DIR}/lib/glad") - -if(NOT EXISTS ${GLAD_INCLUDE_DIR}) - message(FATAL_ERROR "GLAD include directory not found: ${GLAD_INCLUDE_DIR}") -endif() - -if(NOT EXISTS ${GLAD_SOURCE_DIR}) - message(FATAL_ERROR "GLAD source directory not found: ${GLAD_SOURCE_DIR}") -endif() - -# STB library path -set(STB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/lib/stb") - -if(NOT EXISTS ${STB_INCLUDE_DIR}) - message(FATAL_ERROR "STB include directory not found: ${STB_INCLUDE_DIR}") -endif() - -# Collect all source files from src/ -file(GLOB_RECURSE ARE_SOURCES - "${CMAKE_SOURCE_DIR}/src/*.cpp" - "${CMAKE_SOURCE_DIR}/src/*.c" -) - -# Collect all GLAD source files -file(GLOB GLAD_SOURCES - "${GLAD_SOURCE_DIR}/*.c" -) - -# Add GLAD sources to ARE sources -list(APPEND ARE_SOURCES ${GLAD_SOURCES}) - -# Collect all header files -file(GLOB_RECURSE ARE_HEADERS - "${CMAKE_SOURCE_DIR}/include/*.h" - "${CMAKE_SOURCE_DIR}/include/*.hpp" -) - -# Create library -if(ARE_BUILD_SHARED) - add_library(are SHARED ${ARE_SOURCES} ${ARE_HEADERS}) - target_compile_definitions(are PRIVATE ARE_BUILD_SHARED) - message(STATUS "Building shared library") -else() - add_library(are STATIC ${ARE_SOURCES} ${ARE_HEADERS}) - message(STATUS "Building static library") -endif() - -# Set target properties -set_target_properties(are PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR} - PUBLIC_HEADER "${ARE_HEADERS}" -) - -# Include directories -target_include_directories(are - PUBLIC - $ - $ - PRIVATE - ${CMAKE_SOURCE_DIR}/src - ${GLAD_INCLUDE_DIR} - ${STB_INCLUDE_DIR} -) - -# Link libraries -target_link_libraries(are - PUBLIC - OpenGL::GL - glfw - glm::glm -) - -# Link spdlog -if(spdlog_FOUND) - target_link_libraries(are PUBLIC spdlog::spdlog) -else() - target_link_libraries(are PUBLIC spdlog) - target_include_directories(are PRIVATE ${SPDLOG_INCLUDE_DIR}) -endif() - -# Link OpenMP if available -if(OpenMP_CXX_FOUND) - target_link_libraries(are PUBLIC OpenMP::OpenMP_CXX) -endif() - -# Platform-specific libraries -if(UNIX AND NOT APPLE) - target_link_libraries(are PUBLIC dl pthread) -endif() - -# Compile definitions -if(ARE_ENABLE_PROFILING) - target_compile_definitions(are PUBLIC ARE_ENABLE_PROFILING) - message(STATUS "Profiling enabled") -endif() - -if(ARE_ENABLE_DEBUG_VIS) - target_compile_definitions(are PUBLIC ARE_ENABLE_DEBUG_VIS) - message(STATUS "Debug visualization enabled") -endif() - -# Build examples -if(ARE_BUILD_EXAMPLES) - # Define helper function for creating examples - function(add_are_example EXAMPLE_NAME) - add_executable(${EXAMPLE_NAME} ${ARGN}) - target_link_libraries(${EXAMPLE_NAME} PRIVATE are) - set_target_properties(${EXAMPLE_NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin - ) - endfunction() - - # Add example subdirectories - add_subdirectory(examples/00_phase1_test) - add_subdirectory(examples/01_phase2_test) - add_subdirectory(examples/02_visual_test) - add_subdirectory(examples/02_phase3_test) - add_subdirectory(examples/03_phase4_test) - - message(STATUS "Examples will be built") -endif() - -# Installation rules -install(TARGETS are - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin - PUBLIC_HEADER DESTINATION include/are -) - -install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/are - DESTINATION include - FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp" -) - -install(DIRECTORY ${CMAKE_SOURCE_DIR}/shaders - DESTINATION share/are/shaders -) - -# Print configuration summary -message(STATUS "") -message(STATUS "========================================") -message(STATUS "Aurora Rendering Engine Configuration") -message(STATUS "========================================") -message(STATUS " Version: ${PROJECT_VERSION}") -message(STATUS " Build type: ${CMAKE_BUILD_TYPE}") -message(STATUS " Library type: ${ARE_BUILD_SHARED}") -message(STATUS " C++ standard: ${CMAKE_CXX_STANDARD}") -message(STATUS " Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") -message(STATUS "") -message(STATUS "Features:") -message(STATUS " OpenMP support: ${ARE_USE_OPENMP}") -message(STATUS " Build examples: ${ARE_BUILD_EXAMPLES}") -message(STATUS " Enable profiling: ${ARE_ENABLE_PROFILING}") -message(STATUS " Enable debug vis: ${ARE_ENABLE_DEBUG_VIS}") -message(STATUS "") -message(STATUS "Dependencies:") -message(STATUS " OpenGL: ${OPENGL_LIBRARIES}") -message(STATUS " GLFW: Found") -message(STATUS " GLM: Found") -if(spdlog_FOUND) - message(STATUS " spdlog: Found (system)") -else() - message(STATUS " spdlog: Found (local)") -endif() -message(STATUS " GLAD: ${GLAD_INCLUDE_DIR}") -message(STATUS " STB: ${STB_INCLUDE_DIR}") -message(STATUS "") -message(STATUS "Output directories:") -message(STATUS " Executables: ${CMAKE_BINARY_DIR}/bin") -message(STATUS " Libraries: ${CMAKE_BINARY_DIR}/lib") -message(STATUS "========================================") -message(STATUS "") -``` - -目前你只需要实现Phase 5所要求的文件即可,其他大部分模块已经实现。 diff --git a/examples/00_phase1_test/CMakeLists.txt b/examples/00_phase1_test/CMakeLists.txt deleted file mode 100644 index 8f8f65e..0000000 --- a/examples/00_phase1_test/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -# Phase 1 test program -# Note: add_are_example is defined in parent CMakeLists.txt - -add_are_example(phase1_test main.cpp) diff --git a/examples/00_phase1_test/main.cpp b/examples/00_phase1_test/main.cpp deleted file mode 100644 index 85121e7..0000000 --- a/examples/00_phase1_test/main.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/** - * @file main.cpp - * @brief Phase 1 verification program - * - * Tests core, platform, and utils modules. - */ - -#include -#include -#include -#include -#include - -void test_core_modules() { - std::cout << "\n=== Testing Core Modules ===" << std::endl; - - // Test config - are::AreConfig config; - config.window.width = 800; - config.window.height = 600; - config.window.title = "Phase 1 Test"; - - if (config.validate()) { - ARE_LOG_INFO("Config validation passed"); - config.print(); - } else { - ARE_LOG_ERROR("Config validation failed"); - } - - // Test profiler - ARE_PROFILE_BEGIN("test_section"); - - // Simulate some work - double sum = 0.0; - for (int i = 0; i < 1000000; ++i) { - sum += i * 0.001; - } - - ARE_PROFILE_END("test_section"); - - ARE_LOG_INFO("Profiler test completed (sum = " + std::to_string(sum) + ")"); -} - -void test_platform_modules() { - std::cout << "\n=== Testing Platform Modules ===" << std::endl; - - try { - // Create window - are::WindowConfig win_config; - win_config.width = 800; - win_config.height = 600; - win_config.title = "Phase 1 Platform Test"; - - are::Window window(win_config); - ARE_LOG_INFO("Window created successfully"); - - // Initialize OpenGL context - if (are::GLContext::initialize()) { - ARE_LOG_INFO("OpenGL context initialized"); - are::GLContext::print_info(); - } else { - ARE_LOG_ERROR("Failed to initialize OpenGL context"); - return; - } - - // Clear screen to blue - glClearColor(0.2f, 0.3f, 0.8f, 1.0f); - - // Simple render loop (5 seconds) - ARE_LOG_INFO("Running render loop for 5 seconds..."); - - double start_time = glfwGetTime(); - int frame_count = 0; - - while (!window.should_close() && (glfwGetTime() - start_time) < 5.0) { - glClear(GL_COLOR_BUFFER_BIT); - - window.swap_buffers(); - window.poll_events(); - - frame_count++; - } - - double elapsed = glfwGetTime() - start_time; - double fps = frame_count / elapsed; - - ARE_LOG_INFO("Rendered " + std::to_string(frame_count) + " frames in " + - std::to_string(elapsed) + " seconds"); - ARE_LOG_INFO("Average FPS: " + std::to_string(fps)); - - } catch (const std::exception& e) { - ARE_LOG_ERROR("Platform test failed: " + std::string(e.what())); - } -} - -void test_utils_modules() { - std::cout << "\n=== Testing Utils Modules ===" << std::endl; - - // Test math utils - are::Vec3 a(1, 0, 0); - are::Vec3 b(0, 1, 0); - are::Vec3 c(0, 0, 1); - are::Vec3 p(0.3f, 0.3f, 0.4f); - - are::Real u, v, w; - are::compute_barycentric(p, a, b, c, u, v, w); - - ARE_LOG_INFO("Barycentric coordinates: u=" + std::to_string(u) + - ", v=" + std::to_string(v) + ", w=" + std::to_string(w)); - - // Test random - are::RandomGenerator rng(12345); - - ARE_LOG_INFO("Random float [0,1): " + std::to_string(rng.random_float())); - ARE_LOG_INFO("Random float [10,20): " + std::to_string(rng.random_float(10.0f, 20.0f))); - ARE_LOG_INFO("Random int [1,100]: " + std::to_string(rng.random_int(1, 100))); - - are::Vec3 random_vec = rng.random_unit_vector(); - ARE_LOG_INFO("Random unit vector: (" + std::to_string(random_vec.x) + ", " + - std::to_string(random_vec.y) + ", " + std::to_string(random_vec.z) + ")"); - - // Test file utils - std::string test_dir = "test_output"; - if (are::create_directory(test_dir)) { - ARE_LOG_INFO("Created directory: " + test_dir); - - std::string test_file = test_dir + "/test.txt"; - std::string content = "Hello, Aurora Rendering Engine!"; - - if (are::write_string_to_file(test_file, content)) { - ARE_LOG_INFO("Wrote test file: " + test_file); - - std::string read_content = are::read_file_to_string(test_file); - if (read_content == content) { - ARE_LOG_INFO("File read/write test passed"); - } else { - ARE_LOG_ERROR("File content mismatch"); - } - } - } - - // Test image I/O (create a simple test image) - are::ImageData test_image; - test_image.width_ = 256; - test_image.height_ = 256; - test_image.channels_ = 3; - test_image.data_.resize(256 * 256 * 3); - - // Create gradient - for (int y = 0; y < 256; ++y) { - for (int x = 0; x < 256; ++x) { - int idx = (y * 256 + x) * 3; - test_image.data_[idx + 0] = static_cast(x); - test_image.data_[idx + 1] = static_cast(y); - test_image.data_[idx + 2] = static_cast((x + y) / 2); - } - } - - std::string image_file = test_dir + "/gradient.png"; - if (are::save_image(image_file, test_image)) { - ARE_LOG_INFO("Saved test image: " + image_file); - } -} - -int main() { - // Initialize engine - if (!are::initialize()) { - std::cerr << "Failed to initialize Aurora Rendering Engine" << std::endl; - return -1; - } - - ARE_LOG_INFO("Starting Phase 1 verification tests..."); - - // Run tests - test_core_modules(); - test_utils_modules(); - test_platform_modules(); - - // Print profiler results - are::Profiler::print_results(); - - ARE_LOG_INFO("All Phase 1 tests completed!"); - - // Shutdown engine - are::shutdown(); - - return 0; -} diff --git a/examples/01_hello_triangle/CMakeLists.txt b/examples/01_hello_triangle/CMakeLists.txt deleted file mode 100644 index b95b384..0000000 --- a/examples/01_hello_triangle/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# examples/01_hello_triangle/CMakeLists.txt -add_are_example(hello_triangle main.cpp) diff --git a/examples/01_phase2_test/CMakeLists.txt b/examples/01_phase2_test/CMakeLists.txt deleted file mode 100644 index eb2f04a..0000000 --- a/examples/01_phase2_test/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# Phase 2 verification example - -add_are_example(phase2_test - main.cpp -) - -# Copy to bin directory for easy execution -set_target_properties(phase2_test PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin -) diff --git a/examples/01_phase2_test/main.cpp b/examples/01_phase2_test/main.cpp deleted file mode 100644 index a0b82f0..0000000 --- a/examples/01_phase2_test/main.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/** - * @file main.cpp - * @brief Phase 2 verification program - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -using namespace are; - -// Test result tracking -struct TestResult { - std::string name; - bool passed; - std::string message; -}; - -std::vector test_results; - -void report_test(const std::string& name, bool passed, const std::string& message = "") { - test_results.push_back({name, passed, message}); - if (passed) { - ARE_LOG_INFO("✓ " + name); - } else { - ARE_LOG_ERROR("✗ " + name + ": " + message); - } -} - -// Test 1: Vertex operations -void test_vertex() { - Vertex v1(Vec3(1, 2, 3)); - Vertex v2(Vec3(4, 5, 6), Vec3(0, 1, 0)); - Vertex v3 = Vertex::lerp(v1, v2, 0.5f); - - bool passed = glm::length(v3.position_ - Vec3(2.5f, 3.5f, 4.5f)) < are_epsilon; - report_test("Vertex interpolation", passed); -} - -// Test 2: AABB operations -void test_aabb() { - AABB aabb1(Vec3(-1, -1, -1), Vec3(1, 1, 1)); - AABB aabb2(Vec3(0, 0, 0), Vec3(2, 2, 2)); - - bool test1 = aabb1.is_valid(); - bool test2 = aabb1.contains(Vec3(0, 0, 0)); - bool test3 = aabb1.intersects(aabb2); - bool test4 = aabb1.longest_axis() == 0; // All axes equal - - AABB merged = AABB::merge(aabb1, aabb2); - bool test5 = merged.contains(Vec3(-1, -1, -1)) && merged.contains(Vec3(2, 2, 2)); - - report_test("AABB validity", test1); - report_test("AABB contains point", test2); - report_test("AABB intersection", test3); - report_test("AABB merge", test5); -} - -// Test 3: Triangle operations -void test_triangle() { - Vertex v0(Vec3(0, 0, 0), Vec3(0, 0, 1)); - Vertex v1(Vec3(1, 0, 0), Vec3(0, 0, 1)); - Vertex v2(Vec3(0, 1, 0), Vec3(0, 0, 1)); - - Triangle tri(v0, v1, v2); - - Vec3 centroid = tri.centroid(); - bool test1 = glm::length(centroid - Vec3(1.0f/3.0f, 1.0f/3.0f, 0.0f)) < are_epsilon; - - Vec3 normal = tri.normal(); - bool test2 = glm::length(normal - Vec3(0, 0, 1)) < are_epsilon; - - Real area = tri.area(); - bool test3 = std::abs(area - 0.5f) < are_epsilon; - - AABB aabb = tri.compute_aabb(); - bool test4 = aabb.contains(Vec3(0, 0, 0)) && aabb.contains(Vec3(1, 0, 0)); - - report_test("Triangle centroid", test1); - report_test("Triangle normal", test2); - report_test("Triangle area", test3); - report_test("Triangle AABB", test4); -} - -// Test 4: Ray-Triangle intersection -void test_ray_triangle_intersection() { - Vertex v0(Vec3(0, 0, 0), Vec3(0, 0, 1)); - Vertex v1(Vec3(1, 0, 0), Vec3(0, 0, 1)); - Vertex v2(Vec3(0, 1, 0), Vec3(0, 0, 1)); - - Triangle tri(v0, v1, v2); - - // Ray hitting the triangle - Ray ray1(Vec3(0.25f, 0.25f, -1.0f), Vec3(0, 0, 1)); - HitRecord hit1; - bool test1 = tri.intersect(ray1, hit1); - - // Ray missing the triangle - Ray ray2(Vec3(2, 2, -1), Vec3(0, 0, 1)); - HitRecord hit2; - bool test2 = !tri.intersect(ray2, hit2); - - report_test("Ray-Triangle hit", test1); - report_test("Ray-Triangle miss", test2); -} - -// Test 5: Transform operations -void test_transform() { - Transform t1 = Transform::translate(Vec3(1, 2, 3)); - Transform t2 = Transform::rotate(Vec3(0, are_pi / 2, 0)); - Transform t3 = Transform::scale(Vec3(2, 2, 2)); - - Vec3 point = Vec3(1, 0, 0); - Vec3 transformed = t1.transform_point(point); - bool test1 = glm::length(transformed - Vec3(2, 2, 3)) < are_epsilon; - - Vec3 scaled = t3.transform_point(point); - bool test2 = glm::length(scaled - Vec3(2, 0, 0)) < are_epsilon; - - report_test("Transform translation", test1); - report_test("Transform scale", test2); -} - -// Test 6: Camera operations -void test_camera() { - Camera camera(Vec3(0, 0, 5), Vec3(0, 0, 0)); - camera.set_perspective(45.0f, 16.0f / 9.0f, 0.1f, 100.0f); - - Vec3 forward = camera.get_forward(); - bool test1 = glm::length(forward - Vec3(0, 0, -1)) < are_epsilon; - - Vec3 origin, direction; - camera.generate_ray(0.5f, 0.5f, origin, direction); - bool test2 = glm::length(origin - Vec3(0, 0, 5)) < are_epsilon; - bool test3 = glm::length(direction - Vec3(0, 0, -1)) < 0.1f; // Approximate - - report_test("Camera forward vector", test1); - report_test("Camera ray generation origin", test2); - report_test("Camera ray generation direction", test3); -} - -// Test 7: Mesh operations -void test_mesh() { - std::vector vertices = { - Vertex(Vec3(0, 0, 0), Vec3(0, 0, 1)), - Vertex(Vec3(1, 0, 0), Vec3(0, 0, 1)), - Vertex(Vec3(0, 1, 0), Vec3(0, 0, 1)) - }; - - std::vector indices = {0, 1, 2}; - - Mesh mesh(vertices, indices); - - bool test1 = mesh.get_vertex_count() == 3; - bool test2 = mesh.get_triangle_count() == 1; - bool test3 = mesh.get_aabb().is_valid(); - - Vertex v0, v1, v2; - bool test4 = mesh.get_triangle(0, v0, v1, v2); - - report_test("Mesh vertex count", test1); - report_test("Mesh triangle count", test2); - report_test("Mesh AABB", test3); - report_test("Mesh get triangle", test4); -} - -// Test 8: Material operations -void test_material() { - Material mat; - mat.set_albedo(Vec3(0.8f, 0.2f, 0.1f)); - mat.set_metallic(0.5f); - mat.set_roughness(0.3f); - mat.set_emissive(Vec3(1.0f, 0.5f, 0.0f)); - - bool test1 = glm::length(mat.get_albedo() - Vec3(0.8f, 0.2f, 0.1f)) < are_epsilon; - bool test2 = std::abs(mat.get_metallic() - 0.5f) < are_epsilon; - bool test3 = mat.is_emissive(); - - mat.set_albedo_map("textures/albedo.png"); - bool test4 = mat.has_albedo_map(); - - report_test("Material albedo", test1); - report_test("Material metallic", test2); - report_test("Material emissive", test3); - report_test("Material texture map", test4); -} - -// Test 9: Light operations -void test_lights() { - // Directional light - DirectionalLight dir_light(Vec3(0, -1, 0), Vec3(1, 1, 1), 1.0f); - bool test1 = dir_light.affects_point(Vec3(100, 100, 100)); - - // Point light - PointLight point_light(Vec3(0, 0, 0), Vec3(1, 1, 1), 1.0f, 10.0f); - bool test2 = point_light.affects_point(Vec3(5, 0, 0)); - bool test3 = !point_light.affects_point(Vec3(20, 0, 0)); - - // Spot light - SpotLight spot_light(Vec3(0, 0, 0), Vec3(0, 0, -1), 30.0f, 45.0f); - bool test4 = spot_light.affects_point(Vec3(0, 0, -5)); - - report_test("Directional light affects all points", test1); - report_test("Point light range (inside)", test2); - report_test("Point light range (outside)", test3); - report_test("Spot light cone", test4); -} - -// Test 10: SceneManager operations -void test_scene_manager() { - SceneManager scene; - - // Add mesh - std::vector vertices = { - Vertex(Vec3(0, 0, 0)), - Vertex(Vec3(1, 0, 0)), - Vertex(Vec3(0, 1, 0)) - }; - std::vector indices = {0, 1, 2}; - Mesh mesh(vertices, indices); - - MeshHandle mesh_handle = scene.add_mesh(mesh); - bool test1 = mesh_handle != are_invalid_handle; - bool test2 = scene.get_mesh_count() == 1; - - // Add material - Material mat; - MaterialHandle mat_handle = scene.add_material(mat); - bool test3 = mat_handle != are_invalid_handle; - bool test4 = scene.get_material_count() == 1; - - // Add light - auto light = std::make_shared(); - LightHandle light_handle = scene.add_light(light); - bool test5 = light_handle != are_invalid_handle; - bool test6 = scene.get_light_count() == 1; - - // Test dirty flag - bool test7 = scene.is_dirty(); - scene.clear_dirty(); - bool test8 = !scene.is_dirty(); - - // Remove mesh - scene.remove_mesh(mesh_handle); - bool test9 = scene.get_mesh_count() == 0; - - report_test("SceneManager add mesh", test1); - report_test("SceneManager mesh count", test2); - report_test("SceneManager add material", test3); - report_test("SceneManager material count", test4); - report_test("SceneManager add light", test5); - report_test("SceneManager light count", test6); - report_test("SceneManager dirty flag (set)", test7); - report_test("SceneManager dirty flag (clear)", test8); - report_test("SceneManager remove mesh", test9); -} - -int main() { - // Initialize logger - Logger::init(LogLevel::ARE_LOG_INFO); - - ARE_LOG_INFO("========================================"); - ARE_LOG_INFO("Phase 2 Verification Program"); - ARE_LOG_INFO("========================================"); - - // Run all tests - test_vertex(); - test_aabb(); - test_triangle(); - test_ray_triangle_intersection(); - test_transform(); - test_camera(); - test_mesh(); - test_material(); - test_lights(); - test_scene_manager(); - - // Print summary - ARE_LOG_INFO("========================================"); - ARE_LOG_INFO("Test Summary"); - ARE_LOG_INFO("========================================"); - - int passed = 0; - int failed = 0; - - for (const auto& result : test_results) { - if (result.passed) { - ++passed; - } else { - ++failed; - } - } - - ARE_LOG_INFO("Total tests: " + std::to_string(test_results.size())); - ARE_LOG_INFO("Passed: " + std::to_string(passed)); - ARE_LOG_INFO("Failed: " + std::to_string(failed)); - - if (failed == 0) { - ARE_LOG_INFO("========================================"); - ARE_LOG_INFO("✓ All Phase 2 tests passed!"); - ARE_LOG_INFO("========================================"); - } else { - ARE_LOG_ERROR("========================================"); - ARE_LOG_ERROR("✗ Some tests failed. Please review."); - ARE_LOG_ERROR("========================================"); - } - - Logger::shutdown(); - - return failed == 0 ? 0 : 1; -} diff --git a/examples/02_cornell_box/CMakeLists.txt b/examples/02_cornell_box/CMakeLists.txt deleted file mode 100644 index 67aed32..0000000 --- a/examples/02_cornell_box/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# examples/02_cornell_box/CMakeLists.txt -add_are_example(cornell_box main.cpp) diff --git a/examples/02_phase3_test/CMakeLists.txt b/examples/02_phase3_test/CMakeLists.txt deleted file mode 100644 index 775859e..0000000 --- a/examples/02_phase3_test/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Phase 3 verification example - -add_are_example(phase3_test - main.cpp -) - -# Copy to bin directory for easy execution -set_target_properties(phase3_test PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin -) - -# Copy shaders to build directory -add_custom_command(TARGET phase3_test POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_SOURCE_DIR}/shaders - ${CMAKE_BINARY_DIR}/bin/shaders - COMMENT "Copying shaders to build directory" -) diff --git a/examples/02_phase3_test/main.cpp b/examples/02_phase3_test/main.cpp deleted file mode 100644 index 9ed82ad..0000000 --- a/examples/02_phase3_test/main.cpp +++ /dev/null @@ -1,478 +0,0 @@ -/** - * @file main.cpp - * @brief Phase 3 verification program - G-Buffer rendering test - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "../lib/glad/glad/glad.h" -#include - -using namespace are; - -/** - * @brief Create a simple cube mesh - */ -Mesh create_cube_mesh() { - std::vector vertices = { - // Front face - Vertex(Vec3(-0.5f, -0.5f, 0.5f), Vec3(0, 0, 1), Vec2(0, 0)), - Vertex(Vec3(0.5f, -0.5f, 0.5f), Vec3(0, 0, 1), Vec2(1, 0)), - Vertex(Vec3(0.5f, 0.5f, 0.5f), Vec3(0, 0, 1), Vec2(1, 1)), - Vertex(Vec3(-0.5f, 0.5f, 0.5f), Vec3(0, 0, 1), Vec2(0, 1)), - - // Back face - Vertex(Vec3(0.5f, -0.5f, -0.5f), Vec3(0, 0, -1), Vec2(0, 0)), - Vertex(Vec3(-0.5f, -0.5f, -0.5f), Vec3(0, 0, -1), Vec2(1, 0)), - Vertex(Vec3(-0.5f, 0.5f, -0.5f), Vec3(0, 0, -1), Vec2(1, 1)), - Vertex(Vec3(0.5f, 0.5f, -0.5f), Vec3(0, 0, -1), Vec2(0, 1)), - - // Top face - Vertex(Vec3(-0.5f, 0.5f, 0.5f), Vec3(0, 1, 0), Vec2(0, 0)), - Vertex(Vec3(0.5f, 0.5f, 0.5f), Vec3(0, 1, 0), Vec2(1, 0)), - Vertex(Vec3(0.5f, 0.5f, -0.5f), Vec3(0, 1, 0), Vec2(1, 1)), - Vertex(Vec3(-0.5f, 0.5f, -0.5f), Vec3(0, 1, 0), Vec2(0, 1)), - - // Bottom face - Vertex(Vec3(-0.5f, -0.5f, -0.5f), Vec3(0, -1, 0), Vec2(0, 0)), - Vertex(Vec3(0.5f, -0.5f, -0.5f), Vec3(0, -1, 0), Vec2(1, 0)), - Vertex(Vec3(0.5f, -0.5f, 0.5f), Vec3(0, -1, 0), Vec2(1, 1)), - Vertex(Vec3(-0.5f, -0.5f, 0.5f), Vec3(0, -1, 0), Vec2(0, 1)), - - // Right face - Vertex(Vec3(0.5f, -0.5f, 0.5f), Vec3(1, 0, 0), Vec2(0, 0)), - Vertex(Vec3(0.5f, -0.5f, -0.5f), Vec3(1, 0, 0), Vec2(1, 0)), - Vertex(Vec3(0.5f, 0.5f, -0.5f), Vec3(1, 0, 0), Vec2(1, 1)), - Vertex(Vec3(0.5f, 0.5f, 0.5f), Vec3(1, 0, 0), Vec2(0, 1)), - - // Left face - Vertex(Vec3(-0.5f, -0.5f, -0.5f), Vec3(-1, 0, 0), Vec2(0, 0)), - Vertex(Vec3(-0.5f, -0.5f, 0.5f), Vec3(-1, 0, 0), Vec2(1, 0)), - Vertex(Vec3(-0.5f, 0.5f, 0.5f), Vec3(-1, 0, 0), Vec2(1, 1)), - Vertex(Vec3(-0.5f, 0.5f, -0.5f), Vec3(-1, 0, 0), Vec2(0, 1)) - }; - - std::vector indices = { - // Front - 0, 1, 2, 2, 3, 0, - // Back - 4, 5, 6, 6, 7, 4, - // Top - 8, 9, 10, 10, 11, 8, - // Bottom - 12, 13, 14, 14, 15, 12, - // Right - 16, 17, 18, 18, 19, 16, - // Left - 20, 21, 22, 22, 23, 20 - }; - - return Mesh(vertices, indices); -} - -/** - * @brief Create a simple triangle mesh (positioned in front of cube) - */ -Mesh create_triangle_mesh() { - std::vector vertices = { - Vertex(Vec3(-0.5f, -0.5f, 1.0f), Vec3(0, 0, 1), Vec2(0, 0)), // Z = 1.0 - Vertex(Vec3( 0.5f, -0.5f, 1.0f), Vec3(0, 0, 1), Vec2(1, 0)), // Z = 1.0 - Vertex(Vec3( 0.0f, 0.5f, 1.0f), Vec3(0, 0, 1), Vec2(0.5f, 1)) // Z = 1.0 - }; - - std::vector indices = {0, 1, 2}; - - return Mesh(vertices, indices); -} - -/** - * @brief Fullscreen quad shader for G-Buffer visualization - */ -const char *fullscreen_vert_source = R"( -#version 430 core -layout(location = 0) in vec2 a_position; -layout(location = 1) in vec2 a_texcoord; -out vec2 v_texcoord; -void main() { - v_texcoord = a_texcoord; - gl_Position = vec4(a_position, 0.0, 1.0); -} -)"; - -const char *visualize_frag_source = R"( -#version 430 core -in vec2 v_texcoord; -out vec4 frag_color; - -uniform sampler2D u_texture; -uniform int u_mode; // 0=position, 1=normal, 2=albedo, 3=material - -void main() { - vec4 value = texture(u_texture, v_texcoord); - - if (u_mode == 0) { - // Position: normalize to [0,1] range for visualization - frag_color = vec4(value.xyz * 0.5 + 0.5, 1.0); - } else if (u_mode == 1) { - // Normal: normalize to [0,1] range - frag_color = vec4(value.xyz * 0.5 + 0.5, 1.0); - } else if (u_mode == 2) { - // Albedo: direct output - frag_color = vec4(value.rgb, 1.0); - } else if (u_mode == 3) { - // Material: roughness in R, AO in G - frag_color = vec4(value.r, value.g, 0.0, 1.0); - } else { - frag_color = value; - } -} -)"; - -/** - * @brief Create fullscreen quad VAO - */ -uint32_t create_fullscreen_quad() { - float vertices[] = { - // Position // Texcoord - -1.0f, -1.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 0.0f, 1.0f - }; - - uint32_t indices[] = { 0, 1, 2, 2, 3, 0 }; - - uint32_t vao, vbo, ebo; - - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glGenBuffers(1, &ebo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)0); - - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)(2 * sizeof(float))); - - glBindVertexArray(0); - - return vao; -} - -int main() { - // Initialize logger - Logger::init(LogLevel::ARE_LOG_DEBUG); - Profiler::init(); - - ARE_LOG_INFO("========================================"); - ARE_LOG_INFO("Phase 3 Verification Program"); - ARE_LOG_INFO("G-Buffer Rendering Test"); - ARE_LOG_INFO("========================================"); - - // Create window configuration - WindowConfig window_config; - window_config.width = 800; - window_config.height = 600; - window_config.title = "Phase 3 - G-Buffer Test"; - window_config.vsync = true; - - // Create window - Window window(window_config); - - // Initialize OpenGL - if (!GLContext::initialize()) { - ARE_LOG_CRITICAL("Failed to initialize OpenGL context"); - return -1; - } - - GLContext::print_info(); - - // Get shader directory (relative to executable) - std::string shader_dir = "shaders/"; - - // Create rasterizer - int fb_width, fb_height; - window.get_framebuffer_size(fb_width, fb_height); - Rasterizer rasterizer(fb_width, fb_height); - - // Initialize shaders - // First, create G-Buffer shader manually for testing - ShaderProgram gbuffer_shader; - - // Try to load from file first - bool shader_loaded = false; - if (file_exists(shader_dir + "gbuffer/gbuffer.vert") && file_exists(shader_dir + "gbuffer/gbuffer.frag")) { - if (gbuffer_shader.load_shader(ShaderType::ARE_SHADER_VERTEX, shader_dir + "gbuffer/gbuffer.vert") && gbuffer_shader.load_shader(ShaderType::ARE_SHADER_FRAGMENT, shader_dir + "gbuffer/gbuffer.frag") && gbuffer_shader.link()) { - shader_loaded = true; - ARE_LOG_INFO("Loaded G-Buffer shaders from files"); - } - } - - // Fallback to embedded shaders - if (!shader_loaded) { - ARE_LOG_WARN("Shader files not found, using embedded shaders"); - - const char *gbuffer_vert = R"( -#version 430 core -layout(location = 0) in vec3 a_position; -layout(location = 1) in vec3 a_normal; -layout(location = 2) in vec2 a_texcoord; -layout(location = 3) in vec3 a_tangent; - -uniform mat4 u_model; -uniform mat4 u_view; -uniform mat4 u_projection; -uniform mat3 u_normal_matrix; - -out vec3 v_world_position; -out vec3 v_world_normal; -out vec2 v_texcoord; -out vec3 v_world_tangent; - -void main() { - vec4 world_pos = u_model * vec4(a_position, 1.0); - v_world_position = world_pos.xyz; - v_world_normal = normalize(u_normal_matrix * a_normal); - v_world_tangent = normalize(u_normal_matrix * a_tangent); - v_texcoord = a_texcoord; - gl_Position = u_projection * u_view * world_pos; -} -)"; - - const char *gbuffer_frag = R"( -#version 430 core -in vec3 v_world_position; -in vec3 v_world_normal; -in vec2 v_texcoord; -in vec3 v_world_tangent; - -uniform vec3 u_albedo; -uniform float u_metallic; -uniform float u_roughness; - -layout(location = 0) out vec3 g_position; -layout(location = 1) out vec3 g_normal; -layout(location = 2) out vec4 g_albedo_metallic; -layout(location = 3) out vec2 g_roughness_ao; - -void main() { - g_position = v_world_position; - g_normal = normalize(v_world_normal); - g_albedo_metallic = vec4(u_albedo, u_metallic); - g_roughness_ao = vec2(u_roughness, 1.0); -} -)"; - - if (!gbuffer_shader.compile_shader(ShaderType::ARE_SHADER_VERTEX, gbuffer_vert) || !gbuffer_shader.compile_shader(ShaderType::ARE_SHADER_FRAGMENT, gbuffer_frag) || !gbuffer_shader.link()) { - ARE_LOG_CRITICAL("Failed to compile embedded G-Buffer shaders"); - return -1; - } - } - - // Create visualization shader - ShaderProgram vis_shader; - if (!vis_shader.compile_shader(ShaderType::ARE_SHADER_VERTEX, fullscreen_vert_source) || !vis_shader.compile_shader(ShaderType::ARE_SHADER_FRAGMENT, visualize_frag_source) || !vis_shader.link()) { - ARE_LOG_CRITICAL("Failed to compile visualization shaders"); - return -1; - } - - // Create fullscreen quad - uint32_t fullscreen_quad_vao = create_fullscreen_quad(); - - // Create scene - SceneManager scene; - - // Create materials - Material red_material; - red_material.set_albedo(Vec3(0.8f, 0.2f, 0.2f)); - red_material.set_metallic(0.0f); - red_material.set_roughness(0.5f); - MaterialHandle red_mat_handle = scene.add_material(red_material); - - Material green_material; - green_material.set_albedo(Vec3(0.2f, 0.8f, 0.2f)); - green_material.set_metallic(0.5f); - green_material.set_roughness(0.3f); - MaterialHandle green_mat_handle = scene.add_material(green_material); - - // Create meshes - Mesh cube = create_cube_mesh(); - cube.set_material(red_mat_handle); - cube.compute_tangents(); - - Mesh triangle = create_triangle_mesh(); - triangle.set_material(green_mat_handle); - triangle.compute_tangents(); - - // Upload meshes to GPU - rasterizer.upload_mesh(cube); - rasterizer.upload_mesh(triangle); - - // Add meshes to scene - scene.add_mesh(cube); - scene.add_mesh(triangle); - - // Create camera - Camera camera(Vec3(0, 0, 3), Vec3(0, 0, 0)); - camera.set_perspective(45.0f, static_cast(fb_width) / fb_height, 0.1f, 100.0f); - - // Visualization mode (0=position, 1=normal, 2=albedo, 3=material) - int vis_mode = 2; // Start with albedo - - ARE_LOG_INFO("Controls:"); - ARE_LOG_INFO(" 1 - View Position buffer"); - ARE_LOG_INFO(" 2 - View Normal buffer"); - ARE_LOG_INFO(" 3 - View Albedo buffer"); - ARE_LOG_INFO(" 4 - View Material buffer (Roughness/AO)"); - ARE_LOG_INFO(" ESC - Exit"); - - // Main loop - float time = 0.0f; - while (!window.should_close()) { - ARE_PROFILE_SCOPE("Frame"); - - // Poll events - window.poll_events(); - - // Handle input - if (window.is_key_pressed(256)) { // ESC - window.set_should_close(true); - } - if (window.is_key_pressed(49)) - vis_mode = 0; // 1 - Position - if (window.is_key_pressed(50)) - vis_mode = 1; // 2 - Normal - if (window.is_key_pressed(51)) - vis_mode = 2; // 3 - Albedo - if (window.is_key_pressed(52)) - vis_mode = 3; // 4 - Material - - // Update camera position (orbit around origin) - time += 0.016f; - float cam_x = std::sin(time * 0.5f) * 3.0f; - float cam_z = std::cos(time * 0.5f) * 3.0f; - camera.set_position(Vec3(cam_x, 1.5f, cam_z)); - camera.set_target(Vec3(0, 0, 0)); - - // Render to G-Buffer - { - ARE_PROFILE_SCOPE("Render G-Buffer"); - - // Manually render since we're using our own shader - GBuffer &gbuffer = rasterizer.get_gbuffer(); - gbuffer.bind(); - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - - gbuffer_shader.use(); - gbuffer_shader.set_uniform("u_view", camera.get_view_matrix()); - gbuffer_shader.set_uniform("u_projection", camera.get_projection_matrix()); - - // Render all meshes - const auto &meshes = scene.get_all_meshes(); - const auto &materials = scene.get_all_materials(); - - for (const auto &mesh : meshes) { - if (!mesh.has_gpu_resources()) - continue; - - Mat4 model = Mat4(1.0f); - gbuffer_shader.set_uniform("u_model", model); - - Mat3 normal_matrix = glm::transpose(glm::inverse(Mat3(model))); - gbuffer_shader.set_uniform("u_normal_matrix", normal_matrix); - - MaterialHandle mat_handle = mesh.get_material(); - if (mat_handle != are_invalid_handle && mat_handle <= materials.size()) { - const Material &mat = materials[mat_handle - 1]; - gbuffer_shader.set_uniform("u_albedo", mat.get_albedo()); - gbuffer_shader.set_uniform("u_metallic", mat.get_metallic()); - gbuffer_shader.set_uniform("u_roughness", mat.get_roughness()); - } else { - gbuffer_shader.set_uniform("u_albedo", Vec3(0.8f)); - gbuffer_shader.set_uniform("u_metallic", 0.0f); - gbuffer_shader.set_uniform("u_roughness", 0.5f); - } - - glBindVertexArray(mesh.get_vao()); - glDrawElements(GL_TRIANGLES, - static_cast(mesh.get_index_count()), - GL_UNSIGNED_INT, - nullptr); - } - - glBindVertexArray(0); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - - gbuffer.unbind(); - } - - // Visualize G-Buffer - { - ARE_PROFILE_SCOPE("Visualize G-Buffer"); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, fb_width, fb_height); - glClearColor(0.1f, 0.1f, 0.1f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - - vis_shader.use(); - vis_shader.set_uniform("u_mode", vis_mode); - vis_shader.set_uniform("u_texture", 0); - - // Bind appropriate G-Buffer texture - GBuffer &gbuffer = rasterizer.get_gbuffer(); - gbuffer.bind_texture(vis_mode, 0); - - glBindVertexArray(fullscreen_quad_vao); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); - glBindVertexArray(0); - } - - // Swap buffers - window.swap_buffers(); - } - - // Cleanup - glDeleteVertexArrays(1, &fullscreen_quad_vao); - - // Print profiling results - Profiler::print_results(); - - ARE_LOG_INFO("========================================"); - ARE_LOG_INFO("Phase 3 test completed successfully!"); - ARE_LOG_INFO("========================================"); - - Profiler::shutdown(); - Logger::shutdown(); - - return 0; -} diff --git a/examples/02_visual_test/CMakeLists.txt b/examples/02_visual_test/CMakeLists.txt deleted file mode 100644 index 36b99be..0000000 --- a/examples/02_visual_test/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# Phase 2 visual verification example - -add_are_example(visual_test - main.cpp -) - -# Copy to bin directory -set_target_properties(visual_test PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin -) diff --git a/examples/02_visual_test/main.cpp b/examples/02_visual_test/main.cpp deleted file mode 100644 index 0ed0014..0000000 --- a/examples/02_visual_test/main.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/** - * @file main.cpp - * @brief Visual verification using software rasterization - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define STB_IMAGE_WRITE_IMPLEMENTATION -#include "../lib/stb/stb_image_write.h" - -#include -#include -#include - -using namespace are; - -// Simple framebuffer -struct Framebuffer { - int width; - int height; - std::vector pixels; // RGB format - - Framebuffer(int w, int h) : width(w), height(h) { - pixels.resize(w * h * 3, 0); - } - - void set_pixel(int x, int y, uint8_t r, uint8_t g, uint8_t b) { - if (x < 0 || x >= width || y < 0 || y >= height) - return; - int index = (y * width + x) * 3; - pixels[index + 0] = r; - pixels[index + 1] = g; - pixels[index + 2] = b; - } - - void set_pixel(int x, int y, const Vec3 &color) { - uint8_t r = static_cast(std::min(color.x * 255.0f, 255.0f)); - uint8_t g = static_cast(std::min(color.y * 255.0f, 255.0f)); - uint8_t b = static_cast(std::min(color.z * 255.0f, 255.0f)); - set_pixel(x, y, r, g, b); - } - - bool save(const std::string &filename) { - return stbi_write_png(filename.c_str(), width, height, 3, - pixels.data(), width * 3) - != 0; - } -}; - -// Simple shading function -Vec3 shade_hit(const HitRecord &hit, const Vec3 &light_dir) { - // Lambertian shading - float ndotl = std::max(0.0f, glm::dot(hit.normal_, light_dir)); - - // Base color based on normal (for visualization) - Vec3 base_color = (hit.normal_ + Vec3(1.0f)) * 0.5f; - - // Apply lighting - Vec3 ambient = base_color * 0.2f; - Vec3 diffuse = base_color * ndotl * 0.8f; - - return ambient + diffuse; -} - -// Render a single triangle -void render_triangle(Framebuffer &fb, const Triangle &tri, Camera &camera) { - Vec3 light_dir = glm::normalize(Vec3(0.5f, 1.0f, 0.5f)); - - for (int y = 0; y < fb.height; ++y) { - for (int x = 0; x < fb.width; ++x) { - // Generate ray - float u = (x + 0.5f) / fb.width; - float v = (y + 0.5f) / fb.height; - - Vec3 origin, direction; - camera.generate_ray(u, v, origin, direction); - Ray ray(origin, direction); - - // Test intersection - HitRecord hit; - if (tri.intersect(ray, hit)) { - Vec3 color = shade_hit(hit, light_dir); - fb.set_pixel(x, y, color); - } else { - // Background gradient - Vec3 bg_color = Vec3(0.5f, 0.7f, 1.0f) * (1.0f - v) + Vec3(1.0f, 1.0f, 1.0f) * v; - fb.set_pixel(x, y, bg_color); - } - } - } -} - -// Render multiple triangles (mesh) -void render_mesh(Framebuffer &fb, const Mesh &mesh, Camera &camera) { - Vec3 light_dir = glm::normalize(Vec3(0.5f, 1.0f, 0.5f)); - - for (int y = 0; y < fb.height; ++y) { - for (int x = 0; x < fb.width; ++x) { - // Generate ray - float u = (x + 0.5f) / fb.width; - float v = (y + 0.5f) / fb.height; - - Vec3 origin, direction; - camera.generate_ray(u, v, origin, direction); - Ray ray(origin, direction); - - // Test intersection with all triangles - HitRecord closest_hit; - closest_hit.t_ = ray.t_max_; - bool hit_any = false; - - for (size_t i = 0; i < mesh.get_triangle_count(); ++i) { - Vertex v0, v1, v2; - if (mesh.get_triangle(i, v0, v1, v2)) { - Triangle tri(v0, v1, v2); - HitRecord hit; - if (tri.intersect(ray, hit) && hit.t_ < closest_hit.t_) { - closest_hit = hit; - hit_any = true; - } - } - } - - if (hit_any) { - Vec3 color = shade_hit(closest_hit, light_dir); - fb.set_pixel(x, y, color); - } else { - // Background gradient - Vec3 bg_color = Vec3(0.5f, 0.7f, 1.0f) * (1.0f - v) + Vec3(1.0f, 1.0f, 1.0f) * v; - fb.set_pixel(x, y, bg_color); - } - } - } -} - -int main() { - Logger::init(LogLevel::ARE_LOG_INFO); - - ARE_LOG_INFO("========================================"); - ARE_LOG_INFO("Phase 2 Visual Verification"); - ARE_LOG_INFO("========================================"); - - const int width = 800; - const int height = 600; - - // Test 1: Single triangle - { - ARE_LOG_INFO("Rendering single triangle..."); - - Framebuffer fb(width, height); - - // Create triangle - Vertex v0(Vec3(-1, -1, 0), Vec3(0, 0, 1)); - Vertex v1(Vec3(1, -1, 0), Vec3(0, 0, 1)); - Vertex v2(Vec3(0, 1, 0), Vec3(0, 0, 1)); - Triangle tri(v0, v1, v2); - - // Setup camera - Camera camera(Vec3(0, 0, 3), Vec3(0, 0, 0)); - camera.set_perspective(45.0f, (float)width / height, 0.1f, 100.0f); - - // Render - render_triangle(fb, tri, camera); - - // Save - if (fb.save("output_triangle.png")) { - ARE_LOG_INFO("✓ Saved: output_triangle.png"); - } else { - ARE_LOG_ERROR("✗ Failed to save output_triangle.png"); - } - } - - // Test 2: Colored triangle (using normals) - { - ARE_LOG_INFO("Rendering colored triangle..."); - - Framebuffer fb(width, height); - - // Create triangle with different normals for each vertex - Vertex v0(Vec3(-1, -1, 0), Vec3(1, 0, 0)); // Red - Vertex v1(Vec3(1, -1, 0), Vec3(0, 1, 0)); // Green - Vertex v2(Vec3(0, 1, 0), Vec3(0, 0, 1)); // Blue - Triangle tri(v0, v1, v2); - - Camera camera(Vec3(0, 0, 3), Vec3(0, 0, 0)); - camera.set_perspective(45.0f, (float)width / height, 0.1f, 100.0f); - - render_triangle(fb, tri, camera); - - if (fb.save("output_colored_triangle.png")) { - ARE_LOG_INFO("✓ Saved: output_colored_triangle.png"); - } else { - ARE_LOG_ERROR("✗ Failed to save output_colored_triangle.png"); - } - } - - // Test 3: Cube (mesh with multiple triangles) - { - ARE_LOG_INFO("Rendering cube..."); - - Framebuffer fb(width, height); - - // Create cube vertices - std::vector vertices = { - // Front face - Vertex(Vec3(-1, -1, 1), Vec3(0, 0, 1)), - Vertex(Vec3(1, -1, 1), Vec3(0, 0, 1)), - Vertex(Vec3(1, 1, 1), Vec3(0, 0, 1)), - Vertex(Vec3(-1, 1, 1), Vec3(0, 0, 1)), - // Back face - Vertex(Vec3(-1, -1, -1), Vec3(0, 0, -1)), - Vertex(Vec3(1, -1, -1), Vec3(0, 0, -1)), - Vertex(Vec3(1, 1, -1), Vec3(0, 0, -1)), - Vertex(Vec3(-1, 1, -1), Vec3(0, 0, -1)), - }; - - // Create cube indices - std::vector indices = { - // Front - 0, 1, 2, 2, 3, 0, - // Right - 1, 5, 6, 6, 2, 1, - // Back - 5, 4, 7, 7, 6, 5, - // Left - 4, 0, 3, 3, 7, 4, - // Top - 3, 2, 6, 6, 7, 3, - // Bottom - 4, 5, 1, 1, 0, 4 - }; - - Mesh cube(vertices, indices); - - // Setup camera (slightly angled view) - Camera camera(Vec3(3, 2, 4), Vec3(0, 0, 0)); - camera.set_perspective(45.0f, (float)width / height, 0.1f, 100.0f); - - // Render - render_mesh(fb, cube, camera); - - if (fb.save("output_cube.png")) { - ARE_LOG_INFO("✓ Saved: output_cube.png"); - } else { - ARE_LOG_ERROR("✗ Failed to save output_cube.png"); - } - } - - // Test 4: Cornell Box (corrected) - { - ARE_LOG_INFO("Rendering Cornell Box..."); - - Framebuffer fb(width, height); - - std::vector vertices; - std::vector indices; - - // Helper function to add a quad - auto add_quad = [&](const Vec3 &v0, const Vec3 &v1, const Vec3 &v2, const Vec3 &v3, const Vec3 &normal) { - unsigned int base = vertices.size(); - vertices.push_back(Vertex(v0, normal)); - vertices.push_back(Vertex(v1, normal)); - vertices.push_back(Vertex(v2, normal)); - vertices.push_back(Vertex(v3, normal)); - indices.insert(indices.end(), { base + 0, base + 1, base + 2, base + 2, base + 3, base + 0 }); - }; - - // Floor (white) - add_quad( - Vec3(-2, -2, 2), Vec3(2, -2, 2), - Vec3(2, -2, -2), Vec3(-2, -2, -2), - Vec3(0, 1, 0)); - - // Ceiling (white) - add_quad( - Vec3(-2, 2, -2), Vec3(2, 2, -2), - Vec3(2, 2, 2), Vec3(-2, 2, 2), - Vec3(0, -1, 0)); - - // Back wall (white) - add_quad( - Vec3(-2, -2, -2), Vec3(2, -2, -2), - Vec3(2, 2, -2), Vec3(-2, 2, -2), - Vec3(0, 0, 1)); - - // Left wall (red) - add_quad( - Vec3(-2, -2, 2), Vec3(-2, -2, -2), - Vec3(-2, 2, -2), Vec3(-2, 2, 2), - Vec3(1, 0, 0)); - - // Right wall (green) - add_quad( - Vec3(2, -2, -2), Vec3(2, -2, 2), - Vec3(2, 2, 2), Vec3(2, 2, -2), - Vec3(-1, 0, 0)); - - Mesh cornell_box(vertices, indices); - - Camera camera(Vec3(0, 0, 5), Vec3(0, 0, 0)); - camera.set_perspective(45.0f, (float)width / height, 0.1f, 100.0f); - - render_mesh(fb, cornell_box, camera); - - if (fb.save("output_cornell_box.png")) { - ARE_LOG_INFO("✓ Saved: output_cornell_box.png"); - } - } - - ARE_LOG_INFO("========================================"); - ARE_LOG_INFO("✓ All images generated successfully!"); - ARE_LOG_INFO("Check the following files:"); - ARE_LOG_INFO(" - output_triangle.png"); - ARE_LOG_INFO(" - output_colored_triangle.png"); - ARE_LOG_INFO(" - output_cube.png"); - ARE_LOG_INFO(" - output_cornell_box.png"); - ARE_LOG_INFO("========================================"); - - Logger::shutdown(); - return 0; -} diff --git a/examples/03_material_showcase/CMakeLists.txt b/examples/03_material_showcase/CMakeLists.txt deleted file mode 100644 index 6f951cf..0000000 --- a/examples/03_material_showcase/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# examples/03_material_showcase/CMakeLists.txt -add_are_example(material_showcase main.cpp) diff --git a/examples/03_phase4_test/CMakeLists.txt b/examples/03_phase4_test/CMakeLists.txt deleted file mode 100644 index cf7772b..0000000 --- a/examples/03_phase4_test/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# Phase 4 verification example - -add_are_example(phase4_test - main.cpp -) - -# Copy to bin directory for easy execution -set_target_properties(phase4_test PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin -) diff --git a/examples/03_phase4_test/main.cpp b/examples/03_phase4_test/main.cpp deleted file mode 100644 index 04ce684..0000000 --- a/examples/03_phase4_test/main.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/** - * @file main.cpp - * @brief Phase 4 verification program - BVH construction and traversal test - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -using namespace are; - -// Test result tracking -struct TestResult { - std::string name; - bool passed; - std::string message; -}; - -std::vector test_results; - -void report_test(const std::string &name, bool passed, const std::string &message = "") { - test_results.push_back({ name, passed, message }); - if (passed) { - ARE_LOG_INFO("✓ " + name); - } else { - ARE_LOG_ERROR("✗ " + name + ": " + message); - } -} - -/** - * @brief Create a simple scene with a few triangles - */ -std::vector create_simple_scene() { - std::vector triangles; - - // Ground plane (2 triangles) - Vertex v0(Vec3(-5, 0, -5), Vec3(0, 1, 0)); - Vertex v1(Vec3(5, 0, -5), Vec3(0, 1, 0)); - Vertex v2(Vec3(5, 0, 5), Vec3(0, 1, 0)); - Vertex v3(Vec3(-5, 0, 5), Vec3(0, 1, 0)); - - triangles.emplace_back(v0, v1, v2); - triangles.emplace_back(v0, v2, v3); - - // Cube (12 triangles) - Vec3 cube_min(-1, 1, -1); - Vec3 cube_max(1, 3, 1); - - // Front face - triangles.emplace_back( - Vertex(Vec3(cube_min.x, cube_min.y, cube_max.z), Vec3(0, 0, 1)), - Vertex(Vec3(cube_max.x, cube_min.y, cube_max.z), Vec3(0, 0, 1)), - Vertex(Vec3(cube_max.x, cube_max.y, cube_max.z), Vec3(0, 0, 1))); - triangles.emplace_back( - Vertex(Vec3(cube_min.x, cube_min.y, cube_max.z), Vec3(0, 0, 1)), - Vertex(Vec3(cube_max.x, cube_max.y, cube_max.z), Vec3(0, 0, 1)), - Vertex(Vec3(cube_min.x, cube_max.y, cube_max.z), Vec3(0, 0, 1))); - - // Add more faces... (simplified for brevity) - - return triangles; -} - -/** - * @brief Create a complex scene with many triangles - */ -std::vector create_complex_scene(int num_triangles) { - std::vector triangles; - triangles.reserve(num_triangles); - - std::mt19937 rng(42); - std::uniform_real_distribution dist(-10.0f, 10.0f); - - for (int i = 0; i < num_triangles; ++i) { - Vec3 p0(dist(rng), dist(rng), dist(rng)); - Vec3 p1 = p0 + Vec3(dist(rng) * 0.5f, dist(rng) * 0.5f, dist(rng) * 0.5f); - Vec3 p2 = p0 + Vec3(dist(rng) * 0.5f, dist(rng) * 0.5f, dist(rng) * 0.5f); - - Vec3 normal = glm::normalize(glm::cross(p1 - p0, p2 - p0)); - - triangles.emplace_back( - Vertex(p0, normal), - Vertex(p1, normal), - Vertex(p2, normal)); - } - - return triangles; -} - -/** - * @brief Test 1: BVH construction - */ -void test_bvh_construction() { - auto triangles = create_simple_scene(); - - BVH bvh; - BVHBuildConfig config; - config.split_method_ = BVHSplitMethod::ARE_BVH_SPLIT_MIDDLE; - config.max_leaf_size_ = 4; - - bool success = bvh.build(triangles, config); - - report_test("BVH construction (simple scene)", success); - report_test("BVH is built", bvh.is_built()); - report_test("BVH has nodes", !bvh.get_nodes().empty()); -} - -/** - * @brief Test 2: BVH construction with SAH - */ -void test_bvh_construction_sah() { - auto triangles = create_simple_scene(); - - BVH bvh; - BVHBuildConfig config; - config.split_method_ = BVHSplitMethod::ARE_BVH_SPLIT_SAH; - config.max_leaf_size_ = 2; - - bool success = bvh.build(triangles, config); - - report_test("BVH construction with SAH", success); -} - -/** - * @brief Test 3: Ray-BVH intersection - */ -void test_ray_bvh_intersection() { - auto triangles = create_simple_scene(); - - BVH bvh; - bvh.build(triangles); - - // Ray hitting the ground plane - Ray ray1(Vec3(0, 5, 0), Vec3(0, -1, 0)); - HitRecord hit1; - bool test1 = bvh.intersect(ray1, hit1); - - // Ray missing everything - Ray ray2(Vec3(100, 5, 100), Vec3(0, -1, 0)); - HitRecord hit2; - bool test2 = !bvh.intersect(ray2, hit2); - - report_test("Ray-BVH intersection (hit)", test1); - report_test("Ray-BVH intersection (miss)", test2); -} - -/** - * @brief Test 4: BVH occlusion test - */ -void test_bvh_occlusion() { - auto triangles = create_simple_scene(); - - BVH bvh; - bvh.build(triangles); - - // Ray with occlusion - Ray ray1(Vec3(0, 5, 0), Vec3(0, -1, 0)); - bool test1 = bvh.intersect_any(ray1, 10.0f); - - // Ray without occlusion - Ray ray2(Vec3(100, 5, 100), Vec3(0, -1, 0)); - bool test2 = !bvh.intersect_any(ray2, 10.0f); - - report_test("BVH occlusion test (occluded)", test1); - report_test("BVH occlusion test (not occluded)", test2); -} - -/** - * @brief Test 5: BVH performance with complex scene - */ -void test_bvh_performance() { - const int num_triangles = 10000; - auto triangles = create_complex_scene(num_triangles); - - ARE_LOG_INFO("Building BVH for " + std::to_string(num_triangles) + " triangles..."); - - BVH bvh; - BVHBuildConfig config; - config.split_method_ = BVHSplitMethod::ARE_BVH_SPLIT_SAH; - - auto start_build = std::chrono::high_resolution_clock::now(); - bool success = bvh.build(triangles, config); - auto end_build = std::chrono::high_resolution_clock::now(); - - double build_time = std::chrono::duration(end_build - start_build).count(); - - ARE_LOG_INFO("BVH build time: " + std::to_string(build_time) + " ms"); - - // Test ray tracing performance - const int num_rays = 10000; - std::mt19937 rng(42); - std::uniform_real_distribution dist(-10.0f, 10.0f); - - int hit_count = 0; - - auto start_trace = std::chrono::high_resolution_clock::now(); - - for (int i = 0; i < num_rays; ++i) { - Vec3 origin(dist(rng), dist(rng), dist(rng)); - Vec3 direction = glm::normalize(Vec3(dist(rng), dist(rng), dist(rng))); - - Ray ray(origin, direction); - HitRecord hit; - - if (bvh.intersect(ray, hit)) { - hit_count++; - } - } - - auto end_trace = std::chrono::high_resolution_clock::now(); - double trace_time = std::chrono::duration(end_trace - start_trace).count(); - - ARE_LOG_INFO("Ray tracing time: " + std::to_string(trace_time) + " ms for " + std::to_string(num_rays) + " rays"); - ARE_LOG_INFO("Hit rate: " + std::to_string(hit_count) + "/" + std::to_string(num_rays) + " (" + std::to_string(100.0 * hit_count / num_rays) + "%)"); - ARE_LOG_INFO("Average time per ray: " + std::to_string(trace_time / num_rays) + " ms"); - - report_test("BVH performance test", success && build_time < 5000.0); // Should build in < 5 seconds -} - -/** - * @brief Test 6: BVH memory usage - */ -void test_bvh_memory() { - auto triangles = create_complex_scene(1000); - - BVH bvh; - bvh.build(triangles); - - size_t memory = bvh.get_memory_usage(); - ARE_LOG_INFO("BVH memory usage: " + std::to_string(memory / 1024) + " KB"); - - report_test("BVH memory usage", memory > 0); -} - -/** - * @brief Test 7: BVH clear and rebuild - */ -void test_bvh_clear_rebuild() { - auto triangles = create_simple_scene(); - - BVH bvh; - bvh.build(triangles); - - bool test1 = bvh.is_built(); - - bvh.clear(); - bool test2 = !bvh.is_built(); - - bvh.build(triangles); - bool test3 = bvh.is_built(); - - report_test("BVH clear and rebuild (initial build)", test1); - report_test("BVH clear and rebuild (after clear)", test2); - report_test("BVH clear and rebuild (rebuild)", test3); -} - -/** - * @brief Test 8: BVH with empty scene - */ -void test_bvh_empty_scene() { - std::vector empty_triangles; - - BVH bvh; - bool success = bvh.build(empty_triangles); - - report_test("BVH with empty scene", !success); -} - -/** - * @brief Test 9: BVH node structure - */ -void test_bvh_node_structure() { - auto triangles = create_simple_scene(); - - BVH bvh; - bvh.build(triangles); - - const auto &nodes = bvh.get_nodes(); - - bool test1 = !nodes.empty(); - - // Check root node - bool test2 = nodes[0].bounds_.is_valid(); - - // Count leaf and internal nodes - int leaf_count = 0; - int internal_count = 0; - - for (const auto &node : nodes) { - if (node.is_leaf()) { - leaf_count++; - } else { - internal_count++; - } - } - - bool test3 = leaf_count > 0; - bool test4 = internal_count >= 0; - - ARE_LOG_INFO("BVH structure: " + std::to_string(nodes.size()) + " nodes (" + std::to_string(leaf_count) + " leaves, " + std::to_string(internal_count) + " internal)"); - - report_test("BVH node structure (has nodes)", test1); - report_test("BVH node structure (valid root)", test2); - report_test("BVH node structure (has leaves)", test3); - report_test("BVH node structure (node counts)", test4); -} - -/** - * @brief Test 10: BVH traversal correctness - */ -void test_bvh_traversal_correctness() { - // Create a simple scene with known geometry - std::vector triangles; - - // Single triangle at origin - Vertex v0(Vec3(-1, 0, -1), Vec3(0, 1, 0)); - Vertex v1(Vec3(1, 0, -1), Vec3(0, 1, 0)); - Vertex v2(Vec3(0, 0, 1), Vec3(0, 1, 0)); - - triangles.emplace_back(v0, v1, v2); - - BVH bvh; - bvh.build(triangles); - - // Ray hitting the triangle from above - Ray ray(Vec3(0, 5, 0), Vec3(0, -1, 0)); - HitRecord hit; - - bool intersected = bvh.intersect(ray, hit); - - bool test1 = intersected; - bool test2 = hit.t_ > 0.0f && hit.t_ < 10.0f; - bool test3 = glm::length(hit.normal_ - Vec3(0, 1, 0)) < 0.01f; - - report_test("BVH traversal correctness (intersection)", test1); - report_test("BVH traversal correctness (t value)", test2); - report_test("BVH traversal correctness (normal)", test3); -} - -int main() { - // Initialize logger and profiler - Logger::init(LogLevel::ARE_LOG_INFO); - Profiler::init(); - - ARE_LOG_INFO("========================================"); - ARE_LOG_INFO("Phase 4 Verification Program"); - ARE_LOG_INFO("BVH Construction and Traversal Test"); - ARE_LOG_INFO("========================================"); - - // Run all tests - test_bvh_construction(); - test_bvh_construction_sah(); - test_ray_bvh_intersection(); - test_bvh_occlusion(); - test_bvh_performance(); - test_bvh_memory(); - test_bvh_clear_rebuild(); - test_bvh_empty_scene(); - test_bvh_node_structure(); - test_bvh_traversal_correctness(); - - // Print summary - ARE_LOG_INFO("========================================"); - ARE_LOG_INFO("Test Summary"); - ARE_LOG_INFO("========================================"); - - int passed = 0; - int failed = 0; - - for (const auto &result : test_results) { - if (result.passed) { - ++passed; - } else { - ++failed; - } - } - - ARE_LOG_INFO("Total tests: " + std::to_string(test_results.size())); - ARE_LOG_INFO("Passed: " + std::to_string(passed)); - ARE_LOG_INFO("Failed: " + std::to_string(failed)); - - if (failed == 0) { - ARE_LOG_INFO("========================================"); - ARE_LOG_INFO("✓ All Phase 4 tests passed!"); - ARE_LOG_INFO("========================================"); - } else { - ARE_LOG_ERROR("========================================"); - ARE_LOG_ERROR("✗ Some tests failed. Please review."); - ARE_LOG_ERROR("========================================"); - } - - // Print profiling results - Profiler::print_results(); - - Profiler::shutdown(); - Logger::shutdown(); - - return failed == 0 ? 0 : 1; -} diff --git a/examples/04_phase5_test/CMakeLists.txt b/examples/04_phase5_test/CMakeLists.txt deleted file mode 100644 index 758345d..0000000 --- a/examples/04_phase5_test/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -add_are_example(phase5_test - main.cpp -) - -set_target_properties(phase5_test PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin -) diff --git a/examples/04_phase5_test/main.cpp b/examples/04_phase5_test/main.cpp deleted file mode 100644 index 31202c2..0000000 --- a/examples/04_phase5_test/main.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/** - * @file main.cpp - * @brief Phase 5 test: Hybrid GBuffer-driven CPU raytracing with primitive-id - */ - -#include -#include - -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "../lib/glad/glad/glad.h" - -#include -#include -#include -#include - -using namespace are; - -namespace { - -uint32_t create_fullscreen_quad_vao() { - float vertices[] = { - -1.0f, -1.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 0.0f, 1.0f - }; - uint32_t indices[] = { 0, 1, 2, 2, 3, 0 }; - - uint32_t vao = 0, vbo = 0, ebo = 0; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glGenBuffers(1, &ebo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); - - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); - - glBindVertexArray(0); - return vao; -} - -uint32_t create_output_texture_rgba16f(int width, int height) { - uint32_t tex = 0; - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glBindTexture(GL_TEXTURE_2D, 0); - return tex; -} - -} // namespace - -int main() { - try { - Logger::init(LogLevel::ARE_LOG_INFO); - Profiler::init(); - - WindowConfig wc; - wc.width = 960; - wc.height = 540; - wc.title = "ARE Phase5 - Hybrid + PrimitiveID"; - wc.vsync = true; - - Window window(wc); - - if (!GLContext::initialize()) { - ARE_LOG_CRITICAL("GLContext initialize failed"); - return -1; - } - - int fb_w = 0, fb_h = 0; - for (int i = 0; i < 240; ++i) { - window.poll_events(); - window.get_framebuffer_size(fb_w, fb_h); - if (fb_w > 0 && fb_h > 0) break; - window.swap_buffers(); - } - if (fb_w <= 0 || fb_h <= 0) { - ARE_LOG_CRITICAL("Invalid framebuffer size"); - return -1; - } - - Rasterizer rasterizer(fb_w, fb_h); - rasterizer.initialize_shaders("shaders/"); - - uint32_t output_tex = create_output_texture_rgba16f(fb_w, fb_h); - uint32_t quad_vao = create_fullscreen_quad_vao(); - - // Display shader (simple) - const char* vs = R"( -#version 430 core -layout(location = 0) in vec2 a_pos; -layout(location = 1) in vec2 a_uv; -out vec2 v_uv; -void main(){ v_uv=a_uv; gl_Position=vec4(a_pos,0,1); } -)"; - const char* fs = R"( -#version 430 core -in vec2 v_uv; -out vec4 frag_color; -uniform sampler2D u_tex; -void main(){ frag_color = texture(u_tex, v_uv); } -)"; - - ShaderProgram display; - if (!display.compile_shader(ShaderType::ARE_SHADER_VERTEX, vs) || - !display.compile_shader(ShaderType::ARE_SHADER_FRAGMENT, fs) || - !display.link()) { - ARE_LOG_CRITICAL("Display shader compile failed"); - return -1; - } - - // Scene setup - SceneManager scene; - - Material mat; - mat.set_albedo(Vec3(0.8f, 0.2f, 0.2f)); - mat.set_roughness(0.6f); - MaterialHandle mat_h = scene.add_material(mat); - - std::vector ground_v = { - Vertex(Vec3(-4, 0, -4), Vec3(0, 1, 0), Vec2(0, 0)), - Vertex(Vec3( 4, 0, -4), Vec3(0, 1, 0), Vec2(1, 0)), - Vertex(Vec3( 4, 0, 4), Vec3(0, 1, 0), Vec2(1, 1)), - Vertex(Vec3(-4, 0, 4), Vec3(0, 1, 0), Vec2(0, 1)), - }; - std::vector ground_i = { 0, 1, 2, 2, 3, 0 }; - Mesh ground(ground_v, ground_i, mat_h); - ground.compute_tangents(); - - std::vector tri_v = { - Vertex(Vec3(-0.8f, 0.2f, 0.0f), Vec3(0, 1, 0), Vec2(0, 0)), - Vertex(Vec3( 0.8f, 0.2f, 0.0f), Vec3(0, 1, 0), Vec2(1, 0)), - Vertex(Vec3( 0.0f, 1.2f, 0.3f), Vec3(0, 1, 0), Vec2(0.5f, 1)), - }; - std::vector tri_i = { 0, 1, 2 }; - Mesh tri_mesh(tri_v, tri_i, mat_h); - tri_mesh.compute_tangents(); - - // Upload meshes BEFORE adding (SceneManager stores copy) - rasterizer.upload_mesh(ground); - scene.add_mesh(ground); - - rasterizer.upload_mesh(tri_mesh); - scene.add_mesh(tri_mesh); - - auto sun = std::make_shared(Vec3(-1, -1, -0.5f), Vec3(1.0f), 2.0f); - sun->set_cast_shadows(true); - scene.add_light(sun); - - auto point = std::make_shared(Vec3(0, 2.5f, 1.5f), Vec3(1.0f, 0.95f, 0.8f), 10.0f, 10.0f); - point->set_cast_shadows(true); - scene.add_light(point); - - Camera camera(Vec3(0.0f, 1.8f, 4.5f), Vec3(0.0f, 0.6f, 0.0f)); - camera.set_perspective(45.0f, static_cast(fb_w) / static_cast(fb_h), 0.1f, 200.0f); - - // Geometry cache: single source of truth - GeometryCache geom; - if (!geom.build_from_scene(scene)) { - ARE_LOG_CRITICAL("GeometryCache build failed"); - return -1; - } - - // Provide triangle base offsets to rasterizer for primitive id output - rasterizer.set_triangle_base_provider([&](size_t mesh_index) { - return geom.get_mesh_triangle_base(mesh_index); - }); - - // CPU ray tracer uses the same BVH (same triangle layout) - RayTracingConfig rtc; - rtc.backend = RayTracingBackend::ARE_RT_BACKEND_CPU; - rtc.spp = 1; - rtc.max_depth = 3; - rtc.enable_gi = false; - rtc.enable_ao = false; - rtc.ao_samples = 4; - rtc.ao_radius = 1.0f; - - CPURayTracer tracer(rtc); - tracer.update_bvh(geom.get_bvh()); - - bool request_render = true; - - while (!window.should_close()) { - window.poll_events(); - - if (window.is_key_pressed(256)) { - window.set_should_close(true); - } - - int new_fb_w = 0, new_fb_h = 0; - window.get_framebuffer_size(new_fb_w, new_fb_h); - if (new_fb_w <= 0 || new_fb_h <= 0) { - window.swap_buffers(); - continue; - } - - if (new_fb_w != fb_w || new_fb_h != fb_h) { - fb_w = new_fb_w; - fb_h = new_fb_h; - - rasterizer.resize(fb_w, fb_h); - glDeleteTextures(1, &output_tex); - output_tex = create_output_texture_rgba16f(fb_w, fb_h); - camera.set_aspect_ratio(static_cast(fb_w) / static_cast(fb_h)); - - request_render = true; - } - - if (request_render) { - rasterizer.render_gbuffer(scene, camera); - tracer.render(scene, camera, &rasterizer.get_gbuffer(), output_tex); - request_render = false; - } - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, fb_w, fb_h); - glDisable(GL_DEPTH_TEST); - - display.use(); - display.set_uniform("u_tex", 0); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, output_tex); - - glBindVertexArray(quad_vao); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); - glBindVertexArray(0); - - glBindTexture(GL_TEXTURE_2D, 0); - window.swap_buffers(); - } - - glDeleteTextures(1, &output_tex); - glDeleteVertexArrays(1, &quad_vao); - - Profiler::shutdown(); - Logger::shutdown(); - return 0; - - } catch (const std::exception& e) { - Logger::init(LogLevel::ARE_LOG_INFO); - ARE_LOG_CRITICAL(std::string("Unhandled exception: ") + e.what()); - Logger::shutdown(); - return -1; - } -} diff --git a/examples/04performance_test/CMakeLists.txt b/examples/04performance_test/CMakeLists.txt deleted file mode 100644 index 39e6361..0000000 --- a/examples/04performance_test/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# examples/04_performance_test/CMakeLists.txt -add_are_example(performance_test main.cpp) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt deleted file mode 100644 index 1458f6b..0000000 --- a/examples/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# examples/CMakeLists.txt - -# Helper function to create example targets -function(add_are_example EXAMPLE_NAME) - add_executable(${EXAMPLE_NAME} ${ARGN}) - target_link_libraries(${EXAMPLE_NAME} PRIVATE are) - set_target_properties(${EXAMPLE_NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/examples - ) -endfunction() - -# Add subdirectories for each example -add_subdirectory(01_hello_triangle) -add_subdirectory(02_cornell_box) -add_subdirectory(03_material_showcase) -add_subdirectory(04_performance_test) diff --git a/files.md b/files.md deleted file mode 100644 index aca15ab..0000000 --- a/files.md +++ /dev/null @@ -1,1933 +0,0 @@ -### 文件:include/are/core/types.h -```cpp -/** - * @file types.h - * @brief Basic type definitions and constants - */ - -#ifndef ARE_INCLUDE_CORE_TYPES_H -#define ARE_INCLUDE_CORE_TYPES_H - -#include -#include - -namespace are { - -// Floating point precision -using Real = float; - -// Common vector types -using Vec2 = glm::vec2; -using Vec3 = glm::vec3; -using Vec4 = glm::vec4; - -using Vec2i = glm::ivec2; -using Vec3i = glm::ivec3; -using Vec4i = glm::ivec4; - -// Matrix types -using Mat3 = glm::mat3; -using Mat4 = glm::mat4; - -// Color type (RGBA) -using Color = Vec4; - -// Handle types for resource management -using MeshHandle = uint32_t; -using MaterialHandle = uint32_t; -using LightHandle = uint32_t; -using TextureHandle = uint32_t; - -// Invalid handle constant -constexpr uint32_t are_invalid_handle = 0xFFFFFFFF; - -// Mathematical constants -constexpr Real are_pi = 3.14159265358979323846f; -constexpr Real are_two_pi = 6.28318530717958647692f; -constexpr Real are_inv_pi = 0.31830988618379067154f; -constexpr Real are_inv_two_pi = 0.15915494309189533577f; -constexpr Real are_epsilon = 1e-6f; - -// Ray tracing backend types -enum class RayTracingBackend { - ARE_RT_BACKEND_CPU, - ARE_RT_BACKEND_COMPUTE_SHADER -}; - -// Tone mapping operators -enum class ToneMappingOperator { - ARE_TONEMAP_NONE, - ARE_TONEMAP_REINHARD, - ARE_TONEMAP_ACES -}; - -// G-Buffer visualization modes -enum class GBufferVisualizationMode { - ARE_GBUFFER_VIS_NONE, - ARE_GBUFFER_VIS_POSITION, - ARE_GBUFFER_VIS_NORMAL, - ARE_GBUFFER_VIS_ALBEDO, - ARE_GBUFFER_VIS_METALLIC, - ARE_GBUFFER_VIS_ROUGHNESS, - ARE_GBUFFER_VIS_DEPTH -}; - -} // namespace are - -#endif // ARE_INCLUDE_CORE_TYPES_H -``` - -### 文件:include/are/core/logger.h -```cpp -/** - * @file logger.h - * @brief Logging system for the rendering engine - */ - -#ifndef ARE_INCLUDE_CORE_LOGGER_H -#define ARE_INCLUDE_CORE_LOGGER_H - -#include -#include - -namespace are { - -/** - * @enum LogLevel - * @brief Logging severity levels - */ -enum class LogLevel { - ARE_LOG_TRACE, - ARE_LOG_DEBUG, - ARE_LOG_INFO, - ARE_LOG_WARN, - ARE_LOG_ERROR, - ARE_LOG_CRITICAL -}; - -/** - * @class Logger - * @brief Thread-safe logging system - * - * This class provides a simple interface for logging messages with different - * severity levels. It wraps spdlog for actual logging functionality. - */ -class Logger { -public: - /** - * @brief Initialize the logging system - * @param min_level Minimum log level to display - */ - static void init(LogLevel min_level = LogLevel::ARE_LOG_INFO); - - /** - * @brief Shutdown the logging system - */ - static void shutdown(); - - /** - * @brief Log a message with file/function/line information - * @param level Log severity level - * @param file Source file name - * @param func Function name - * @param line Line number - * @param message Log message - */ - static void log(LogLevel level, const char* file, const char* func, - int line, const std::string& message); - - /** - * @brief Set minimum log level - * @param level Minimum log level to display - */ - static void set_level(LogLevel level); - -private: - static std::shared_ptr logger_impl_; ///< Internal logger implementation - static bool initialized_; ///< Initialization flag -}; - -} // namespace are - -// Logging macros -#define ARE_LOG_TRACE(msg) are::Logger::log(are::LogLevel::ARE_LOG_TRACE, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_DEBUG(msg) are::Logger::log(are::LogLevel::ARE_LOG_DEBUG, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_INFO(msg) are::Logger::log(are::LogLevel::ARE_LOG_INFO, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_WARN(msg) are::Logger::log(are::LogLevel::ARE_LOG_WARN, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_ERROR(msg) are::Logger::log(are::LogLevel::ARE_LOG_ERROR, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_CRITICAL(msg) are::Logger::log(are::LogLevel::ARE_LOG_CRITICAL, __FILE__, __func__, __LINE__, msg) - -#endif // ARE_INCLUDE_CORE_LOGGER_H -``` - -### 文件:include/are/core/config.h -```cpp -/** - * @file config.h - * @brief Configuration system for the rendering engine - */ - -#ifndef ARE_INCLUDE_CORE_CONFIG_H -#define ARE_INCLUDE_CORE_CONFIG_H - -#include -#include - -namespace are { - -/** - * @struct WindowConfig - * @brief Configuration for window creation - */ -struct WindowConfig { - int width = 1280; ///< Window width in pixels - int height = 720; ///< Window height in pixels - std::string title = "Aurora Rendering Engine"; ///< Window title - bool resizable = true; ///< Whether window is resizable - bool vsync = true; ///< Enable vertical synchronization - int samples = 1; ///< MSAA samples (1 = disabled) -}; - -/** - * @struct RayTracingConfig - * @brief Configuration for ray tracing - */ -struct RayTracingConfig { - RayTracingBackend backend = RayTracingBackend::ARE_RT_BACKEND_COMPUTE_SHADER; - int spp = 64; ///< Samples per pixel - int max_depth = 8; ///< Maximum ray bounce depth - bool enable_gi = true; ///< Enable global illumination - bool enable_ao = true; ///< Enable ambient occlusion - bool enable_soft_shadows = false; ///< Enable soft shadows - int ao_samples = 16; ///< AO sample count - Real ao_radius = 1.0f; ///< AO sampling radius -}; - -/** - * @struct RenderConfig - * @brief General rendering configuration - */ -struct RenderConfig { - ToneMappingOperator tonemap_op = ToneMappingOperator::ARE_TONEMAP_ACES; - Real exposure = 1.0f; ///< Exposure value for tone mapping - bool use_hdr = true; ///< Use HDR rendering pipeline - GBufferVisualizationMode gbuffer_vis_mode = GBufferVisualizationMode::ARE_GBUFFER_VIS_NONE; -}; - -/** - * @struct PerformanceConfig - * @brief Performance-related configuration - */ -struct PerformanceConfig { - int num_threads = 0; ///< Number of threads (0 = auto-detect) - bool enable_bvh_multithreading = true; ///< Use multithreading for BVH construction - bool enable_profiling = false; ///< Enable performance profiling -}; - -/** - * @struct PathConfig - * @brief File path configuration - */ -struct PathConfig { - std::string shader_dir = "shaders/"; ///< Directory containing shader files - std::string texture_dir = "textures/"; ///< Default texture directory - std::string output_dir = "output/"; ///< Default output directory -}; - -/** - * @class AreConfig - * @brief Main configuration class for Aurora Rendering Engine - */ -class AreConfig { -public: - WindowConfig window; ///< Window configuration - RayTracingConfig ray_tracing; ///< Ray tracing configuration - RenderConfig render; ///< Rendering configuration - PerformanceConfig performance; ///< Performance configuration - PathConfig paths; ///< Path configuration - - /** - * @brief Constructor with default values - */ - AreConfig() = default; - - /** - * @brief Validate configuration values - * @return true if configuration is valid, false otherwise - */ - bool validate() const; - - /** - * @brief Print configuration to console - */ - void print() const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_CORE_CONFIG_H -``` - -### 文件:include/are/utils/math_utils.h -```cpp -/** - * @file math_utils.h - * @brief Mathematical utility functions - */ - -#ifndef ARE_INCLUDE_UTILS_MATH_UTILS_H -#define ARE_INCLUDE_UTILS_MATH_UTILS_H - -#include -#include - -namespace are { - -/** - * @brief Clamp value to range [min, max] - * @param value Value to clamp - * @param min Minimum value - * @param max Maximum value - * @return Clamped value - */ -template -inline T clamp(T value, T min, T max) { - return std::max(min, std::min(value, max)); -} - -/** - * @brief Linear interpolation - * @param a Start value - * @param b End value - * @param t Interpolation factor [0, 1] - * @return Interpolated value - */ -template -inline T lerp(T a, T b, Real t) { - return a + (b - a) * t; -} - -/** - * @brief Convert degrees to radians - * @param degrees Angle in degrees - * @return Angle in radians - */ -inline Real degrees_to_radians(Real degrees) { - return degrees * are_pi / 180.0f; -} - -/** - * @brief Convert radians to degrees - * @param radians Angle in radians - * @return Angle in degrees - */ -inline Real radians_to_degrees(Real radians) { - return radians * 180.0f / are_pi; -} - -/** - * @brief Check if two floating point values are approximately equal - * @param a First value - * @param b Second value - * @param epsilon Tolerance - * @return true if approximately equal - */ -inline bool approx_equal(Real a, Real b, Real epsilon = are_epsilon) { - return std::abs(a - b) < epsilon; -} - -/** - * @brief Compute barycentric coordinates - * @param p Point - * @param a Triangle vertex A - * @param b Triangle vertex B - * @param c Triangle vertex C - * @param u Output barycentric coordinate u - * @param v Output barycentric coordinate v - * @param w Output barycentric coordinate w - */ -void compute_barycentric(const Vec3& p, const Vec3& a, const Vec3& b, const Vec3& c, - Real& u, Real& v, Real& w); - -/** - * @brief Reflect vector around normal - * @param incident Incident vector - * @param normal Surface normal (normalized) - * @return Reflected vector - */ -Vec3 reflect(const Vec3& incident, const Vec3& normal); - -/** - * @brief Refract vector through surface - * @param incident Incident vector (normalized) - * @param normal Surface normal (normalized) - * @param eta Ratio of refractive indices - * @param refracted Output refracted vector - * @return true if refraction occurred (false for total internal reflection) - */ -bool refract(const Vec3& incident, const Vec3& normal, Real eta, Vec3& refracted); - -/** - * @brief Compute Fresnel reflectance (Schlick approximation) - * @param cos_theta Cosine of angle between view and normal - * @param f0 Reflectance at normal incidence - * @return Fresnel reflectance - */ -Real fresnel_schlick(Real cos_theta, Real f0); - -/** - * @brief Create orthonormal basis from normal - * @param normal Normal vector (normalized) - * @param tangent Output tangent vector - * @param bitangent Output bitangent vector - */ -void create_orthonormal_basis(const Vec3& normal, Vec3& tangent, Vec3& bitangent); - -/** - * @brief Transform direction from tangent space to world space - * @param tangent_dir Direction in tangent space - * @param normal Surface normal - * @param tangent Surface tangent - * @param bitangent Surface bitangent - * @return Direction in world space - */ -Vec3 tangent_to_world(const Vec3& tangent_dir, const Vec3& normal, - const Vec3& tangent, const Vec3& bitangent); - -} // namespace are - -#endif // ARE_INCLUDE_UTILS_MATH_UTILS_H -``` - -### 文件:include/are/core/profiler.h -```cpp -/** - * @file profiler.h - * @brief Performance profiling utilities - */ - -#ifndef ARE_INCLUDE_CORE_PROFILER_H -#define ARE_INCLUDE_CORE_PROFILER_H - -#include -#include -#include -#include - -namespace are { - -/** - * @struct ProfileResult - * @brief Result of a profiling measurement - */ -struct ProfileResult { - std::string name_; ///< Profile section name - double duration_ms_; ///< Duration in milliseconds - uint64_t call_count_; ///< Number of times called - double avg_duration_ms_; ///< Average duration per call -}; - -/** - * @class Profiler - * @brief Simple performance profiler - * - * This class provides basic timing functionality for performance analysis. - * It is only active when ARE_ENABLE_PROFILING is defined. - */ -class Profiler { -public: - /** - * @brief Initialize the profiler - */ - static void init(); - - /** - * @brief Shutdown the profiler and print results - */ - static void shutdown(); - - /** - * @brief Begin a profiling section - * @param name Section name - */ - static void begin(const std::string& name); - - /** - * @brief End a profiling section - * @param name Section name - */ - static void end(const std::string& name); - - /** - * @brief Get profiling results - * @return Map of section names to profile results - */ - static const std::unordered_map& get_results(); - - /** - * @brief Reset all profiling data - */ - static void reset(); - - /** - * @brief Print profiling results to console - */ - static void print_results(); - -private: - struct SectionData { - std::chrono::high_resolution_clock::time_point start_time_; - double total_duration_ms_ = 0.0; - uint64_t call_count_ = 0; - }; - - static std::unordered_map sections_; - static std::unordered_map results_; - static bool enabled_; -}; - -/** - * @class ScopedProfiler - * @brief RAII-style profiler for automatic timing - */ -class ScopedProfiler { -public: - /** - * @brief Constructor - begins profiling - * @param name Section name - */ - explicit ScopedProfiler(const std::string& name); - - /** - * @brief Destructor - ends profiling - */ - ~ScopedProfiler(); - -private: - std::string name_; -}; - -} // namespace are - -// Profiling macros -#ifdef ARE_ENABLE_PROFILING - #define ARE_PROFILE_BEGIN(name) are::Profiler::begin(name) - #define ARE_PROFILE_END(name) are::Profiler::end(name) - #define ARE_PROFILE_SCOPE(name) are::ScopedProfiler are_profiler_##__LINE__(name) - #define ARE_PROFILE_FUNCTION() ARE_PROFILE_SCOPE(__func__) -#else - #define ARE_PROFILE_BEGIN(name) ((void)0) - #define ARE_PROFILE_END(name) ((void)0) - #define ARE_PROFILE_SCOPE(name) ((void)0) - #define ARE_PROFILE_FUNCTION() ((void)0) -#endif - -#endif // ARE_INCLUDE_CORE_PROFILER_H -``` - -### 文件:src/core/logger.cpp -```cpp -/** - * @file logger.cpp - * @brief Implementation of logging system - */ - -#include -#include -#include -#include -#include -#include - -namespace are { - -std::shared_ptr Logger::logger_impl_ = nullptr; -bool Logger::initialized_ = false; - -void Logger::init(LogLevel min_level) { - if (initialized_) { - return; - } - - try { - // Create console sink with color support - auto console_sink = std::make_shared(); - console_sink->set_pattern("[%H:%M:%S.%e] [%^%l%$] %v"); - - // Create logger with console sink - auto logger = std::make_shared("are", console_sink); - - // Set log level - switch (min_level) { - case LogLevel::ARE_LOG_TRACE: - logger->set_level(spdlog::level::trace); - break; - case LogLevel::ARE_LOG_DEBUG: - logger->set_level(spdlog::level::debug); - break; - case LogLevel::ARE_LOG_INFO: - logger->set_level(spdlog::level::info); - break; - case LogLevel::ARE_LOG_WARN: - logger->set_level(spdlog::level::warn); - break; - case LogLevel::ARE_LOG_ERROR: - logger->set_level(spdlog::level::err); - break; - case LogLevel::ARE_LOG_CRITICAL: - logger->set_level(spdlog::level::critical); - break; - } - - // Flush on error or higher - logger->flush_on(spdlog::level::err); - - // Set as default logger - spdlog::set_default_logger(logger); - logger_impl_ = logger; - initialized_ = true; - - } catch (const std::exception& e) { - fprintf(stderr, "[ARE] Failed to initialize logger: %s\n", e.what()); - } -} - -void Logger::shutdown() { - if (!initialized_) { - return; - } - - try { - spdlog::shutdown(); - logger_impl_.reset(); - initialized_ = false; - } catch (const std::exception& e) { - fprintf(stderr, "[ARE] Error during logger shutdown: %s\n", e.what()); - } -} - -void Logger::log(LogLevel level, const char* file, const char* func, - int line, const std::string& message) { - if (!initialized_) { - init(); - } - - // Extract filename from full path - const char* filename = file; - const char* last_slash = nullptr; - - for (const char* p = file; *p; ++p) { - if (*p == '/' || *p == '\\') { - last_slash = p; - } - } - - if (last_slash) { - filename = last_slash + 1; - } - - // Format message with location information - std::string formatted = message + " (" + filename + ":" + std::to_string(line) + ")"; - - try { - auto logger = std::static_pointer_cast(logger_impl_); - - switch (level) { - case LogLevel::ARE_LOG_TRACE: - logger->trace(formatted); - break; - case LogLevel::ARE_LOG_DEBUG: - logger->debug(formatted); - break; - case LogLevel::ARE_LOG_INFO: - logger->info(formatted); - break; - case LogLevel::ARE_LOG_WARN: - logger->warn(formatted); - break; - case LogLevel::ARE_LOG_ERROR: - logger->error(formatted); - break; - case LogLevel::ARE_LOG_CRITICAL: - logger->critical(formatted); - break; - } - } catch (const std::exception& e) { - fprintf(stderr, "[ARE] Logging error: %s\n", e.what()); - } -} - -void Logger::set_level(LogLevel level) { - if (!initialized_) { - return; - } - - try { - auto logger = std::static_pointer_cast(logger_impl_); - - switch (level) { - case LogLevel::ARE_LOG_TRACE: - logger->set_level(spdlog::level::trace); - break; - case LogLevel::ARE_LOG_DEBUG: - logger->set_level(spdlog::level::debug); - break; - case LogLevel::ARE_LOG_INFO: - logger->set_level(spdlog::level::info); - break; - case LogLevel::ARE_LOG_WARN: - logger->set_level(spdlog::level::warn); - break; - case LogLevel::ARE_LOG_ERROR: - logger->set_level(spdlog::level::err); - break; - case LogLevel::ARE_LOG_CRITICAL: - logger->set_level(spdlog::level::critical); - break; - } - } catch (const std::exception& e) { - fprintf(stderr, "[ARE] Error setting log level: %s\n", e.what()); - } -} - -} // namespace are -``` - -### 文件:CMakeLists.txt -```CMakeLists.txt -cmake_minimum_required(VERSION 3.15) -project(AuroraRenderingEngine VERSION 0.1.0 LANGUAGES CXX C) - -# Set C++ standard -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - -# Set C standard for GLAD -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED ON) - -# Build options -option(ARE_BUILD_SHARED "Build shared library" OFF) -option(ARE_BUILD_EXAMPLES "Build example programs" ON) -option(ARE_ENABLE_PROFILING "Enable performance profiling" ON) -option(ARE_ENABLE_DEBUG_VIS "Enable debug visualization" ON) - -# Set output directories -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) - -# Compiler flags -if(MSVC) - add_compile_options(/W4) - add_compile_definitions(_CRT_SECURE_NO_WARNINGS) - # Disable specific warnings that are too strict - add_compile_options(/wd4100) # unreferenced formal parameter -else() - add_compile_options(-Wall -Wextra -pedantic) - # Disable specific warnings - add_compile_options(-Wno-unused-parameter) -endif() - -# Find required packages -find_package(OpenGL REQUIRED) -find_package(glfw3 REQUIRED) -find_package(glm REQUIRED) - -# Try to find spdlog (system installation) -find_package(spdlog QUIET) - -if(NOT spdlog_FOUND) - message(STATUS "spdlog not found in system, using local version") - # Use local spdlog - set(SPDLOG_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/lib/spdlog/include") - if(NOT EXISTS ${SPDLOG_INCLUDE_DIR}) - message(FATAL_ERROR "spdlog not found. Please install spdlog or place it in lib/spdlog/") - endif() - add_library(spdlog INTERFACE) - target_include_directories(spdlog INTERFACE ${SPDLOG_INCLUDE_DIR}) - # spdlog compile definitions - target_compile_definitions(spdlog INTERFACE SPDLOG_COMPILED_LIB) -endif() - -# Find OpenMP (optional) -find_package(OpenMP) -if(OpenMP_CXX_FOUND) - set(ARE_USE_OPENMP ON) - add_compile_definitions(ARE_USE_OPENMP) - message(STATUS "OpenMP found and enabled") -else() - message(STATUS "OpenMP not found, multithreading will use std::thread") -endif() - -# GLAD library path -set(GLAD_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/lib/glad") -set(GLAD_SOURCE_DIR "${CMAKE_SOURCE_DIR}/lib/glad") - -if(NOT EXISTS ${GLAD_INCLUDE_DIR}) - message(FATAL_ERROR "GLAD include directory not found: ${GLAD_INCLUDE_DIR}") -endif() - -if(NOT EXISTS ${GLAD_SOURCE_DIR}) - message(FATAL_ERROR "GLAD source directory not found: ${GLAD_SOURCE_DIR}") -endif() - -# STB library path -set(STB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/lib/stb") - -if(NOT EXISTS ${STB_INCLUDE_DIR}) - message(FATAL_ERROR "STB include directory not found: ${STB_INCLUDE_DIR}") -endif() - -# Collect all source files from src/ -file(GLOB_RECURSE ARE_SOURCES - "${CMAKE_SOURCE_DIR}/src/*.cpp" - "${CMAKE_SOURCE_DIR}/src/*.c" -) - -# Collect all GLAD source files -file(GLOB GLAD_SOURCES - "${GLAD_SOURCE_DIR}/*.c" -) - -# Add GLAD sources to ARE sources -list(APPEND ARE_SOURCES ${GLAD_SOURCES}) - -# Collect all header files -file(GLOB_RECURSE ARE_HEADERS - "${CMAKE_SOURCE_DIR}/include/*.h" - "${CMAKE_SOURCE_DIR}/include/*.hpp" -) - -# Create library -if(ARE_BUILD_SHARED) - add_library(are SHARED ${ARE_SOURCES} ${ARE_HEADERS}) - target_compile_definitions(are PRIVATE ARE_BUILD_SHARED) - message(STATUS "Building shared library") -else() - add_library(are STATIC ${ARE_SOURCES} ${ARE_HEADERS}) - message(STATUS "Building static library") -endif() - -# Set target properties -set_target_properties(are PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR} - PUBLIC_HEADER "${ARE_HEADERS}" -) - -# Include directories -target_include_directories(are - PUBLIC - $ - $ - PRIVATE - ${CMAKE_SOURCE_DIR}/src - ${GLAD_INCLUDE_DIR} - ${STB_INCLUDE_DIR} -) - -# Link libraries -target_link_libraries(are - PUBLIC - OpenGL::GL - glfw - glm::glm -) - -# Link spdlog -if(spdlog_FOUND) - target_link_libraries(are PUBLIC spdlog::spdlog) -else() - target_link_libraries(are PUBLIC spdlog) - target_include_directories(are PRIVATE ${SPDLOG_INCLUDE_DIR}) -endif() - -# Link OpenMP if available -if(OpenMP_CXX_FOUND) - target_link_libraries(are PUBLIC OpenMP::OpenMP_CXX) -endif() - -# Platform-specific libraries -if(UNIX AND NOT APPLE) - target_link_libraries(are PUBLIC dl pthread) -endif() - -# Compile definitions -if(ARE_ENABLE_PROFILING) - target_compile_definitions(are PUBLIC ARE_ENABLE_PROFILING) - message(STATUS "Profiling enabled") -endif() - -if(ARE_ENABLE_DEBUG_VIS) - target_compile_definitions(are PUBLIC ARE_ENABLE_DEBUG_VIS) - message(STATUS "Debug visualization enabled") -endif() - -# Build examples -if(ARE_BUILD_EXAMPLES) - # Define helper function for creating examples - function(add_are_example EXAMPLE_NAME) - add_executable(${EXAMPLE_NAME} ${ARGN}) - target_link_libraries(${EXAMPLE_NAME} PRIVATE are) - set_target_properties(${EXAMPLE_NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin - ) - endfunction() - - # Add example subdirectories - add_subdirectory(examples/00_phase1_test) - - message(STATUS "Examples will be built") -endif() - -# Installation rules -install(TARGETS are - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin - PUBLIC_HEADER DESTINATION include/are -) - -install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/are - DESTINATION include - FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp" -) - -install(DIRECTORY ${CMAKE_SOURCE_DIR}/shaders - DESTINATION share/are/shaders -) - -# Print configuration summary -message(STATUS "") -message(STATUS "========================================") -message(STATUS "Aurora Rendering Engine Configuration") -message(STATUS "========================================") -message(STATUS " Version: ${PROJECT_VERSION}") -message(STATUS " Build type: ${CMAKE_BUILD_TYPE}") -message(STATUS " Library type: ${ARE_BUILD_SHARED}") -message(STATUS " C++ standard: ${CMAKE_CXX_STANDARD}") -message(STATUS " Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") -message(STATUS "") -message(STATUS "Features:") -message(STATUS " OpenMP support: ${ARE_USE_OPENMP}") -message(STATUS " Build examples: ${ARE_BUILD_EXAMPLES}") -message(STATUS " Enable profiling: ${ARE_ENABLE_PROFILING}") -message(STATUS " Enable debug vis: ${ARE_ENABLE_DEBUG_VIS}") -message(STATUS "") -message(STATUS "Dependencies:") -message(STATUS " OpenGL: ${OPENGL_LIBRARIES}") -message(STATUS " GLFW: Found") -message(STATUS " GLM: Found") -if(spdlog_FOUND) - message(STATUS " spdlog: Found (system)") -else() - message(STATUS " spdlog: Found (local)") -endif() -message(STATUS " GLAD: ${GLAD_INCLUDE_DIR}") -message(STATUS " STB: ${STB_INCLUDE_DIR}") -message(STATUS "") -message(STATUS "Output directories:") -message(STATUS " Executables: ${CMAKE_BINARY_DIR}/bin") -message(STATUS " Libraries: ${CMAKE_BINARY_DIR}/lib") -message(STATUS "========================================") -message(STATUS "") -``` - -接下来,其实我已经实现了所有头文件,下面是Phase 2的头文件: -### 文件:vertex.h -```cpp -/** - * @file vertex.h - * @brief Vertex data structure definition - */ - -#ifndef ARE_INCLUDE_GEOMETRY_VERTEX_H -#define ARE_INCLUDE_GEOMETRY_VERTEX_H - -#include - -namespace are { - -/** - * @struct Vertex - * @brief Standard vertex structure for mesh data - * - * Contains position, normal, texture coordinates, and tangent information - * for PBR rendering pipeline. - */ -struct Vertex { - Vec3 position_;///< Vertex position in object space - Vec3 normal_; ///< Vertex normal (normalized) - Vec2 texcoord_; ///< Texture coordinates (UV) - Vec3 tangent_; ///< Tangent vector for normal mapping - - Vertex() = default; - - /** - * @brief Construct vertex with position only - * @param pos Position - */ - explicit Vertex(const Vec3& pos); - - /** - * @brief Construct vertex with position and normal - * @param pos Position - * @param norm Normal - */ - Vertex(const Vec3& pos, const Vec3& norm); - - /** - * @brief Construct vertex with position, normal, and texcoord - * @param pos Position - * @param norm Normal - * @param uv Texture coordinates - */ - Vertex(const Vec3& pos, const Vec3& norm, const Vec2& uv); - - /** - * @brief Construct vertex with all attributes - * @param pos Position - * @param norm Normal - * @param uv Texture coordinates - * @param tan Tangent - */ - Vertex(const Vec3& pos, const Vec3& norm, const Vec2& uv, const Vec3& tan); - - /** - * @brief Interpolate between two vertices - * @param a First vertex - * @param b Second vertex - * @param t Interpolation factor [0, 1] - * @return Interpolated vertex - */ - static Vertex lerp(const Vertex& a, const Vertex& b, Real t); -}; - -/** - * @brief Get vertex attribute stride for OpenGL - * @return Size of Vertex structure in bytes - */ -constexpr size_t get_vertex_stride() { - return sizeof(Vertex); -} - -/** - * @brief Get offset of position attribute - * @return Offset in bytes - */ -constexpr size_t get_position_offset() { - return offsetof(Vertex, position_); -} - -/** - * @brief Get offset of normal attribute - * @return Offset in bytes - */ -constexpr size_t get_normal_offset() { - return offsetof(Vertex, normal_); -} - -/** - * @brief Get offset of texcoord attribute - * @return Offset in bytes - */ -constexpr size_t get_texcoord_offset() { - return offsetof(Vertex, texcoord_); -} - -/** - * @brief Get offset of tangent attribute - * @return Offset in bytes - */ -constexpr size_t get_tangent_offset() { - return offsetof(Vertex, tangent_); -} - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_VERTEX_H -``` - -### 文件:triangle.h -```cpp -/** - * @file triangle.h - * @brief Triangle primitive definition - */ - -#ifndef ARE_INCLUDE_GEOMETRY_TRIANGLE_H -#define ARE_INCLUDE_GEOMETRY_TRIANGLE_H - -#include -#include -#include - -namespace are { - -// Forward declaration -struct Ray; -struct HitRecord; - -/** - * @struct Triangle - * @brief Triangle primitive for ray tracing - * - * Stores three vertices and provides intersection testing. - */ -struct Triangle { - Vertex v0_; ///< First vertex - Vertex v1_; ///< Second vertex - Vertex v2_; ///< Third vertex - MaterialHandle material_; ///< Material handle - - /** - * @brief Default constructor - */ - Triangle(); - - /** - * @brief Construct triangle from three vertices - * @param v0 First vertex - * @param v1 Second vertex - * @param v2 Third vertex - * @param material Material handle - */ - Triangle(const Vertex& v0, const Vertex& v1, const Vertex& v2, - MaterialHandle material = are_invalid_handle); - - /** - * @brief Get triangle centroid - * @return Centroid position - */ - Vec3 centroid() const; - - /** - * @brief Get triangle normal (geometric normal) - * @return Normal vector (normalized) - */ - Vec3 normal() const; - - /** - * @brief Get triangle area - * @return Area - */ - Real area() const; - - /** - * @brief Compute axis-aligned bounding box - * @return AABB containing the triangle - */ - AABB compute_aabb() const; - - /** - * @brief Ray-triangle intersection test (Möller-Trumbore algorithm) - * @param ray Ray to test - * @param hit Output hit record - * @return true if intersection occurred - */ - bool intersect(const Ray& ray, HitRecord& hit) const; - - /** - * @brief Fast ray-triangle intersection test (no hit record) - * @param ray Ray to test - * @param t_max Maximum t value - * @return true if intersection occurred - */ - bool intersect_fast(const Ray& ray, Real t_max) const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_TRIANGLE_H -``` - -### 文件:aabb.h -```cpp -/** - * @file aabb.h - * @brief Axis-Aligned Bounding Box implementation - */ - -#ifndef ARE_INCLUDE_GEOMETRY_AABB_H -#define ARE_INCLUDE_GEOMETRY_AABB_H - -#include - -namespace are { - -// Forward declaration -struct Ray; - -/** - * @class AABB - * @brief Axis-Aligned Bounding Box for spatial queries - * - * Used for BVH construction and ray intersection acceleration. - */ -class AABB { -public: - Vec3 min_; ///< Minimum corner - Vec3 max_; ///< Maximum corner - - /** - * @brief Default constructor - creates invalid AABB - */ - AABB(); - - /** - * @brief Construct AABB from min and max corners - * @param min Minimum corner - * @param max Maximum corner - */ - AABB(const Vec3& min, const Vec3& max); - - /** - * @brief Construct AABB containing a single point - * @param point Point to contain - */ - explicit AABB(const Vec3& point); - - /** - * @brief Check if AABB is valid (min <= max) - * @return true if valid - */ - bool is_valid() const; - - /** - * @brief Get center of AABB - * @return Center point - */ - Vec3 center() const; - - /** - * @brief Get size (extent) of AABB - * @return Size vector - */ - Vec3 size() const; - - /** - * @brief Get surface area of AABB - * @return Surface area - */ - Real surface_area() const; - - /** - * @brief Get volume of AABB - * @return Volume - */ - Real volume() const; - - /** - * @brief Get longest axis index (0=x, 1=y, 2=z) - * @return Axis index - */ - int longest_axis() const; - - /** - * @brief Expand AABB to include a point - * @param point Point to include - */ - void expand(const Vec3& point); - - /** - * @brief Expand AABB to include another AABB - * @param other AABB to include - */ - void expand(const AABB& other); - - /** - * @brief Check if AABB contains a point - * @param point Point to check - * @return true if point is inside AABB - */ - bool contains(const Vec3& point) const; - - /** - * @brief Check if AABB intersects another AABB - * @param other AABB to check - * @return true if AABBs intersect - */ - bool intersects(const AABB& other) const; - - /** - * @brief Ray-AABB intersection test - * @param ray Ray to test - * @param t_min Minimum t value (output) - * @param t_max Maximum t value (output) - * @return true if ray intersects AABB - */ - bool intersect_ray(const Ray& ray, Real& t_min, Real& t_max) const; - - /** - * @brief Merge two AABBs - * @param a First AABB - * @param b Second AABB - * @return Merged AABB containing both - */ - static AABB merge(const AABB& a, const AABB& b); - - /** - * @brief Create invalid AABB (for initialization) - * @return Invalid AABB - */ - static AABB invalid(); -}; - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_AABB_H -``` - -### 文件:transform.h -```cpp -/** - * @file transform.h - * @brief Transformation matrix utilities - */ - -#ifndef ARE_INCLUDE_GEOMETRY_TRANSFORM_H -#define ARE_INCLUDE_GEOMETRY_TRANSFORM_H - -#include - -namespace are { - -/** - * @class Transform - * @brief 3D transformation (position, rotation, scale) - * - * Provides convenient interface for building transformation matrices. - */ -class Transform { -public: - /** - * @brief Default constructor (identity transform) - */ - Transform(); - - /** - * @brief Construct from position, rotation, and scale - * @param position Translation - * @param rotation Rotation (Euler angles in radians) - * @param scale Scale factors - */ - Transform(const Vec3& position, const Vec3& rotation, const Vec3& scale); - - // Setters - void set_position(const Vec3& position); - void set_rotation(const Vec3& rotation); - void set_scale(const Vec3& scale); - void set_scale(Real uniform_scale); - - // Getters - const Vec3& get_position() const { return position_; } - const Vec3& get_rotation() const { return rotation_; } - const Vec3& get_scale() const { return scale_; } - - // Matrix operations - Mat4 get_matrix() const; - Mat4 get_inverse_matrix() const; - Mat3 get_normal_matrix() const; - - /** - * @brief Transform a point - * @param point Point to transform - * @return Transformed point - */ - Vec3 transform_point(const Vec3& point) const; - - /** - * @brief Transform a direction (ignores translation) - * @param direction Direction to transform - * @return Transformed direction - */ - Vec3 transform_direction(const Vec3& direction) const; - - /** - * @brief Transform a normal (uses inverse transpose) - * @param normal Normal to transform - * @return Transformed normal - */ - Vec3 transform_normal(const Vec3& normal) const; - - /** - * @brief Combine two transforms - * @param other Other transform - * @return Combined transform - */ - Transform operator*(const Transform& other) const; - - /** - * @brief Create identity transform - * @return Identity transform - */ - static Transform identity(); - - /** - * @brief Create translation transform - * @param translation Translation vector - * @return Translation transform - */ - static Transform translate(const Vec3& translation); - - /** - * @brief Create rotation transform - * @param rotation Rotation (Euler angles in radians) - * @return Rotation transform - */ - static Transform rotate(const Vec3& rotation); - - /** - * @brief Create scale transform - * @param scale Scale factors - * @return Scale transform - */ - static Transform scale(const Vec3& scale); - -private: - void mark_dirty(); - void update_matrix() const; - - Vec3 position_; ///< Translation - Vec3 rotation_; ///< Rotation (Euler angles) - Vec3 scale_; ///< Scale factors - - mutable Mat4 matrix_; ///< Cached transformation matrix - mutable Mat4 inverse_matrix_; ///< Cached inverse matrix - mutable bool dirty_; ///< Matrix needs update -}; - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_TRANSFORM_H -``` - -### 文件:camera.h -```cpp -/** - * @file camera.h - * @brief Camera class for view and projection management - */ - -#ifndef ARE_INCLUDE_SCENE_CAMERA_H -#define ARE_INCLUDE_SCENE_CAMERA_H - -#include - -namespace are { - -/** - * @class Camera - * @brief Perspective camera for rendering - * - * Manages view and projection matrices, and provides ray generation - * for ray tracing. - */ -class Camera { -public: - /** - * @brief Default constructor - */ - Camera(); - - /** - * @brief Construct camera with position and target - * @param position Camera position - * @param target Look-at target - * @param up Up vector - */ - Camera(const Vec3& position, const Vec3& target, const Vec3& up = Vec3(0, 1, 0)); - - // Position and orientation setters - void set_position(const Vec3& position); - void set_target(const Vec3& target); - void set_up(const Vec3& up); - void look_at(const Vec3& position, const Vec3& target, const Vec3& up = Vec3(0, 1, 0)); - - // Projection setters - void set_fov(Real fov_degrees); - void set_aspect_ratio(Real aspect); - void set_near_plane(Real near); - void set_far_plane(Real far); - void set_perspective(Real fov_degrees, Real aspect, Real near, Real far); - - // Getters - const Vec3& get_position() const { return position_; } - const Vec3& get_target() const { return target_; } - const Vec3& get_up() const { return up_; } - Real get_fov() const { return fov_; } - Real get_aspect_ratio() const { return aspect_ratio_; } - Real get_near_plane() const { return near_plane_; } - Real get_far_plane() const { return far_plane_; } - - // Direction vectors - Vec3 get_forward() const; - Vec3 get_right() const; - - // Matrix getters - const Mat4& get_view_matrix() const; - const Mat4& get_projection_matrix() const; - Mat4 get_view_projection_matrix() const; - - /** - * @brief Generate ray for given pixel coordinates - * @param u Normalized x coordinate [0, 1] - * @param v Normalized y coordinate [0, 1] - * @param origin Output ray origin - * @param direction Output ray direction (normalized) - */ - void generate_ray(Real u, Real v, Vec3& origin, Vec3& direction) const; - - /** - * @brief Check if camera parameters have changed - * @return true if matrices need recalculation - */ - bool is_dirty() const { return dirty_; } - - /** - * @brief Mark camera as clean after matrix update - */ - void clear_dirty() { dirty_ = false; } - -private: - void update_view_matrix() const; - void update_projection_matrix() const; - - Vec3 position_; ///< Camera position - Vec3 target_; ///< Look-at target - Vec3 up_; ///< Up vector - - Real fov_; ///< Field of view in degrees - Real aspect_ratio_; ///< Aspect ratio (width/height) - Real near_plane_; ///< Near clipping plane - Real far_plane_; ///< Far clipping plane - - mutable Mat4 view_matrix_; ///< Cached view matrix - mutable Mat4 projection_matrix_; ///< Cached projection matrix - mutable bool view_dirty_; ///< View matrix needs update - mutable bool projection_dirty_; ///< Projection matrix needs update - bool dirty_; ///< Any parameter changed -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_CAMERA_H -``` - -### 文件:mesh.h -```cpp -/** - * @file mesh.h - * @brief Mesh class for geometry storage - */ - -#ifndef ARE_INCLUDE_SCENE_MESH_H -#define ARE_INCLUDE_SCENE_MESH_H - -#include -#include -#include -#include - -namespace are { - -/** - * @class Mesh - * @brief Triangle mesh container - * - * Stores vertex and index data for a triangle mesh. - * Supports automatic AABB computation. - */ -class Mesh { -public: - /** - * @brief Default constructor - creates empty mesh - */ - Mesh(); - - /** - * @brief Construct mesh from vertex and index data - * @param vertices Vertex array - * @param indices Index array (triangles) - * @param material_id Material handle - */ - Mesh(const std::vector& vertices, - const std::vector& indices, - MaterialHandle material_id = are_invalid_handle); - - /** - * @brief Construct mesh from raw arrays - * @param vertices Vertex array pointer - * @param vertex_count Number of vertices - * @param indices Index array pointer - * @param index_count Number of indices - * @param material_id Material handle - */ - Mesh(const Vertex* vertices, size_t vertex_count, - const uint32_t* indices, size_t index_count, - MaterialHandle material_id = are_invalid_handle); - - // Data setters - void set_vertices(const std::vector& vertices); - void set_indices(const std::vector& indices); - void set_material(MaterialHandle material_id); - - // Data getters - const std::vector& get_vertices() const { return vertices_; } - const std::vector& get_indices() const { return indices_; } - MaterialHandle get_material() const { return material_id_; } - - // Geometry queries - size_t get_vertex_count() const { return vertices_.size(); } - size_t get_index_count() const { return indices_.size(); } - size_t get_triangle_count() const { return indices_.size() / 3; } - bool is_empty() const { return vertices_.empty() || indices_.empty(); } - - // AABB - const AABB& get_aabb() const { return aabb_; } - void compute_aabb(); - - /** - * @brief Compute tangent vectors for normal mapping - */ - void compute_tangents();/** - * @brief Get triangle vertices by index - * @param triangle_index Triangle index - * @param v0 Output first vertex - * @param v1 Output second vertex - * @param v2 Output third vertex - * @return true if triangle exists - */ - bool get_triangle(size_t triangle_index, Vertex& v0, Vertex& v1, Vertex& v2) const; - - // GPU resource handles (set by Renderer) - void set_vao(uint32_t vao) { vao_ = vao; } - void set_vbo(uint32_t vbo) { vbo_ = vbo; } - void set_ebo(uint32_t ebo) { ebo_ = ebo; } - uint32_t get_vao() const { return vao_; } - uint32_t get_vbo() const { return vbo_; } - uint32_t get_ebo() const { return ebo_; } - bool has_gpu_resources() const { return vao_ != 0; } - -private: - std::vector vertices_; ///< Vertex data - std::vector indices_; ///< Index data (triangles) - MaterialHandle material_id_; ///< Associated material - AABB aabb_; ///< Bounding box - - // GPU resources - uint32_t vao_; ///< Vertex Array Object - uint32_t vbo_; ///< Vertex Buffer Object - uint32_t ebo_; ///< Element Buffer Object -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_MESH_H -``` - -### 文件:material.h -```cpp -/** - * @file material.h - * @brief PBR material definition - */ - -#ifndef ARE_INCLUDE_SCENE_MATERIAL_H -#define ARE_INCLUDE_SCENE_MATERIAL_H - -#include -#include - -namespace are { - -/** - * @class Material - * @brief Physically-based rendering material - * - * Supports standard PBR workflow with metallic-roughness model. - */ -class Material { -public: - /** - * @brief Default constructor - creates default white material - */ - Material(); - - // Albedo (base color) - void set_albedo(const Vec3& albedo); - void set_albedo_map(const std::string& path); - const Vec3& get_albedo() const { return albedo_; } - const std::string& get_albedo_map() const { return albedo_map_; } - bool has_albedo_map() const { return !albedo_map_.empty(); } - - // Metallic - void set_metallic(Real metallic); - void set_metallic_map(const std::string& path); - Real get_metallic() const { return metallic_; } - const std::string& get_metallic_map() const { return metallic_map_; } - bool has_metallic_map() const { return !metallic_map_.empty(); } - - // Roughness - void set_roughness(Real roughness); - void set_roughness_map(const std::string& path); - Real get_roughness() const { return roughness_; } - const std::string& get_roughness_map() const { return roughness_map_; } - bool has_roughness_map() const { return !roughness_map_.empty(); } - - // Normal map - void set_normal_map(const std::string& path); - const std::string& get_normal_map() const { return normal_map_; } - bool has_normal_map() const { return !normal_map_.empty(); } - - // Ambient occlusion - void set_ao_map(const std::string& path); - const std::string& get_ao_map() const { return ao_map_; } - bool has_ao_map() const { return !ao_map_.empty(); } - - // Emissive - void set_emissive(const Vec3& emissive); - void set_emissive_map(const std::string& path); - const Vec3& get_emissive() const { return emissive_; } - const std::string& get_emissive_map() const { return emissive_map_; } - bool has_emissive_map() const { return !emissive_map_.empty(); } - bool is_emissive() const; - - // Texture handles (set by TextureManager) - void set_albedo_texture_handle(TextureHandle handle) { albedo_tex_handle_ = handle; } - void set_metallic_texture_handle(TextureHandle handle) { metallic_tex_handle_ = handle; } - void set_roughness_texture_handle(TextureHandle handle) { roughness_tex_handle_ = handle; } - void set_normal_texture_handle(TextureHandle handle) { normal_tex_handle_ = handle; } - void set_ao_texture_handle(TextureHandle handle) { ao_tex_handle_ = handle; } - void set_emissive_texture_handle(TextureHandle handle) { emissive_tex_handle_ = handle; } - - TextureHandle get_albedo_texture_handle() const { return albedo_tex_handle_; } - TextureHandle get_metallic_texture_handle() const { return metallic_tex_handle_; } - TextureHandle get_roughness_texture_handle() const { return roughness_tex_handle_; } - TextureHandle get_normal_texture_handle() const { return normal_tex_handle_; } - TextureHandle get_ao_texture_handle() const { return ao_tex_handle_; } - TextureHandle get_emissive_texture_handle() const { return emissive_tex_handle_; } - -private: - // Base values - Vec3 albedo_;///< Base color (RGB) - Real metallic_; ///< Metallic factor [0, 1] - Real roughness_; ///< Roughness factor [0, 1] - Vec3 emissive_; ///< Emissive color (RGB) - - // Texture paths - std::string albedo_map_; - std::string metallic_map_; - std::string roughness_map_; - std::string normal_map_; - std::string ao_map_; - std::string emissive_map_; - - // Texture handles (GPU resources) - TextureHandle albedo_tex_handle_; - TextureHandle metallic_tex_handle_; - TextureHandle roughness_tex_handle_; - TextureHandle normal_tex_handle_; - TextureHandle ao_tex_handle_; - TextureHandle emissive_tex_handle_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_MATERIAL_H -``` - -### 文件:light.h -```cpp -/** - * @file light.h - * @brief Base light class and common light utilities - */ - -#ifndef ARE_INCLUDE_SCENE_LIGHT_H -#define ARE_INCLUDE_SCENE_LIGHT_H - -#include - -namespace are { - -/** - * @enum LightType - * @brief Types of light sources - */ -enum class LightType { - ARE_LIGHT_DIRECTIONAL, - ARE_LIGHT_POINT, - ARE_LIGHT_SPOT -}; - -/** - * @struct LightData - * @brief Packed light data for GPU transfer - * - * This structure is designed to be efficiently transferred to GPU - * via SSBO or UBO. - */ -struct LightData { - Vec4 position_type_; ///< xyz: position, w: light type - Vec4 direction_range_; ///< xyz: direction, w: range - Vec4 color_intensity_; ///< xyz: color, w: intensity - Vec4 params_; ///< Light-specific parameters -}; - -/** - * @class Light - * @brief Base class for all light types - */ -class Light { -public: - /** - * @brief Constructor - * @param type Light type - */ - explicit Light(LightType type); - - virtual ~Light() = default; - - // Common properties - void set_color(const Vec3& color); - void set_intensity(Real intensity); - void set_cast_shadows(bool cast); - - const Vec3& get_color() const { return color_; } - Real get_intensity() const { return intensity_; } - bool get_cast_shadows() const { return cast_shadows_; } - LightType get_type() const { return type_; } - - /** - * @brief Pack light data for GPU transfer - * @return Packed light data - */ - virtual LightData pack() const = 0; - - /** - * @brief Check if light affects a point - * @param point World position - * @return true if light can affect the point - */ - virtual bool affects_point(const Vec3& point) const = 0; - -protected: - LightType type_; ///< Light type - Vec3 color_; ///< Light color (RGB) - Real intensity_; ///< Light intensity - bool cast_shadows_; ///< Whether light casts shadows -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_LIGHT_H -``` - -### 文件:scene_manager.h -```cpp -/** - * @file scene_manager.h - * @brief Scene data management - */ - -#ifndef ARE_INCLUDE_SCENE_SCENE_MANAGER_H -#define ARE_INCLUDE_SCENE_SCENE_MANAGER_H - -#include -#include -#include -#include -#include -#include -#include - -namespace are { - -/** - * @class SceneManager - * @brief Manages all scene objects (meshes, materials, lights) - * - * Provides handle-based access to scene resources and tracks - * scene modifications for BVH rebuilding. - */ -class SceneManager { -public: - /** - * @brief Constructor - */ - SceneManager(); - - /** - * @brief Destructor - */ - ~SceneManager(); - - // Mesh management - MeshHandle add_mesh(const Mesh& mesh); - void remove_mesh(MeshHandle handle); - void update_mesh(MeshHandle handle, const Mesh& mesh); - Mesh* get_mesh(MeshHandle handle); - const Mesh* get_mesh(MeshHandle handle) const; - const std::vector& get_all_meshes() const { return meshes_; } - - // Material management - MaterialHandle add_material(const Material& material); - void remove_material(MaterialHandle handle); - void update_material(MaterialHandle handle, const Material& material); - Material* get_material(MaterialHandle handle); - const Material* get_material(MaterialHandle handle) const; - const std::vector& get_all_materials() const { return materials_; } - - // Light management - LightHandle add_light(const std::shared_ptr& light); - void remove_light(LightHandle handle); - std::shared_ptr get_light(LightHandle handle); - const std::vector>& get_all_lights() const { return lights_; } - - // Scene queries - size_t get_mesh_count() const { return meshes_.size(); } - size_t get_material_count() const { return materials_.size(); } - size_t get_light_count() const { return lights_.size(); } - size_t get_total_triangle_count() const; - - // Scene state - bool is_dirty() const { return dirty_; } - void mark_dirty() { dirty_ = true; } - void clear_dirty() { dirty_ = false; } - - /** - * @brief Clear all scene data - */ - void clear(); - - /** - * @brief Validate all handles and remove invalid entries - */ - void compact(); - -private: - std::vector meshes_; ///< Mesh storage - std::vector materials_; ///< Material storage - std::vector> lights_; ///< Light storage - - std::unordered_map mesh_handle_map_; - std::unordered_map material_handle_map_; - std::unordered_map light_handle_map_; - - MeshHandle next_mesh_handle_; - MaterialHandle next_material_handle_; - LightHandle next_light_handle_; - - bool dirty_; ///< Scene modified flag -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_SCENE_MANAGER_H -``` -关于异常部分,你直接ARE_LOG_CRITICAL然后返回或者throw std::runtime_error即可;GLM已经有了自定义别名,且已经启用GLM扩展。 -关于命名空间的话,就像你刚才看到的一样,代码包裹在are命名空间中。 -还有需要我提供的东西吗?没有的话,你可以开始分步骤实现Phase 2。 diff --git a/include/are/acceleration/bvh.h b/include/are/acceleration/bvh.h deleted file mode 100644 index f5b45bd..0000000 --- a/include/are/acceleration/bvh.h +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file bvh.h - * @brief BVH interface and traversal - */ - -#ifndef ARE_INCLUDE_ACCELERATION_BVH_H -#define ARE_INCLUDE_ACCELERATION_BVH_H - -#include -#include -#include -#include -#include -#include -#include - -namespace are { - -/** - * @class BVH - * @brief Bounding Volume Hierarchy for ray tracing acceleration - */ -class BVH { -public: - /** - * @brief Constructor - */ - BVH(); - - /** - * @brief Destructor - */ - ~BVH(); - - /** - * @brief Build BVH from triangle list - * @param triangles Triangle list - * @param config Build configuration - * @return true if build succeeded - */ - bool build(const std::vector &triangles, - const BVHBuildConfig &config = BVHBuildConfig()); - - /** - * @brief Traverse BVH and find closest intersection - * @param ray Ray to trace - * @param hit Output hit record - * @return true if intersection found - */ - bool intersect(const Ray &ray, HitRecord &hit) const; - - /** - * @brief Fast occlusion test (any hit) - * @param ray Ray to trace - * @param t_max Maximum t value - * @return true if any intersection found - */ - bool intersect_any(const Ray &ray, Real t_max) const; - /** - * @brief Fast occlusion test (any hit), with ignored triangle id - * @param ray Ray to trace - * @param t_max Maximum t value - * @param ignore_triangle_index Triangle index to ignore (e.g. self primitive id) - * @return true if any intersection found (excluding ignored triangle) - */ - bool intersect_any(const Ray &ray, Real t_max, uint32_t ignore_triangle_index) const; - - /** - * @brief Check if BVH is built - * @return true if built - */ - bool is_built() const { - return !nodes_.empty(); - } - - /** - * @brief Get BVH nodes (for GPU upload) - * @return Node array - */ - const std::vector &get_nodes() const { - return nodes_; - } - - /** - * @brief Get primitive indices - * @return Index array - */ - const std::vector &get_primitive_indices() const { - return primitive_indices_; - } - - /** - * @brief Get triangles - * @return Triangle array - */ - const std::vector &get_triangles() const { - return triangles_; - } - - /** - * @brief Get memory usage in bytes - * @return Memory usage - */ - size_t get_memory_usage() const; - - /** - * @brief Clear BVH data - */ - void clear(); - -private: - // Recursive traversal (kept for reference) - bool intersect_recursive(uint32_t node_index, const Ray &ray, HitRecord &hit) const; - bool intersect_any_recursive(uint32_t node_index, const Ray &ray, Real t_max) const; - - // Optimized iterative traversal - bool intersect_iterative(const Ray &ray, HitRecord &hit) const; - bool intersect_any_iterative(const Ray &ray, Real t_max) const; - - // Fast intersection helpers - inline bool intersect_aabb_fast(const AABB &bounds, const Ray &ray, - const Vec3 &inv_dir, Real t_max, - Real &t_min_out, Real &t_max_out) const; - inline bool intersect_triangle_fast(const Triangle &triangle, const Ray &ray, - Real t_max, HitRecord &hit) const; - - std::vector nodes_; ///< BVH nodes - std::vector primitive_indices_; ///< Primitive index array - std::vector triangles_; ///< Triangle data - uint32_t root_index_; ///< Root node index -}; - -} // namespace are - -#endif // ARE_INCLUDE_ACCELERATION_BVH_H diff --git a/include/are/acceleration/bvh_builder.h b/include/are/acceleration/bvh_builder.h deleted file mode 100644 index cc9ed6a..0000000 --- a/include/are/acceleration/bvh_builder.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * @file bvh_builder.h - * @brief BVH construction algorithms - */ - -#ifndef ARE_INCLUDE_ACCELERATION_BVH_BUILDER_H -#define ARE_INCLUDE_ACCELERATION_BVH_BUILDER_H - -#include -#include -#include -#include - -namespace are { - -/** - * @enum BVHSplitMethod - * @brief BVH splitting strategies - */ -enum class BVHSplitMethod { - ARE_BVH_SPLIT_MIDDLE, ///< Split at midpoint - ARE_BVH_SPLIT_SAH ///< Surface Area Heuristic -}; - -/** - * @struct BVHBuildConfig - * @brief Configuration for BVH construction - */ -struct BVHBuildConfig { - BVHSplitMethod split_method_ = BVHSplitMethod::ARE_BVH_SPLIT_SAH; - int max_leaf_size_ = 4; ///< Maximum triangles per leaf - int max_depth_ = 64; ///< Maximum tree depth - bool use_multithreading_ = true; ///< Use parallel construction -}; - -/** - * @class BVHBuilder - * @brief Constructs BVH from triangle list - */ -class BVHBuilder { -public: - /** - * @brief Constructor - * @param config Build configuration - */ - explicit BVHBuilder(const BVHBuildConfig& config = BVHBuildConfig()); - - /** - * @brief Build BVH from triangles - * @param triangles Triangle list - * @param nodes Output node list - * @param primitive_indices Output primitive index list - * @return Root node index - */ - uint32_t build(const std::vector& triangles, - std::vector& nodes, - std::vector& primitive_indices); - - /** - * @brief Get build statistics - * @param node_count Output node count - * @param leaf_count Output leaf count - * @param max_depth Output maximum depth reached - */ - void get_stats(size_t& node_count, size_t& leaf_count, int& max_depth) const; - -private: - struct BuildEntry { - uint32_t parent_; - uint32_t start_; - uint32_t end_; - int depth_; - }; - - uint32_t build_recursive(const std::vector& triangles, - std::vector& nodes, - std::vector& primitive_indices, - uint32_t start, uint32_t end, int depth); - - int find_best_split_axis(const std::vector& triangles, - const std::vector& indices, - uint32_t start, uint32_t end); - - Real compute_sah_cost(const AABB& bounds, uint32_t count); - - BVHBuildConfig config_; - size_t node_count_; - size_t leaf_count_; - int max_depth_reached_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_ACCELERATION_BVH_BUILDER_H diff --git a/include/are/acceleration/bvh_node.h b/include/are/acceleration/bvh_node.h deleted file mode 100644 index 7d90c5c..0000000 --- a/include/are/acceleration/bvh_node.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file bvh_node.h - * @brief BVH node structure - */ - -#ifndef ARE_INCLUDE_ACCELERATION_BVH_NODE_H -#define ARE_INCLUDE_ACCELERATION_BVH_NODE_H - -#include -#include - -namespace are { - -/** - * @struct BVHNode - * @brief Node in Bounding Volume Hierarchy - * - * Uses a compact representation for efficient GPU transfer. - */ -struct BVHNode { - AABB bounds_; ///< Node bounding box - - union { - uint32_t left_child_; ///< Left child index (internal node) - uint32_t first_primitive_; ///< First primitive index (leaf node) - }; - - union { - uint32_t right_child_; ///< Right child index (internal node) - uint32_t primitive_count_; ///< Number of primitives (leaf node) - }; - - /** - * @brief Check if node is a leaf - * @return true if leaf node - */ - bool is_leaf() const { - return primitive_count_ > 0; - } - - /** - * @brief Get node surface area (for SAH) - * @return Surface area - */ - Real surface_area() const { - return bounds_.surface_area(); - } -}; - -} // namespace are - -#endif // ARE_INCLUDE_ACCELERATION_BVH_NODE_H diff --git a/include/are/are.h b/include/are/are.h deleted file mode 100644 index 175abcd..0000000 --- a/include/are/are.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file are.h - * @brief Aurora Rendering Engine - Main header file - * - * This header includes all public interfaces of the Aurora Rendering Engine. - * Users only need to include this single header to access all functionality. - * - * @author Ternary_Operator - * @version 1.0 - */ - -#ifndef ARE_INCLUDE_ARE_H -#define ARE_INCLUDE_ARE_H - -// Core modules -#include -#include -#include -#include - -// Platform modules -#include -#include - -// Geometry modules -#include -#include -#include -#include - -// Scene modules -#include -#include -#include -#include -#include -#include -#include -#include - -// Acceleration modules -#include - -// Renderer modules -#include -#include - -// Utility modules -#include -#include - -/** - * @namespace are - * @brief Main namespace for Aurora Rendering Engine - */ -namespace are { - -/** - * @brief Get the version string of the engine - * @return Version string in format "major.minor.patch" - */ -const char* get_version(); - -/** - * @brief Initialize the Aurora Rendering Engine - * @return true if initialization succeeded, false otherwise - */ -bool initialize(); - -/** - * @brief Shutdown the Aurora Rendering Engine - */ -void shutdown(); - -} // namespace are - -#endif // ARE_INCLUDE_ARE_H diff --git a/include/are/core/config.h b/include/are/core/config.h deleted file mode 100644 index 0c83fb9..0000000 --- a/include/are/core/config.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file config.h - * @brief Configuration system for the rendering engine - */ - -#ifndef ARE_INCLUDE_CORE_CONFIG_H -#define ARE_INCLUDE_CORE_CONFIG_H - -#include -#include - -namespace are { - -/** - * @struct WindowConfig - * @brief Configuration for window creation - */ -struct WindowConfig { - int width = 1280; ///< Window width in pixels - int height = 720; ///< Window height in pixels - std::string title = "Aurora Rendering Engine"; ///< Window title - bool resizable = true; ///< Whether window is resizable - bool vsync = true; ///< Enable vertical synchronization - int samples = 1; ///< MSAA samples (1 = disabled) -}; - -/** - * @struct RayTracingConfig - * @brief Configuration for ray tracing - */ -struct RayTracingConfig { - RayTracingBackend backend = RayTracingBackend::ARE_RT_BACKEND_COMPUTE_SHADER; - int spp = 64; ///< Samples per pixel - int max_depth = 8; ///< Maximum ray bounce depth - bool enable_gi = true; ///< Enable global illumination - bool enable_ao = true; ///< Enable ambient occlusion - bool enable_soft_shadows = false; ///< Enable soft shadows - int ao_samples = 16; ///< AO sample count - Real ao_radius = 1.0f; ///< AO sampling radius -}; - -/** - * @struct RenderConfig - * @brief General rendering configuration - */ -struct RenderConfig { - ToneMappingOperator tonemap_op = ToneMappingOperator::ARE_TONEMAP_ACES; - Real exposure = 1.0f; ///< Exposure value for tone mapping - bool use_hdr = true; ///< Use HDR rendering pipeline - GBufferVisualizationMode gbuffer_vis_mode = GBufferVisualizationMode::ARE_GBUFFER_VIS_NONE; -}; - -/** - * @struct PerformanceConfig - * @brief Performance-related configuration - */ -struct PerformanceConfig { - int num_threads = 0; ///< Number of threads (0 = auto-detect) - bool enable_bvh_multithreading = true; ///< Use multithreading for BVH construction - bool enable_profiling = false; ///< Enable performance profiling -}; - -/** - * @struct PathConfig - * @brief File path configuration - */ -struct PathConfig { - std::string shader_dir = "shaders/"; ///< Directory containing shader files - std::string texture_dir = "textures/"; ///< Default texture directory - std::string output_dir = "output/"; ///< Default output directory -}; - -/** - * @class AreConfig - * @brief Main configuration class for Aurora Rendering Engine - */ -class AreConfig { -public: - WindowConfig window; ///< Window configuration - RayTracingConfig ray_tracing; ///< Ray tracing configuration - RenderConfig render; ///< Rendering configuration - PerformanceConfig performance; ///< Performance configuration - PathConfig paths; ///< Path configuration - - /** - * @brief Constructor with default values - */ - AreConfig() = default; - - /** - * @brief Validate configuration values - * @return true if configuration is valid, false otherwise - */ - bool validate() const; - - /** - * @brief Print configuration to console - */ - void print() const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_CORE_CONFIG_H diff --git a/include/are/core/logger.h b/include/are/core/logger.h deleted file mode 100644 index e0bc34a..0000000 --- a/include/are/core/logger.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @file logger.h - * @brief Logging system for the rendering engine - */ - -#ifndef ARE_INCLUDE_CORE_LOGGER_H -#define ARE_INCLUDE_CORE_LOGGER_H - -#include -#include - -namespace are { - -/** - * @enum LogLevel - * @brief Logging severity levels - */ -enum class LogLevel { - ARE_LOG_TRACE, - ARE_LOG_DEBUG, - ARE_LOG_INFO, - ARE_LOG_WARN, - ARE_LOG_ERROR, - ARE_LOG_CRITICAL -}; - -/** - * @class Logger - * @brief Thread-safe logging system - * - * This class provides a simple interface for logging messages with different - * severity levels. It wraps spdlog for actual logging functionality. - */ -class Logger { -public: - /** - * @brief Initialize the logging system - * @param min_level Minimum log level to display - */ - static void init(LogLevel min_level = LogLevel::ARE_LOG_INFO); - - /** - * @brief Shutdown the logging system - */ - static void shutdown(); - - /** - * @brief Log a message with file/function/line information - * @param level Log severity level - * @param file Source file name - * @param func Function name - * @param line Line number - * @param message Log message - */ - static void log(LogLevel level, const char* file, const char* func, - int line, const std::string& message); - - /** - * @brief Set minimum log level - * @param level Minimum log level to display - */ - static void set_level(LogLevel level); - -private: - static std::shared_ptr logger_impl_; ///< Internal logger implementation - static bool initialized_; ///< Initialization flag -}; - -} // namespace are - -// Logging macros -#define ARE_LOG_TRACE(msg) are::Logger::log(are::LogLevel::ARE_LOG_TRACE, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_DEBUG(msg) are::Logger::log(are::LogLevel::ARE_LOG_DEBUG, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_INFO(msg) are::Logger::log(are::LogLevel::ARE_LOG_INFO, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_WARN(msg) are::Logger::log(are::LogLevel::ARE_LOG_WARN, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_ERROR(msg) are::Logger::log(are::LogLevel::ARE_LOG_ERROR, __FILE__, __func__, __LINE__, msg) -#define ARE_LOG_CRITICAL(msg) are::Logger::log(are::LogLevel::ARE_LOG_CRITICAL, __FILE__, __func__, __LINE__, msg) - -#endif // ARE_INCLUDE_CORE_LOGGER_H diff --git a/include/are/core/profiler.h b/include/are/core/profiler.h deleted file mode 100644 index cbbb663..0000000 --- a/include/are/core/profiler.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @file profiler.h - * @brief Performance profiling utilities - */ - -#ifndef ARE_INCLUDE_CORE_PROFILER_H -#define ARE_INCLUDE_CORE_PROFILER_H - -#include -#include -#include -#include - -namespace are { - -/** - * @struct ProfileResult - * @brief Result of a profiling measurement - */ -struct ProfileResult { - std::string name_; ///< Profile section name - double duration_ms_; ///< Duration in milliseconds - uint64_t call_count_; ///< Number of times called - double avg_duration_ms_; ///< Average duration per call -}; - -/** - * @class Profiler - * @brief Simple performance profiler - * - * This class provides basic timing functionality for performance analysis. - * It is only active when ARE_ENABLE_PROFILING is defined. - */ -class Profiler { -public: - /** - * @brief Initialize the profiler - */ - static void init(); - - /** - * @brief Shutdown the profiler and print results - */ - static void shutdown(); - - /** - * @brief Begin a profiling section - * @param name Section name - */ - static void begin(const std::string& name); - - /** - * @brief End a profiling section - * @param name Section name - */ - static void end(const std::string& name); - - /** - * @brief Get profiling results - * @return Map of section names to profile results - */ - static const std::unordered_map& get_results(); - - /** - * @brief Reset all profiling data - */ - static void reset(); - - /** - * @brief Print profiling results to console - */ - static void print_results(); - -private: - struct SectionData { - std::chrono::high_resolution_clock::time_point start_time_; - double total_duration_ms_ = 0.0; - uint64_t call_count_ = 0; - }; - - static std::unordered_map sections_; - static std::unordered_map results_; - static bool enabled_; -}; - -/** - * @class ScopedProfiler - * @brief RAII-style profiler for automatic timing - */ -class ScopedProfiler { -public: - /** - * @brief Constructor - begins profiling - * @param name Section name - */ - explicit ScopedProfiler(const std::string& name); - - /** - * @brief Destructor - ends profiling - */ - ~ScopedProfiler(); - -private: - std::string name_; -}; - -} // namespace are - -// Profiling macros -#ifdef ARE_ENABLE_PROFILING - #define ARE_PROFILE_BEGIN(name) are::Profiler::begin(name) - #define ARE_PROFILE_END(name) are::Profiler::end(name) - #define ARE_PROFILE_SCOPE(name) are::ScopedProfiler are_profiler_##__LINE__(name) - #define ARE_PROFILE_FUNCTION() ARE_PROFILE_SCOPE(__func__) -#else - #define ARE_PROFILE_BEGIN(name) ((void)0) - #define ARE_PROFILE_END(name) ((void)0) - #define ARE_PROFILE_SCOPE(name) ((void)0) - #define ARE_PROFILE_FUNCTION() ((void)0) -#endif - -#endif // ARE_INCLUDE_CORE_PROFILER_H diff --git a/include/are/core/types.h b/include/are/core/types.h deleted file mode 100644 index 29abb94..0000000 --- a/include/are/core/types.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file types.h - * @brief Basic type definitions and constants - */ - -#ifndef ARE_INCLUDE_CORE_TYPES_H -#define ARE_INCLUDE_CORE_TYPES_H - -#include -#include - -namespace are { - -// Floating point precision -using Real = float; - -// Common vector types -using Vec2 = glm::vec2; -using Vec3 = glm::vec3; -using Vec4 = glm::vec4; - -using Vec2i = glm::ivec2; -using Vec3i = glm::ivec3; -using Vec4i = glm::ivec4; - -// Matrix types -using Mat3 = glm::mat3; -using Mat4 = glm::mat4; - -// Color type (RGBA) -using Color = Vec4; - -// Handle types for resource management -using MeshHandle = uint32_t; -using MaterialHandle = uint32_t; -using LightHandle = uint32_t; -using TextureHandle = uint32_t; - -// Invalid handle constant -constexpr uint32_t are_invalid_handle = 0xFFFFFFFF; - -// Mathematical constants -constexpr Real are_pi = 3.14159265358979323846f; -constexpr Real are_two_pi = 6.28318530717958647692f; -constexpr Real are_inv_pi = 0.31830988618379067154f; -constexpr Real are_inv_two_pi = 0.15915494309189533577f; -constexpr Real are_epsilon = 1e-6f; - -// Ray tracing backend types -enum class RayTracingBackend { - ARE_RT_BACKEND_CPU, - ARE_RT_BACKEND_COMPUTE_SHADER -}; - -// Tone mapping operators -enum class ToneMappingOperator { - ARE_TONEMAP_NONE, - ARE_TONEMAP_REINHARD, - ARE_TONEMAP_ACES -}; - -// G-Buffer visualization modes -enum class GBufferVisualizationMode { - ARE_GBUFFER_VIS_NONE, - ARE_GBUFFER_VIS_POSITION, - ARE_GBUFFER_VIS_NORMAL, - ARE_GBUFFER_VIS_ALBEDO, - ARE_GBUFFER_VIS_METALLIC, - ARE_GBUFFER_VIS_ROUGHNESS, - ARE_GBUFFER_VIS_DEPTH -}; - -} // namespace are - -#endif // ARE_INCLUDE_CORE_TYPES_H diff --git a/include/are/geometry/aabb.h b/include/are/geometry/aabb.h deleted file mode 100644 index 6c301b0..0000000 --- a/include/are/geometry/aabb.h +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @file aabb.h - * @brief Axis-Aligned Bounding Box implementation - */ - -#ifndef ARE_INCLUDE_GEOMETRY_AABB_H -#define ARE_INCLUDE_GEOMETRY_AABB_H - -#include - -namespace are { - -// Forward declaration -struct Ray; - -/** - * @class AABB - * @brief Axis-Aligned Bounding Box for spatial queries - * - * Used for BVH construction and ray intersection acceleration. - */ -class AABB { -public: - Vec3 min_; ///< Minimum corner - Vec3 max_; ///< Maximum corner - - /** - * @brief Default constructor - creates invalid AABB - */ - AABB(); - - /** - * @brief Construct AABB from min and max corners - * @param min Minimum corner - * @param max Maximum corner - */ - AABB(const Vec3& min, const Vec3& max); - - /** - * @brief Construct AABB containing a single point - * @param point Point to contain - */ - explicit AABB(const Vec3& point); - - /** - * @brief Check if AABB is valid (min <= max) - * @return true if valid - */ - bool is_valid() const; - - /** - * @brief Get center of AABB - * @return Center point - */ - Vec3 center() const; - - /** - * @brief Get size (extent) of AABB - * @return Size vector - */ - Vec3 size() const; - - /** - * @brief Get surface area of AABB - * @return Surface area - */ - Real surface_area() const; - - /** - * @brief Get volume of AABB - * @return Volume - */ - Real volume() const; - - /** - * @brief Get longest axis index (0=x, 1=y, 2=z) - * @return Axis index - */ - int longest_axis() const; - - /** - * @brief Expand AABB to include a point - * @param point Point to include - */ - void expand(const Vec3& point); - - /** - * @brief Expand AABB to include another AABB - * @param other AABB to include - */ - void expand(const AABB& other); - - /** - * @brief Check if AABB contains a point - * @param point Point to check - * @return true if point is inside AABB - */ - bool contains(const Vec3& point) const; - - /** - * @brief Check if AABB intersects another AABB - * @param other AABB to check - * @return true if AABBs intersect - */ - bool intersects(const AABB& other) const; - - /** - * @brief Ray-AABB intersection test - * @param ray Ray to test - * @param t_min Minimum t value (output) - * @param t_max Maximum t value (output) - * @return true if ray intersects AABB - */ - bool intersect_ray(const Ray& ray, Real& t_min, Real& t_max) const; - - /** - * @brief Merge two AABBs - * @param a First AABB - * @param b Second AABB - * @return Merged AABB containing both - */ - static AABB merge(const AABB& a, const AABB& b); - - /** - * @brief Create invalid AABB (for initialization) - * @return Invalid AABB - */ - static AABB invalid(); -}; - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_AABB_H diff --git a/include/are/geometry/transform.h b/include/are/geometry/transform.h deleted file mode 100644 index b79f284..0000000 --- a/include/are/geometry/transform.h +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @file transform.h - * @brief Transformation matrix utilities - */ - -#ifndef ARE_INCLUDE_GEOMETRY_TRANSFORM_H -#define ARE_INCLUDE_GEOMETRY_TRANSFORM_H - -#include - -namespace are { - -/** - * @class Transform - * @brief 3D transformation (position, rotation, scale) - * - * Provides convenient interface for building transformation matrices. - */ -class Transform { -public: - /** - * @brief Default constructor (identity transform) - */ - Transform(); - - /** - * @brief Construct from position, rotation, and scale - * @param position Translation - * @param rotation Rotation (Euler angles in radians) - * @param scale Scale factors - */ - Transform(const Vec3& position, const Vec3& rotation, const Vec3& scale); - - // Setters - void set_position(const Vec3& position); - void set_rotation(const Vec3& rotation); - void set_scale(const Vec3& scale); - void set_scale(Real uniform_scale); - - // Getters - const Vec3& get_position() const { return position_; } - const Vec3& get_rotation() const { return rotation_; } - const Vec3& get_scale() const { return scale_; } - - // Matrix operations - Mat4 get_matrix() const; - Mat4 get_inverse_matrix() const; - Mat3 get_normal_matrix() const; - - /** - * @brief Transform a point - * @param point Point to transform - * @return Transformed point - */ - Vec3 transform_point(const Vec3& point) const; - - /** - * @brief Transform a direction (ignores translation) - * @param direction Direction to transform - * @return Transformed direction - */ - Vec3 transform_direction(const Vec3& direction) const; - - /** - * @brief Transform a normal (uses inverse transpose) - * @param normal Normal to transform - * @return Transformed normal - */ - Vec3 transform_normal(const Vec3& normal) const; - - /** - * @brief Combine two transforms - * @param other Other transform - * @return Combined transform - */ - Transform operator*(const Transform& other) const; - - /** - * @brief Create identity transform - * @return Identity transform - */ - static Transform identity(); - - /** - * @brief Create translation transform - * @param translation Translation vector - * @return Translation transform - */ - static Transform translate(const Vec3& translation); - - /** - * @brief Create rotation transform - * @param rotation Rotation (Euler angles in radians) - * @return Rotation transform - */ - static Transform rotate(const Vec3& rotation); - - /** - * @brief Create scale transform - * @param scale Scale factors - * @return Scale transform - */ - static Transform scale(const Vec3& scale); - -private: - void mark_dirty(); - void update_matrix() const; - - Vec3 position_; ///< Translation - Vec3 rotation_; ///< Rotation (Euler angles) - Vec3 scale_; ///< Scale factors - - mutable Mat4 matrix_; ///< Cached transformation matrix - mutable Mat4 inverse_matrix_; ///< Cached inverse matrix - mutable bool dirty_; ///< Matrix needs update -}; - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_TRANSFORM_H diff --git a/include/are/geometry/triangle.h b/include/are/geometry/triangle.h deleted file mode 100644 index 0df0809..0000000 --- a/include/are/geometry/triangle.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file triangle.h - * @brief Triangle primitive definition - */ - -#ifndef ARE_INCLUDE_GEOMETRY_TRIANGLE_H -#define ARE_INCLUDE_GEOMETRY_TRIANGLE_H - -#include -#include -#include - -namespace are { - -// Forward declaration -struct Ray; -struct HitRecord; - -/** - * @struct Triangle - * @brief Triangle primitive for ray tracing - * - * Stores three vertices and provides intersection testing. - */ -struct Triangle { - Vertex v0_; ///< First vertex - Vertex v1_; ///< Second vertex - Vertex v2_; ///< Third vertex - MaterialHandle material_; ///< Material handle - - /** - * @brief Default constructor - */ - Triangle(); - - /** - * @brief Construct triangle from three vertices - * @param v0 First vertex - * @param v1 Second vertex - * @param v2 Third vertex - * @param material Material handle - */ - Triangle(const Vertex& v0, const Vertex& v1, const Vertex& v2, - MaterialHandle material = are_invalid_handle); - - /** - * @brief Get triangle centroid - * @return Centroid position - */ - Vec3 centroid() const; - - /** - * @brief Get triangle normal (geometric normal) - * @return Normal vector (normalized) - */ - Vec3 normal() const; - - /** - * @brief Get triangle area - * @return Area - */ - Real area() const; - - /** - * @brief Compute axis-aligned bounding box - * @return AABB containing the triangle - */ - AABB compute_aabb() const; - - /** - * @brief Ray-triangle intersection test (Möller-Trumbore algorithm) - * @param ray Ray to test - * @param hit Output hit record - * @return true if intersection occurred - */ - bool intersect(const Ray& ray, HitRecord& hit) const; - - /** - * @brief Fast ray-triangle intersection test (no hit record) - * @param ray Ray to test - * @param t_max Maximum t value - * @return true if intersection occurred - */ - bool intersect_fast(const Ray& ray, Real t_max) const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_TRIANGLE_H diff --git a/include/are/geometry/vertex.h b/include/are/geometry/vertex.h deleted file mode 100644 index 398805b..0000000 --- a/include/are/geometry/vertex.h +++ /dev/null @@ -1,110 +0,0 @@ -/** - * @file vertex.h - * @brief Vertex data structure definition - */ - -#ifndef ARE_INCLUDE_GEOMETRY_VERTEX_H -#define ARE_INCLUDE_GEOMETRY_VERTEX_H - -#include - -namespace are { - -/** - * @struct Vertex - * @brief Standard vertex structure for mesh data - * - * Contains position, normal, texture coordinates, and tangent information - * for PBR rendering pipeline. - */ -struct Vertex { - Vec3 position_;///< Vertex position in object space - Vec3 normal_; ///< Vertex normal (normalized) - Vec2 texcoord_; ///< Texture coordinates (UV) - Vec3 tangent_; ///< Tangent vector for normal mapping - - Vertex() = default; - - /** - * @brief Construct vertex with position only - * @param pos Position - */ - explicit Vertex(const Vec3& pos); - - /** - * @brief Construct vertex with position and normal - * @param pos Position - * @param norm Normal - */ - Vertex(const Vec3& pos, const Vec3& norm); - - /** - * @brief Construct vertex with position, normal, and texcoord - * @param pos Position - * @param norm Normal - * @param uv Texture coordinates - */ - Vertex(const Vec3& pos, const Vec3& norm, const Vec2& uv); - - /** - * @brief Construct vertex with all attributes - * @param pos Position - * @param norm Normal - * @param uv Texture coordinates - * @param tan Tangent - */ - Vertex(const Vec3& pos, const Vec3& norm, const Vec2& uv, const Vec3& tan); - - /** - * @brief Interpolate between two vertices - * @param a First vertex - * @param b Second vertex - * @param t Interpolation factor [0, 1] - * @return Interpolated vertex - */ - static Vertex lerp(const Vertex& a, const Vertex& b, Real t); -}; - -/** - * @brief Get vertex attribute stride for OpenGL - * @return Size of Vertex structure in bytes - */ -constexpr size_t get_vertex_stride() { - return sizeof(Vertex); -} - -/** - * @brief Get offset of position attribute - * @return Offset in bytes - */ -constexpr size_t get_position_offset() { - return offsetof(Vertex, position_); -} - -/** - * @brief Get offset of normal attribute - * @return Offset in bytes - */ -constexpr size_t get_normal_offset() { - return offsetof(Vertex, normal_); -} - -/** - * @brief Get offset of texcoord attribute - * @return Offset in bytes - */ -constexpr size_t get_texcoord_offset() { - return offsetof(Vertex, texcoord_); -} - -/** - * @brief Get offset of tangent attribute - * @return Offset in bytes - */ -constexpr size_t get_tangent_offset() { - return offsetof(Vertex, tangent_); -} - -} // namespace are - -#endif // ARE_INCLUDE_GEOMETRY_VERTEX_H diff --git a/include/are/platform/gl_context.h b/include/are/platform/gl_context.h deleted file mode 100644 index 74640fb..0000000 --- a/include/are/platform/gl_context.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file gl_context.h - * @brief OpenGL context management - */ - -#ifndef ARE_INCLUDE_PLATFORM_GL_CONTEXT_H -#define ARE_INCLUDE_PLATFORM_GL_CONTEXT_H - -#include -#include - -namespace are { - -/** - * @class GLContext - * @brief OpenGL context initialization and management - * - * Handles GLAD initialization and provides OpenGL utility functions. - */ -class GLContext { -public: - /** - * @brief Initialize OpenGL context (load function pointers) - * @return true if initialization succeeded - */ - static bool initialize(); - - /** - * @brief Check if context is initialized - * @return true if initialized - */ - static bool is_initialized(); - - /** - * @brief Get OpenGL version string - * @return Version string - */ - static std::string get_version(); - - /** - * @brief Get OpenGL renderer string - * @return Renderer string - */ - static std::string get_renderer(); - - /** - * @brief Get OpenGL vendor string - * @return Vendor string - */ - static std::string get_vendor(); - - /** - * @brief Check if OpenGL extension is supported - * @param extension Extension name - * @return true if supported - */ - static bool is_extension_supported(const std::string& extension); - - /** - * @brief Print OpenGL information to console - */ - static void print_info(); - - /** - * @brief Check for OpenGL errors - * @param file Source file - * @param line Line number - * @return true if error occurred - */ - static bool check_error(const char* file, int line); - - /** - * @brief Clear all OpenGL errors - */ - static void clear_errors(); - -private: - static bool initialized_; ///< Initialization flag -}; - -} // namespace are - -// OpenGL error checking macro -#ifdef ARE_ENABLE_DEBUG_VIS - #define ARE_GL_CHECK() are::GLContext::check_error(__FILE__, __LINE__) -#else - #define ARE_GL_CHECK() ((void)0) -#endif - -#endif // ARE_INCLUDE_PLATFORM_GL_CONTEXT_H diff --git a/include/are/platform/window.h b/include/are/platform/window.h deleted file mode 100644 index 720ef24..0000000 --- a/include/are/platform/window.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file window.h - * @brief Window management using GLFW - */ - -#ifndef ARE_INCLUDE_PLATFORM_WINDOW_H -#define ARE_INCLUDE_PLATFORM_WINDOW_H - -#include -#include -#include - -// Forward declare GLFW types to avoid including GLFW in header -struct GLFWwindow; - -namespace are { - -/** - * @class Window - * @brief GLFW window wrapper - * - * Manages window creation, input handling, and OpenGL context. - */ -class Window { -public: - /** - * @brief Constructor - * @param config Window configuration - */ - explicit Window(const WindowConfig& config); - - /** - * @brief Destructor - */ - ~Window(); - - // Window control - bool should_close() const; - void set_should_close(bool should_close); - void swap_buffers(); - void poll_events(); - - // Window properties - int get_width() const; - int get_height() const; - Real get_aspect_ratio() const; - const std::string& get_title() const; - - void set_title(const std::string& title); - void set_size(int width, int height); - - // Framebuffer size (may differ from window size on high-DPI displays) - void get_framebuffer_size(int& width, int& height) const; - - // VSync control - void set_vsync(bool enabled); - bool get_vsync() const; - - // Input queries (basic support) - bool is_key_pressed(int key) const; - bool is_mouse_button_pressed(int button) const; - void get_cursor_pos(double& x, double& y) const; - - // Internal - GLFWwindow* get_native_window() const { return window_; } - -private: - void initialize_glfw(); - void create_window(); - void setup_callbacks(); - - static void framebuffer_size_callback(GLFWwindow* window, int width, int height); - static void error_callback(int error, const char* description); - - GLFWwindow* window_; ///< GLFW window handle - WindowConfig config_; ///< Window configuration - bool vsync_enabled_; ///< VSync state - - static int instance_count_; ///< Number of Window instances -}; - -} // namespace are - -#endif // ARE_INCLUDE_PLATFORM_WINDOW_H diff --git a/include/are/rasterizer/gbuffer.h b/include/are/rasterizer/gbuffer.h deleted file mode 100644 index ac5081f..0000000 --- a/include/are/rasterizer/gbuffer.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file gbuffer.h - * @brief G-Buffer management for deferred rendering - */ - -#ifndef ARE_INCLUDE_RASTERIZER_GBUFFER_H -#define ARE_INCLUDE_RASTERIZER_GBUFFER_H - -#include -#include - -namespace are { - -/** - * @class GBuffer - * @brief G-Buffer for deferred rendering - * - * Attachment layout: - * 0: position (RGB16F) - * 1: normal (RGB16F) - * 2: albedo+metallic (RGBA8) - * 3: roughness+ao (RG8) - * 4: primitive id (R32UI) - * Depth: depth texture (DEPTH_COMPONENT24) - */ -class GBuffer { -public: - /** - * @brief Constructor - * @param width Buffer width - * @param height Buffer height - */ - GBuffer(int width, int height); - - /** - * @brief Destructor - */ - ~GBuffer(); - - /** - * @brief Resize G-Buffer - * @param width New width - * @param height New height - */ - void resize(int width, int height); - - /** - * @brief Bind G-Buffer for rendering - */ - void bind(); - - /** - * @brief Unbind G-Buffer - */ - void unbind(); - - /** - * @brief Clear all buffers - */ - void clear(); - - /** - * @brief Bind texture for reading - * @param index Texture index - * @param texture_unit Texture unit to bind to - */ - void bind_texture(int index, int texture_unit); - - // Texture getters - uint32_t get_position_texture() const { return position_texture_; } - uint32_t get_normal_texture() const { return normal_texture_; } - uint32_t get_albedo_texture() const { return albedo_texture_; } - uint32_t get_material_texture() const { return material_texture_; } - uint32_t get_depth_texture() const { return depth_texture_; } - uint32_t get_primitive_id_texture() const { return primitive_id_texture_; } - - // Dimensions - int get_width() const { return width_; } - int get_height() const { return height_; } - - /** - * @brief Read pixel data from G-Buffer - * - * Index mapping: - * - 0: position (RGB16F) -> GL_RGB/GL_FLOAT - * - 1: normal (RGB16F) -> GL_RGB/GL_FLOAT - * - 2: albedo_metallic (RGBA8) -> GL_RGBA/GL_UNSIGNED_BYTE - * - 3: material (RG8) -> GL_RG/GL_UNSIGNED_BYTE - * - 4: depth (DEPTH_COMPONENT24) -> GL_DEPTH_COMPONENT/GL_FLOAT - * - 5: primitive id (R32UI) -> GL_RED_INTEGER/GL_UNSIGNED_INT - * - * @param index Buffer index - * @param data Output data pointer - */ - void read_pixels(int index, void* data); - -private: - void create_textures(); - void delete_textures(); - void create_framebuffer(); - - uint32_t fbo_; ///< Framebuffer object - uint32_t rbo_depth_; ///< Legacy depth renderbuffer (unused) - - uint32_t position_texture_; - uint32_t normal_texture_; - uint32_t albedo_texture_; - uint32_t material_texture_; - uint32_t depth_texture_; - uint32_t primitive_id_texture_; - - int width_; - int height_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_RASTERIZER_GBUFFER_H diff --git a/include/are/rasterizer/rasterizer.h b/include/are/rasterizer/rasterizer.h deleted file mode 100644 index 8117fa3..0000000 --- a/include/are/rasterizer/rasterizer.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file rasterizer.h - * @brief Rasterization pipeline for G-Buffer generation - */ - -#ifndef ARE_INCLUDE_RASTERIZER_RASTERIZER_H -#define ARE_INCLUDE_RASTERIZER_RASTERIZER_H - -#include -#include -#include -#include - -namespace are { - -class GBuffer; -class ShaderProgram; -class SceneManager; -class Camera; -class Mesh; - -/** - * @struct RasterizerState - * @brief Rasterizer fixed-function state (configurable) - */ -struct RasterizerState { - bool enable_depth_test = true; - bool enable_cull_face = false; - uint32_t cull_face_mode = 0x0405; // GL_BACK - uint32_t front_face = 0x0901; // GL_CCW -}; - -class Rasterizer { -public: - Rasterizer(int width, int height); - ~Rasterizer(); - - void resize(int width, int height); - - void render_gbuffer(const SceneManager& scene, const Camera& camera); - - GBuffer& get_gbuffer(); - const GBuffer& get_gbuffer() const; - - void upload_mesh(Mesh& mesh); - void delete_mesh(Mesh& mesh); - - void initialize_shaders(const std::string& shader_dir); - - void set_triangle_base_provider(std::function provider); - - /** - * @brief Set rasterizer fixed-function state - * @param state State - */ - void set_state(const RasterizerState& state); - -private: - void setup_mesh_buffers(Mesh& mesh); - - std::unique_ptr gbuffer_; - std::unique_ptr gbuffer_shader_; - - std::function triangle_base_provider_; - RasterizerState state_; - - int width_; - int height_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_RASTERIZER_RASTERIZER_H diff --git a/include/are/rasterizer/shader_program.h b/include/are/rasterizer/shader_program.h deleted file mode 100644 index 9e5f118..0000000 --- a/include/are/rasterizer/shader_program.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file shader_program.h - * @brief OpenGL shader program wrapper - */ - -#ifndef ARE_INCLUDE_RASTERIZER_SHADER_PROGRAM_H -#define ARE_INCLUDE_RASTERIZER_SHADER_PROGRAM_H - -#include -#include -#include - -namespace are { - -enum class ShaderType { - ARE_SHADER_VERTEX, - ARE_SHADER_FRAGMENT, - ARE_SHADER_COMPUTE -}; - -class ShaderProgram { -public: - ShaderProgram(); - ~ShaderProgram(); - - bool load_shader(ShaderType type, const std::string& filepath); - bool compile_shader(ShaderType type, const std::string& source); - bool link(); - - void use() const; - - bool is_valid() const { return program_ != 0 && linked_; } - uint32_t get_program() const { return program_; } - - void set_uniform(const std::string& name, int value); - void set_uniform(const std::string& name, uint32_t value); ///< NEW - void set_uniform(const std::string& name, float value); - void set_uniform(const std::string& name, const Vec2& value); - void set_uniform(const std::string& name, const Vec3& value); - void set_uniform(const std::string& name, const Vec4& value); - void set_uniform(const std::string& name, const Mat3& value); - void set_uniform(const std::string& name, const Mat4& value); - - int get_uniform_location(const std::string& name); - -private: - bool check_compile_errors(uint32_t shader, ShaderType type); - bool check_link_errors(); - - uint32_t program_; - uint32_t vertex_shader_; - uint32_t fragment_shader_; - uint32_t compute_shader_; - bool linked_; - std::unordered_map uniform_cache_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_RASTERIZER_SHADER_PROGRAM_H diff --git a/include/are/raytracer/compute_raytracer.h b/include/are/raytracer/compute_raytracer.h deleted file mode 100644 index a74f97e..0000000 --- a/include/are/raytracer/compute_raytracer.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file compute_raytracer.h - * @brief GPU compute shader ray tracing implementation - */ - -#ifndef ARE_INCLUDE_RAYTRACER_COMPUTE_RAYTRACER_H -#define ARE_INCLUDE_RAYTRACER_COMPUTE_RAYTRACER_H - -#include -#include -#include - -namespace are { - -/** - * @class ComputeRayTracer - * @brief GPU-based ray tracing using compute shaders - */ -class ComputeRayTracer : public RayTracer { -public: - /** - * @brief Constructor - * @param config Ray tracing configuration - */ - explicit ComputeRayTracer(const RayTracingConfig& config); - - /** - * @brief Destructor - */ - ~ComputeRayTracer() override; - - /** - * @brief Render scene using compute shader ray tracing - * @param scene Scene manager - * @param camera Camera - * @param gbuffer G-Buffer (optional) - * @param output Output texture ID - */ - void render(const SceneManager& scene, - const Camera& camera, - const GBuffer* gbuffer, - uint32_t output_texture) override; - - /** - * @brief Update BVH - * @param bvh BVH reference - */ - void update_bvh(const BVH& bvh) override; - -private: - void initialize_compute_shader(const std::string& shader_dir); - void upload_scene_data(const SceneManager& scene); - void upload_bvh_data(const BVH& bvh); - void upload_camera_data(const Camera& camera); - - std::unique_ptr compute_shader_; ///< Ray tracing compute shader - - // GPU buffers (SSBOs) - uint32_t bvh_buffer_; ///< BVH nodes buffer - uint32_t triangle_buffer_; ///< Triangle data buffer - uint32_t material_buffer_; ///< Material data buffer - uint32_t light_buffer_; ///< Light data buffer - - bool buffers_initialized_; ///< Buffer initialization flag -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_COMPUTE_RAYTRACER_H diff --git a/include/are/raytracer/cpu_raytracer.h b/include/are/raytracer/cpu_raytracer.h deleted file mode 100644 index 883333a..0000000 --- a/include/are/raytracer/cpu_raytracer.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file cpu_raytracer.h - * @brief CPU-based ray tracing implementation - */ - -#ifndef ARE_INCLUDE_RAYTRACER_CPU_RAYTRACER_H -#define ARE_INCLUDE_RAYTRACER_CPU_RAYTRACER_H - -#include -#include -#include -#include - -namespace are { - -/** - * @class CPURayTracer - * @brief CPU-based ray tracing implementation - * - * Uses multithreading for parallel ray tracing on CPU. - */ -class CPURayTracer : public RayTracer { -public: - /** - * @brief Constructor - * @param config Ray tracing configuration - */ - explicit CPURayTracer(const RayTracingConfig& config); - - /** - * @brief Destructor - */ - ~CPURayTracer() override; - - /** - * @brief Render scene using CPU ray tracing - * @param scene Scene manager - * @param camera Camera - * @param gbuffer G-Buffer (optional) - * @param output Output texture ID - */ - void render(const SceneManager& scene, - const Camera& camera, - const GBuffer* gbuffer, - uint32_t output_texture) override; - - /** - * @brief Update BVH - * @param bvh BVH reference - */ - void update_bvh(const BVH& bvh) override; - -private: - /** - * @brief Trace a single ray - * @param ray Ray to trace - * @param depth Current recursion depth - * @return Ray color - */ - Vec3 trace_ray(const Ray& ray, int depth); - - /** - * @brief Shade hit point - * @param hit Hit record - * @param ray Incident ray - * @param depth Current recursion depth - * @return Shaded color - */ - Vec3 shade(const HitRecord& hit, const Ray& ray, int depth); - - /** - * @brief Compute direct lighting - * @param hit Hit record - * @return Direct lighting contribution - */ - Vec3 compute_direct_lighting(const HitRecord& hit); - - /** - * @brief Compute ambient occlusion - * @param hit Hit record - * @return AO factor [0, 1] - */ - Real compute_ambient_occlusion(const HitRecord& hit); - - /** - * @brief Check shadow ray - * @param origin Shadow ray origin - * @param direction Shadow ray direction - * @param max_distance Maximum distance - * @return true if in shadow - */ - bool is_in_shadow(const Vec3& origin, const Vec3& direction, Real max_distance, uint32_t ignore_triangle); - - const BVH* bvh_; ///< BVH reference - const SceneManager* scene_; ///< Scene reference - std::vector framebuffer_; ///< CPU framebuffer (HDR) - int width_; ///< Framebuffer width - int height_; ///< Framebuffer height -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_CPU_RAYTRACER_H diff --git a/include/are/raytracer/hit_record.h b/include/are/raytracer/hit_record.h deleted file mode 100644 index 81195c4..0000000 --- a/include/are/raytracer/hit_record.h +++ /dev/null @@ -1,48 +0,0 @@ -/** - * @file hit_record.h - * @brief Ray-surface intersection record - */ - -#ifndef ARE_INCLUDE_RAYTRACER_HIT_RECORD_H -#define ARE_INCLUDE_RAYTRACER_HIT_RECORD_H - -#include - -namespace are { - -/** - * @struct HitRecord - * @brief Information about ray-surface intersection - */ -struct HitRecord { - Vec3 position_; ///< Hit position in world space - Vec3 normal_; ///< Surface normal at hit point - Vec2 texcoord_; ///< Texture coordinates at hit point - Vec3 tangent_; ///< Tangent vector at hit point - Real t_; ///< Ray parameter at hit point - MaterialHandle material_; ///< Material at hit point - uint32_t triangle_index_; ///< Triangle index that was hit - bool front_face_; ///< Whether ray hit front face - - /** - * @brief Default constructor - */ - HitRecord(); - - /** - * @brief Set face normal based on ray direction - * @param ray_direction Ray direction - * @param outward_normal Outward-facing normal - */ - void set_face_normal(const Vec3& ray_direction, const Vec3& outward_normal); - - /** - * @brief Check if hit record is valid - * @return true if hit occurred - */ - bool is_valid() const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_HIT_RECORD_H diff --git a/include/are/raytracer/ray.h b/include/are/raytracer/ray.h deleted file mode 100644 index c007401..0000000 --- a/include/are/raytracer/ray.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @file ray.h - * @brief Ray structure for ray tracing - */ - -#ifndef ARE_INCLUDE_RAYTRACER_RAY_H -#define ARE_INCLUDE_RAYTRACER_RAY_H - -#include - -namespace are { - -/** - * @struct Ray - * @brief Ray representation for ray tracing - */ -struct Ray { - Vec3 origin_; ///< Ray origin - Vec3 direction_; ///< Ray direction (normalized) - Real t_min_; ///< Minimum t value - Real t_max_; ///< Maximum t value - - /** - * @brief Default constructor - */ - Ray(); - - /** - * @brief Construct ray with origin and direction - * @param origin Ray origin - * @param direction Ray direction (will be normalized) - * @param t_min Minimum t value - * @param t_max Maximum t value - */ - Ray(const Vec3& origin, const Vec3& direction, - Real t_min = are_epsilon, Real t_max = 1e30f); - - /** - * @brief Evaluate ray at parameter t - * @param t Parameter value - * @return Point on ray - */ - Vec3 at(Real t) const; - - /** - * @brief Check if t is within valid range - * @param t Parameter value - * @return true if t is valid - */ - bool is_valid_t(Real t) const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_RAY_H diff --git a/include/are/raytracer/raytracer.h b/include/are/raytracer/raytracer.h deleted file mode 100644 index 86d3eb0..0000000 --- a/include/are/raytracer/raytracer.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file raytracer.h - * @brief Ray tracing interface - */ - -#ifndef ARE_INCLUDE_RAYTRACER_RAYTRACER_H -#define ARE_INCLUDE_RAYTRACER_RAYTRACER_H - -#include -#include - -namespace are { - -// Forward declarations -class SceneManager; -class Camera; -class GBuffer; -class BVH; - -/** - * @class RayTracer - * @brief Abstract ray tracing interface - * - * Base class for CPU and GPU ray tracing implementations. - */ -class RayTracer { -public: - /** - * @brief Constructor - * @param config Ray tracing configuration - */ - explicit RayTracer(const RayTracingConfig& config); - - /** - * @brief Virtual destructor - */ - virtual ~RayTracer() = default; - - /** - * @brief Render scene using ray tracing - * @param scene Scene manager - * @param camera Camera - * @param gbuffer G-Buffer (optional, for hybrid rendering) - * @param output Output texture ID - */ - virtual void render(const SceneManager& scene, - const Camera& camera, - const GBuffer* gbuffer, - uint32_t output_texture) = 0; - - /** - * @brief Update BVH - * @param bvh BVH reference - */ - virtual void update_bvh(const BVH& bvh) = 0; - - /** - * @brief Set configuration - * @param config New configuration - */ - virtual void set_config(const RayTracingConfig& config); - - /** - * @brief Get configuration - * @return Current configuration - */ - const RayTracingConfig& get_config() const { return config_; } - -protected: - RayTracingConfig config_; ///< Ray tracing configuration -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_RAYTRACER_H diff --git a/include/are/renderer/geometry_cache.h b/include/are/renderer/geometry_cache.h deleted file mode 100644 index 1a0c941..0000000 --- a/include/are/renderer/geometry_cache.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file geometry_cache.h - * @brief Frame-level geometry cache for consistent BVH and GBuffer primitive ids - */ - -#ifndef ARE_INCLUDE_RENDERER_GEOMETRY_CACHE_H -#define ARE_INCLUDE_RENDERER_GEOMETRY_CACHE_H - -#include -#include -#include -#include -#include - -namespace are { - -/** - * @class GeometryCache - * @brief Builds a global triangle list and BVH from a SceneManager snapshot. - * - * Provides a single source of truth for: - * - Global triangle array layout (used by BVH and RayTracer) - * - Mesh -> triangle base mapping (used by Rasterizer for primitive id output) - */ -class GeometryCache { -public: - /** - * @brief Build cache from scene - * @param scene Scene manager - * @param bvh_config BVH build config - * @return true if succeeded - */ - bool build_from_scene(const SceneManager& scene, - const BVHBuildConfig& bvh_config = BVHBuildConfig()); - - /** - * @brief Get BVH reference - * @return BVH - */ - const BVH& get_bvh() const { return bvh_; } - - /** - * @brief Get global triangles - * @return Triangle array - */ - const std::vector& get_triangles() const { return triangles_; } - - /** - * @brief Get triangle base for mesh by index into scene.get_all_meshes() - * @param mesh_index Mesh index in scene.get_all_meshes() - * @return Base triangle id - */ - uint32_t get_mesh_triangle_base(size_t mesh_index) const; - -private: - std::vector triangles_; - std::vector mesh_triangle_base_; - BVH bvh_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_RENDERER_GEOMETRY_CACHE_H diff --git a/include/are/renderer/render_context.h b/include/are/renderer/render_context.h deleted file mode 100644 index 352db1f..0000000 --- a/include/are/renderer/render_context.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file render_context.h - * @brief Rendering context and state management - */ - -#ifndef ARE_INCLUDE_RENDERER_RENDER_CONTEXT_H -#define ARE_INCLUDE_RENDERER_RENDER_CONTEXT_H - -#include -#include - -namespace are { - -/** - * @struct RenderContext - * @brief Rendering context information - * - * Contains current rendering state and frame information. - */ -struct RenderContext { - int frame_number_; ///< Current frame number - double time_; ///< Total elapsed time in seconds - double delta_time_; ///< Time since last frame - - int viewport_width_; ///< Viewport width - int viewport_height_; ///< Viewport height - - RayTracingBackend current_backend_; ///< Current ray tracing backend - bool scene_dirty_; ///< Scene needs BVH rebuild - bool camera_moved_; ///< Camera moved this frame - - /** - * @brief Constructor - */ - RenderContext(); - - /** - * @brief Reset context - */ - void reset(); - - /** - * @brief Update frame timing - * @param current_time Current time in seconds - */ - void update_timing(double current_time); -}; - -} // namespace are - -#endif // ARE_INCLUDE_RENDERER_RENDER_CONTEXT_H diff --git a/include/are/renderer/render_stats.h b/include/are/renderer/render_stats.h deleted file mode 100644 index 1e660cb..0000000 --- a/include/are/renderer/render_stats.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file render_stats.h - * @brief Rendering statistics tracking - */ - -#ifndef ARE_INCLUDE_RENDERER_RENDER_STATS_H -#define ARE_INCLUDE_RENDERER_RENDER_STATS_H - -#include -#include - -namespace are { - -/** - * @struct RenderStats - * @brief Statistics for rendering performance analysis - */ -struct RenderStats { - // Frame timing - double frame_time_ms_; ///< Total frame time in milliseconds - double rasterization_time_ms_; ///< Rasterization time - double ray_tracing_time_ms_; ///< Ray tracing time - double bvh_build_time_ms_; ///< BVH construction time - double present_time_ms_; ///< Present/swap time - - // Scene statistics - uint32_t mesh_count_; ///< Number of meshes - uint32_t triangle_count_; ///< Total triangle count - uint32_t light_count_; ///< Number of lights - uint32_t material_count_; ///< Number of materials - - // Ray tracing statistics - uint64_t primary_rays_; ///< Number of primary rays - uint64_t secondary_rays_; ///< Number of secondary rays - uint64_t shadow_rays_; ///< Number of shadow rays - uint64_t bvh_traversals_; ///< BVH traversal count - uint64_t triangle_tests_; ///< Triangle intersection tests - - // Memory statistics - size_t vertex_memory_bytes_; ///< Vertex buffer memory - size_t index_memory_bytes_; ///< Index buffer memory - size_t texture_memory_bytes_; ///< Texture memory - size_t bvh_memory_bytes_; ///< BVH memory - - // FPS - double fps_; ///< Frames per second - - /** - * @brief Reset all statistics to zero - */ - void reset(); - - /** - * @brief Print statistics to console - */ - void print() const; - - /** - * @brief Update FPS based on frame time - */ - void update_fps(); -}; - -} // namespace are - -#endif // ARE_INCLUDE_RENDERER_RENDER_STATS_H diff --git a/include/are/renderer/renderer.h b/include/are/renderer/renderer.h deleted file mode 100644 index 77bd5eb..0000000 --- a/include/are/renderer/renderer.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @file renderer.h - * @brief Main renderer interface - */ - -#ifndef ARE_INCLUDE_RENDERER_RENDERER_H -#define ARE_INCLUDE_RENDERER_RENDERER_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace are { - -// Forward declarations -class Window; -class SceneManager; -class Rasterizer; -class RayTracer; -class TextureManager; - -/** - * @class Renderer - * @brief Main rendering interface for Aurora Rendering Engine - * - * This class provides the primary API for rendering scenes using - * hybrid rasterization and ray tracing techniques. - */ -class Renderer { -public: - /** - * @brief Constructor - * @param config Rendering configuration - */ - explicit Renderer(const AreConfig& config); - - /** - * @brief Destructor - */ - ~Renderer(); - - // Configuration - void set_config(const AreConfig& config); - const AreConfig& get_config() const; - - // Camera management - void set_camera(const Camera& camera); - Camera& get_camera(); - const Camera& get_camera() const; - - // Scene management - MeshHandle add_mesh(const Mesh& mesh); - MaterialHandle add_material(const Material& material); - LightHandle add_light(const std::shared_ptr& light); - - void remove_mesh(MeshHandle handle); - void remove_material(MaterialHandle handle); - void remove_light(LightHandle handle); - - void update_mesh(MeshHandle handle, const Mesh& mesh); - void update_material(MaterialHandle handle, const Material& material); - - void clear_scene(); - - // Ray tracing backend control - void set_ray_tracing_backend(RayTracingBackend backend); - RayTracingBackend get_ray_tracing_backend() const; - - // Rendering - void begin_frame(); - void render(); - void end_frame(); - void present(); - - // Frame capture - void capture_frame_ldr(uint8_t** pixels, int* width, int* height); - void capture_frame_hdr(float** pixels, int* width, int* height); - void save_frame(const std::string& filename, const uint8_t* pixels, - int width, int height); - - // Window control - bool should_close() const; - void set_should_close(bool should_close); - - // Statistics - const RenderStats& get_stats() const; - void reset_stats(); - - // Debug visualization - void set_gbuffer_visualization_mode(GBufferVisualizationMode mode); - GBufferVisualizationMode get_gbuffer_visualization_mode() const; - -private: - void initialize_subsystems(); - void shutdown_subsystems(); - void rebuild_bvh_if_needed(); - void check_scene_dirty(); - - AreConfig config_; ///< Current configuration - - std::unique_ptr window_; ///< Window management - std::unique_ptr scene_manager_; ///< Scene data management - std::unique_ptr rasterizer_; ///< Rasterization pipeline - std::unique_ptr raytracer_; ///< Ray tracing pipeline - std::unique_ptr texture_manager_; ///< Texture management - - Camera camera_; ///< Active camera - RenderStats stats_; ///< Rendering statistics - - bool scene_dirty_; ///< Scene needs BVH rebuild - bool initialized_; ///< Initialization flag -}; - -} // namespace are - -#endif // ARE_INCLUDE_RENDERER_RENDERER_H diff --git a/include/are/scene/camera.h b/include/are/scene/camera.h deleted file mode 100644 index 1a8ad09..0000000 --- a/include/are/scene/camera.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @file camera.h - * @brief Camera class for view and projection management - */ - -#ifndef ARE_INCLUDE_SCENE_CAMERA_H -#define ARE_INCLUDE_SCENE_CAMERA_H - -#include - -namespace are { - -/** - * @class Camera - * @brief Perspective camera for rendering - * - * Manages view and projection matrices, and provides ray generation - * for ray tracing. - */ -class Camera { -public: - /** - * @brief Default constructor - */ - Camera(); - - /** - * @brief Construct camera with position and target - * @param position Camera position - * @param target Look-at target - * @param up Up vector - */ - Camera(const Vec3& position, const Vec3& target, const Vec3& up = Vec3(0, 1, 0)); - - // Position and orientation setters - void set_position(const Vec3& position); - void set_target(const Vec3& target); - void set_up(const Vec3& up); - void look_at(const Vec3& position, const Vec3& target, const Vec3& up = Vec3(0, 1, 0)); - - // Projection setters - void set_fov(Real fov_degrees); - void set_aspect_ratio(Real aspect); - void set_near_plane(Real near); - void set_far_plane(Real far); - void set_perspective(Real fov_degrees, Real aspect, Real near, Real far); - - // Getters - const Vec3& get_position() const { return position_; } - const Vec3& get_target() const { return target_; } - const Vec3& get_up() const { return up_; } - Real get_fov() const { return fov_; } - Real get_aspect_ratio() const { return aspect_ratio_; } - Real get_near_plane() const { return near_plane_; } - Real get_far_plane() const { return far_plane_; } - - // Direction vectors - Vec3 get_forward() const; - Vec3 get_right() const; - - // Matrix getters - const Mat4& get_view_matrix() const; - const Mat4& get_projection_matrix() const; - Mat4 get_view_projection_matrix() const; - - /** - * @brief Generate ray for given pixel coordinates - * @param u Normalized x coordinate [0, 1] - * @param v Normalized y coordinate [0, 1] - * @param origin Output ray origin - * @param direction Output ray direction (normalized) - */ - void generate_ray(Real u, Real v, Vec3& origin, Vec3& direction) const; - - /** - * @brief Check if camera parameters have changed - * @return true if matrices need recalculation - */ - bool is_dirty() const { return dirty_; } - - /** - * @brief Mark camera as clean after matrix update - */ - void clear_dirty() { dirty_ = false; } - -private: - void update_view_matrix() const; - void update_projection_matrix() const; - - Vec3 position_; ///< Camera position - Vec3 target_; ///< Look-at target - Vec3 up_; ///< Up vector - - Real fov_; ///< Field of view in degrees - Real aspect_ratio_; ///< Aspect ratio (width/height) - Real near_plane_; ///< Near clipping plane - Real far_plane_; ///< Far clipping plane - - mutable Mat4 view_matrix_; ///< Cached view matrix - mutable Mat4 projection_matrix_; ///< Cached projection matrix - mutable bool view_dirty_; ///< View matrix needs update - mutable bool projection_dirty_; ///< Projection matrix needs update - bool dirty_; ///< Any parameter changed -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_CAMERA_H diff --git a/include/are/scene/directional_light.h b/include/are/scene/directional_light.h deleted file mode 100644 index 402eb51..0000000 --- a/include/are/scene/directional_light.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @file directional_light.h - * @brief Directional light implementation - */ - -#ifndef ARE_INCLUDE_SCENE_DIRECTIONAL_LIGHT_H -#define ARE_INCLUDE_SCENE_DIRECTIONAL_LIGHT_H - -#include - -namespace are { - -/** - * @class DirectionalLight - * @brief Directional light source (sun-like) - * - * Represents an infinitely distant light source with parallel rays. - */ -class DirectionalLight : public Light { -public: - /** - * @brief Default constructor - */ - DirectionalLight(); - - /** - * @brief Construct with direction and color - * @param direction Light direction (will be normalized) - * @param color Light color - * @param intensity Light intensity - */ - DirectionalLight(const Vec3& direction, const Vec3& color = Vec3(1.0f), - Real intensity = 1.0f); - - // Direction - void set_direction(const Vec3& direction); - const Vec3& get_direction() const { return direction_; } - - // Light interface - LightData pack() const override; - bool affects_point(const Vec3& point) const override; - -private: - Vec3 direction_; ///< Light direction (normalized) -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_DIRECTIONAL_LIGHT_H diff --git a/include/are/scene/light.h b/include/are/scene/light.h deleted file mode 100644 index 1b6e121..0000000 --- a/include/are/scene/light.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file light.h - * @brief Base light class and common light utilities - */ - -#ifndef ARE_INCLUDE_SCENE_LIGHT_H -#define ARE_INCLUDE_SCENE_LIGHT_H - -#include - -namespace are { - -/** - * @enum LightType - * @brief Types of light sources - */ -enum class LightType { - ARE_LIGHT_DIRECTIONAL, - ARE_LIGHT_POINT, - ARE_LIGHT_SPOT -}; - -/** - * @struct LightData - * @brief Packed light data for GPU transfer - * - * This structure is designed to be efficiently transferred to GPU - * via SSBO or UBO. - */ -struct LightData { - Vec4 position_type_; ///< xyz: position, w: light type - Vec4 direction_range_; ///< xyz: direction, w: range - Vec4 color_intensity_; ///< xyz: color, w: intensity - Vec4 params_; ///< Light-specific parameters -}; - -/** - * @class Light - * @brief Base class for all light types - */ -class Light { -public: - /** - * @brief Constructor - * @param type Light type - */ - explicit Light(LightType type); - - virtual ~Light() = default; - - // Common properties - void set_color(const Vec3& color); - void set_intensity(Real intensity); - void set_cast_shadows(bool cast); - - const Vec3& get_color() const { return color_; } - Real get_intensity() const { return intensity_; } - bool get_cast_shadows() const { return cast_shadows_; } - LightType get_type() const { return type_; } - - /** - * @brief Pack light data for GPU transfer - * @return Packed light data - */ - virtual LightData pack() const = 0; - - /** - * @brief Check if light affects a point - * @param point World position - * @return true if light can affect the point - */ - virtual bool affects_point(const Vec3& point) const = 0; - -protected: - LightType type_; ///< Light type - Vec3 color_; ///< Light color (RGB) - Real intensity_; ///< Light intensity - bool cast_shadows_; ///< Whether light casts shadows -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_LIGHT_H diff --git a/include/are/scene/material.h b/include/are/scene/material.h deleted file mode 100644 index 6819177..0000000 --- a/include/are/scene/material.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @file material.h - * @brief PBR material definition - */ - -#ifndef ARE_INCLUDE_SCENE_MATERIAL_H -#define ARE_INCLUDE_SCENE_MATERIAL_H - -#include -#include - -namespace are { - -/** - * @class Material - * @brief Physically-based rendering material - * - * Supports standard PBR workflow with metallic-roughness model. - */ -class Material { -public: - /** - * @brief Default constructor - creates default white material - */ - Material(); - - // Albedo (base color) - void set_albedo(const Vec3& albedo); - void set_albedo_map(const std::string& path); - const Vec3& get_albedo() const { return albedo_; } - const std::string& get_albedo_map() const { return albedo_map_; } - bool has_albedo_map() const { return !albedo_map_.empty(); } - - // Metallic - void set_metallic(Real metallic); - void set_metallic_map(const std::string& path); - Real get_metallic() const { return metallic_; } - const std::string& get_metallic_map() const { return metallic_map_; } - bool has_metallic_map() const { return !metallic_map_.empty(); } - - // Roughness - void set_roughness(Real roughness); - void set_roughness_map(const std::string& path); - Real get_roughness() const { return roughness_; } - const std::string& get_roughness_map() const { return roughness_map_; } - bool has_roughness_map() const { return !roughness_map_.empty(); } - - // Normal map - void set_normal_map(const std::string& path); - const std::string& get_normal_map() const { return normal_map_; } - bool has_normal_map() const { return !normal_map_.empty(); } - - // Ambient occlusion - void set_ao_map(const std::string& path); - const std::string& get_ao_map() const { return ao_map_; } - bool has_ao_map() const { return !ao_map_.empty(); } - - // Emissive - void set_emissive(const Vec3& emissive); - void set_emissive_map(const std::string& path); - const Vec3& get_emissive() const { return emissive_; } - const std::string& get_emissive_map() const { return emissive_map_; } - bool has_emissive_map() const { return !emissive_map_.empty(); } - bool is_emissive() const; - - // Texture handles (set by TextureManager) - void set_albedo_texture_handle(TextureHandle handle) { albedo_tex_handle_ = handle; } - void set_metallic_texture_handle(TextureHandle handle) { metallic_tex_handle_ = handle; } - void set_roughness_texture_handle(TextureHandle handle) { roughness_tex_handle_ = handle; } - void set_normal_texture_handle(TextureHandle handle) { normal_tex_handle_ = handle; } - void set_ao_texture_handle(TextureHandle handle) { ao_tex_handle_ = handle; } - void set_emissive_texture_handle(TextureHandle handle) { emissive_tex_handle_ = handle; } - - TextureHandle get_albedo_texture_handle() const { return albedo_tex_handle_; } - TextureHandle get_metallic_texture_handle() const { return metallic_tex_handle_; } - TextureHandle get_roughness_texture_handle() const { return roughness_tex_handle_; } - TextureHandle get_normal_texture_handle() const { return normal_tex_handle_; } - TextureHandle get_ao_texture_handle() const { return ao_tex_handle_; } - TextureHandle get_emissive_texture_handle() const { return emissive_tex_handle_; } - -private: - // Base values - Vec3 albedo_;///< Base color (RGB) - Real metallic_; ///< Metallic factor [0, 1] - Real roughness_; ///< Roughness factor [0, 1] - Vec3 emissive_; ///< Emissive color (RGB) - - // Texture paths - std::string albedo_map_; - std::string metallic_map_; - std::string roughness_map_; - std::string normal_map_; - std::string ao_map_; - std::string emissive_map_; - - // Texture handles (GPU resources) - TextureHandle albedo_tex_handle_; - TextureHandle metallic_tex_handle_; - TextureHandle roughness_tex_handle_; - TextureHandle normal_tex_handle_; - TextureHandle ao_tex_handle_; - TextureHandle emissive_tex_handle_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_MATERIAL_H diff --git a/include/are/scene/mesh.h b/include/are/scene/mesh.h deleted file mode 100644 index 2103c62..0000000 --- a/include/are/scene/mesh.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @file mesh.h - * @brief Mesh class for geometry storage - */ - -#ifndef ARE_INCLUDE_SCENE_MESH_H -#define ARE_INCLUDE_SCENE_MESH_H - -#include -#include -#include -#include - -namespace are { - -/** - * @class Mesh - * @brief Triangle mesh container - * - * Stores vertex and index data for a triangle mesh. - * Supports automatic AABB computation. - */ -class Mesh { -public: - /** - * @brief Default constructor - creates empty mesh - */ - Mesh(); - - /** - * @brief Construct mesh from vertex and index data - * @param vertices Vertex array - * @param indices Index array (triangles) - * @param material_id Material handle - */ - Mesh(const std::vector& vertices, - const std::vector& indices, - MaterialHandle material_id = are_invalid_handle); - - /** - * @brief Construct mesh from raw arrays - * @param vertices Vertex array pointer - * @param vertex_count Number of vertices - * @param indices Index array pointer - * @param index_count Number of indices - * @param material_id Material handle - */ - Mesh(const Vertex* vertices, size_t vertex_count, - const uint32_t* indices, size_t index_count, - MaterialHandle material_id = are_invalid_handle); - - // Data setters - void set_vertices(const std::vector& vertices); - void set_indices(const std::vector& indices); - void set_material(MaterialHandle material_id); - - // Data getters - const std::vector& get_vertices() const { return vertices_; } - const std::vector& get_indices() const { return indices_; } - MaterialHandle get_material() const { return material_id_; } - - // Geometry queries - size_t get_vertex_count() const { return vertices_.size(); } - size_t get_index_count() const { return indices_.size(); } - size_t get_triangle_count() const { return indices_.size() / 3; } - bool is_empty() const { return vertices_.empty() || indices_.empty(); } - - // AABB - const AABB& get_aabb() const { return aabb_; } - void compute_aabb(); - - /** - * @brief Compute tangent vectors for normal mapping - */ - void compute_tangents();/** - * @brief Get triangle vertices by index - * @param triangle_index Triangle index - * @param v0 Output first vertex - * @param v1 Output second vertex - * @param v2 Output third vertex - * @return true if triangle exists - */ - bool get_triangle(size_t triangle_index, Vertex& v0, Vertex& v1, Vertex& v2) const; - - // GPU resource handles (set by Renderer) - void set_vao(uint32_t vao) { vao_ = vao; } - void set_vbo(uint32_t vbo) { vbo_ = vbo; } - void set_ebo(uint32_t ebo) { ebo_ = ebo; } - uint32_t get_vao() const { return vao_; } - uint32_t get_vbo() const { return vbo_; } - uint32_t get_ebo() const { return ebo_; } - bool has_gpu_resources() const { return vao_ != 0; } - -private: - std::vector vertices_; ///< Vertex data - std::vector indices_; ///< Index data (triangles) - MaterialHandle material_id_; ///< Associated material - AABB aabb_; ///< Bounding box - - // GPU resources - uint32_t vao_; ///< Vertex Array Object - uint32_t vbo_; ///< Vertex Buffer Object - uint32_t ebo_; ///< Element Buffer Object -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_MESH_H diff --git a/include/are/scene/point_light.h b/include/are/scene/point_light.h deleted file mode 100644 index 2a47dde..0000000 --- a/include/are/scene/point_light.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file point_light.h - * @brief Point light implementation - */ - -#ifndef ARE_INCLUDE_SCENE_POINT_LIGHT_H -#define ARE_INCLUDE_SCENE_POINT_LIGHT_H - -#include - -namespace are { - -/** - * @class PointLight - * @brief Point light source - * - * Emits light equally in all directions from a single point. - */ -class PointLight : public Light { -public: - /** - * @brief Default constructor - */ - PointLight(); - - /** - * @brief Construct with position and color - * @param position Light position - * @param color Light color - * @param intensity Light intensity - * @param range Light range (attenuation distance) - */ - PointLight(const Vec3& position, const Vec3& color = Vec3(1.0f), - Real intensity = 1.0f, Real range = 10.0f); - - // Position - void set_position(const Vec3& position); - const Vec3& get_position() const { return position_; } - - // Range (attenuation) - void set_range(Real range); - Real get_range() const { return range_; } - - // Attenuation parameters - void set_attenuation(Real constant, Real linear, Real quadratic); - Real get_constant_attenuation() const { return attenuation_constant_; } - Real get_linear_attenuation() const { return attenuation_linear_; } - Real get_quadratic_attenuation() const { return attenuation_quadratic_; } - - /** - * @brief Calculate attenuation at given distance - * @param distance Distance from light - * @return Attenuation factor [0, 1] - */ - Real calculate_attenuation(Real distance) const; - - // Light interface - LightData pack() const override; - bool affects_point(const Vec3& point) const override; - -private: - Vec3 position_; ///< Light position - Real range_; ///< Light range - Real attenuation_constant_; ///< Constant attenuation factor - Real attenuation_linear_; ///< Linear attenuation factor - Real attenuation_quadratic_; ///< Quadratic attenuation factor -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_POINT_LIGHT_H diff --git a/include/are/scene/scene_manager.h b/include/are/scene/scene_manager.h deleted file mode 100644 index 3e6abda..0000000 --- a/include/are/scene/scene_manager.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file scene_manager.h - * @brief Scene data management - */ - -#ifndef ARE_INCLUDE_SCENE_SCENE_MANAGER_H -#define ARE_INCLUDE_SCENE_SCENE_MANAGER_H - -#include -#include -#include -#include -#include -#include -#include - -namespace are { - -/** - * @class SceneManager - * @brief Manages all scene objects (meshes, materials, lights) - * - * Provides handle-based access to scene resources and tracks - * scene modifications for BVH rebuilding. - */ -class SceneManager { -public: - /** - * @brief Constructor - */ - SceneManager(); - - /** - * @brief Destructor - */ - ~SceneManager(); - - // Mesh management - MeshHandle add_mesh(const Mesh& mesh); - void remove_mesh(MeshHandle handle); - void update_mesh(MeshHandle handle, const Mesh& mesh); - Mesh* get_mesh(MeshHandle handle); - const Mesh* get_mesh(MeshHandle handle) const; - const std::vector& get_all_meshes() const { return meshes_; } - - // Material management - MaterialHandle add_material(const Material& material); - void remove_material(MaterialHandle handle); - void update_material(MaterialHandle handle, const Material& material); - Material* get_material(MaterialHandle handle); - const Material* get_material(MaterialHandle handle) const; - const std::vector& get_all_materials() const { return materials_; } - - // Light management - LightHandle add_light(const std::shared_ptr& light); - void remove_light(LightHandle handle); - std::shared_ptr get_light(LightHandle handle); - const std::vector>& get_all_lights() const { return lights_; } - - // Scene queries - size_t get_mesh_count() const { return meshes_.size(); } - size_t get_material_count() const { return materials_.size(); } - size_t get_light_count() const { return lights_.size(); } - size_t get_total_triangle_count() const; - - // Scene state - bool is_dirty() const { return dirty_; } - void mark_dirty() { dirty_ = true; } - void clear_dirty() { dirty_ = false; } - - /** - * @brief Clear all scene data - */ - void clear(); - - /** - * @brief Validate all handles and remove invalid entries - */ - void compact(); - -private: - std::vector meshes_; ///< Mesh storage - std::vector materials_; ///< Material storage - std::vector> lights_; ///< Light storage - - std::unordered_map mesh_handle_map_; - std::unordered_map material_handle_map_; - std::unordered_map light_handle_map_; - - MeshHandle next_mesh_handle_; - MaterialHandle next_material_handle_; - LightHandle next_light_handle_; - - bool dirty_; ///< Scene modified flag -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_SCENE_MANAGER_H diff --git a/include/are/scene/spot_light.h b/include/are/scene/spot_light.h deleted file mode 100644 index ae466c5..0000000 --- a/include/are/scene/spot_light.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file spot_light.h - * @brief Spot light implementation - */ - -#ifndef ARE_INCLUDE_SCENE_SPOT_LIGHT_H -#define ARE_INCLUDE_SCENE_SPOT_LIGHT_H - -#include - -namespace are { - -/** - * @class SpotLight - * @brief Spot light source - * - * Emits light in a cone from a single point. - */ -class SpotLight : public Light { -public: - /** - * @brief Default constructor - */ - SpotLight(); - - /** - * @brief Construct with position, direction, and angles - * @param position Light position - * @param direction Light direction - * @param inner_angle Inner cone angle in degrees - * @param outer_angle Outer cone angle in degrees - * @param color Light color - * @param intensity Light intensity - */ - SpotLight(const Vec3& position, const Vec3& direction,Real inner_angle, Real outer_angle, - const Vec3& color = Vec3(1.0f), Real intensity = 1.0f); - - // Position and direction - void set_position(const Vec3& position); - void set_direction(const Vec3& direction); - const Vec3& get_position() const { return position_; } - const Vec3& get_direction() const { return direction_; } - - // Cone angles (in degrees) - void set_inner_angle(Real angle); - void set_outer_angle(Real angle); - Real get_inner_angle() const { return inner_angle_; } - Real get_outer_angle() const { return outer_angle_; } - - // Range - void set_range(Real range); - Real get_range() const { return range_; } - - /** - * @brief Calculate spotlight intensity at given direction - * @param to_point Direction from light to point (normalized) - * @return Spotlight factor [0, 1] - */ - Real calculate_spot_factor(const Vec3& to_point) const; - - // Light interface - LightData pack() const override; - bool affects_point(const Vec3& point) const override; - -private: - Vec3 position_; ///< Light position - Vec3 direction_; ///< Light direction (normalized) - Real inner_angle_; ///< Inner cone angle (degrees) - Real outer_angle_; ///< Outer cone angle (degrees) - Real range_; ///< Light range - Real cos_inner_; ///< Cosine of inner angle (cache - Real cos_outer_; ///< Cosine of outer angle (cached) -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_SPOT_LIGHT_H diff --git a/include/are/texture/sampler.h b/include/are/texture/sampler.h deleted file mode 100644 index 4b7d993..0000000 --- a/include/are/texture/sampler.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file sampler.h - * @brief Texture sampling utilities - */ - -#ifndef ARE_INCLUDE_TEXTURE_SAMPLER_H -#define ARE_INCLUDE_TEXTURE_SAMPLER_H - -#include -#include - -namespace are { - -/** - * @class Sampler - * @brief Texture sampling utilities for CPU ray tracing - * - * Provides bilinear filtering and wrapping modes for CPU-side texture access. - */ -class Sampler { -public: - /** - * @brief Sample texture at UV coordinates - * @param texture Texture to sample - * @param uv UV coordinates - * @return Sampled color (RGBA) - */ - static Vec4 sample(const Texture& texture, const Vec2& uv); - - /** - * @brief Sample texture with bilinear filtering - * @param texture Texture to sample - * @param uv UV coordinates - * @return Sampled color (RGBA) - */ - static Vec4 sample_bilinear(const Texture& texture, const Vec2& uv); - - /** - * @brief Sample texture at nearest pixel - * @param texture Texture to sample - * @param uv UV coordinates - * @return Sampled color (RGBA) - */ - static Vec4 sample_nearest(const Texture& texture, const Vec2& uv); - -private: - static Vec2 apply_wrap(const Vec2& uv, TextureWrap wrap); -}; - -} // namespace are - -#endif // ARE_INCLUDE_TEXTURE_SAMPLER_H diff --git a/include/are/texture/texture.h b/include/are/texture/texture.h deleted file mode 100644 index de26d36..0000000 --- a/include/are/texture/texture.h +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file texture.h - * @brief Texture resource management - */ - -#ifndef ARE_INCLUDE_TEXTURE_TEXTURE_H -#define ARE_INCLUDE_TEXTURE_TEXTURE_H - -#include -#include - -namespace are { - -/** - * @enum TextureFormat - * @brief Texture internal formats - */ -enum class TextureFormat { - ARE_TEXTURE_R8, - ARE_TEXTURE_RG8, - ARE_TEXTURE_RGB8, - ARE_TEXTURE_RGBA8, - ARE_TEXTURE_R16F, - ARE_TEXTURE_RG16F, - ARE_TEXTURE_RGB16F, - ARE_TEXTURE_RGBA16F, - ARE_TEXTURE_R32F, - ARE_TEXTURE_RG32F, - ARE_TEXTURE_RGB32F, - ARE_TEXTURE_RGBA32F -}; - -/** - * @enum TextureFilter - * @brief Texture filtering modes - */ -enum class TextureFilter { - ARE_TEXTURE_FILTER_NEAREST, - ARE_TEXTURE_FILTER_LINEAR, - ARE_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST, - ARE_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST, - ARE_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR, - ARE_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR -}; - -/** - * @enum TextureWrap - * @brief Texture wrapping modes - */ -enum class TextureWrap { - ARE_TEXTURE_WRAP_REPEAT, - ARE_TEXTURE_WRAP_CLAMP_TO_EDGE, - ARE_TEXTURE_WRAP_CLAMP_TO_BORDER, - ARE_TEXTURE_WRAP_MIRRORED_REPEAT -}; - -/** - * @class Texture - * @brief OpenGL texture wrapper - */ -class Texture { -public: - /** - * @brief Constructor - */ - Texture(); - - /** - * @brief Destructor - */ - ~Texture(); - - /** - * @brief Load texture from file - * @param filepath Image file path - * @param format Desired texture format - * @param generate_mipmaps Generate mipmaps - * @return true if load succeeded - */ - bool load_from_file(const std::string& filepath, - TextureFormat format = TextureFormat::ARE_TEXTURE_RGBA8, - bool generate_mipmaps = true); - - /** - * @brief Create texture from raw data - * @param width Texture width - * @param height Texture height - * @param format Texture format - * @param data Pixel data - * @param generate_mipmaps Generate mipmaps - * @return true if creation succeeded - */ - bool create_from_data(int width, int height, - TextureFormat format, - const void* data, - bool generate_mipmaps = true); - - /** - * @brief Bind texture to texture unit - * @param unit Texture unit (0-31) - */ - void bind(int unit = 0) const; - - /** - * @brief Unbind texture - */ - void unbind() const; - - /** - * @brief Set texture filtering - * @param min_filter Minification filter - * @param mag_filter Magnification filter - */ - void set_filter(TextureFilter min_filter, TextureFilter mag_filter); - - /** - * @brief Set texture wrapping - * @param wrap_s S-axis wrapping - * @param wrap_t T-axis wrapping - */ - void set_wrap(TextureWrap wrap_s, TextureWrap wrap_t); - - /** - * @brief Generate mipmaps - */ - void generate_mipmaps(); - - // Getters - uint32_t get_id() const { return texture_id_; } - int get_width() const { return width_; } - int get_height() const { return height_; } - TextureFormat get_format() const { return format_; } - bool is_valid() const { return texture_id_ != 0; } - - /** - * @brief Delete texture - */ - void destroy(); - -private: - uint32_t texture_id_; ///< OpenGL texture ID - int width_; ///< Texture width - int height_; ///< Texture height - TextureFormat format_; ///< Texture format -}; - -} // namespace are - -#endif // ARE_INCLUDE_TEXTURE_TEXTURE_H diff --git a/include/are/texture/texture_manager.h b/include/are/texture/texture_manager.h deleted file mode 100644 index de1d3b2..0000000 --- a/include/are/texture/texture_manager.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file texture_manager.h - * @brief Texture resource management and caching - */ - -#ifndef ARE_INCLUDE_TEXTURE_TEXTURE_MANAGER_H -#define ARE_INCLUDE_TEXTURE_TEXTURE_MANAGER_H - -#include -#include -#include -#include -#include - -namespace are { - -/** - * @class TextureManager - * @brief Manages texture loading and caching - * - * Automatically handles texture deduplication and lifetime management. - */ -class TextureManager { -public: - /** - * @brief Constructor - */ - TextureManager(); - - /** - * @brief Destructor - */ - ~TextureManager(); - - /** - * @brief Load texture from file (with caching) - * @param filepath Texture file path - * @param format Desired texture format - * @param generate_mipmaps Generate mipmaps - * @return Texture handle (are_invalid_handle if failed) - */ - TextureHandle load_texture(const std::string& filepath, - TextureFormat format = TextureFormat::ARE_TEXTURE_RGBA8, - bool generate_mipmaps = true); - - /** - * @brief Create texture from raw data - * @param name Texture name (for caching) - * @param width Texture width - * @param height Texture height - * @param format Texture format - * @param data Pixel data - * @param generate_mipmaps Generate mipmaps - * @return Texture handle - */ - TextureHandle create_texture(const std::string& name, - int width, int height, - TextureFormat format, - const void* data, - bool generate_mipmaps = true); - - /** - * @brief Get texture by handle - * @param handle Texture handle - * @return Texture pointer (nullptr if not found) - */ - Texture* get_texture(TextureHandle handle); - const Texture* get_texture(TextureHandle handle) const; - - /** - * @brief Unload texture - * @param handle Texture handle - */ - void unload_texture(TextureHandle handle); - - /** - * @brief Clear all textures - */ - void clear(); - - /** - * @brief Get total texture memory usage - * @return Memory usage in bytes - */ - size_t get_memory_usage() const; - - /** - * @brief Get number of loaded textures - * @return Texture count - */ - size_t get_texture_count() const { return textures_.size(); } - -private: - std::unordered_map path_to_handle_; - std::unordered_map> textures_; - TextureHandle next_handle_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_TEXTURE_TEXTURE_MANAGER_H diff --git a/include/are/utils/file_utils.h b/include/are/utils/file_utils.h deleted file mode 100644 index 8d610f2..0000000 --- a/include/are/utils/file_utils.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file file_utils.h - * @brief File system utilities - */ - -#ifndef ARE_INCLUDE_UTILS_FILE_UTILS_H -#define ARE_INCLUDE_UTILS_FILE_UTILS_H - -#include -#include -#include - -namespace are { - -/** - * @brief Read entire file into string - * @param filepath File path - * @return File contents (empty if failed) - */ -std::string read_file_to_string(const std::string& filepath); - -/** - * @brief Read entire file into byte array - * @param filepath File path - * @return File contents (empty if failed) - */ -std::vector read_file_to_bytes(const std::string& filepath); - -/** - * @brief Write string to file - * @param filepath File path - * @param content Content to write - * @return true if write succeeded - */ -bool write_string_to_file(const std::string& filepath, const std::string& content); - -/** - * @brief Write bytes to file - * @param filepath File path - * @param data Data pointer - * @param size Data size in bytes - * @return true if write succeeded - */ -bool write_bytes_to_file(const std::string& filepath, const void* data, size_t size); - -/** - * @brief Check if file exists - * @param filepath File path - * @return true if file exists - */ -bool file_exists(const std::string& filepath); - -/** - * @brief Check if path is directory - * @param path Directory path - * @return true if directory exists - */ -bool is_directory(const std::string& path); - -/** - * @brief Create directory (including parent directories) - * @param path Directory path - * @return true if creation succeeded - */ -bool create_directory(const std::string& path); - -/** - * @brief Get file extension - * @param filepath File path - * @return Extension (lowercase, without dot) - */ -std::string get_file_extension(const std::string& filepath); - -/** - * @brief Get filename from path - * @param filepath File path - * @return Filename (without directory) - */ -std::string get_filename(const std::string& filepath); - -/** - * @brief Get directory from path - * @param filepath File path - * @return Directory path - */ -std::string get_directory(const std::string& filepath); - -/** - * @brief Join path components - * @param parts Path components - * @return Joined path - */ -std::string join_path(const std::vector& parts); - -/** - * @brief Normalize path (resolve .. and .) - * @param path Path to normalize - * @return Normalized path - */ -std::string normalize_path(const std::string& path); - -} // namespace are - -#endif // ARE_INCLUDE_UTILS_FILE_UTILS_H diff --git a/include/are/utils/image_io.h b/include/are/utils/image_io.h deleted file mode 100644 index 945743b..0000000 --- a/include/are/utils/image_io.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file image_io.h - * @brief Image loading and saving utilities - */ - -#ifndef ARE_INCLUDE_UTILS_IMAGE_IO_H -#define ARE_INCLUDE_UTILS_IMAGE_IO_H - -#include -#include -#include - -namespace are { - -/** - * @enum ImageFormat - * @brief Supported image formats - */ -enum class ImageFormat { - ARE_IMAGE_FORMAT_PPM, - ARE_IMAGE_FORMAT_BMP, - ARE_IMAGE_FORMAT_PNG, - ARE_IMAGE_FORMAT_JPG -}; - -/** - * @struct ImageData - * @brief Container for image data - */ -struct ImageData { - int width_; ///< Image width - int height_; ///< Image height - int channels_; ///< Number of channels (3=RGB, 4=RGBA) - std::vector data_; ///< Pixel data (row-major) - - /** - * @brief Check if image data is valid - * @return true if valid - */ - bool is_valid() const; - - /** - * @brief Get pixel at (x, y) - * @param x X coordinate - * @param y Y coordinate - * @return Pointer to pixel data (RGB or RGBA) - */ - const uint8_t* get_pixel(int x, int y) const; - - /** - * @brief Set pixel at (x, y) - * @param x X coordinate - * @param y Y coordinate - * @param r Red channel - * @param g Green channel - * @param b Blue channel - * @param a Alpha channel (optional) - */ - void set_pixel(int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255); -}; - -/** - * @brief Load image from file - * @param filename Image file path - * @param flip_vertically Whether to flip image vertically - * @return Image data (empty if failed) - */ -ImageData load_image(const std::string& filename, bool flip_vertically = false); - -/** - * @brief Save image to file - * @param filename Output file path - * @param data Image data - * @param format Output format (auto-detected from extension if not specified) - * @return true if save succeeded - */ -bool save_image(const std::string& filename, const ImageData& data, - ImageFormat format = ImageFormat::ARE_IMAGE_FORMAT_PNG); - -/** - * @brief Save raw pixel data to file - * @param filename Output file path - * @param pixels Pixel data pointer - * @param width Image width - * @param height Image height - * @param channels Number of channels - * @param format Output format - * @return true if save succeeded - */ -bool save_image(const std::string& filename, const uint8_t* pixels, - int width, int height, int channels, - ImageFormat format = ImageFormat::ARE_IMAGE_FORMAT_PNG); - -/** - * @brief Detect image format from file extension - * @param filename File path - * @return Detected format - */ -ImageFormat detect_format(const std::string& filename); - -} // namespace are - -#endif // ARE_INCLUDE_UTILS_IMAGE_IO_H diff --git a/include/are/utils/math_utils.h b/include/are/utils/math_utils.h deleted file mode 100644 index f0360ff..0000000 --- a/include/are/utils/math_utils.h +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @file math_utils.h - * @brief Mathematical utility functions - */ - -#ifndef ARE_INCLUDE_UTILS_MATH_UTILS_H -#define ARE_INCLUDE_UTILS_MATH_UTILS_H - -#include -#include - -namespace are { - -/** - * @brief Clamp value to range [min, max] - * @param value Value to clamp - * @param min Minimum value - * @param max Maximum value - * @return Clamped value - */ -template -inline T clamp(T value, T min, T max) { - return std::max(min, std::min(value, max)); -} - -/** - * @brief Linear interpolation - * @param a Start value - * @param b End value - * @param t Interpolation factor [0, 1] - * @return Interpolated value - */ -template -inline T lerp(T a, T b, Real t) { - return a + (b - a) * t; -} - -/** - * @brief Convert degrees to radians - * @param degrees Angle in degrees - * @return Angle in radians - */ -inline Real degrees_to_radians(Real degrees) { - return degrees * are_pi / 180.0f; -} - -/** - * @brief Convert radians to degrees - * @param radians Angle in radians - * @return Angle in degrees - */ -inline Real radians_to_degrees(Real radians) { - return radians * 180.0f / are_pi; -} - -/** - * @brief Check if two floating point values are approximately equal - * @param a First value - * @param b Second value - * @param epsilon Tolerance - * @return true if approximately equal - */ -inline bool approx_equal(Real a, Real b, Real epsilon = are_epsilon) { - return std::abs(a - b) < epsilon; -} - -/** - * @brief Compute barycentric coordinates - * @param p Point - * @param a Triangle vertex A - * @param b Triangle vertex B - * @param c Triangle vertex C - * @param u Output barycentric coordinate u - * @param v Output barycentric coordinate v - * @param w Output barycentric coordinate w - */ -void compute_barycentric(const Vec3& p, const Vec3& a, const Vec3& b, const Vec3& c, - Real& u, Real& v, Real& w); - -/** - * @brief Reflect vector around normal - * @param incident Incident vector - * @param normal Surface normal (normalized) - * @return Reflected vector - */ -Vec3 reflect(const Vec3& incident, const Vec3& normal); - -/** - * @brief Refract vector through surface - * @param incident Incident vector (normalized) - * @param normal Surface normal (normalized) - * @param eta Ratio of refractive indices - * @param refracted Output refracted vector - * @return true if refraction occurred (false for total internal reflection) - */ -bool refract(const Vec3& incident, const Vec3& normal, Real eta, Vec3& refracted); - -/** - * @brief Compute Fresnel reflectance (Schlick approximation) - * @param cos_theta Cosine of angle between view and normal - * @param f0 Reflectance at normal incidence - * @return Fresnel reflectance - */ -Real fresnel_schlick(Real cos_theta, Real f0); - -/** - * @brief Create orthonormal basis from normal - * @param normal Normal vector (normalized) - * @param tangent Output tangent vector - * @param bitangent Output bitangent vector - */ -void create_orthonormal_basis(const Vec3& normal, Vec3& tangent, Vec3& bitangent); - -/** - * @brief Transform direction from tangent space to world space - * @param tangent_dir Direction in tangent space - * @param normal Surface normal - * @param tangent Surface tangent - * @param bitangent Surface bitangent - * @return Direction in world space - */ -Vec3 tangent_to_world(const Vec3& tangent_dir, const Vec3& normal, - const Vec3& tangent, const Vec3& bitangent); - -} // namespace are - -#endif // ARE_INCLUDE_UTILS_MATH_UTILS_H diff --git a/include/are/utils/random.h b/include/are/utils/random.h deleted file mode 100644 index 705e800..0000000 --- a/include/are/utils/random.h +++ /dev/null @@ -1,119 +0,0 @@ -/** - * @file random.h - * @brief Random number generation utilities - */ - -#ifndef ARE_INCLUDE_UTILS_RANDOM_H -#define ARE_INCLUDE_UTILS_RANDOM_H - -#include -#include - -namespace are { - -/** - * @class RandomGenerator - * @brief Thread-safe random number generator - * - * Uses PCG (Permuted Congruential Generator) for high-quality random numbers. - */ -class RandomGenerator { -public: - /** - * @brief Constructor with optional seed - * @param seed Random seed (0 = use random device) - */ - explicit RandomGenerator(uint64_t seed = 0); - - /** - * @brief Generate random float in [0, 1) - * @return Random float - */ - Real random_float(); - - /** - * @brief Generate random float in [min, max) - * @param min Minimum value - * @param max Maximum value - * @return Random float - */ - Real random_float(Real min, Real max); - - /** - * @brief Generate random integer in [min, max] - * @param min Minimum value - * @param max Maximum value - * @return Random integer - */ - int random_int(int min, int max); - - /** - * @brief Generate random point in unit disk - * @return Random point (z = 0) - */ - Vec3 random_in_unit_disk(); - - /** - * @brief Generate random point in unit sphere - * @return Random point - */ - Vec3 random_in_unit_sphere(); - - /** - * @brief Generate random unit vector - * @return Random unit vector - */ - Vec3 random_unit_vector(); - - /** - * @brief Generate random vector in hemisphere - * @param normal Hemisphere normal - * @return Random vector in hemisphere - */ - Vec3 random_in_hemisphere(const Vec3 &normal); - - /** - * @brief Generate random cosine-weighted direction - * @param normal Surface normal - * @return Random direction (cosine-weighted) - */ - Vec3 random_cosine_direction(const Vec3 &normal); - - /** - * @brief Set seed for reproducible results - * @param seed Random seed - */ - void set_seed(uint64_t seed); - -private: - std::mt19937_64 rng_; ///< Random number generator - std::uniform_real_distribution dist_; ///< Uniform distribution [0, 1) -}; - -/** - * @brief Get thread-local random generator - * @return Reference to thread-local generator - */ -RandomGenerator &get_thread_random(); - -/** - * @brief Generate random float in [0, 1) using thread-local generator - * @return Random float - */ -inline Real random_float() { - return get_thread_random().random_float(); -} - -/** - * @brief Generate random float in [min, max) using thread-local generator - * @param min Minimum value - * @param max Maximum value - * @return Random float - */ -inline Real random_float(Real min, Real max) { - return get_thread_random().random_float(min, max); -} - -} // namespace are - -#endif // ARE_INCLUDE_UTILS_RANDOM_H diff --git a/new_conversation.md b/new_conversation.md deleted file mode 100644 index 431443d..0000000 --- a/new_conversation.md +++ /dev/null @@ -1,854 +0,0 @@ -我正在开发 Aurora Rendering Engine (ARE),一个 C++17 跨平台混合渲染引擎。 - -**核心特性**: -- 混合渲染:光栅化(G-Buffer)+ 光线追踪(GI/AO/软阴影) -- 双后端:CPU 和 Compute Shader 光线追踪,可运行时切换 -- BVH 加速结构 -- PBR 材质系统 -- 工业级可扩展性 - -**技术栈**: -- C++17, OpenGL 4.3+, GLFW, GLAD, GLM, spdlog, stb_image -- 平台:Windows + Linux -- 构建:CMake 3.15+ - -**编码规范(NanoEra)**: -- 命名:函数/变量 `snake_case`,类 `PascalCase`,类成员后缀 `_`(但用户直接使用的结构体成员不加下划线) -- 全局宏前缀 `are_`,头文件保护 `ARE_INCLUDE_[路径]_H` -- 注释:全英文,重要接口用 Doxygen -- 禁用虚函数(性能优先,但不影响性能时可用) - -**重要设计决策**: -1. 配置系统:纯代码配置,不支持文件加载 -2. 错误处理:简化设计,直接输出,无堆栈累积 -3. Shader 管理:外部文件,用户在 config 中指定路径 -4. 场景数据:渲染器拷贝数据(用户友好) -5. BVH 构建:延迟构建(在 begin_frame 时检测并构建) -6. 材质系统:Mesh 持有 Material ID,支持复用 - -**文件目录树**: -``` -aurora-rendering-engine/ -├── include/ # 头文件目录 -│ ├── are/ # 主命名空间目录 -│ │ ├── are.h # 总头文件(包含所有公共接口) -│ │ ├── core/ # 核心模块 -│ │ │ ├── config.h # 配置系统 -│ │ │ ├── logger.h # 日志系统 -│ │ │ ├── types.h # 基础类型定义 -│ │ │ └── profiler.h # 性能分析器 -│ │ ├── renderer/ # 渲染器模块 -│ │ │ ├── renderer.h # 主渲染器接口 -│ │ │ ├── render_context.h # 渲染上下文 -│ │ │ └── render_stats.h # 渲染统计信息 -│ │ ├── scene/ # 场景管理模块 -│ │ │ ├── camera.h # 相机 -│ │ │ ├── mesh.h # 网格 -│ │ │ ├── material.h # 材质 -│ │ │ ├── light.h # 光源(基类) -│ │ │ ├── directional_light.h # 平行光 -│ │ │ ├── point_light.h # 点光源 -│ │ │ ├── spot_light.h # 聚光灯 -│ │ │ └── scene_manager.h # 场景管理器 -│ │ ├── geometry/ # 几何处理模块 -│ │ │ ├── vertex.h # 顶点结构 -│ │ │ ├── triangle.h # 三角形 -│ │ │ ├── aabb.h # 轴对齐包围盒 -│ │ │ └── transform.h # 变换矩阵 -│ │ ├── acceleration/ # 加速结构模块 -│ │ │ ├── bvh.h # BVH 接口 -│ │ │ ├── bvh_node.h # BVH 节点 -│ │ │ └── bvh_builder.h # BVH 构建器 -│ │ ├── rasterizer/ # 光栅化模块 -│ │ │ ├── rasterizer.h # 光栅化器接口 -│ │ │ ├── gbuffer.h # G-Buffer 管理 -│ │ │ └── shader_program.h # Shader 程序封装 -│ │ ├── raytracer/ # 光线追踪模块 -│ │ │ ├── raytracer.h # 光线追踪器接口 -│ │ │ ├── ray.h # 光线结构 -│ │ │ ├── hit_record.h # 碰撞记录 -│ │ │ ├── cpu_raytracer.h # CPU 光线追踪实现 -│ │ │ └── compute_raytracer.h # Compute Shader 实现 -│ │ ├── texture/ # 纹理模块 -│ │ │ ├── texture.h # 纹理接口 -│ │ │ ├── texture_manager.h # 纹理管理器 -│ │ │ └── sampler.h # 采样器 -│ │ ├── utils/ # 工具模块 -│ │ │ ├── image_io.h # 图像读写 -│ │ │ ├── random.h # 随机数生成 -│ │ │ ├── math_utils.h # 数学工具函数 -│ │ │ └── file_utils.h # 文件工具函数 -│ │ └── platform/ # 平台相关模块 -│ │ ├── window.h # 窗口管理 -│ │ └── gl_context.h # OpenGL 上下文 -│ └── extended_folders.list # 模块分类文件夹列表 -│ -├── src/ # 源代码目录 -│ ├── core/ -│ │ ├── config.cpp -│ │ ├── logger.cpp -│ │ └── profiler.cpp -│ ├── renderer/ -│ │ ├── renderer.cpp -│ │ ├── render_context.cpp -│ │ └── render_stats.cpp -│ ├── scene/ -│ │ ├── camera.cpp -│ │ ├── mesh.cpp -│ │ ├── material.cpp -│ │ ├── light.cpp -│ │ ├── directional_light.cpp -│ │ ├── point_light.cpp -│ │ ├── spot_light.cpp -│ │ └── scene_manager.cpp -│ ├── geometry/ -│ │ ├── vertex.cpp -│ │ ├── triangle.cpp -│ │ ├── aabb.cpp -│ │ └── transform.cpp -│ ├── acceleration/ -│ │ ├── bvh.cpp -│ │ ├── bvh_node.cpp -│ │ └── bvh_builder.cpp -│ ├── rasterizer/ -│ │ ├── rasterizer.cpp -│ │ ├── gbuffer.cpp -│ │ └── shader_program.cpp -│ ├── raytracer/ -│ │ ├── raytracer.cpp -│ │ ├── ray.cpp -│ │ ├── hit_record.cpp -│ │ ├── cpu_raytracer.cpp -│ │ └── compute_raytracer.cpp -│ ├── texture/ -│ │ ├── texture.cpp -│ │ ├── texture_manager.cpp -│ │ └── sampler.cpp -│ ├── utils/ -│ │ ├── image_io.cpp -│ │ ├── random.cpp -│ │ ├── math_utils.cpp -│ │ └── file_utils.cpp -│ └── platform/ -│ ├── window.cpp -│ └── gl_context.cpp -│ -├── shaders/ # Shader 文件目录 -│ ├── gbuffer/ -│ │ ├── gbuffer.vert # G-Buffer 顶点着色器 -│ │ └── gbuffer.frag # G-Buffer 片段着色器 -│ ├── raytracing/ -│ │ └── raytracing.comp # 光线追踪计算着色器 -│ ├── post_process/ -│ │ ├── tonemap.vert # Tone Mapping 顶点着色器 -│ │ ├── tonemap.frag # Tone Mapping 片段着色器 -│ │ └── fullscreen_quad.vert # 全屏四边形顶点着色器 -│ └── debug/ -│ ├── visualize_gbuffer.frag # G-Buffer 可视化 -│ └── visualize_bvh.frag # BVH 可视化 -│ -├── lib/ # 第三方库目录(用户自行安装) -│ ├── glfw/ # GLFW(用户提供) -│ ├── glad/ # GLAD(用户提供) -│ ├── glm/ # GLM(用户提供) -│ ├── spdlog/ # spdlog(用户提供) -│ └── stb/ # stb 库(项目包含) -│ ├── stb_image.h -│ └── stb_image_write.h -│ -├── examples/ # 示例程序目录 -│ ├── 01_hello_triangle/ -│ │ ├── main.cpp # 基础三角形示例 -│ │ └── CMakeLists.txt -│ ├── 02_cornell_box/ -│ │ ├── main.cpp # Cornell Box 示例 -│ │ └── CMakeLists.txt -│ ├── 03_material_showcase/ -│ │ ├── main.cpp # 材质展示示例 -│ │ └── CMakeLists.txt -│ └── 04_performance_test/ -│ ├── main.cpp # 性能测试示例 -│ └── CMakeLists.txt -│ -├── experiments/ # 实验和测试记录目录 -│ └── .gitkeep -│ -├── docs/ # 文档目录 -│ ├── API.md # API 文档 -│ ├── ARCHITECTURE.md # 架构设计文档 -│ ├── BUILD.md # 构建指南 -│ └── CODING_STYLE.md # 编码规范 -│ -├── scripts/ # 脚本目录 -│ ├── export_modules_requirements.sh # 导出模块依赖 -│ ├── check_code.sh # 代码规范检查 -│ └── setup_dependencies.sh # 依赖配置脚本(您后续编写) -│ -├── res/ # 资源文件目录 -│ └── icon.png # 项目图标 -│ -├── CMakeLists.txt # 主 CMake 配置文件 -├── .gitignore # Git 忽略文件 -├── .gitmodules # Git 子模块配置(如果使用) -├── LICENSE # 许可证 -└── README.md # 项目说明 -``` -如下是模块间依赖关系示意图: -``` -┌─────────────────────────────────────────────────────────────┐ -│ Renderer │ -│ (主渲染器接口) │ -└────────────┬────────────────────────────────┬───────────────┘ - │ │ - ▼ ▼ - ┌────────────────┐ ┌─────────────────┐ - │ Rasterizer │ │ RayTracer │ - │ (光栅化器) │ │ (光线追踪器) │ - └────────┬───────┘ └────────┬────────┘ - │ │ - ▼ ▼ - ┌────────────────┐ ┌─────────────────┐ - │ GBuffer │ │ CPU/Compute │ - │ (G-Buffer) │ │ (双实现) │ - └────────────────┘ └────────┬────────┘ - │ - ▼ - ┌─────────────────┐ - │ BVH │ - │ (加速结构) │ - └────────┬────────┘ - │ - ┌───────────────────────────────┴───────────────┐ - │ │ - ▼ ▼ - ┌────────────────┐ ┌─────────────────┐ - │ SceneManager │ │ Geometry │ - │ (场景管理) │ │ (几何数据) │ - └────────┬───────┘ └─────────────────┘ - │ - ├─────► Camera (相机) - ├─────► Mesh (网格) - ├─────► Material (材质) - └─────► Light (光源) - │ - ├─────► DirectionalLight - ├─────► PointLight - └─────► SpotLight - -┌─────────────────────────────────────────────────────────────┐ -│ 支撑模块 (底层) │ -├─────────────────────────────────────────────────────────────┤ -│ Core: Config, Logger, Profiler, Types │ -│ Texture: TextureManager, Sampler │ -│ Utils: ImageIO, Random, MathUtils, FileUtils │ -│ Platform: Window, GLContext │ -└─────────────────────────────────────────────────────────────┘ -``` - -关于项目实现架构,我有以下步骤: -### Phase 1: 基础设施搭建(Week 1-2) -**目标**:建立项目骨架,确保编译通过 - -#### Step 1.1: 核心模块 -``` -优先级: ★★★★★ -文件: - - include/are/core/types.h # 基础类型定义 - - include/are/core/config.h # 配置系统 - - include/are/core/logger.h # 日志系统 - - src/core/config.cpp - - src/core/logger.cpp - -依赖: spdlog - -验证: 能够创建 Config 对象并输出日志 -``` - -#### Step 1.2: 平台层 -``` -优先级: ★★★★★ -文件: - - include/are/platform/window.h # 窗口管理 - - include/are/platform/gl_context.h # OpenGL 上下文 - - src/platform/window.cpp - - src/platform/gl_context.cpp - -依赖: GLFW, GLAD - -验证: 能够创建窗口并初始化 OpenGL 上下文 -``` - -#### Step 1.3: 工具模块 -``` -优先级: ★★★★☆ -文件: - - include/are/utils/math_utils.h # 数学工具 - - include/are/utils/file_utils.h # 文件工具 - - include/are/utils/random.h # 随机数生成 - - src/utils/*.cpp - -依赖: GLM - -验证: 基础工具函数可用 -``` - ---- - -### Phase 2: 几何与场景系统(Week 2-3) - -**目标**:能够构建和管理场景数据 - -#### Step 2.1: 几何数据结构 -``` -优先级: ★★★★★ -文件: - - include/are/geometry/vertex.h # 顶点结构 - - include/are/geometry/triangle.h # 三角形 - - include/are/geometry/aabb.h # 包围盒 - - include/are/geometry/transform.h # 变换 - - src/geometry/*.cpp - -依赖: GLM - -验证: 能够创建和操作几何数据 -``` - -#### Step 2.2: 场景对象 -``` -优先级: ★★★★★ -文件: - - include/are/scene/camera.h # 相机 - - include/are/scene/mesh.h # 网格 - - include/are/scene/material.h # 材质 - - include/are/scene/light.h # 光源基类 - - include/are/scene/directional_light.h - - include/are/scene/point_light.h - - include/are/scene/spot_light.h - - src/scene/*.cpp - -依赖: geometry - -验证: 能够创建场景对象 -``` - -#### Step 2.3: 场景管理器 -``` -优先级: ★★★★☆ -文件: - - include/are/scene/scene_manager.h - - src/scene/scene_manager.cpp - -依赖: scene/* - -验证: 能够添加/删除/查询场景对象 -``` - ---- - -### Phase 3: 光栅化管线(Week 3-4) - -**目标**:实现 G-Buffer 生成 - -#### Step 3.1: Shader 管理 -``` -优先级: ★★★★★ -文件: - - include/are/rasterizer/shader_program.h - - src/rasterizer/shader_program.cpp - - shaders/gbuffer/gbuffer.vert - - shaders/gbuffer/gbuffer.frag - -依赖: platform/gl_context - -验证: 能够加载和编译 Shader -``` - -#### Step 3.2: G-Buffer -``` -优先级: ★★★★★ -文件: - - include/are/rasterizer/gbuffer.h - - src/rasterizer/gbuffer.cpp - -依赖: shader_program - -验证: 能够创建 G-Buffer 纹理 -``` - -#### Step 3.3: 光栅化器 -``` -优先级: ★★★★★ -文件: - - include/are/rasterizer/rasterizer.h - - src/rasterizer/rasterizer.cpp - -依赖: gbuffer, scene_manager - -验证: 能够渲染场景到 G-Buffer -``` - ---- - -### Phase 4: 加速结构(Week 4-5) - -**目标**:实现 BVH 构建 - -#### Step 4.1: BVH 节点 -``` -优先级: ★★★★★ -文件: - - include/are/acceleration/bvh_node.h - - src/acceleration/bvh_node.cpp - -依赖: geometry/aabb - -验证: 能够创建 BVH 节点 -``` - -#### Step 4.2: BVH 构建器 -``` -优先级: ★★★★★ -文件: - - include/are/acceleration/bvh_builder.h - - src/acceleration/bvh_builder.cpp - -依赖: bvh_node, scene/mesh - -验证: 能够从三角形列表构建 BVH(使用 SAH 或中点分割) -``` - -#### Step 4.3: BVH 接口 -``` -优先级: ★★★★☆ -文件: - - include/are/acceleration/bvh.h - - src/acceleration/bvh.cpp - -依赖: bvh_builder - -验证: 提供统一的 BVH 查询接口 -``` - ---- - -### Phase 5: CPU 光线追踪(Week 5-6) - -**目标**:实现基础的 CPU 光线追踪 - -#### Step 5.1: 光线与碰撞 -``` -优先级: ★★★★★ -文件: - - include/are/raytracer/ray.h - - include/are/raytracer/hit_record.h - - src/raytracer/ray.cpp - - src/raytracer/hit_record.cpp - -依赖: geometry - -验证: 能够进行光线-三角形相交测试 -``` - -#### Step 5.2: CPU 光线追踪器 -``` -优先级: ★★★★★ -文件: - - include/are/raytracer/cpu_raytracer.h - - src/raytracer/cpu_raytracer.cpp - -依赖: ray, hit_record, bvh, scene_manager - -验证: 能够追踪光线并计算基础着色(漫反射) -``` - -#### Step 5.3: 多线程优化 -``` -优先级: ★★★★☆ -修改: src/raytracer/cpu_raytracer.cpp - -依赖: OpenMP 或 std::thread - -验证: 多线程加速光线追踪 -``` - ---- - -### Phase 6: Compute Shader 光线追踪(Week 6-7) - -**目标**:实现 GPU 光线追踪 - -#### Step 6.1: Compute Shader 编写 -``` -优先级: ★★★★★ -文件: - - shaders/raytracing/raytracing.comp - -依赖: OpenGL 4.3+ - -验证: Shader 能够编译通过 -``` - -#### Step 6.2: GPU 数据传输 -``` -优先级: ★★★★★ -文件: - - include/are/raytracer/compute_raytracer.h - - src/raytracer/compute_raytracer.cpp - -依赖: rasterizer/shader_program, bvh - -验证: 能够将 BVH 和场景数据上传到 GPU(SSBO) -``` - -#### Step 6.3: GPU 光线追踪实现 -``` -优先级: ★★★★★ -修改: shaders/raytracing/raytracing.comp - src/raytracer/compute_raytracer.cpp - -验证: GPU 光线追踪能够产生正确结果 -``` - ---- - -### Phase 7: 主渲染器集成(Week 7-8) - -**目标**:整合所有模块 - -#### Step 7.1: 渲染上下文 -``` -优先级: ★★★★★ -文件: - - include/are/renderer/render_context.h - - include/are/renderer/render_stats.h - - src/renderer/render_context.cpp - - src/renderer/render_stats.cpp - -依赖: 所有模块 - -验证: 能够管理渲染状态 -``` - -#### Step 7.2: 主渲染器 -``` -优先级: ★★★★★ -文件: - - include/are/renderer/renderer.h - - src/renderer/renderer.cpp - -依赖: rasterizer, raytracer, scene_manager - -验证: 能够完成完整的混合渲染流程 -``` - -#### Step 7.3: 后处理(Tone Mapping) -``` -优先级: ★★★★☆ -文件: - - shaders/post_process/tonemap.vert - - shaders/post_process/tonemap.frag - -修改: src/renderer/renderer.cpp - -验证: HDR 到 LDR 的转换 -``` - ---- - -### Phase 8: 纹理系统(Week 8-9) - -**目标**:支持纹理贴图 - -#### Step 8.1: 图像 I/O -``` -优先级: ★★★★☆ -文件: - - include/are/utils/image_io.h - - src/utils/image_io.cpp - -依赖: stb_image, stb_image_write - -验证: 能够加载和保存图像 -``` - -#### Step 8.2: 纹理管理 -``` -优先级: ★★★★☆ -文件: - - include/are/texture/texture.h - - include/are/texture/texture_manager.h - - include/are/texture/sampler.h - - src/texture/*.cpp - -依赖: image_io - -验证: 能够加载纹理并在材质中使用 -``` - -#### Step 8.3: 集成到渲染管线 -``` -优先级: ★★★★☆ -修改: src/rasterizer/rasterizer.cpp - src/raytracer/cpu_raytracer.cpp - shaders/raytracing/raytracing.comp - -验证: 纹理能够正确显示 -``` - ---- - -### Phase 9: 高级光线追踪特性(Week 9-11) - -**目标**:实现高质量渲染特性 - -#### Step 9.1: 环境光遮蔽(AO) -``` -优先级: ★★★★☆ -修改: src/raytracer/cpu_raytracer.cpp - shaders/raytracing/raytracing.comp - -验证: AO 效果正确 -``` - -#### Step 9.2: 软阴影 -``` -优先级: ★★★☆☆ -修改: 光线追踪器实现 - -验证: 软阴影效果 -``` - -#### Step 9.3: 镜面反射 -``` -优先级: ★★★☆☆ -修改: 光线追踪器实现 - -验证: 镜面反射效果 -``` - -#### Step 9.4: 折射/透明 -``` -优先级: ★★☆☆☆ -修改: 光线追踪器实现 - -验证: 透明材质效果 -``` - ---- - -### Phase 10: 调试与性能分析(Week 11-12) - -**目标**:提供调试工具和性能优化 - -#### Step 10.1: 性能分析器 -``` -优先级: ★★★★☆ -文件: - - include/are/core/profiler.h - - src/core/profiler.cpp - -依赖: logger - -验证: 能够测量各阶段耗时 -``` - -#### Step 10.2: 调试可视化 -``` -优先级: ★★★☆☆ -文件: - - shaders/debug/visualize_gbuffer.frag - - shaders/debug/visualize_bvh.frag - -修改: src/renderer/renderer.cpp - -验证: 能够可视化 G-Buffer 各通道和 BVH 包围盒 -``` - -#### Step 10.3: 帧捕获功能 -``` -优先级: ★★★★☆ -修改: src/renderer/renderer.cpp - src/utils/image_io.cpp - -验证: 能够保存渲染结果到文件 -``` - ---- - -### Phase 11: 示例程序(Week 12-13) - -**目标**:提供完整的使用示例 - -#### Step 11.1: Hello Triangle -``` -优先级: ★★★★★ -文件: - - examples/01_hello_triangle/main.cpp - - examples/01_hello_triangle/CMakeLists.txt - -验证: 最简单的三角形渲染 -``` - -#### Step 11.2: Cornell Box -``` -优先级: ★★★★☆ -文件: - - examples/02_cornell_box/main.cpp - - examples/02_cornell_box/CMakeLists.txt - -验证: 经典的 Cornell Box 场景,展示全局光照 -``` - -#### Step 11.3: Material Showcase -``` -优先级: ★★★☆☆ -文件: - - examples/03_material_showcase/main.cpp - - examples/03_material_showcase/CMakeLists.txt - -验证: 展示不同材质参数的效果 -``` - -#### Step 11.4: Performance Test -``` -优先级: ★★★☆☆ -文件: - - examples/04_performance_test/main.cpp - - examples/04_performance_test/CMakeLists.txt - -验证: CPU vs GPU 性能对比 -``` - ---- - -接下来是开发策略说明 - -### 开发原则 - -1. **自底向上构建**: - - 先实现底层模块(core, utils, platform) - - 再实现数据层(geometry, scene) - - 最后实现算法层和接口层 - -2. **增量验证**: - - 每个 Phase 完成后都有明确的验证目标 - - 通过简单的测试程序验证功能正确性 - - 避免大量代码堆积后才发现问题 - -3. **并行开发可能性**: - - Phase 3(光栅化)和 Phase 4(BVH)可以并行开发 - - Phase 5(CPU 光追)和 Phase 6(GPU 光追)可以并行开发 - - 但建议先完成 CPU 版本,再实现 GPU 版本(便于调试) - -4. **性能优先**: - - 初期实现注重正确性 - - 后期通过 Profiler 识别瓶颈 - - 针对性优化热点代码 - -### 关键里程碑 - -**Milestone 1(Week 4)**:能够渲染静态场景到 G-Buffer -```cpp -// 验证代码 -are::Renderer renderer(config); -renderer.add_mesh(triangle_mesh); -renderer.begin_frame(); -renderer.render_gbuffer(); // 只渲染 G-Buffer -renderer.end_frame(); -renderer.save_frame("gbuffer.png"); -``` - -**Milestone 2(Week 6)**:CPU 光线追踪能够产生正确结果 -```cpp -// 验证代码 -config.ray_tracing.backend = are::ARE_RT_BACKEND_CPU; -config.ray_tracing.spp = 16; -renderer.render(); // 完整的混合渲染 -renderer.save_frame("cpu_result.png"); -``` - -**Milestone 3(Week 8)**:GPU 光线追踪能够产生正确结果 -```cpp -// 验证代码 -config.ray_tracing.backend = are::ARE_RT_BACKEND_COMPUTE_SHADER; -renderer.render(); -renderer.save_frame("gpu_result.png"); -// 对比 CPU 和 GPU 结果,误差应在可接受范围内 -``` - -**Milestone 4(Week 10)**:支持纹理和多种光源 -```cpp -// 验证代码 -material.set_albedo_map("brick.png"); -renderer.add_light(directional_light); -renderer.add_light(point_light); -renderer.render(); -``` - -**Milestone 5(Week 14)**:项目完成,所有示例可运行 - -### 风险控制 - -**潜在风险**: -1. **BVH 构建性能**:如果场景复杂,构建时间可能过长 - - 缓解:使用多线程构建,考虑增量更新 - -2. **GPU 内存限制**:大场景可能超出 GPU 内存 - - 缓解:实现场景分块,按需加载 - -3. **Compute Shader 调试困难**:GPU 代码难以调试 - - 缓解:先在 CPU 上验证算法正确性,再移植到 GPU - -4. **跨平台兼容性**:Windows 和 Linux 的差异 - - 缓解:使用 CMake 和标准库,避免平台特定代码 - -接下来是一些小总结 - -### 项目规模估算 -- **总文件数**:约 80-100 个文件(头文件 + 源文件 + Shader) -- **代码量**:约 15,000-20,000 行(不含注释和空行) -- **开发周期**:14 周(约 3.5 个月) -- **核心模块**:10 个(core, platform, utils, geometry, scene, acceleration, rasterizer, raytracer, texture, renderer) - -### 技术栈 -- **语言**:C++17 -- **图形 API**:OpenGL 4.3+ -- **依赖库**:GLFW, GLAD, GLM, spdlog, stb -- **构建系统**:CMake 3.15+ -- **并行**:OpenMP / std::thread - -### 设计亮点 -1. **模块化设计**:清晰的层次结构,低耦合高内聚 -2. **双后端支持**:CPU 和 GPU 光线追踪可运行时切换 -3. **工业级可扩展性**:预留接口,便于后期添加新特性 -4. **性能优先**:BVH 加速、多线程、GPU 计算 -5. **易于调试**:完善的日志系统、性能分析、可视化工具 - ---- - -此外,还有一些额外要求: -### ⚠️ 关键修改记录 -1. **config.h 成员变量已去除下划线** - - 原因:用户直接使用的结构体成员不加下划线 - - 影响:所有访问 config 的代码都使用无下划线版本 - - 示例:`config.window.width` 而不是 `config.window.width_` - -### 📌 API 一致性检查清单 -在实现时应该: -- [ ] 检查头文件中声明的所有函数是否都实现 -- [ ] 不创造头文件中未声明的公共函数 -- [ ] 成员变量命名符合规范(类成员变量后缀 `_`,用户结构体,即public成员变量不加) -- [ ] 所有公共 API 都有 Doxygen 注释 -- [ ] 错误处理使用 `ARE_LOG_ERROR` -- [ ] 性能关键函数使用 `ARE_PROFILE_FUNCTION()` - -### 🎯 Phase 2 成功标准 -- [ ] 所有源文件编译通过(0 错误 0 警告) -- [ ] 验证程序能够创建场景对象 -- [ ] 相机能够生成光线 -- [ ] 网格能够计算 AABB -- [ ] 光源能够打包数据 -- [ ] 场景管理器能够管理对象 - -对于目前的进度,我们已经实现到了Phase 4,正在实现Phase 5,请你帮我们进行Phase 5以及后续代码的实现。 -但是因为我还没有给你我们已有的代码,因此你需要哪些头文件的代码?请在下一轮向我询问,然后我们会开始Phase 5的开发。 diff --git a/phase3.md b/phase3.md deleted file mode 100644 index d013a07..0000000 --- a/phase3.md +++ /dev/null @@ -1,605 +0,0 @@ -### 文件:include/are/platform/window.h -```cpp -/** - * @file window.h - * @brief Window management using GLFW - */ - -#ifndef ARE_INCLUDE_PLATFORM_WINDOW_H -#define ARE_INCLUDE_PLATFORM_WINDOW_H - -#include -#include -#include - -// Forward declare GLFW types to avoid including GLFW in header -struct GLFWwindow; - -namespace are { - -/** - * @class Window - * @brief GLFW window wrapper - * - * Manages window creation, input handling, and OpenGL context. - */ -class Window { -public: - /** - * @brief Constructor - * @param config Window configuration - */ - explicit Window(const WindowConfig& config); - - /** - * @brief Destructor - */ - ~Window(); - - // Window control - bool should_close() const; - void set_should_close(bool should_close); - void swap_buffers(); - void poll_events(); - - // Window properties - int get_width() const; - int get_height() const; - Real get_aspect_ratio() const; - const std::string& get_title() const; - - void set_title(const std::string& title); - void set_size(int width, int height); - - // Framebuffer size (may differ from window size on high-DPI displays) - void get_framebuffer_size(int& width, int& height) const; - - // VSync control - void set_vsync(bool enabled); - bool get_vsync() const; - - // Input queries (basic support) - bool is_key_pressed(int key) const; - bool is_mouse_button_pressed(int button) const; - void get_cursor_pos(double& x, double& y) const; - - // Internal - GLFWwindow* get_native_window() const { return window_; } - -private: - void initialize_glfw(); - void create_window(); - void setup_callbacks(); - - static void framebuffer_size_callback(GLFWwindow* window, int width, int height); - static void error_callback(int error, const char* description); - - GLFWwindow* window_; ///< GLFW window handle - WindowConfig config_; ///< Window configuration - bool vsync_enabled_; ///< VSync state - - static int instance_count_; ///< Number of Window instances -}; - -} // namespace are - -#endif // ARE_INCLUDE_PLATFORM_WINDOW_H -``` - -### 文件:include/are/platform/gl_context.h -```cpp -/** - * @file gl_context.h - * @brief OpenGL context management - */ - -#ifndef ARE_INCLUDE_PLATFORM_GL_CONTEXT_H -#define ARE_INCLUDE_PLATFORM_GL_CONTEXT_H - -#include -#include - -namespace are { - -/** - * @class GLContext - * @brief OpenGL context initialization and management - * - * Handles GLAD initialization and provides OpenGL utility functions. - */ -class GLContext { -public: - /** - * @brief Initialize OpenGL context (load function pointers) - * @return true if initialization succeeded - */ - static bool initialize(); - - /** - * @brief Check if context is initialized - * @return true if initialized - */ - static bool is_initialized(); - - /** - * @brief Get OpenGL version string - * @return Version string - */ - static std::string get_version(); - - /** - * @brief Get OpenGL renderer string - * @return Renderer string - */ - static std::string get_renderer(); - - /** - * @brief Get OpenGL vendor string - * @return Vendor string - */ - static std::string get_vendor(); - - /** - * @brief Check if OpenGL extension is supported - * @param extension Extension name - * @return true if supported - */ - static bool is_extension_supported(const std::string& extension); - - /** - * @brief Print OpenGL information to console - */ - static void print_info(); - - /** - * @brief Check for OpenGL errors - * @param file Source file - * @param line Line number - * @return true if error occurred - */ - static bool check_error(const char* file, int line); - - /** - * @brief Clear all OpenGL errors - */ - static void clear_errors(); - -private: - static bool initialized_; ///< Initialization flag -}; - -} // namespace are - -// OpenGL error checking macro -#ifdef ARE_ENABLE_DEBUG_VIS - #define ARE_GL_CHECK() are::GLContext::check_error(__FILE__, __LINE__) -#else - #define ARE_GL_CHECK() ((void)0) -#endif - -#endif // ARE_INCLUDE_PLATFORM_GL_CONTEXT_H -``` - -### 文件:include/are/utils/file_utils.h -```cpp -/** - * @file file_utils.h - * @brief File system utilities - */ - -#ifndef ARE_INCLUDE_UTILS_FILE_UTILS_H -#define ARE_INCLUDE_UTILS_FILE_UTILS_H - -#include -#include -#include - -namespace are { - -/** - * @brief Read entire file into string - * @param filepath File path - * @return File contents (empty if failed) - */ -std::string read_file_to_string(const std::string& filepath); - -/** - * @brief Read entire file into byte array - * @param filepath File path - * @return File contents (empty if failed) - */ -std::vector read_file_to_bytes(const std::string& filepath); - -/** - * @brief Write string to file - * @param filepath File path - * @param content Content to write - * @return true if write succeeded - */ -bool write_string_to_file(const std::string& filepath, const std::string& content); - -/** - * @brief Write bytes to file - * @param filepath File path - * @param data Data pointer - * @param size Data size in bytes - * @return true if write succeeded - */ -bool write_bytes_to_file(const std::string& filepath, const void* data, size_t size); - -/** - * @brief Check if file exists - * @param filepath File path - * @return true if file exists - */ -bool file_exists(const std::string& filepath); - -/** - * @brief Check if path is directory - * @param path Directory path - * @return true if directory exists - */ -bool is_directory(const std::string& path); - -/** - * @brief Create directory (including parent directories) - * @param path Directory path - * @return true if creation succeeded - */ -bool create_directory(const std::string& path); - -/** - * @brief Get file extension - * @param filepath File path - * @return Extension (lowercase, without dot) - */ -std::string get_file_extension(const std::string& filepath); - -/** - * @brief Get filename from path - * @param filepath File path - * @return Filename (without directory) - */ -std::string get_filename(const std::string& filepath); - -/** - * @brief Get directory from path - * @param filepath File path - * @return Directory path - */ -std::string get_directory(const std::string& filepath); - -/** - * @brief Join path components - * @param parts Path components - * @return Joined path - */ -std::string join_path(const std::vector& parts); - -/** - * @brief Normalize path (resolve .. and .) - * @param path Path to normalize - * @return Normalized path - */ -std::string normalize_path(const std::string& path); - -} // namespace are - -#endif // ARE_INCLUDE_UTILS_FILE_UTILS_H -``` - -这是你所要求的三个头文件,如果还需要更多头文件的代码,请随时向我提出。同时,平台层着三个函数的代码我也已经实现,你只需要专心考虑渲染管线即可。此外,渲染管线的头文件我也实现了,你只需要负责实现渲染管线的shader以及代码实现即可。 -### 文件:include/are/rasterizer/shader_program.h -```cpp -/** - * @file shader_program.h - * @brief OpenGL shader program wrapper - */ - -#ifndef ARE_INCLUDE_RASTERIZER_SHADER_PROGRAM_H -#define ARE_INCLUDE_RASTERIZER_SHADER_PROGRAM_H - -#include -#include -#include - -namespace are { - -/** - * @enum ShaderType - * @brief Shader stage types - */ -enum class ShaderType { - ARE_SHADER_VERTEX, - ARE_SHADER_FRAGMENT, - ARE_SHADER_COMPUTE -}; - -/** - * @class ShaderProgram - * @brief OpenGL shader program management - */ -class ShaderProgram { -public: - /** - * @brief Constructor - */ - ShaderProgram(); - - /** - * @brief Destructor - */ - ~ShaderProgram(); - - /** - * @brief Load and compile shader from file - * @param type Shader type - * @param filepath Shader file path - * @return true if compilation succeeded - */ - bool load_shader(ShaderType type, const std::string& filepath); - - /** - * @brief Compile shader from source string - * @param type Shader type - * @param source Shader source code - * @return true if compilation succeeded - */ - bool compile_shader(ShaderType type, const std::string& source); - - /** - * @brief Link shader program - * @return true if linking succeeded - */ - bool link(); - - /** - * @brief Use this shader program - */ - void use() const; - - /** - * @brief Check if program is valid - * @return true if valid - */ - bool is_valid() const { return program_ != 0 && linked_; } - - /** - * @brief Get OpenGL program ID - * @return Program ID - */ - uint32_t get_program() const { return program_; } - - // Uniform setters - void set_uniform(const std::string& name, int value); - void set_uniform(const std::string& name, float value); - void set_uniform(const std::string& name, const Vec2& value); - void set_uniform(const std::string& name, const Vec3& value); - void set_uniform(const std::string& name, const Vec4& value); - void set_uniform(const std::string& name, const Mat3& value); - void set_uniform(const std::string& name, const Mat4& value); - - /** - * @brief Get uniform location (cached) - * @param name Uniform name - * @return Uniform location (-1 if not found) - */ - int get_uniform_location(const std::string& name); - -private: - bool check_compile_errors(uint32_t shader, ShaderType type); - bool check_link_errors(); - - uint32_t program_; ///< OpenGL program ID - uint32_t vertex_shader_; ///< Vertex shader ID - uint32_t fragment_shader_; ///< Fragment shader ID - uint32_t compute_shader_; ///< Compute shader ID - - bool linked_; ///< Link status - std::unordered_map uniform_cache_; ///< Uniform location cache -}; - -} // namespace are - -#endif // ARE_INCLUDE_RASTERIZER_SHADER_PROGRAM_H -``` - -### 文件:include/are/rasterizer/gbuffer.h -```cpp -/** - * @file gbuffer.h - * @brief G-Buffer management for deferred rendering - */ - -#ifndef ARE_INCLUDE_RASTERIZER_GBUFFER_H -#define ARE_INCLUDE_RASTERIZER_GBUFFER_H - -#include -#include - -namespace are { - -/** - * @class GBuffer - * @brief G-Buffer for deferred rendering - * - * Contains multiple render targets for position, normal, albedo, etc. - */ -class GBuffer { -public: - /** - * @brief Constructor - * @param width Buffer width - * @param height Buffer height - */ - GBuffer(int width, int height); - - /** - * @brief Destructor - */ - ~GBuffer(); - - /** - * @brief Resize G-Buffer - * @param width New width - * @param height New height - */ - void resize(int width, int height); - - /** - * @brief Bind G-Buffer for rendering - */ - void bind(); - - /** - * @brief Unbind G-Buffer - */ - void unbind(); - - /** - * @brief Clear all buffers - */ - void clear(); - - /** - * @brief Bind texture for reading - * @param index Texture index (0=position, 1=normal, 2=albedo, etc.) - * @param texture_unit Texture unit to bind to - */ - void bind_texture(int index, int texture_unit); - - // Texture getters - uint32_t get_position_texture() const { return position_texture_; } - uint32_t get_normal_texture() const { return normal_texture_; } - uint32_t get_albedo_texture() const { return albedo_texture_; } - uint32_t get_material_texture() const { return material_texture_; } - uint32_t get_depth_texture() const { return depth_texture_; } - - // Dimensions - int get_width() const { return width_; } - int get_height() const { return height_; } - - /** - * @brief Read pixel data from G-Buffer - * @param index Buffer index - * @param data Output data pointer - */ - void read_pixels(int index, void* data); - -private: - void create_textures(); - void delete_textures(); - void create_framebuffer(); - - uint32_t fbo_; ///< Framebuffer object - uint32_t rbo_depth_; ///< Depth renderbuffer - - // G-Buffer textures - uint32_t position_texture_; ///< World position (RGB16F) - uint32_t normal_texture_; ///< World normal (RGB16F) - uint32_t albedo_texture_; ///< Albedo + Metallic (RGBA8) - uint32_t material_texture_; ///< Roughness + AO (RG8) - uint32_t depth_texture_; ///< Depth (R32F) - - int width_; ///< Buffer width - int height_; ///< Buffer height -}; - -} // namespace are - -#endif // ARE_INCLUDE_RASTERIZER_GBUFFER_H -``` - -### 文件:include/are/rasterizer/rasterizer.h -```cpp -/** - * @file rasterizer.h - * @brief Rasterization pipeline for G-Buffer generation - */ - -#ifndef ARE_INCLUDE_RASTERIZER_RASTERIZER_H -#define ARE_INCLUDE_RASTERIZER_RASTERIZER_H - -#include -#include -#include - -namespace are { - -// Forward declarations -class GBuffer; -class ShaderProgram; -class SceneManager; -class Camera; -class Mesh; - -/** - * @class Rasterizer - * @brief OpenGL rasterization pipeline - * - * Renders scene geometry to G-Buffer using traditional rasterization. - */ -class Rasterizer { -public: - /** - * @brief Constructor - * @param width Framebuffer width - * @param height Framebuffer height - */ - Rasterizer(int width, int height); - - /** - * @brief Destructor - */ - ~Rasterizer(); - - /** - * @brief Resize framebuffer - * @param width New width - * @param height New height - */ - void resize(int width, int height); - - /** - * @brief Render scene to G-Buffer - * @param scene Scene manager - * @param camera Camera - */ - void render_gbuffer(const SceneManager& scene, const Camera& camera); - - /** - * @brief Get G-Buffer - * @return G-Buffer reference - */ - GBuffer& get_gbuffer(); - const GBuffer& get_gbuffer() const; - - /** - * @brief Upload mesh data to GPU - * @param mesh Mesh to upload - */ - void upload_mesh(Mesh& mesh); - - /** - * @brief Delete mesh GPU resources - * @param mesh Mesh to delete - */ - void delete_mesh(Mesh& mesh); - -private: - void initialize_shaders(const std::string& shader_dir); - void setup_mesh_buffers(Mesh& mesh); - - std::unique_ptr gbuffer_; ///< G-Buffer - std::unique_ptr gbuffer_shader_; ///< G-Buffer shader - - int width_; ///< Framebuffer width - int height_; ///< Framebuffer height -}; - -} // namespace are - -#endif // ARE_INCLUDE_RASTERIZER_RASTERIZER_H -``` - -如果没有还需要我给出的内容的话,你就可以开始实现了。 diff --git a/phase4.md b/phase4.md deleted file mode 100644 index 1d5ae67..0000000 --- a/phase4.md +++ /dev/null @@ -1,270 +0,0 @@ -很好!让我们来实现Phase 4吧! -如下是我已经实现的Phase 4头文件: -### 文件:include/are/acceleration/bvh_node.h -```cpp -/** - * @file bvh_node.h - * @brief BVH node structure - */ - -#ifndef ARE_INCLUDE_ACCELERATION_BVH_NODE_H -#define ARE_INCLUDE_ACCELERATION_BVH_NODE_H - -#include -#include - -namespace are { - -/** - * @struct BVHNode - * @brief Node in Bounding Volume Hierarchy - * - * Uses a compact representation for efficient GPU transfer. - */ -struct BVHNode { - AABB bounds_; ///< Node bounding box - - union { - uint32_t left_child_; ///< Left child index (internal node) - uint32_t first_primitive_; ///< First primitive index (leaf node) - }; - - union { - uint32_t right_child_; ///< Right child index (internal node) - uint32_t primitive_count_; ///< Number of primitives (leaf node) - }; - - /** - * @brief Check if node is a leaf - * @return true if leaf node - */ - bool is_leaf() const { - return primitive_count_ > 0; - } - - /** - * @brief Get node surface area (for SAH) - * @return Surface area - */ - Real surface_area() const { - return bounds_.surface_area(); - } -}; - -} // namespace are - -#endif // ARE_INCLUDE_ACCELERATION_BVH_NODE_H -``` - -### 文件:include/are/acceleration/bvh_builder.h -```cpp -/** - * @file bvh_builder.h - * @brief BVH construction algorithms - */ - -#ifndef ARE_INCLUDE_ACCELERATION_BVH_BUILDER_H -#define ARE_INCLUDE_ACCELERATION_BVH_BUILDER_H - -#include -#include -#include -#include - -namespace are { - -/** - * @enum BVHSplitMethod - * @brief BVH splitting strategies - */ -enum class BVHSplitMethod { - ARE_BVH_SPLIT_MIDDLE, ///< Split at midpoint - ARE_BVH_SPLIT_SAH ///< Surface Area Heuristic -}; - -/** - * @struct BVHBuildConfig - * @brief Configuration for BVH construction - */ -struct BVHBuildConfig { - BVHSplitMethod split_method_ = BVHSplitMethod::ARE_BVH_SPLIT_SAH; - int max_leaf_size_ = 4; ///< Maximum triangles per leaf - int max_depth_ = 64; ///< Maximum tree depth - bool use_multithreading_ = true; ///< Use parallel construction -}; - -/** - * @class BVHBuilder - * @brief Constructs BVH from triangle list - */ -class BVHBuilder { -public: - /** - * @brief Constructor - * @param config Build configuration - */ - explicit BVHBuilder(const BVHBuildConfig& config = BVHBuildConfig()); - - /** - * @brief Build BVH from triangles - * @param triangles Triangle list - * @param nodes Output node list - * @param primitive_indices Output primitive index list - * @return Root node index - */ - uint32_t build(const std::vector& triangles, - std::vector& nodes, - std::vector& primitive_indices); - - /** - * @brief Get build statistics - * @param node_count Output node count - * @param leaf_count Output leaf count - * @param max_depth Output maximum depth reached - */ - void get_stats(size_t& node_count, size_t& leaf_count, int& max_depth) const; - -private: - struct BuildEntry { - uint32_t parent_; - uint32_t start_; - uint32_t end_; - int depth_; - }; - - uint32_t build_recursive(const std::vector& triangles, - std::vector& nodes, - std::vector& primitive_indices, - uint32_t start, uint32_t end, int depth); - - int find_best_split_axis(const std::vector& triangles, - const std::vector& indices, - uint32_t start, uint32_t end); - - Real compute_sah_cost(const AABB& bounds, uint32_t count); - - BVHBuildConfig config_; - size_t node_count_; - size_t leaf_count_; - int max_depth_reached_; -}; - -} // namespace are - -#endif // ARE_INCLUDE_ACCELERATION_BVH_BUILDER_H -``` - -### 文件:include/are/acceleration/bvh.h -```cpp -/** - * @file bvh.h - * @brief BVH interface and traversal - */ - -#ifndef ARE_INCLUDE_ACCELERATION_BVH_H -#define ARE_INCLUDE_ACCELERATION_BVH_H - -#include -#include -#include -#include -#include -#include -#include - -namespace are { - -/** - * @class BVH - * @brief Bounding Volume Hierarchy for ray tracing acceleration - */ -class BVH { -public: - /** - * @brief Constructor - */ - BVH(); - - /** - * @brief Destructor - */ - ~BVH(); - - /** - * @brief Build BVH from triangle list - * @param triangles Triangle list - * @param config Build configuration - * @return true if build succeeded - */ - bool build(const std::vector& triangles, - const BVHBuildConfig& config = BVHBuildConfig()); - - /** - * @brief Traverse BVH and find closest intersection - * @param ray Ray to trace - * @param hit Output hit record - * @return true if intersection found - */ - bool intersect(const Ray& ray, HitRecord& hit) const; - - /** - * @brief Fast occlusion test (any hit) - * @param ray Ray to trace - * @param t_max Maximum t value - * @return true if any intersection found - */ - bool intersect_any(const Ray& ray, Real t_max) const; - - /** - * @brief Check if BVH is built - * @return true if built - */ - bool is_built() const { return !nodes_.empty(); } - - /** - * @brief Get BVH nodes (for GPU upload) - * @return Node array - */ - const std::vector& get_nodes() const { return nodes_; } - - /** - * @brief Get primitive indices - * @return Index array - */ - const std::vector& get_primitive_indices() const { - return primitive_indices_; - } - - /** - * @brief Get triangles - * @return Triangle array - */ - const std::vector& get_triangles() const { return triangles_; } - - /** - * @brief Get memory usage in bytes - * @return Memory usage - */ - size_t get_memory_usage() const; - - /** - * @brief Clear BVH data - */ - void clear(); - -private: - bool intersect_recursive(uint32_t node_index, const Ray& ray, HitRecord& hit) const; - bool intersect_any_recursive(uint32_t node_index, const Ray& ray, Real t_max) const; - - std::vector nodes_; ///< BVH nodes - std::vector primitive_indices_; ///< Primitive index array - std::vector triangles_; ///< Triangle data - uint32_t root_index_; ///< Root node index -}; - -} // namespace are - -#endif // ARE_INCLUDE_ACCELERATION_BVH_H -``` - -如果有依赖或者需要给你的头文件或实现文件我还没有给你,欢迎提出! diff --git a/phase5.md b/phase5.md deleted file mode 100644 index f79c9bc..0000000 --- a/phase5.md +++ /dev/null @@ -1,310 +0,0 @@ -很好!现在让我们开始Phase 5的实现吧!如下是Phase 5我已经写好的头文件与依赖文件(注:ray.h/cpp&hit_record.h/cpp在前面的代码中你已经实现了,现在只需要再检查一遍之前的实现是否正确即可): -### 文件:include/are/raytracer/cpu_raytracer.h -```cpp -/** - * @file cpu_raytracer.h - * @brief CPU-based ray tracing implementation - */ - -#ifndef ARE_INCLUDE_RAYTRACER_CPU_RAYTRACER_H -#define ARE_INCLUDE_RAYTRACER_CPU_RAYTRACER_H - -#include -#include -#include -#include - -namespace are { - -/** - * @class CPURayTracer - * @brief CPU-based ray tracing implementation - * - * Uses multithreading for parallel ray tracing on CPU. - */ -class CPURayTracer : public RayTracer { -public: - /** - * @brief Constructor - * @param config Ray tracing configuration - */ - explicit CPURayTracer(const RayTracingConfig& config); - - /** - * @brief Destructor - */ - ~CPURayTracer() override; - - /** - * @brief Render scene using CPU ray tracing - * @param scene Scene manager - * @param camera Camera - * @param gbuffer G-Buffer (optional) - * @param output Output texture ID - */ - void render(const SceneManager& scene, - const Camera& camera, - const GBuffer* gbuffer, - uint32_t output_texture) override; - - /** - * @brief Update BVH - * @param bvh BVH reference - */ - void update_bvh(const BVH& bvh) override; - -private: - /** - * @brief Trace a single ray - * @param ray Ray to trace - * @param depth Current recursion depth - * @return Ray color - */ - Vec3 trace_ray(const Ray& ray, int depth); - - /** - * @brief Shade hit point - * @param hit Hit record - * @param ray Incident ray - * @param depth Current recursion depth - * @return Shaded color - */ - Vec3 shade(const HitRecord& hit, const Ray& ray, int depth); - - /** - * @brief Compute direct lighting - * @param hit Hit record - * @return Direct lighting contribution - */ - Vec3 compute_direct_lighting(const HitRecord& hit); - - /** - * @brief Compute ambient occlusion - * @param hit Hit record - * @return AO factor [0, 1] - */ - Real compute_ambient_occlusion(const HitRecord& hit); - - /** - * @brief Check shadow ray - * @param origin Shadow ray origin - * @param direction Shadow ray direction - * @param max_distance Maximum distance - * @return true if in shadow - */ - bool is_in_shadow(const Vec3& origin, const Vec3& direction, Real max_distance); - - const BVH* bvh_; ///< BVH reference - const SceneManager* scene_; ///< Scene reference - std::vector framebuffer_; ///< CPU framebuffer (HDR) - int width_; ///< Framebuffer width - int height_; ///< Framebuffer height -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_CPU_RAYTRACER_H -``` - -### 文件:include/are/raytracer/raytracer.h -```cpp -/** - * @file raytracer.h - * @brief Ray tracing interface - */ - -#ifndef ARE_INCLUDE_RAYTRACER_RAYTRACER_H -#define ARE_INCLUDE_RAYTRACER_RAYTRACER_H - -#include -#include - -namespace are { - -// Forward declarations -class SceneManager; -class Camera; -class GBuffer; -class BVH; - -/** - * @class RayTracer - * @brief Abstract ray tracing interface - * - * Base class for CPU and GPU ray tracing implementations. - */ -class RayTracer { -public: - /** - * @brief Constructor - * @param config Ray tracing configuration - */ - explicit RayTracer(const RayTracingConfig& config); - - /** - * @brief Virtual destructor - */ - virtual ~RayTracer() = default; - - /** - * @brief Render scene using ray tracing - * @param scene Scene manager - * @param camera Camera - * @param gbuffer G-Buffer (optional, for hybrid rendering) - * @param output Output texture ID - */ - virtual void render(const SceneManager& scene, - const Camera& camera, - const GBuffer* gbuffer, - uint32_t output_texture) = 0; - - /** - * @brief Update BVH - * @param bvh BVH reference - */ - virtual void update_bvh(const BVH& bvh) = 0; - - /** - * @brief Set configuration - * @param config New configuration - */ - virtual void set_config(const RayTracingConfig& config); - - /** - * @brief Get configuration - * @return Current configuration - */ - const RayTracingConfig& get_config() const { return config_; } - -protected: - RayTracingConfig config_; ///< Ray tracing configuration -}; - -} // namespace are -#endif // ARE_INCLUDE_RAYTRACER_RAYTRACER_H -``` -此外,你可能需要随机数模块。 -### 文件:include/utils/random.h -```cpp -/** - * @file random.h - * @brief Random number generation utilities - */ - -#ifndef ARE_INCLUDE_UTILS_RANDOM_H -#define ARE_INCLUDE_UTILS_RANDOM_H - -#include -#include - -namespace are { - -/** - * @class RandomGenerator - * @brief Thread-safe random number generator - * - * Uses PCG (Permuted Congruential Generator) for high-quality random numbers. - */ -class RandomGenerator { -public: - /** - * @brief Constructor with optional seed - * @param seed Random seed (0 = use random device) - */ - explicit RandomGenerator(uint64_t seed = 0); - - /** - * @brief Generate random float in [0, 1) - * @return Random float - */ - Real random_float(); - - /** - * @brief Generate random float in [min, max) - * @param min Minimum value - * @param max Maximum value - * @return Random float - */ - Real random_float(Real min, Real max); - - /** - * @brief Generate random integer in [min, max] - * @param min Minimum value - * @param max Maximum value - * @return Random integer - */ - int random_int(int min, int max); - - /** - * @brief Generate random point in unit disk - * @return Random point (z = 0) - */ - Vec3 random_in_unit_disk(); - - /** - * @brief Generate random point in unit sphere - * @return Random point - */ - Vec3 random_in_unit_sphere(); - - /** - * @brief Generate random unit vector - * @return Random unit vector - */ - Vec3 random_unit_vector(); - - /** - * @brief Generate random vector in hemisphere - * @param normal Hemisphere normal - * @return Random vector in hemisphere - */ - Vec3 random_in_hemisphere(const Vec3 &normal); - - /** - * @brief Generate random cosine-weighted direction - * @param normal Surface normal - * @return Random direction (cosine-weighted) - */ - Vec3 random_cosine_direction(const Vec3 &normal); - - /** - * @brief Set seed for reproducible results - * @param seed Random seed - */ - void set_seed(uint64_t seed); - -private: - std::mt19937_64 rng_; ///< Random number generator - std::uniform_real_distribution dist_; ///< Uniform distribution [0, 1) -}; - -/** - * @brief Get thread-local random generator - * @return Reference to thread-local generator - */ -RandomGenerator &get_thread_random(); - -/** - * @brief Generate random float in [0, 1) using thread-local generator - * @return Random float - */ -inline Real random_float() { - return get_thread_random().random_float(); -} - -/** - * @brief Generate random float in [min, max) using thread-local generator - * @param min Minimum value - * @param max Maximum value - * @return Random float - */ -inline Real random_float(Real min, Real max) { - return get_thread_random().random_float(min, max); -} - -} // namespace are - -#endif // ARE_INCLUDE_UTILS_RANDOM_H -``` - -同样地,如果有依赖或者需要给你的头文件/实现文件还没有给你,欢迎提出;如果已有的数学或者随机数模块需要补充,请分别给出函数声明与实现。 diff --git a/request2.md b/request2.md deleted file mode 100644 index 7c7cedf..0000000 --- a/request2.md +++ /dev/null @@ -1,322 +0,0 @@ -你对代码的观察非常敏锐!我对你的实现计划表示认同,下面是你要求到的和可能用到的头文件: -### 文件:include/are/raytracer/ray.h -```cpp -/** - * @file ray.h - * @brief Ray structure for ray tracing - */ - -#ifndef ARE_INCLUDE_RAYTRACER_RAY_H -#define ARE_INCLUDE_RAYTRACER_RAY_H - -#include - -namespace are { - -/** - * @struct Ray - * @brief Ray representation for ray tracing - */ -struct Ray { - Vec3 origin_; ///< Ray origin - Vec3 direction_; ///< Ray direction (normalized) - Real t_min_; ///< Minimum t value - Real t_max_; ///< Maximum t value - - /** - * @brief Default constructor - */ - Ray(); - - /** - * @brief Construct ray with origin and direction - * @param origin Ray origin - * @param direction Ray direction (will be normalized) - * @param t_min Minimum t value - * @param t_max Maximum t value - */ - Ray(const Vec3& origin, const Vec3& direction, - Real t_min = are_epsilon, Real t_max = 1e30f); - - /** - * @brief Evaluate ray at parameter t - * @param t Parameter value - * @return Point on ray - */ - Vec3 at(Real t) const; - - /** - * @brief Check if t is within valid range - * @param t Parameter value - * @return true if t is valid - */ - bool is_valid_t(Real t) const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_RAY_H -``` - -### 文件:include/are/raytracer/hit_record.h -```cpp -/** - * @file hit_record.h - * @brief Ray-surface intersection record - */ - -#ifndef ARE_INCLUDE_RAYTRACER_HIT_RECORD_H -#define ARE_INCLUDE_RAYTRACER_HIT_RECORD_H - -#include - -namespace are { - -/** - * @struct HitRecord - * @brief Information about ray-surface intersection - */ -struct HitRecord { - Vec3 position_; ///< Hit position in world space - Vec3 normal_; ///< Surface normal at hit point - Vec2 texcoord_; ///< Texture coordinates at hit point - Vec3 tangent_; ///< Tangent vector at hit point - Real t_; ///< Ray parameter at hit point - MaterialHandle material_; ///< Material at hit point - uint32_t triangle_index_; ///< Triangle index that was hit - bool front_face_; ///< Whether ray hit front face - - /** - * @brief Default constructor - */ - HitRecord(); - - /** - * @brief Set face normal based on ray direction - * @param ray_direction Ray direction - * @param outward_normal Outward-facing normal - */ - void set_face_normal(const Vec3& ray_direction, const Vec3& outward_normal); - - /** - * @brief Check if hit record is valid - * @return true if hit occurred - */ - bool is_valid() const; -}; - -} // namespace are - -#endif // ARE_INCLUDE_RAYTRACER_HIT_RECORD_H -``` - -### 文件:include/are/scene/directional_light.h -```cpp -/** - * @file directional_light.h - * @brief Directional light implementation - */ - -#ifndef ARE_INCLUDE_SCENE_DIRECTIONAL_LIGHT_H -#define ARE_INCLUDE_SCENE_DIRECTIONAL_LIGHT_H - -#include - -namespace are { - -/** - * @class DirectionalLight - * @brief Directional light source (sun-like) - * - * Represents an infinitely distant light source with parallel rays. - */ -class DirectionalLight : public Light { -public: - /** - * @brief Default constructor - */ - DirectionalLight(); - - /** - * @brief Construct with direction and color - * @param direction Light direction (will be normalized) - * @param color Light color - * @param intensity Light intensity - */ - DirectionalLight(const Vec3& direction, const Vec3& color = Vec3(1.0f), - Real intensity = 1.0f); - - // Direction - void set_direction(const Vec3& direction); - const Vec3& get_direction() const { return direction_; } - - // Light interface - LightData pack() const override; - bool affects_point(const Vec3& point) const override; - -private: - Vec3 direction_; ///< Light direction (normalized) -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_DIRECTIONAL_LIGHT_H -``` - -### 文件:include/are/scene/point_light.h -```cpp -/** - * @file point_light.h - * @brief Point light implementation - */ - -#ifndef ARE_INCLUDE_SCENE_POINT_LIGHT_H -#define ARE_INCLUDE_SCENE_POINT_LIGHT_H - -#include - -namespace are { - -/** - * @class PointLight - * @brief Point light source - * - * Emits light equally in all directions from a single point. - */ -class PointLight : public Light { -public: - /** - * @brief Default constructor - */ - PointLight(); - - /** - * @brief Construct with position and color - * @param position Light position - * @param color Light color - * @param intensity Light intensity - * @param range Light range (attenuation distance) - */ - PointLight(const Vec3& position, const Vec3& color = Vec3(1.0f), - Real intensity = 1.0f, Real range = 10.0f); - - // Position - void set_position(const Vec3& position); - const Vec3& get_position() const { return position_; } - - // Range (attenuation) - void set_range(Real range); - Real get_range() const { return range_; } - - // Attenuation parameters - void set_attenuation(Real constant, Real linear, Real quadratic); - Real get_constant_attenuation() const { return attenuation_constant_; } - Real get_linear_attenuation() const { return attenuation_linear_; } - Real get_quadratic_attenuation() const { return attenuation_quadratic_; } - - /** - * @brief Calculate attenuation at given distance - * @param distance Distance from light - * @return Attenuation factor [0, 1] - */ - Real calculate_attenuation(Real distance) const; - - // Light interface - LightData pack() const override; - bool affects_point(const Vec3& point) const override; - -private: - Vec3 position_; ///< Light position - Real range_; ///< Light range - Real attenuation_constant_; ///< Constant attenuation factor - Real attenuation_linear_; ///< Linear attenuation factor - Real attenuation_quadratic_; ///< Quadratic attenuation factor -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_POINT_LIGHT_H -``` - -### 文件:include/are/scene/spot_light.h -```cpp -/** - * @file spot_light.h - * @brief Spot light implementation - */ - -#ifndef ARE_INCLUDE_SCENE_SPOT_LIGHT_H -#define ARE_INCLUDE_SCENE_SPOT_LIGHT_H - -#include - -namespace are { - -/** - * @class SpotLight - * @brief Spot light source - * - * Emits light in a cone from a single point. - */ -class SpotLight : public Light { -public: - /** - * @brief Default constructor - */ - SpotLight(); - - /** - * @brief Construct with position, direction, and angles - * @param position Light position - * @param direction Light direction - * @param inner_angle Inner cone angle in degrees - * @param outer_angle Outer cone angle in degrees - * @param color Light color - * @param intensity Light intensity - */ - SpotLight(const Vec3& position, const Vec3& direction,Real inner_angle, Real outer_angle, - const Vec3& color = Vec3(1.0f), Real intensity = 1.0f); - - // Position and direction - void set_position(const Vec3& position); - void set_direction(const Vec3& direction); - const Vec3& get_position() const { return position_; } - const Vec3& get_direction() const { return direction_; } - - // Cone angles (in degrees) - void set_inner_angle(Real angle); - void set_outer_angle(Real angle); - Real get_inner_angle() const { return inner_angle_; } - Real get_outer_angle() const { return outer_angle_; } - - // Range - void set_range(Real range); - Real get_range() const { return range_; } - - /** - * @brief Calculate spotlight intensity at given direction - * @param to_point Direction from light to point (normalized) - * @return Spotlight factor [0, 1] - */ - Real calculate_spot_factor(const Vec3& to_point) const; - - // Light interface - LightData pack() const override; - bool affects_point(const Vec3& point) const override; - -private: - Vec3 position_; ///< Light position - Vec3 direction_; ///< Light direction (normalized) - Real inner_angle_; ///< Inner cone angle (degrees) - Real outer_angle_; ///< Outer cone angle (degrees) - Real range_; ///< Light range - Real cos_inner_; ///< Cosine of inner angle (cache - Real cos_outer_; ///< Cosine of outer angle (cached) -}; - -} // namespace are - -#endif // ARE_INCLUDE_SCENE_SPOT_LIGHT_H -``` - -还有缺失的头文件需要补充吗?如果没有的话,我们就可以开始实现Phase 2了。 diff --git a/shaders/gbuffer/gbuffer.frag b/shaders/gbuffer/gbuffer.frag deleted file mode 100644 index 93dad07..0000000 --- a/shaders/gbuffer/gbuffer.frag +++ /dev/null @@ -1,26 +0,0 @@ -#version 430 core - -in vec3 v_world_position; -in vec3 v_world_normal; -in vec2 v_texcoord; -flat in uint v_triangle_id_base; - -uniform vec3 u_albedo; -uniform float u_metallic; -uniform float u_roughness; - -layout(location = 0) out vec3 g_position; -layout(location = 1) out vec3 g_normal; -layout(location = 2) out vec4 g_albedo_metallic; -layout(location = 3) out vec2 g_roughness_ao; -layout(location = 4) out uint g_primitive_id; - -void main() { - g_position = v_world_position; - g_normal = normalize(v_world_normal); - g_albedo_metallic = vec4(u_albedo, u_metallic); - g_roughness_ao = vec2(u_roughness, 1.0); - - // Global primitive ID = mesh base + primitive id within draw call - g_primitive_id = v_triangle_id_base + uint(gl_PrimitiveID); -} diff --git a/shaders/gbuffer/gbuffer.vert b/shaders/gbuffer/gbuffer.vert deleted file mode 100644 index edb994a..0000000 --- a/shaders/gbuffer/gbuffer.vert +++ /dev/null @@ -1,29 +0,0 @@ -#version 430 core - -layout(location = 0) in vec3 a_position; -layout(location = 1) in vec3 a_normal; -layout(location = 2) in vec2 a_texcoord; -layout(location = 3) in vec3 a_tangent; - -uniform mat4 u_model; -uniform mat4 u_view; -uniform mat4 u_projection; -uniform mat3 u_normal_matrix; - -// NOTE: We store it as int uniform in C++ for simplicity; GLSL expects uint. -uniform uint u_triangle_id_base; - -out vec3 v_world_position; -out vec3 v_world_normal; -out vec2 v_texcoord; -flat out uint v_triangle_id_base; - -void main() { - vec4 world_pos = u_model * vec4(a_position, 1.0); - v_world_position = world_pos.xyz; - v_world_normal = normalize(u_normal_matrix * a_normal); - v_texcoord = a_texcoord; - v_triangle_id_base = u_triangle_id_base; - - gl_Position = u_projection * u_view * world_pos; -} diff --git a/src/acceleration/bvh.cpp b/src/acceleration/bvh.cpp deleted file mode 100644 index 243e6f7..0000000 --- a/src/acceleration/bvh.cpp +++ /dev/null @@ -1,512 +0,0 @@ -/** - * @file bvh.cpp - * @brief Implementation of BVH class (optimized version) - */ - -#include -#include -#include -#include -#include - -namespace are { - -BVH::BVH() - : root_index_(0) { -} - -BVH::~BVH() { - clear(); -} - -bool BVH::build(const std::vector &triangles, const BVHBuildConfig &config) { - ARE_PROFILE_FUNCTION(); - - if (triangles.empty()) { - ARE_LOG_WARN("BVH: Cannot build from empty triangle list"); - return false; - } - - // Clear existing data - clear(); - - // Copy triangles - triangles_ = triangles; - - // Build BVH - BVHBuilder builder(config); - root_index_ = builder.build(triangles_, nodes_, primitive_indices_); - - // Get statistics - size_t node_count, leaf_count; - int max_depth; - builder.get_stats(node_count, leaf_count, max_depth); - - ARE_LOG_INFO("BVH: Built successfully"); - ARE_LOG_INFO(" Triangles: " + std::to_string(triangles_.size())); - ARE_LOG_INFO(" Nodes: " + std::to_string(node_count)); - ARE_LOG_INFO(" Leaves: " + std::to_string(leaf_count)); - ARE_LOG_INFO(" Max depth: " + std::to_string(max_depth)); - ARE_LOG_INFO(" Memory: " + std::to_string(get_memory_usage() / 1024) + " KB"); - - return true; -} - -bool BVH::intersect(const Ray &ray, HitRecord &hit) const { - // Note: No profiling here - this is a hot path - - if (!is_built()) { - return false; - } - - // Use iterative traversal with stack for better performance - return intersect_iterative(ray, hit); -} - -bool BVH::intersect_any(const Ray &ray, Real t_max) const { - // Note: No profiling here - this is a hot path - - if (!is_built()) { - return false; - } - - return intersect_any_iterative(ray, t_max); -} - -bool BVH::intersect_any(const Ray& ray, Real t_max, uint32_t ignore_triangle_index) const { - ARE_PROFILE_FUNCTION(); - - if (!is_built()) { - return false; - } - - // iterative traversal is safer than recursion for deep trees, but keep style consistent - std::stack stack; - stack.push(root_index_); - - while (!stack.empty()) { - uint32_t node_index = stack.top(); - stack.pop(); - - const BVHNode& node = nodes_[node_index]; - - Real t0, t1; - if (!node.bounds_.intersect_ray(ray, t0, t1)) { - continue; - } - if (t0 > t_max) { - continue; - } - - if (node.is_leaf()) { - for (uint32_t i = 0; i < node.primitive_count_; ++i) { - uint32_t prim_idx = primitive_indices_[node.first_primitive_ + i]; - if (prim_idx == ignore_triangle_index) { - continue; - } - if (prim_idx >= triangles_.size()) { - continue; - } - if (triangles_[prim_idx].intersect_fast(ray, t_max)) { - return true; - } - } - } else { - stack.push(node.left_child_); - stack.push(node.right_child_); - } - } - - return false; -} - -size_t BVH::get_memory_usage() const { - size_t total = 0; - total += nodes_.size() * sizeof(BVHNode); - total += primitive_indices_.size() * sizeof(uint32_t); - total += triangles_.size() * sizeof(Triangle); - return total; -} - -void BVH::clear() { - nodes_.clear(); - primitive_indices_.clear(); - triangles_.clear(); - root_index_ = 0; -} - -bool BVH::intersect_iterative(const Ray &ray, HitRecord &hit) const { - // Precompute inverse direction for faster AABB tests - Vec3 inv_dir( - 1.0f / ray.direction_.x, - 1.0f / ray.direction_.y, - 1.0f / ray.direction_.z); - - // Stack-based traversal (64 levels is enough for most scenes) - uint32_t stack[64]; - int stack_ptr = 0; - stack[stack_ptr++] = root_index_; - - bool hit_anything = false; - Real closest_t = ray.t_max_; - - while (stack_ptr > 0) { - uint32_t node_index = stack[--stack_ptr]; - - if (node_index >= nodes_.size()) { - continue; - } - - const BVHNode &node = nodes_[node_index]; - - // Fast AABB test with precomputed inverse direction - Real t_min, t_max; - if (!intersect_aabb_fast(node.bounds_, ray, inv_dir, closest_t, t_min, t_max)) { - continue; - } - - if (node.is_leaf()) { - // Test all primitives in leaf - for (uint32_t i = 0; i < node.primitive_count_; ++i) { - uint32_t prim_idx = primitive_indices_[node.first_primitive_ + i]; - - if (prim_idx >= triangles_.size()) { - continue; - } - - const Triangle &triangle = triangles_[prim_idx]; - - HitRecord temp_hit; - if (intersect_triangle_fast(triangle, ray, closest_t, temp_hit)) { - closest_t = temp_hit.t_; - hit = temp_hit; - hit.triangle_index_ = prim_idx; - hit_anything = true; - } - } - } else { - // Push children to stack (far child first, so near child is processed first) - if (node.left_child_ >= nodes_.size() || node.right_child_ >= nodes_.size()) { - continue; - } - - const BVHNode &left = nodes_[node.left_child_]; - const BVHNode &right = nodes_[node.right_child_]; - - Real t_left_min, t_left_max; - Real t_right_min, t_right_max; - - bool hit_left = intersect_aabb_fast(left.bounds_, ray, inv_dir, closest_t, - t_left_min, t_left_max); - bool hit_right = intersect_aabb_fast(right.bounds_, ray, inv_dir, closest_t, - t_right_min, t_right_max); - - if (hit_left && hit_right) { - // Push far child first (so near child is popped first) - if (t_left_min < t_right_min) { - if (stack_ptr < 64) - stack[stack_ptr++] = node.right_child_; - if (stack_ptr < 64) - stack[stack_ptr++] = node.left_child_; - } else { - if (stack_ptr < 64) - stack[stack_ptr++] = node.left_child_; - if (stack_ptr < 64) - stack[stack_ptr++] = node.right_child_; - } - } else if (hit_left) { - if (stack_ptr < 64) - stack[stack_ptr++] = node.left_child_; - } else if (hit_right) { - if (stack_ptr < 64) - stack[stack_ptr++] = node.right_child_; - } - } - } - - return hit_anything; -} - -bool BVH::intersect_any_iterative(const Ray &ray, Real t_max) const { - // Precompute inverse direction - Vec3 inv_dir( - 1.0f / ray.direction_.x, - 1.0f / ray.direction_.y, - 1.0f / ray.direction_.z); - - // Stack-based traversal - uint32_t stack[64]; - int stack_ptr = 0; - stack[stack_ptr++] = root_index_; - - while (stack_ptr > 0) { - uint32_t node_index = stack[--stack_ptr]; - - if (node_index >= nodes_.size()) { - continue; - } - - const BVHNode &node = nodes_[node_index]; - - // Fast AABB test - Real t_min, t_max_box; - if (!intersect_aabb_fast(node.bounds_, ray, inv_dir, t_max, t_min, t_max_box)) { - continue; - } - - if (node.is_leaf()) { - // Test all primitives in leaf - for (uint32_t i = 0; i < node.primitive_count_; ++i) { - uint32_t prim_idx = primitive_indices_[node.first_primitive_ + i]; - - if (prim_idx >= triangles_.size()) { - continue; - } - - const Triangle &triangle = triangles_[prim_idx]; - - if (triangle.intersect_fast(ray, t_max)) { - return true; // Early exit on first hit - } - } - } else { - // Push both children - if (node.left_child_ < nodes_.size() && stack_ptr < 64) { - stack[stack_ptr++] = node.left_child_; - } - if (node.right_child_ < nodes_.size() && stack_ptr < 64) { - stack[stack_ptr++] = node.right_child_; - } - } - } - - return false; -} - -inline bool BVH::intersect_aabb_fast(const AABB &bounds, const Ray &ray, - const Vec3 &inv_dir, Real t_max, - Real &t_min_out, Real &t_max_out) const { - // Optimized slab method with precomputed inverse direction - Real t_min = ray.t_min_; - Real t_max_local = t_max; - - // X axis - { - Real t0 = (bounds.min_.x - ray.origin_.x) * inv_dir.x; - Real t1 = (bounds.max_.x - ray.origin_.x) * inv_dir.x; - - if (inv_dir.x < 0.0f) { - Real temp = t0; - t0 = t1; - t1 = temp; - } - - t_min = std::max(t_min, t0); - t_max_local = std::min(t_max_local, t1); - - if (t_max_local < t_min) { - return false; - } - } - - // Y axis - { - Real t0 = (bounds.min_.y - ray.origin_.y) * inv_dir.y; - Real t1 = (bounds.max_.y - ray.origin_.y) * inv_dir.y; - - if (inv_dir.y < 0.0f) { - Real temp = t0; - t0 = t1; - t1 = temp; - } - - t_min = std::max(t_min, t0); - t_max_local = std::min(t_max_local, t1); - - if (t_max_local < t_min) { - return false; - } - } - - // Z axis - { - Real t0 = (bounds.min_.z - ray.origin_.z) * inv_dir.z; - Real t1 = (bounds.max_.z - ray.origin_.z) * inv_dir.z; - - if (inv_dir.z < 0.0f) { - Real temp = t0; - t0 = t1; - t1 = temp; - } - - t_min = std::max(t_min, t0); - t_max_local = std::min(t_max_local, t1); - - if (t_max_local < t_min) { - return false; - } - } - - t_min_out = t_min; - t_max_out = t_max_local; - return true; -} - -inline bool BVH::intersect_triangle_fast(const Triangle &triangle, const Ray &ray, - Real t_max, HitRecord &hit) const { - // Möller-Trumbore algorithm (inlined for performance) - const Vec3 &v0 = triangle.v0_.position_; - const Vec3 &v1 = triangle.v1_.position_; - const Vec3 &v2 = triangle.v2_.position_; - - const Vec3 edge1 = v1 - v0; - const Vec3 edge2 = v2 - v0; - - const Vec3 h = glm::cross(ray.direction_, edge2); - const Real a = glm::dot(edge1, h); - - // Check if ray is parallel to triangle - if (a > -are_epsilon && a < are_epsilon) { - return false; - } - - const Real f = 1.0f / a; - const Vec3 s = ray.origin_ - v0; - const Real u = f * glm::dot(s, h); - - if (u < 0.0f || u > 1.0f) { - return false; - } - - const Vec3 q = glm::cross(s, edge1); - const Real v = f * glm::dot(ray.direction_, q); - - if (v < 0.0f || u + v > 1.0f) { - return false; - } - - const Real t = f * glm::dot(edge2, q); - - if (t < ray.t_min_ || t >= t_max) { - return false; - } - - // Fill hit record - const Real w = 1.0f - u - v; - - hit.t_ = t; - hit.position_ = ray.origin_ + ray.direction_ * t; - hit.material_ = triangle.material_; - - // Interpolate vertex attributes - hit.normal_ = glm::normalize( - w * triangle.v0_.normal_ + u * triangle.v1_.normal_ + v * triangle.v2_.normal_); - - hit.texcoord_ = w * triangle.v0_.texcoord_ + u * triangle.v1_.texcoord_ + v * triangle.v2_.texcoord_; - - hit.tangent_ = glm::normalize( - w * triangle.v0_.tangent_ + u * triangle.v1_.tangent_ + v * triangle.v2_.tangent_); - - // Determine front face - hit.set_face_normal(ray.direction_, hit.normal_); - - return true; -} - -// Keep recursive versions for reference/debugging -bool BVH::intersect_recursive(uint32_t node_index, const Ray &ray, HitRecord &hit) const { - if (node_index >= nodes_.size()) { - return false; - } - - const BVHNode &node = nodes_[node_index]; - - Real t_min, t_max; - if (!node.bounds_.intersect_ray(ray, t_min, t_max)) { - return false; - } - - if (t_min > hit.t_) { - return false; - } - - bool hit_anything = false; - - if (node.is_leaf()) { - for (uint32_t i = 0; i < node.primitive_count_; ++i) { - uint32_t prim_idx = primitive_indices_[node.first_primitive_ + i]; - - if (prim_idx >= triangles_.size()) { - continue; - } - - const Triangle &triangle = triangles_[prim_idx]; - HitRecord temp_hit; - - if (triangle.intersect(ray, temp_hit) && temp_hit.t_ < hit.t_) { - hit = temp_hit; - hit.triangle_index_ = prim_idx; - hit_anything = true; - } - } - } else { - Real t_left_min, t_left_max; - Real t_right_min, t_right_max; - - bool hit_left = nodes_[node.left_child_].bounds_.intersect_ray(ray, t_left_min, t_left_max); - bool hit_right = nodes_[node.right_child_].bounds_.intersect_ray(ray, t_right_min, t_right_max); - - // Traverse closer child first - if (hit_left && hit_right) { - if (t_left_min < t_right_min) { - hit_anything |= intersect_recursive(node.left_child_, ray, hit); - hit_anything |= intersect_recursive(node.right_child_, ray, hit); - } else { - hit_anything |= intersect_recursive(node.right_child_, ray, hit); - hit_anything |= intersect_recursive(node.left_child_, ray, hit); - } - } else if (hit_left) { - hit_anything |= intersect_recursive(node.left_child_, ray, hit); - } else if (hit_right) { - hit_anything |= intersect_recursive(node.right_child_, ray, hit); - } - } - - return hit_anything; -} - -bool BVH::intersect_any_recursive(uint32_t node_index, const Ray &ray, Real t_max) const { - if (node_index >= nodes_.size()) { - return false; - } - - const BVHNode &node = nodes_[node_index]; - - Real t_min, t_max_box; - if (!node.bounds_.intersect_ray(ray, t_min, t_max_box)) { - return false; - } - - if (t_min > t_max) { - return false; - } - - if (node.is_leaf()) { - for (uint32_t i = 0; i < node.primitive_count_; ++i) { - uint32_t prim_idx = primitive_indices_[node.first_primitive_ + i]; - - if (prim_idx >= triangles_.size()) { - continue; - } - - if (triangles_[prim_idx].intersect_fast(ray, t_max)) { - return true; - } - } - return false; - } else { - return intersect_any_recursive(node.left_child_, ray, t_max) || intersect_any_recursive(node.right_child_, ray, t_max); - } -} - -} // namespace are diff --git a/src/acceleration/bvh_builder.cpp b/src/acceleration/bvh_builder.cpp deleted file mode 100644 index 5eeb71c..0000000 --- a/src/acceleration/bvh_builder.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/** - * @file bvh_builder.cpp - * @brief Implementation of BVH construction algorithms - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef ARE_USE_OPENMP -#include -#endif - -namespace are { - -BVHBuilder::BVHBuilder(const BVHBuildConfig& config) - : config_(config) - , node_count_(0) - , leaf_count_(0) - , max_depth_reached_(0) { -} - -uint32_t BVHBuilder::build(const std::vector& triangles, - std::vector& nodes, - std::vector& primitive_indices) { - ARE_PROFILE_FUNCTION(); - - if (triangles.empty()) { - ARE_LOG_WARN("BVHBuilder: Cannot build BVH from empty triangle list"); - return 0; - } - - ARE_LOG_INFO("BVHBuilder: Building BVH for " + std::to_string(triangles.size()) + " triangles"); - - // Reset statistics - node_count_ = 0; - leaf_count_ = 0; - max_depth_reached_ = 0; - - // Initialize primitive indices - primitive_indices.resize(triangles.size()); - for (size_t i = 0; i < triangles.size(); ++i) { - primitive_indices[i] = static_cast(i); - } - - // Reserve space for nodes (estimate: 2 * num_triangles) - nodes.clear(); - nodes.reserve(triangles.size() * 2); - - // Build BVH recursively - uint32_t root_index = build_recursive(triangles, nodes, primitive_indices, - 0, static_cast(triangles.size()), 0); - - ARE_LOG_INFO("BVHBuilder: Built BVH with " + std::to_string(node_count_) + " nodes, " + - std::to_string(leaf_count_) + " leaves, max depth " + - std::to_string(max_depth_reached_)); - - return root_index; -} - -void BVHBuilder::get_stats(size_t& node_count, size_t& leaf_count, int& max_depth) const { - node_count = node_count_; - leaf_count = leaf_count_; - max_depth = max_depth_reached_; -} - -uint32_t BVHBuilder::build_recursive(const std::vector& triangles, - std::vector& nodes, - std::vector& primitive_indices, - uint32_t start, uint32_t end, int depth) { - ARE_PROFILE_FUNCTION(); - - // Update statistics - max_depth_reached_ = std::max(max_depth_reached_, depth); - - // Create new node - uint32_t node_index = static_cast(nodes.size()); - nodes.emplace_back(); - BVHNode& node = nodes[node_index]; - node_count_++; - - // Compute bounding box for all primitives in range - node.bounds_ = AABB::invalid(); - for (uint32_t i = start; i < end; ++i) { - uint32_t prim_idx = primitive_indices[i]; - node.bounds_.expand(triangles[prim_idx].compute_aabb()); - } - - uint32_t count = end - start; - - // Check if we should create a leaf - bool should_create_leaf = (count <= static_cast(config_.max_leaf_size_)) || - (depth >= config_.max_depth_); - - if (should_create_leaf) { - // Create leaf node - node.first_primitive_ = start; - node.primitive_count_ = count; - leaf_count_++; - return node_index; - } - - // Find best split axis - int split_axis = find_best_split_axis(triangles, primitive_indices, start, end); - - // Sort primitives along split axis - std::sort(primitive_indices.begin() + start, - primitive_indices.begin() + end, - [&](uint32_t a, uint32_t b) { - return triangles[a].centroid()[split_axis] < - triangles[b].centroid()[split_axis]; - }); - - // Find split position - uint32_t mid = start + count / 2; - - // Use SAH if enabled - if (config_.split_method_ == BVHSplitMethod::ARE_BVH_SPLIT_SAH) { - Real best_cost = std::numeric_limits::max(); - uint32_t best_split = mid; - - // Try different split positions - const int num_buckets = 12; - for (int i = 1; i < num_buckets; ++i) { - uint32_t test_split = start + (count * i) / num_buckets; - - // Compute bounding boxes for left and right - AABB left_bounds = AABB::invalid(); - AABB right_bounds = AABB::invalid(); - - for (uint32_t j = start; j < test_split; ++j) { - left_bounds.expand(triangles[primitive_indices[j]].compute_aabb()); - } - for (uint32_t j = test_split; j < end; ++j) { - right_bounds.expand(triangles[primitive_indices[j]].compute_aabb()); - } - - // Compute SAH cost - Real left_cost = compute_sah_cost(left_bounds, test_split - start); - Real right_cost = compute_sah_cost(right_bounds, end - test_split); - Real cost = left_cost + right_cost; - - if (cost < best_cost) { - best_cost = cost; - best_split = test_split; - } - } - - mid = best_split; - } - - // Ensure we don't create empty children - if (mid == start || mid == end) { - mid = start + count / 2; - } - - // Create internal node - node.primitive_count_ = 0; // Mark as internal node - - // Build left and right children - uint32_t left_child = build_recursive(triangles, nodes, primitive_indices, - start, mid, depth + 1); - uint32_t right_child = build_recursive(triangles, nodes, primitive_indices, - mid, end, depth + 1); - - // Update node (it may have been reallocated) - nodes[node_index].left_child_ = left_child; - nodes[node_index].right_child_ = right_child; - - return node_index; -} - -int BVHBuilder::find_best_split_axis(const std::vector& triangles, - const std::vector& indices, - uint32_t start, uint32_t end) { - ARE_PROFILE_FUNCTION(); - - // Compute centroid bounds - AABB centroid_bounds = AABB::invalid(); - for (uint32_t i = start; i < end; ++i) { - centroid_bounds.expand(triangles[indices[i]].centroid()); - } - - // Return longest axis - return centroid_bounds.longest_axis(); -} - -Real BVHBuilder::compute_sah_cost(const AABB& bounds, uint32_t count) { - // SAH cost = surface_area * primitive_count - // This is a simplified version; full SAH includes traversal cost - return bounds.surface_area() * static_cast(count); -} - -} // namespace are diff --git a/src/acceleration/bvh_node.cpp b/src/acceleration/bvh_node.cpp deleted file mode 100644 index f536ebb..0000000 --- a/src/acceleration/bvh_node.cpp +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @file bvh_node.cpp - * @brief Implementation of BVHNode structure - */ - -#include - -namespace are { - -// BVHNode is a POD structure, no implementation needed -// All methods are inline in the header - -} // namespace are diff --git a/src/are.cpp b/src/are.cpp deleted file mode 100644 index 898a34f..0000000 --- a/src/are.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @file are.cpp - * @brief Implementation of main engine interface - */ - -#include -#include -#include - -namespace are { - -const char* get_version() { - return "0.1.0"; -} - -bool initialize() { - // Initialize logger first - Logger::init(LogLevel::ARE_LOG_INFO); - - ARE_LOG_INFO("==========================================="); - ARE_LOG_INFO("Aurora Rendering Engine v" + std::string(get_version())); - ARE_LOG_INFO("==========================================="); - ARE_LOG_INFO("Initializing engine..."); - - // Initialize profiler - Profiler::init(); - - ARE_LOG_INFO("Engine initialization complete"); - return true; -} - -void shutdown() { - ARE_LOG_INFO("Shutting down Aurora Rendering Engine..."); - - // Shutdown profiler - Profiler::shutdown(); - - ARE_LOG_INFO("Engine shutdown complete"); - - // Shutdown logger last - Logger::shutdown(); -} - -} // namespace are diff --git a/src/core/config.cpp b/src/core/config.cpp deleted file mode 100644 index 07ad7a9..0000000 --- a/src/core/config.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file config.cpp - * @brief Implementation of configuration system - */ - -#include -#include -#include - -namespace are { - -bool AreConfig::validate() const { - bool valid = true; - - // Validate window config - if (window.width <= 0 || window.height <= 0) { - ARE_LOG_ERROR("Invalid window dimensions: " + - std::to_string(window.width) + "x" + - std::to_string(window.height)); - valid = false; - } - - if (window.samples < 1) { - ARE_LOG_ERROR("Invalid MSAA samples: " + std::to_string(window.samples)); - valid = false; - } - - // Validate ray tracing config - if (ray_tracing.spp <= 0) { - ARE_LOG_ERROR("Invalid SPP value: " + std::to_string(ray_tracing.spp)); - valid = false; - } - - if (ray_tracing.max_depth <= 0) { - ARE_LOG_ERROR("Invalid max ray depth: " + std::to_string(ray_tracing.max_depth)); - valid = false; - } - - if (ray_tracing.ao_samples < 0) { - ARE_LOG_ERROR("Invalid AO samples: " + std::to_string(ray_tracing.ao_samples)); - valid = false; - } - - if (ray_tracing.ao_radius <= 0.0f) { - ARE_LOG_ERROR("Invalid AO radius: " + std::to_string(ray_tracing.ao_radius)); - valid = false; - } - - // Validate render config - if (render.exposure <= 0.0f) { - ARE_LOG_ERROR("Invalid exposure: " + std::to_string(render.exposure)); - valid = false; - } - - // Validate performance config - if (performance.num_threads < 0) { - ARE_LOG_ERROR("Invalid thread count: " + std::to_string(performance.num_threads)); - valid = false; - } - - return valid; -} - -void AreConfig::print() const { - ARE_LOG_INFO("=== Aurora Rendering Engine Configuration ==="); - - // Window configuration - ARE_LOG_INFO("Window:"); - ARE_LOG_INFO(" Size: " + std::to_string(window.width) + "x" + - std::to_string(window.height)); - ARE_LOG_INFO(" Title: " + window.title); - ARE_LOG_INFO(" Resizable: " + std::string(window.resizable ? "yes" : "no")); - ARE_LOG_INFO(" VSync: " + std::string(window.vsync ? "enabled" : "disabled")); - ARE_LOG_INFO(" MSAA: " + std::to_string(window.samples) + "x"); - - // Ray tracing configuration - ARE_LOG_INFO("Ray Tracing:"); - std::string backend_str = (ray_tracing.backend == RayTracingBackend::ARE_RT_BACKEND_CPU) - ? "CPU" : "Compute Shader"; - ARE_LOG_INFO(" Backend: " + backend_str); - ARE_LOG_INFO(" SPP: " + std::to_string(ray_tracing.spp)); - ARE_LOG_INFO(" Max Depth: " + std::to_string(ray_tracing.max_depth)); - ARE_LOG_INFO(" Global Illumination: " + std::string(ray_tracing.enable_gi ? "enabled" : "disabled")); - ARE_LOG_INFO(" Ambient Occlusion: " + std::string(ray_tracing.enable_ao ? "enabled" : "disabled")); - ARE_LOG_INFO(" Soft Shadows: " + std::string(ray_tracing.enable_soft_shadows ? "enabled" : "disabled")); - - if (ray_tracing.enable_ao) { - ARE_LOG_INFO(" AO Samples: " + std::to_string(ray_tracing.ao_samples)); - ARE_LOG_INFO(" AO Radius: " + std::to_string(ray_tracing.ao_radius)); - } - - // Render configuration - ARE_LOG_INFO("Rendering:"); - std::string tonemap_str; - switch (render.tonemap_op) { - case ToneMappingOperator::ARE_TONEMAP_NONE: tonemap_str = "None"; break; - case ToneMappingOperator::ARE_TONEMAP_REINHARD: tonemap_str = "Reinhard"; break; - case ToneMappingOperator::ARE_TONEMAP_ACES: tonemap_str = "ACES"; break; - } - ARE_LOG_INFO(" Tone Mapping: " + tonemap_str); - ARE_LOG_INFO(" Exposure: " + std::to_string(render.exposure)); - ARE_LOG_INFO(" HDR: " + std::string(render.use_hdr ? "enabled" : "disabled")); - - // Performance configuration - ARE_LOG_INFO("Performance:"); - int num_threads = performance.num_threads == 0 ? - static_cast(std::thread::hardware_concurrency()) : performance.num_threads; - ARE_LOG_INFO(" Threads: " + std::to_string(num_threads)); - ARE_LOG_INFO(" BVH Multithreading: " + - std::string(performance.enable_bvh_multithreading ? "enabled" : "disabled")); - ARE_LOG_INFO(" Profiling: " + - std::string(performance.enable_profiling ? "enabled" : "disabled")); - - // Path configuration - ARE_LOG_INFO("Paths:"); - ARE_LOG_INFO(" Shaders: " + paths.shader_dir); - ARE_LOG_INFO(" Textures: " + paths.texture_dir); - ARE_LOG_INFO(" Output: " + paths.output_dir); - - ARE_LOG_INFO("============================================="); -} - -} // namespace are diff --git a/src/core/logger.cpp b/src/core/logger.cpp deleted file mode 100644 index 60c3278..0000000 --- a/src/core/logger.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/** - * @file logger.cpp - * @brief Implementation of logging system - */ - -#include -#include -#include -#include -#include -#include - -namespace are { - -std::shared_ptr Logger::logger_impl_ = nullptr; -bool Logger::initialized_ = false; - -void Logger::init(LogLevel min_level) { - if (initialized_) { - return; - } - - try { - // Create console sink with color support - auto console_sink = std::make_shared(); - console_sink->set_pattern("[%H:%M:%S.%e] [%^%l%$] %v"); - - // Create logger with console sink - auto logger = std::make_shared("are", console_sink); - - // Set log level - switch (min_level) { - case LogLevel::ARE_LOG_TRACE: - logger->set_level(spdlog::level::trace); - break; - case LogLevel::ARE_LOG_DEBUG: - logger->set_level(spdlog::level::debug); - break; - case LogLevel::ARE_LOG_INFO: - logger->set_level(spdlog::level::info); - break; - case LogLevel::ARE_LOG_WARN: - logger->set_level(spdlog::level::warn); - break; - case LogLevel::ARE_LOG_ERROR: - logger->set_level(spdlog::level::err); - break; - case LogLevel::ARE_LOG_CRITICAL: - logger->set_level(spdlog::level::critical); - break; - } - - // Flush on error or higher - logger->flush_on(spdlog::level::err); - - // Set as default logger - spdlog::set_default_logger(logger); - logger_impl_ = logger; - initialized_ = true; - - } catch (const std::exception& e) { - fprintf(stderr, "[ARE] Failed to initialize logger: %s\n", e.what()); - } -} - -void Logger::shutdown() { - if (!initialized_) { - return; - } - - try { - spdlog::shutdown(); - logger_impl_.reset(); - initialized_ = false; - } catch (const std::exception& e) { - fprintf(stderr, "[ARE] Error during logger shutdown: %s\n", e.what()); - } -} - -void Logger::log(LogLevel level, const char* file, const char* func, - int line, const std::string& message) { - if (!initialized_) { - init(); - } - - // Extract filename from full path - const char* filename = file; - const char* last_slash = nullptr; - - for (const char* p = file; *p; ++p) { - if (*p == '/' || *p == '\\') { - last_slash = p; - } - } - - if (last_slash) { - filename = last_slash + 1; - } - - // Format message with location information - std::string formatted = message + " (" + filename + ":" + std::to_string(line) + ")"; - - try { - auto logger = std::static_pointer_cast(logger_impl_); - - switch (level) { - case LogLevel::ARE_LOG_TRACE: - logger->trace(formatted); - break; - case LogLevel::ARE_LOG_DEBUG: - logger->debug(formatted); - break; - case LogLevel::ARE_LOG_INFO: - logger->info(formatted); - break; - case LogLevel::ARE_LOG_WARN: - logger->warn(formatted); - break; - case LogLevel::ARE_LOG_ERROR: - logger->error(formatted); - break; - case LogLevel::ARE_LOG_CRITICAL: - logger->critical(formatted); - break; - } - } catch (const std::exception& e) { - fprintf(stderr, "[ARE] Logging error: %s\n", e.what()); - } -} - -void Logger::set_level(LogLevel level) { - if (!initialized_) { - return; - } - - try { - auto logger = std::static_pointer_cast(logger_impl_); - - switch (level) { - case LogLevel::ARE_LOG_TRACE: - logger->set_level(spdlog::level::trace); - break; - case LogLevel::ARE_LOG_DEBUG: - logger->set_level(spdlog::level::debug); - break; - case LogLevel::ARE_LOG_INFO: - logger->set_level(spdlog::level::info); - break; - case LogLevel::ARE_LOG_WARN: - logger->set_level(spdlog::level::warn); - break; - case LogLevel::ARE_LOG_ERROR: - logger->set_level(spdlog::level::err); - break; - case LogLevel::ARE_LOG_CRITICAL: - logger->set_level(spdlog::level::critical); - break; - } - } catch (const std::exception& e) { - fprintf(stderr, "[ARE] Error setting log level: %s\n", e.what()); - } -} - -} // namespace are diff --git a/src/core/profiler.cpp b/src/core/profiler.cpp deleted file mode 100644 index 9d29cf3..0000000 --- a/src/core/profiler.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/** - * @file profiler.cpp - * @brief Implementation of performance profiler - */ - -#include -#include -#include -#include -#include - -namespace are { - -std::unordered_map Profiler::sections_; -std::unordered_map Profiler::results_; -bool Profiler::enabled_ = false; - -void Profiler::init() { -#ifdef ARE_ENABLE_PROFILING - enabled_ = true; - sections_.clear(); - results_.clear(); - ARE_LOG_INFO("Profiler initialized"); -#else - enabled_ = false; - ARE_LOG_WARN("Profiler disabled (ARE_ENABLE_PROFILING not defined)"); -#endif -} - -void Profiler::shutdown() { - if (!enabled_) { - return; - } - - print_results(); - sections_.clear(); - results_.clear(); - enabled_ = false; -} - -void Profiler::begin(const std::string& name) { - if (!enabled_) { - return; - } - - auto& section = sections_[name]; - section.start_time_ = std::chrono::high_resolution_clock::now(); -} - -void Profiler::end(const std::string& name) { - if (!enabled_) { - return; - } - - auto end_time = std::chrono::high_resolution_clock::now(); - - auto it = sections_.find(name); - if (it == sections_.end()) { - ARE_LOG_WARN("Profiler::end called for unknown section: " + name); - return; - } - - auto& section = it->second; - auto duration = std::chrono::duration_cast( - end_time - section.start_time_ - ); - - section.total_duration_ms_ += duration.count() / 1000.0; - section.call_count_++; -} - -const std::unordered_map& Profiler::get_results() { - if (!enabled_) { - return results_; - } - - results_.clear(); - - for (const auto& [name, section] : sections_) { - ProfileResult result; - result.name_ = name; - result.duration_ms_ = section.total_duration_ms_; - result.call_count_ = section.call_count_; - result.avg_duration_ms_ = (section.call_count_ > 0) - ? (section.total_duration_ms_ / section.call_count_) - : 0.0; - - results_[name] = result; - } - - return results_; -} - -void Profiler::reset() { - if (!enabled_) { - return; - } - - for (auto& [name, section] : sections_) { - section.total_duration_ms_ = 0.0; - section.call_count_ = 0; - } - - results_.clear(); -} - -void Profiler::print_results() { - if (!enabled_) { - return; - } - - get_results(); - - if (results_.empty()) { - ARE_LOG_INFO("No profiling data available"); - return; - } - - // Sort results by total duration (descending) - std::vector sorted_results; - sorted_results.reserve(results_.size()); - - for (const auto& [name, result] : results_) { - sorted_results.push_back(result); - } - - std::sort(sorted_results.begin(), sorted_results.end(), - [](const ProfileResult& a, const ProfileResult& b) { - return a.duration_ms_ > b.duration_ms_; - }); - - // Print header - ARE_LOG_INFO("=== Performance Profile ==="); - ARE_LOG_INFO(std::string(80, '-')); - - std::stringstream header; - header << std::left << std::setw(30) << "Section" - << std::right << std::setw(12) << "Total (ms)" - << std::right << std::setw(12) << "Calls" - << std::right << std::setw(12) << "Avg (ms)" - << std::right << std::setw(12) << "Percent"; - ARE_LOG_INFO(header.str()); - ARE_LOG_INFO(std::string(80, '-')); - - // Calculate total time - double total_time = 0.0; - for (const auto& result : sorted_results) { - total_time += result.duration_ms_; - } - - // Print results - for (const auto& result : sorted_results) { - std::stringstream ss; - double percent = (total_time > 0.0) ? (result.duration_ms_ / total_time * 100.0) : 0.0; - - ss << std::left << std::setw(30) << result.name_ - << std::right << std::setw(12) << std::fixed << std::setprecision(3) << result.duration_ms_ - << std::right << std::setw(12) << result.call_count_ - << std::right << std::setw(12) << std::fixed << std::setprecision(3) << result.avg_duration_ms_ - << std::right << std::setw(11) << std::fixed << std::setprecision(1) << percent << "%"; - - ARE_LOG_INFO(ss.str()); - } - - ARE_LOG_INFO(std::string(80, '-')); - - std::stringstream total_ss; - total_ss << "Total: " << std::fixed << std::setprecision(3) << total_time << " ms"; - ARE_LOG_INFO(total_ss.str()); - ARE_LOG_INFO("==========================="); -} - -// ScopedProfiler implementation -ScopedProfiler::ScopedProfiler(const std::string& name) : name_(name) { - Profiler::begin(name_); -} - -ScopedProfiler::~ScopedProfiler() { - Profiler::end(name_); -} - -} // namespace are diff --git a/src/core/types.cpp b/src/core/types.cpp deleted file mode 100644 index 3e5a0d1..0000000 --- a/src/core/types.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @file types.cpp - * @brief Implementation of basic types (if needed) - */ - -#include - -// This file is intentionally minimal as types.h is mostly type definitions -// Any future type-related utility functions can be added here - -namespace are { - -// Currently no implementation needed for types.h - -} // namespace are diff --git a/src/geometry/aabb.cpp b/src/geometry/aabb.cpp deleted file mode 100644 index 507a94c..0000000 --- a/src/geometry/aabb.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/** - * @file aabb.cpp - * @brief Implementation of Axis-Aligned Bounding Box - */ - -#include -#include -#include -#include -#include -#include - -namespace are { - -AABB::AABB() - : min_(std::numeric_limits::max()) - , max_(std::numeric_limits::lowest()) { -} - -AABB::AABB(const Vec3& min, const Vec3& max) - : min_(min) - , max_(max) { -} - -AABB::AABB(const Vec3& point) - : min_(point) - , max_(point) { -} - -bool AABB::is_valid() const { - return min_.x <= max_.x && min_.y <= max_.y && min_.z <= max_.z; -} - -Vec3 AABB::center() const { - return (min_ + max_) * 0.5f; -} - -Vec3 AABB::size() const { - return max_ - min_; -} - -Real AABB::surface_area() const { - Vec3 d = size(); - return 2.0f * (d.x * d.y + d.y * d.z + d.z * d.x); -} - -Real AABB::volume() const { - Vec3 d = size(); - return d.x * d.y * d.z; -} - -int AABB::longest_axis() const { - Vec3 d = size(); - if (d.x > d.y && d.x > d.z) { - return 0; - } else if (d.y > d.z) { - return 1; - } else { - return 2; - } -} - -void AABB::expand(const Vec3& point) { - min_ = glm::min(min_, point); - max_ = glm::max(max_, point); -} - -void AABB::expand(const AABB& other) { - if (other.is_valid()) { - min_ = glm::min(min_, other.min_); - max_ = glm::max(max_, other.max_); - } -} - -bool AABB::contains(const Vec3& point) const { - return point.x >= min_.x && point.x <= max_.x && - point.y >= min_.y && point.y <= max_.y && - point.z >= min_.z && point.z <= max_.z; -} - -bool AABB::intersects(const AABB& other) const { - return min_.x <= other.max_.x && max_.x >= other.min_.x && - min_.y <= other.max_.y && max_.y >= other.min_.y && - min_.z <= other.max_.z && max_.z >= other.min_.z; -} - -bool AABB::intersect_ray(const Ray& ray, Real& t_min_out, Real& t_max_out) const { - // Slab method for ray-AABB intersection - // Reference: "An Efficient and Robust Ray-Box Intersection Algorithm" by Williams et al. - - Real t_min = ray.t_min_; - Real t_max = ray.t_max_; - - for (int i = 0; i < 3; ++i) { - Real inv_d = 1.0f / ray.direction_[i]; - Real t0 = (min_[i] - ray.origin_[i]) * inv_d; - Real t1 = (max_[i] - ray.origin_[i]) * inv_d; - - if (inv_d < 0.0f) { - std::swap(t0, t1); - } - - t_min = t0 > t_min ? t0 : t_min; - t_max = t1 < t_max ? t1 : t_max; - - if (t_max < t_min) { - return false; - } - } - - t_min_out = t_min; - t_max_out = t_max; - return true; -} - -AABB AABB::merge(const AABB& a, const AABB& b) { - if (!a.is_valid()) return b; - if (!b.is_valid()) return a; - - return AABB( - glm::min(a.min_, b.min_), - glm::max(a.max_, b.max_) - ); -} - -AABB AABB::invalid() { - return AABB(); -} - -} // namespace are diff --git a/src/geometry/transform.cpp b/src/geometry/transform.cpp deleted file mode 100644 index 74bf0dd..0000000 --- a/src/geometry/transform.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/** - * @file transform.cpp - * @brief Implementation of Transform class - */ - -#define GLM_ENABLE_EXPERIMENTAL -#include -#include -#include -#include - -namespace are { - -Transform::Transform() - : position_(0.0f) - , rotation_(0.0f) - , scale_(1.0f) - , matrix_(1.0f) - , inverse_matrix_(1.0f) - , dirty_(true) { -} - -Transform::Transform(const Vec3& position, const Vec3& rotation, const Vec3& scale) - : position_(position) - , rotation_(rotation) - , scale_(scale) - , matrix_(1.0f) - , inverse_matrix_(1.0f) - , dirty_(true) { -} - -void Transform::set_position(const Vec3& position) { - position_ = position; - mark_dirty(); -} - -void Transform::set_rotation(const Vec3& rotation) { - rotation_ = rotation; - mark_dirty(); -} - -void Transform::set_scale(const Vec3& scale) { - scale_ = scale; - mark_dirty(); -} - -void Transform::set_scale(Real uniform_scale) { - scale_ = Vec3(uniform_scale); - mark_dirty(); -} - -Mat4 Transform::get_matrix() const { - if (dirty_) { - update_matrix(); - } - return matrix_; -} - -Mat4 Transform::get_inverse_matrix() const { - if (dirty_) { - update_matrix(); - } - return inverse_matrix_; -} - -Mat3 Transform::get_normal_matrix() const { - if (dirty_) { - update_matrix(); - } - // Normal matrix is the transpose of the inverse of the upper-left 3x3 - return glm::transpose(glm::inverse(Mat3(matrix_))); -} - -Vec3 Transform::transform_point(const Vec3& point) const { - if (dirty_) { - update_matrix(); - } - Vec4 result = matrix_ * Vec4(point, 1.0f); - return Vec3(result); -} - -Vec3 Transform::transform_direction(const Vec3& direction) const { - if (dirty_) { - update_matrix(); - } - Vec4 result = matrix_ * Vec4(direction, 0.0f); - return Vec3(result); -} - -Vec3 Transform::transform_normal(const Vec3& normal) const { - Mat3 normal_matrix = get_normal_matrix(); - return glm::normalize(normal_matrix * normal); -} - -Transform Transform::operator*(const Transform& other) const { - ARE_PROFILE_FUNCTION(); - - // Combine transforms by multiplying matrices - // Note: This is an approximation; for exact results, - // we would need to decompose the combined matrix - Transform result; - - Mat4 combined = get_matrix() * other.get_matrix(); - - // Extract translation - result.position_ = Vec3(combined[3]); - - // Extract scale (approximate) - result.scale_.x = glm::length(Vec3(combined[0])); - result.scale_.y = glm::length(Vec3(combined[1])); - result.scale_.z = glm::length(Vec3(combined[2])); - - // Remove scale from matrix to extract rotation - Mat3 rotation_matrix; - rotation_matrix[0] = Vec3(combined[0]) / result.scale_.x; - rotation_matrix[1] = Vec3(combined[1]) / result.scale_.y; - rotation_matrix[2] = Vec3(combined[2]) / result.scale_.z; - - // Extract Euler angles (approximate, may have gimbal lock issues) - result.rotation_.x = std::atan2(rotation_matrix[2][1], rotation_matrix[2][2]); - result.rotation_.y = std::atan2(-rotation_matrix[2][0],std::sqrt(rotation_matrix[2][1] * rotation_matrix[2][1] + - rotation_matrix[2][2] * rotation_matrix[2][2])); - result.rotation_.z = std::atan2(rotation_matrix[1][0], rotation_matrix[0][0]); - - result.dirty_ = true; - return result; -} - -Transform Transform::identity() { - return Transform(); -} - -Transform Transform::translate(const Vec3& translation) { - return Transform(translation, Vec3(0.0f), Vec3(1.0f)); -} - -Transform Transform::rotate(const Vec3& rotation) { - return Transform(Vec3(0.0f), rotation, Vec3(1.0f)); -} - -Transform Transform::scale(const Vec3& scale) { - return Transform(Vec3(0.0f), Vec3(0.0f), scale); -} - -void Transform::mark_dirty() { - dirty_ = true; -} - -void Transform::update_matrix() const { - ARE_PROFILE_FUNCTION(); - - // Build transformation matrix: T * R * S - // Translation - Mat4 translation_matrix = glm::translate(Mat4(1.0f), position_); - - // Rotation (using Euler angles: YXZ order for typical camera/object rotation) - Mat4 rotation_matrix = glm::eulerAngleYXZ(rotation_.y, rotation_.x, rotation_.z); - - // Scale - Mat4 scale_matrix = glm::scale(Mat4(1.0f), scale_); - - // Combine: T * R * S - matrix_ = translation_matrix * rotation_matrix * scale_matrix; - - // Compute inverse - inverse_matrix_ = glm::inverse(matrix_); - - dirty_ = false; -} - -} // namespace are diff --git a/src/geometry/triangle.cpp b/src/geometry/triangle.cpp deleted file mode 100644 index 899023d..0000000 --- a/src/geometry/triangle.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @file triangle.cpp - * @brief Implementation of Triangle primitive - */ - -#include -#include -#include -#include -#include -#include - -namespace are { - -Triangle::Triangle() - : material_(are_invalid_handle) { -} - -Triangle::Triangle(const Vertex &v0, const Vertex &v1, const Vertex &v2, MaterialHandle material) - : v0_(v0) - , v1_(v1) - , v2_(v2) - , material_(material) { -} - -Vec3 Triangle::centroid() const { - return (v0_.position_ + v1_.position_ + v2_.position_) / 3.0f; -} - -Vec3 Triangle::normal() const { - Vec3 edge1 = v1_.position_ - v0_.position_; - Vec3 edge2 = v2_.position_ - v0_.position_; - return glm::normalize(glm::cross(edge1, edge2)); -} - -Real Triangle::area() const { - Vec3 edge1 = v1_.position_ - v0_.position_; - Vec3 edge2 = v2_.position_ - v0_.position_; - return 0.5f * glm::length(glm::cross(edge1, edge2)); -} - -AABB Triangle::compute_aabb() const { - AABB aabb(v0_.position_); - aabb.expand(v1_.position_); - aabb.expand(v2_.position_); - return aabb; -} - -bool Triangle::intersect(const Ray &ray, HitRecord &hit) const { - ARE_PROFILE_FUNCTION(); - - // Möller-Trumbore algorithm - // Reference: "Fast, Minimum Storage Ray/Triangle Intersection" - - const Vec3 edge1 = v1_.position_ - v0_.position_; - const Vec3 edge2 = v2_.position_ - v0_.position_; - - const Vec3 h = glm::cross(ray.direction_, edge2); - const Real a = glm::dot(edge1, h); - - // Check if ray is parallel to triangle - if (a > -are_epsilon && a < are_epsilon) { - return false; - } - - const Real f = 1.0f / a; - const Vec3 s = ray.origin_ - v0_.position_; - const Real u = f * glm::dot(s, h); - - // Check barycentric coordinate u - if (u < 0.0f || u > 1.0f) { - return false; - } - - const Vec3 q = glm::cross(s, edge1); - const Real v = f * glm::dot(ray.direction_, q); - - // Check barycentric coordinate v - if (v < 0.0f || u + v > 1.0f) { - return false; - } - - // Calculate t parameter - const Real t = f * glm::dot(edge2, q); - - // Check if intersection is within ray bounds - if (!ray.is_valid_t(t)) { - return false; - } - - // Fill hit record - const Real w = 1.0f - u - v; - - hit.t_ = t; - hit.position_ = ray.at(t); - hit.material_ = material_; - - // Interpolate vertex attributes using barycentric coordinates - hit.normal_ = glm::normalize( - w * v0_.normal_ + u * v1_.normal_ + v * v2_.normal_); - hit.texcoord_ = w * v0_.texcoord_ + u * v1_.texcoord_ + v * v2_.texcoord_; - hit.tangent_ = glm::normalize( - w * v0_.tangent_ + u * v1_.tangent_ + v * v2_.tangent_); - - // Determine front face - hit.set_face_normal(ray.direction_, hit.normal_); - - return true; -} - -bool Triangle::intersect_fast(const Ray &ray, Real t_max) const { - ARE_PROFILE_FUNCTION(); - - // Simplified Möller-Trumbore without hit record computation - const Vec3 edge1 = v1_.position_ - v0_.position_; - const Vec3 edge2 = v2_.position_ - v0_.position_; - - const Vec3 h = glm::cross(ray.direction_, edge2); - const Real a = glm::dot(edge1, h); - - if (a > -are_epsilon && a < are_epsilon) { - return false; - } - - const Real f = 1.0f / a; - const Vec3 s = ray.origin_ - v0_.position_; - const Real u = f * glm::dot(s, h); - - if (u < 0.0f || u > 1.0f) { - return false; - } - - const Vec3 q = glm::cross(s, edge1); - const Real v = f * glm::dot(ray.direction_, q); - - if (v < 0.0f || u + v > 1.0f) { - return false; - } - - const Real t = f * glm::dot(edge2, q); - - return t > ray.t_min_ && t < t_max; -} - -} // namespace are diff --git a/src/geometry/vertex.cpp b/src/geometry/vertex.cpp deleted file mode 100644 index b65d613..0000000 --- a/src/geometry/vertex.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/** - * @file vertex.cpp - * @brief Implementation of Vertex structure - */ - -#include -#include - -namespace are { - -Vertex::Vertex(const Vec3& pos) - : position_(pos) - , normal_(0.0f, 1.0f, 0.0f) - , texcoord_(0.0f, 0.0f) - , tangent_(1.0f, 0.0f, 0.0f) { -} - -Vertex::Vertex(const Vec3& pos, const Vec3& norm) - : position_(pos) - , normal_(norm) - , texcoord_(0.0f, 0.0f) - , tangent_(1.0f, 0.0f, 0.0f) { -} - -Vertex::Vertex(const Vec3& pos, const Vec3& norm, const Vec2& uv) - : position_(pos) - , normal_(norm) - , texcoord_(uv) - , tangent_(1.0f, 0.0f, 0.0f) { -} - -Vertex::Vertex(const Vec3& pos, const Vec3& norm, const Vec2& uv, const Vec3& tan) - : position_(pos) - , normal_(norm) - , texcoord_(uv) - , tangent_(tan) { -} - -Vertex Vertex::lerp(const Vertex& a, const Vertex& b, Real t) { - Vertex result; - result.position_ = glm::mix(a.position_, b.position_, t); - result.normal_ = glm::normalize(glm::mix(a.normal_, b.normal_, t)); - result.texcoord_ = glm::mix(a.texcoord_, b.texcoord_, t); - result.tangent_ = glm::normalize(glm::mix(a.tangent_, b.tangent_, t)); - return result; -} - -} // namespace are diff --git a/src/platform/gl_context.cpp b/src/platform/gl_context.cpp deleted file mode 100644 index e890633..0000000 --- a/src/platform/gl_context.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @file gl_context.cpp - * @brief Implementation of OpenGL context management - */ - -#include -#include -#include -#include -#include - -namespace are { - -bool GLContext::initialized_ = false; - -bool GLContext::initialize() { - if (initialized_) { - ARE_LOG_WARN("OpenGL context already initialized"); - return true; - } - - // Load OpenGL function pointers using GLAD - if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { - ARE_LOG_CRITICAL("Failed to initialize GLAD"); - return false; - } - - initialized_ = true; - - ARE_LOG_INFO("OpenGL context initialized successfully"); - print_info(); - - return true; -} - -bool GLContext::is_initialized() { - return initialized_; -} - -std::string GLContext::get_version() { - if (!initialized_) { - return "Not initialized"; - } - - const GLubyte* version = glGetString(GL_VERSION); - return version ? std::string(reinterpret_cast(version)) : "Unknown"; -} - -std::string GLContext::get_renderer() { - if (!initialized_) { - return "Not initialized"; - } - - const GLubyte* renderer = glGetString(GL_RENDERER); - return renderer ? std::string(reinterpret_cast(renderer)) : "Unknown"; -} - -std::string GLContext::get_vendor() { - if (!initialized_) { - return "Not initialized"; - } - - const GLubyte* vendor = glGetString(GL_VENDOR); - return vendor ? std::string(reinterpret_cast(vendor)) : "Unknown"; -} - -bool GLContext::is_extension_supported(const std::string& extension) { - if (!initialized_) { - return false; - } - - GLint num_extensions = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions); - - for (GLint i = 0; i < num_extensions; ++i) { - const GLubyte* ext = glGetStringi(GL_EXTENSIONS, i); - if (ext && extension == reinterpret_cast(ext)) { - return true; - } - } - - return false; -} - -void GLContext::print_info() { - if (!initialized_) { - ARE_LOG_WARN("Cannot print OpenGL info: context not initialized"); - return; - } - - ARE_LOG_INFO("=== OpenGL Information ==="); - ARE_LOG_INFO("Version: " + get_version()); - ARE_LOG_INFO("Renderer: " + get_renderer()); - ARE_LOG_INFO("Vendor: " + get_vendor()); - - // Get GLSL version - const GLubyte* glsl_version = glGetString(GL_SHADING_LANGUAGE_VERSION); - if (glsl_version) { - ARE_LOG_INFO("GLSL Version: " + std::string(reinterpret_cast(glsl_version))); - } - - // Get max texture size - GLint max_texture_size = 0; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); - ARE_LOG_INFO("Max Texture Size: " + std::to_string(max_texture_size)); - - // Get max compute work group size - GLint max_compute_work_group_invocations = 0; - glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &max_compute_work_group_invocations); - ARE_LOG_INFO("Max Compute Work Group Invocations: " + - std::to_string(max_compute_work_group_invocations)); - - ARE_LOG_INFO("=========================="); -} - -bool GLContext::check_error(const char* file, int line) { - GLenum error = glGetError(); - - if (error == GL_NO_ERROR) { - return false; - } - - std::string error_string; - switch (error) { - case GL_INVALID_ENUM: - error_string = "GL_INVALID_ENUM"; - break; - case GL_INVALID_VALUE: - error_string = "GL_INVALID_VALUE"; - break; - case GL_INVALID_OPERATION: - error_string = "GL_INVALID_OPERATION"; - break; - case GL_OUT_OF_MEMORY: - error_string = "GL_OUT_OF_MEMORY"; - break; - case GL_INVALID_FRAMEBUFFER_OPERATION: - error_string = "GL_INVALID_FRAMEBUFFER_OPERATION"; - break; - default: - error_string = "Unknown error " + std::to_string(error); - break; - } - - // Extract filename from path - const char* filename = file; - for (const char* p = file; *p; ++p) { - if (*p == '/' || *p == '\\') { - filename = p + 1; - } - } - - ARE_LOG_ERROR("OpenGL Error: " + error_string + " at " + - filename + ":" + std::to_string(line)); - - return true; -} - -void GLContext::clear_errors() { - while (glGetError() != GL_NO_ERROR) { - // Clear all errors - } -} - -} // namespace are diff --git a/src/platform/window.cpp b/src/platform/window.cpp deleted file mode 100644 index 2e265d5..0000000 --- a/src/platform/window.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/** - * @file window.cpp - * @brief Implementation of GLFW window wrapper - */ - -#include -#include -#include -#include - -namespace are { - -int Window::instance_count_ = 0; - -Window::Window(const WindowConfig& config) - : window_(nullptr) - , config_(config) - , vsync_enabled_(config.vsync) { - - initialize_glfw(); - create_window(); - setup_callbacks(); -} - -Window::~Window() { - if (window_) { - glfwDestroyWindow(window_); - window_ = nullptr; - } - - instance_count_--; - if (instance_count_ == 0) { - glfwTerminate(); - ARE_LOG_INFO("GLFW terminated"); - } -} - -void Window::initialize_glfw() { - if (instance_count_ == 0) { - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) { - ARE_LOG_CRITICAL("Failed to initialize GLFW"); - throw std::runtime_error("GLFW initialization failed"); - } - - ARE_LOG_INFO("GLFW initialized successfully"); - } - - instance_count_++; -} - -void Window::create_window() { - // Set OpenGL version hints - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - -#ifdef __APPLE__ - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); -#endif - - // Set window hints - glfwWindowHint(GLFW_RESIZABLE, config_.resizable ? GLFW_TRUE : GLFW_FALSE); - glfwWindowHint(GLFW_SAMPLES, config_.samples); - - // Create window - window_ = glfwCreateWindow( - config_.width, - config_.height, - config_.title.c_str(), - nullptr, - nullptr - ); - - if (!window_) { - ARE_LOG_CRITICAL("Failed to create GLFW window"); - throw std::runtime_error("Window creation failed"); - } - - // Make context current - glfwMakeContextCurrent(window_); - - // Set VSync - glfwSwapInterval(vsync_enabled_ ? 1 : 0); - - ARE_LOG_INFO("Window created: " + std::to_string(config_.width) + "x" + - std::to_string(config_.height) + " - " + config_.title); -} - -void Window::setup_callbacks() { - // Store this pointer in window user pointer - glfwSetWindowUserPointer(window_, this); - - // Set framebuffer size callback - glfwSetFramebufferSizeCallback(window_, framebuffer_size_callback); -} - -void Window::framebuffer_size_callback(GLFWwindow* window, int width, int height) { - Window* win = static_cast(glfwGetWindowUserPointer(window)); - if (win) { - win->config_.width = width; - win->config_.height = height; - ARE_LOG_DEBUG("Framebuffer resized: " + std::to_string(width) + "x" + std::to_string(height)); - } -} - -void Window::error_callback(int error, const char* description) { - ARE_LOG_ERROR("GLFW Error " + std::to_string(error) + ": " + description); -} - -bool Window::should_close() const { - return glfwWindowShouldClose(window_); -} - -void Window::set_should_close(bool should_close) { - glfwSetWindowShouldClose(window_, should_close ? GLFW_TRUE : GLFW_FALSE); -} - -void Window::swap_buffers() { - glfwSwapBuffers(window_); -} - -void Window::poll_events() { - glfwPollEvents(); -} - -int Window::get_width() const { - return config_.width; -} - -int Window::get_height() const { - return config_.height; -} - -Real Window::get_aspect_ratio() const { - return static_cast(config_.width) / static_cast(config_.height); -} - -const std::string& Window::get_title() const { - return config_.title; -} - -void Window::set_title(const std::string& title) { - config_.title = title; - glfwSetWindowTitle(window_, title.c_str()); -} - -void Window::set_size(int width, int height) { - config_.width = width; - config_.height = height; - glfwSetWindowSize(window_, width, height); -} - -void Window::get_framebuffer_size(int& width, int& height) const { - glfwGetFramebufferSize(window_, &width, &height); -} - -void Window::set_vsync(bool enabled) { - vsync_enabled_ = enabled; - glfwSwapInterval(enabled ? 1 : 0); -} - -bool Window::get_vsync() const { - return vsync_enabled_; -} - -bool Window::is_key_pressed(int key) const { - return glfwGetKey(window_, key) == GLFW_PRESS; -} - -bool Window::is_mouse_button_pressed(int button) const { - return glfwGetMouseButton(window_, button) == GLFW_PRESS; -} - -void Window::get_cursor_pos(double& x, double& y) const { - glfwGetCursorPos(window_, &x, &y); -} - -} // namespace are diff --git a/src/rasterizer/gbuffer.cpp b/src/rasterizer/gbuffer.cpp deleted file mode 100644 index acabdd6..0000000 --- a/src/rasterizer/gbuffer.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/** - * @file gbuffer.cpp - * @brief Implementation of GBuffer class - */ - -#include -#include -#include -#include - -namespace are { - -GBuffer::GBuffer(int width, int height) - : fbo_(0) - , rbo_depth_(0) - , position_texture_(0) - , normal_texture_(0) - , albedo_texture_(0) - , material_texture_(0) - , depth_texture_(0) - , primitive_id_texture_(0) - , width_(width) - , height_(height) { - - create_textures(); - create_framebuffer(); -} - -GBuffer::~GBuffer() { - delete_textures(); - - if (rbo_depth_ != 0) { - glDeleteRenderbuffers(1, &rbo_depth_); - rbo_depth_ = 0; - } - - if (fbo_ != 0) { - glDeleteFramebuffers(1, &fbo_); - fbo_ = 0; - } -} - -void GBuffer::resize(int width, int height) { - ARE_PROFILE_FUNCTION(); - - if (width == width_ && height == height_) { - return; - } - - width_ = width; - height_ = height; - - delete_textures(); - - if (rbo_depth_ != 0) { - glDeleteRenderbuffers(1, &rbo_depth_); - rbo_depth_ = 0; - } - - if (fbo_ != 0) { - glDeleteFramebuffers(1, &fbo_); - fbo_ = 0; - } - - create_textures(); - create_framebuffer(); -} - -void GBuffer::bind() { - glBindFramebuffer(GL_FRAMEBUFFER, fbo_); - glViewport(0, 0, width_, height_); -} - -void GBuffer::unbind() { - glBindFramebuffer(GL_FRAMEBUFFER, 0); -} - -void GBuffer::clear() { - bind(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - unbind(); -} - -void GBuffer::bind_texture(int index, int texture_unit) { - glActiveTexture(GL_TEXTURE0 + texture_unit); - - switch (index) { - case 0: glBindTexture(GL_TEXTURE_2D, position_texture_); break; - case 1: glBindTexture(GL_TEXTURE_2D, normal_texture_); break; - case 2: glBindTexture(GL_TEXTURE_2D, albedo_texture_); break; - case 3: glBindTexture(GL_TEXTURE_2D, material_texture_); break; - case 4: glBindTexture(GL_TEXTURE_2D, depth_texture_); break; - case 5: glBindTexture(GL_TEXTURE_2D, primitive_id_texture_); break; - default: - ARE_LOG_WARN("GBuffer: Invalid texture index " + std::to_string(index)); - break; - } -} - -void GBuffer::read_pixels(int index, void* data) { - ARE_PROFILE_FUNCTION(); - - // Robust: read from texture object (not from FBO read buffer) - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_PACK_ROW_LENGTH, 0); - glPixelStorei(GL_PACK_SKIP_PIXELS, 0); - glPixelStorei(GL_PACK_SKIP_ROWS, 0); - - uint32_t tex = 0; - GLenum format = GL_RGBA; - GLenum type = GL_UNSIGNED_BYTE; - - switch (index) { - case 0: - tex = position_texture_; - format = GL_RGB; - type = GL_FLOAT; - break; - case 1: - tex = normal_texture_; - format = GL_RGB; - type = GL_FLOAT; - break; - case 2: - tex = albedo_texture_; - format = GL_RGBA; - type = GL_UNSIGNED_BYTE; - break; - case 3: - tex = material_texture_; - format = GL_RG; - type = GL_UNSIGNED_BYTE; - break; - case 4: - tex = depth_texture_; - format = GL_DEPTH_COMPONENT; - type = GL_FLOAT; - break; - case 5: - tex = primitive_id_texture_; - format = GL_RED_INTEGER; - type = GL_UNSIGNED_INT; - break; - default: - ARE_LOG_ERROR("GBuffer: Invalid buffer index for read_pixels"); - return; - } - - glBindTexture(GL_TEXTURE_2D, tex); - glGetTexImage(GL_TEXTURE_2D, 0, format, type, data); - glBindTexture(GL_TEXTURE_2D, 0); -} - -void GBuffer::create_textures() { - ARE_PROFILE_FUNCTION(); - - glGenTextures(1, &position_texture_); - glBindTexture(GL_TEXTURE_2D, position_texture_); - 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); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glGenTextures(1, &normal_texture_); - glBindTexture(GL_TEXTURE_2D, normal_texture_); - 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); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glGenTextures(1, &albedo_texture_); - glBindTexture(GL_TEXTURE_2D, albedo_texture_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 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); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glGenTextures(1, &material_texture_); - glBindTexture(GL_TEXTURE_2D, material_texture_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, width_, height_, 0, GL_RG, GL_UNSIGNED_BYTE, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glGenTextures(1, &depth_texture_); - glBindTexture(GL_TEXTURE_2D, depth_texture_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width_, height_, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glGenTextures(1, &primitive_id_texture_); - glBindTexture(GL_TEXTURE_2D, primitive_id_texture_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, width_, height_, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glBindTexture(GL_TEXTURE_2D, 0); -} - -void GBuffer::delete_textures() { - if (position_texture_ != 0) glDeleteTextures(1, &position_texture_); - if (normal_texture_ != 0) glDeleteTextures(1, &normal_texture_); - if (albedo_texture_ != 0) glDeleteTextures(1, &albedo_texture_); - if (material_texture_ != 0) glDeleteTextures(1, &material_texture_); - if (depth_texture_ != 0) glDeleteTextures(1, &depth_texture_); - if (primitive_id_texture_ != 0) glDeleteTextures(1, &primitive_id_texture_); - - position_texture_ = 0; - normal_texture_ = 0; - albedo_texture_ = 0; - material_texture_ = 0; - depth_texture_ = 0; - primitive_id_texture_ = 0; -} - -void GBuffer::create_framebuffer() { - ARE_PROFILE_FUNCTION(); - - glGenFramebuffers(1, &fbo_); - glBindFramebuffer(GL_FRAMEBUFFER, fbo_); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, position_texture_, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normal_texture_, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, albedo_texture_, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, material_texture_, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, primitive_id_texture_, 0); - - GLenum draw_buffers[] = { - GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1, - GL_COLOR_ATTACHMENT2, - GL_COLOR_ATTACHMENT3, - GL_COLOR_ATTACHMENT4 - }; - glDrawBuffers(5, draw_buffers); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture_, 0); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - ARE_LOG_ERROR("GBuffer: Framebuffer incomplete. Status=" + std::to_string(status)); - } - - glBindFramebuffer(GL_FRAMEBUFFER, 0); -} - -} // namespace are diff --git a/src/rasterizer/rasterizer.cpp b/src/rasterizer/rasterizer.cpp deleted file mode 100644 index 92782e5..0000000 --- a/src/rasterizer/rasterizer.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/** - * @file rasterizer.cpp - * @brief Implementation of Rasterizer class - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace are { - -Rasterizer::Rasterizer(int width, int height) - : gbuffer_(std::make_unique(width, height)) - , gbuffer_shader_(std::make_unique()) - , triangle_base_provider_(nullptr) - , state_() - , width_(width) - , height_(height) { -} - -Rasterizer::~Rasterizer() = default; - -void Rasterizer::set_state(const RasterizerState& state) { - state_ = state; -} - -void Rasterizer::set_triangle_base_provider(std::function provider) { - triangle_base_provider_ = std::move(provider); -} - -void Rasterizer::resize(int width, int height) { - ARE_PROFILE_FUNCTION(); - if (width == width_ && height == height_) return; - width_ = width; - height_ = height; - gbuffer_->resize(width_, height_); -} - -void Rasterizer::render_gbuffer(const SceneManager& scene, const Camera& camera) { - ARE_PROFILE_FUNCTION(); - - if (!gbuffer_shader_ || !gbuffer_shader_->is_valid()) { - ARE_LOG_ERROR("Rasterizer: gbuffer shader not ready"); - return; - } - - gbuffer_->bind(); - - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (state_.enable_depth_test) { - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - } else { - glDisable(GL_DEPTH_TEST); - } - - if (state_.enable_cull_face) { - glEnable(GL_CULL_FACE); - glCullFace(static_cast(state_.cull_face_mode)); - glFrontFace(static_cast(state_.front_face)); - } else { - glDisable(GL_CULL_FACE); - } - - gbuffer_shader_->use(); - gbuffer_shader_->set_uniform("u_view", camera.get_view_matrix()); - gbuffer_shader_->set_uniform("u_projection", camera.get_projection_matrix()); - - const auto& meshes = scene.get_all_meshes(); - - for (size_t mi = 0; mi < meshes.size(); ++mi) { - const auto& mesh = meshes[mi]; - if (mesh.is_empty() || !mesh.has_gpu_resources()) continue; - - Mat4 model = Mat4(1.0f); - gbuffer_shader_->set_uniform("u_model", model); - - Mat3 normal_matrix = glm::inverseTranspose(Mat3(model)); - gbuffer_shader_->set_uniform("u_normal_matrix", normal_matrix); - - uint32_t tri_base = triangle_base_provider_ ? triangle_base_provider_(mi) : 0u; - // IMPORTANT: u_triangle_id_base is uint in GLSL, must use glUniform1ui - gbuffer_shader_->set_uniform("u_triangle_id_base", tri_base); - - const Material* mat = scene.get_material(mesh.get_material()); - if (mat) { - gbuffer_shader_->set_uniform("u_albedo", mat->get_albedo()); - gbuffer_shader_->set_uniform("u_metallic", mat->get_metallic()); - gbuffer_shader_->set_uniform("u_roughness", mat->get_roughness()); - } else { - gbuffer_shader_->set_uniform("u_albedo", Vec3(0.8f)); - gbuffer_shader_->set_uniform("u_metallic", 0.0f); - gbuffer_shader_->set_uniform("u_roughness", 0.5f); - } - - glBindVertexArray(mesh.get_vao()); - glDrawElements(GL_TRIANGLES, static_cast(mesh.get_index_count()), GL_UNSIGNED_INT, nullptr); - glBindVertexArray(0); - } - - gbuffer_->unbind(); - ARE_GL_CHECK(); -} - -GBuffer& Rasterizer::get_gbuffer() { return *gbuffer_; } -const GBuffer& Rasterizer::get_gbuffer() const { return *gbuffer_; } - -void Rasterizer::upload_mesh(Mesh& mesh) { - ARE_PROFILE_FUNCTION(); - if (mesh.is_empty()) { - ARE_LOG_WARN("Rasterizer: upload_mesh on empty mesh"); - return; - } - if (mesh.has_gpu_resources()) delete_mesh(mesh); - setup_mesh_buffers(mesh); -} - -void Rasterizer::delete_mesh(Mesh& mesh) { - ARE_PROFILE_FUNCTION(); - - uint32_t vao = mesh.get_vao(); - uint32_t vbo = mesh.get_vbo(); - uint32_t ebo = mesh.get_ebo(); - - if (vao) glDeleteVertexArrays(1, &vao); - if (vbo) glDeleteBuffers(1, &vbo); - if (ebo) glDeleteBuffers(1, &ebo); - - mesh.set_vao(0); - mesh.set_vbo(0); - mesh.set_ebo(0); -} - -void Rasterizer::initialize_shaders(const std::string& shader_dir) { - ARE_PROFILE_FUNCTION(); - - bool ok = true; - ok &= gbuffer_shader_->load_shader(ShaderType::ARE_SHADER_VERTEX, shader_dir + "gbuffer/gbuffer.vert"); - ok &= gbuffer_shader_->load_shader(ShaderType::ARE_SHADER_FRAGMENT, shader_dir + "gbuffer/gbuffer.frag"); - ok &= gbuffer_shader_->link(); - - if (!ok) { - ARE_LOG_ERROR("Rasterizer: Failed to init gbuffer shaders"); - } -} - -void Rasterizer::setup_mesh_buffers(Mesh& mesh) { - ARE_PROFILE_FUNCTION(); - - uint32_t vao = 0, vbo = 0, ebo = 0; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, mesh.get_vertex_count() * sizeof(Vertex), mesh.get_vertices().data(), GL_STATIC_DRAW); - - glGenBuffers(1, &ebo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.get_index_count() * sizeof(uint32_t), mesh.get_indices().data(), GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(get_position_offset())); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(get_normal_offset())); - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(get_texcoord_offset())); - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(get_tangent_offset())); - - glBindVertexArray(0); - - mesh.set_vao(vao); - mesh.set_vbo(vbo); - mesh.set_ebo(ebo); - - ARE_GL_CHECK(); -} - -} // namespace are diff --git a/src/rasterizer/shader_program.cpp b/src/rasterizer/shader_program.cpp deleted file mode 100644 index 04194b9..0000000 --- a/src/rasterizer/shader_program.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/** - * @file shader_program.cpp - * @brief Implementation of ShaderProgram class - */ - -#include -#include -#include -#include -#include -#include - -namespace are { - -ShaderProgram::ShaderProgram() - : program_(0) - , vertex_shader_(0) - , fragment_shader_(0) - , compute_shader_(0) - , linked_(false) { - program_ = glCreateProgram(); - if (program_ == 0) { - ARE_LOG_ERROR("ShaderProgram: Failed to create OpenGL program"); - } -} - -ShaderProgram::~ShaderProgram() { - if (vertex_shader_ != 0) { - glDeleteShader(vertex_shader_); - } - if (fragment_shader_ != 0) { - glDeleteShader(fragment_shader_); - } - if (compute_shader_ != 0) { - glDeleteShader(compute_shader_); - } - if (program_ != 0) { - glDeleteProgram(program_); - } -} - -bool ShaderProgram::load_shader(ShaderType type, const std::string& filepath) { - ARE_PROFILE_FUNCTION(); - - // Read shader source from file - std::string source = read_file_to_string(filepath); - if (source.empty()) { - ARE_LOG_ERROR("ShaderProgram: Failed to read shader file: " + filepath); - return false; - } - - ARE_LOG_INFO("ShaderProgram: Loaded shader from " + filepath); - return compile_shader(type, source); -} - -bool ShaderProgram::compile_shader(ShaderType type, const std::string& source) { - ARE_PROFILE_FUNCTION(); - - GLenum gl_type; - uint32_t* shader_id; - std::string type_name; - - switch (type) { - case ShaderType::ARE_SHADER_VERTEX: - gl_type = GL_VERTEX_SHADER; - shader_id = &vertex_shader_; - type_name = "vertex"; - break; - case ShaderType::ARE_SHADER_FRAGMENT: - gl_type = GL_FRAGMENT_SHADER; - shader_id = &fragment_shader_; - type_name = "fragment"; - break; - case ShaderType::ARE_SHADER_COMPUTE: - gl_type = GL_COMPUTE_SHADER; - shader_id = &compute_shader_; - type_name = "compute"; - break; - default: - ARE_LOG_ERROR("ShaderProgram: Unknown shader type"); - return false; - } - - // Delete existing shader if any - if (*shader_id != 0) { - glDeleteShader(*shader_id); - } - - // Create and compile shader - *shader_id = glCreateShader(gl_type); - const char* source_cstr = source.c_str(); - glShaderSource(*shader_id, 1, &source_cstr, nullptr); - glCompileShader(*shader_id); - - // Check compilation errors - if (!check_compile_errors(*shader_id, type)) { - ARE_LOG_ERROR("ShaderProgram: Failed to compile " + type_name + " shader"); - glDeleteShader(*shader_id); - *shader_id = 0; - return false; - } - - // Attach shader to program - glAttachShader(program_, *shader_id); - - ARE_LOG_INFO("ShaderProgram: Compiled " + type_name + " shader successfully"); - return true; -} - -bool ShaderProgram::link() { - ARE_PROFILE_FUNCTION(); - - if (program_ == 0) { - ARE_LOG_ERROR("ShaderProgram: Cannot link invalid program"); - return false; - } - - // Link program - glLinkProgram(program_); - - // Check link errors - if (!check_link_errors()) { - ARE_LOG_ERROR("ShaderProgram: Failed to link shader program"); - linked_ = false; - return false; - } - - // Detach and delete shaders after successful link - if (vertex_shader_ != 0) { - glDetachShader(program_, vertex_shader_); - glDeleteShader(vertex_shader_); - vertex_shader_ = 0; - } - if (fragment_shader_ != 0) { - glDetachShader(program_, fragment_shader_); - glDeleteShader(fragment_shader_); - fragment_shader_ = 0; - } - if (compute_shader_ != 0) { - glDetachShader(program_, compute_shader_); - glDeleteShader(compute_shader_); - compute_shader_ = 0; - } - - linked_ = true; - ARE_LOG_INFO("ShaderProgram: Linked shader program successfully"); - return true; -} - -void ShaderProgram::use() const { - if (is_valid()) { - glUseProgram(program_); - } else { - ARE_LOG_WARN("ShaderProgram: Attempting to use invalid program"); - } -} - -void ShaderProgram::set_uniform(const std::string& name, uint32_t value) { - glUniform1ui(get_uniform_location(name), value); -} - -void ShaderProgram::set_uniform(const std::string& name, int value) { - glUniform1ui(get_uniform_location(name), value); -} - -void ShaderProgram::set_uniform(const std::string& name, float value) { - glUniform1f(get_uniform_location(name), value); -} - -void ShaderProgram::set_uniform(const std::string& name, const Vec2& value) { - glUniform2fv(get_uniform_location(name), 1, glm::value_ptr(value)); -} - -void ShaderProgram::set_uniform(const std::string& name, const Vec3& value) { - glUniform3fv(get_uniform_location(name), 1, glm::value_ptr(value)); -} - -void ShaderProgram::set_uniform(const std::string& name, const Vec4& value) { - glUniform4fv(get_uniform_location(name), 1, glm::value_ptr(value)); -} - -void ShaderProgram::set_uniform(const std::string& name, const Mat3& value) { - glUniformMatrix3fv(get_uniform_location(name), 1, GL_FALSE, glm::value_ptr(value)); -} - -void ShaderProgram::set_uniform(const std::string& name, const Mat4& value) { - glUniformMatrix4fv(get_uniform_location(name), 1, GL_FALSE, glm::value_ptr(value)); -} - -int ShaderProgram::get_uniform_location(const std::string& name) { - // Check cache first - auto it = uniform_cache_.find(name); - if (it != uniform_cache_.end()) { - return it->second; - } - - // Query OpenGL - int location = glGetUniformLocation(program_, name.c_str()); - if (location == -1) { - ARE_LOG_WARN("ShaderProgram: Uniform '" + name + "' not found"); - } - - // Cache the location - uniform_cache_[name] = location; - return location; -} - -bool ShaderProgram::check_compile_errors(uint32_t shader, ShaderType type) { - GLint success; - glGetShaderiv(shader, GL_COMPILE_STATUS, &success); - - if (!success) { - GLint log_length; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length); - - std::string info_log; - info_log.resize(log_length); - glGetShaderInfoLog(shader, log_length, nullptr, &info_log[0]); - - std::string type_name; - switch (type) { - case ShaderType::ARE_SHADER_VERTEX: type_name = "VERTEX"; break; - case ShaderType::ARE_SHADER_FRAGMENT: type_name = "FRAGMENT"; break; - case ShaderType::ARE_SHADER_COMPUTE: type_name = "COMPUTE"; break; - } - - ARE_LOG_ERROR("ShaderProgram: " + type_name + " shader compilation failed:"); - ARE_LOG_ERROR(info_log); - return false; - } - - return true; -} - -bool ShaderProgram::check_link_errors() { - GLint success; - glGetProgramiv(program_, GL_LINK_STATUS, &success); - - if (!success) { - GLint log_length; - glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &log_length); - - std::string info_log; - info_log.resize(log_length); - glGetProgramInfoLog(program_, log_length, nullptr, &info_log[0]); - - ARE_LOG_ERROR("ShaderProgram: Program linking failed:"); - ARE_LOG_ERROR(info_log); - return false; - } - - return true; -} - -} // namespace are diff --git a/src/raytracer/cpu_raytracer.cpp b/src/raytracer/cpu_raytracer.cpp deleted file mode 100644 index f6bdc18..0000000 --- a/src/raytracer/cpu_raytracer.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/** - * @file cpu_raytracer.cpp - * @brief CPU hybrid ray tracer (GBuffer-driven) with geometric normal offset - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -namespace are { - -namespace { - -inline Real compute_ray_epsilon(const Vec3& p) { - Real s = std::max({std::abs(p.x), std::abs(p.y), std::abs(p.z), 1.0f}); - return 1e-4f * s; -} - -inline Vec3 offset_ray_origin(const Vec3& p, const Vec3& ng) { - Real eps = compute_ray_epsilon(p); - return p + ng * (eps * 4.0f); -} - -inline Vec3 tonemap_reinhard(const Vec3& c, Real exposure) { - Vec3 x = c * exposure; - return x / (Vec3(1.0f) + x); -} - -inline Vec3 decode_albedo_from_rgba8(uint8_t r, uint8_t g, uint8_t b) { - return Vec3(r, g, b) / 255.0f; -} - -inline Real decode_01_from_u8(uint8_t v) { - return static_cast(v) / 255.0f; -} - -inline bool finite_vec3(const Vec3& v) { - return std::isfinite(v.x) && std::isfinite(v.y) && std::isfinite(v.z); -} - -} // namespace - -CPURayTracer::CPURayTracer(const RayTracingConfig& config) - : RayTracer(config) - , bvh_(nullptr) - , scene_(nullptr) - , framebuffer_() - , width_(0) - , height_(0) { -} - -CPURayTracer::~CPURayTracer() = default; - -void CPURayTracer::update_bvh(const BVH& bvh) { - bvh_ = &bvh; -} - -void CPURayTracer::render(const SceneManager& scene, - const Camera& camera, - const GBuffer* gbuffer, - uint32_t output_texture) { - ARE_PROFILE_FUNCTION(); - (void)camera; - - if (!bvh_ || !bvh_->is_built()) { - ARE_LOG_ERROR("CPURayTracer: BVH is null or not built"); - return; - } - - if (!gbuffer) { - ARE_LOG_CRITICAL("CPURayTracer: GBuffer is null (hybrid requires it)"); - throw std::runtime_error("CPURayTracer requires GBuffer in hybrid mode"); - } - - if (output_texture == 0) { - ARE_LOG_ERROR("CPURayTracer: output_texture is 0"); - return; - } - - scene_ = &scene; - width_ = gbuffer->get_width(); - height_ = gbuffer->get_height(); - - if (width_ <= 0 || height_ <= 0) { - ARE_LOG_ERROR("CPURayTracer: Invalid resolution"); - return; - } - - std::vector pos(static_cast(width_ * height_)); - std::vector nrm(static_cast(width_ * height_)); - std::vector albedo_metallic(static_cast(width_ * height_ * 4)); - std::vector rough_ao(static_cast(width_ * height_ * 2)); - std::vector depth(static_cast(width_ * height_)); - std::vector prim_id(static_cast(width_ * height_)); - - const_cast(gbuffer)->read_pixels(0, pos.data()); - const_cast(gbuffer)->read_pixels(1, nrm.data()); - const_cast(gbuffer)->read_pixels(2, albedo_metallic.data()); - const_cast(gbuffer)->read_pixels(3, rough_ao.data()); - const_cast(gbuffer)->read_pixels(4, depth.data()); - const_cast(gbuffer)->read_pixels(5, prim_id.data()); - - framebuffer_.assign(static_cast(width_ * height_), Vec3(0.0f)); - - const int spp = std::max(1, config_.spp); - const int max_depth = std::max(1, config_.max_depth); - const auto& triangles = bvh_->get_triangles(); - - for (int y = 0; y < height_; ++y) { - RandomGenerator& rng = get_thread_random(); - - for (int x = 0; x < width_; ++x) { - const size_t idx = static_cast(y * width_ + x); - - // Depth validity - if (!(depth[idx] > 0.0f && depth[idx] < 0.999999f)) { - framebuffer_[idx] = Vec3(0.0f); - continue; - } - - Vec3 P = pos[idx]; - Vec3 Ns = glm::normalize(nrm[idx]); - - if (!finite_vec3(P) || !finite_vec3(Ns) || glm::length(Ns) < 0.1f) { - framebuffer_[idx] = Vec3(0.0f); - continue; - } - - // Geometric normal from primitive id - Vec3 Ng = Ns; - uint32_t pid = prim_id[idx]; - if (pid < triangles.size()) { - Ng = triangles[pid].normal(); - } - - const uint8_t* am = &albedo_metallic[idx * 4]; - Vec3 albedo = decode_albedo_from_rgba8(am[0], am[1], am[2]); - (void)decode_01_from_u8(am[3]); - - const uint8_t* ra = &rough_ao[idx * 2]; - (void)decode_01_from_u8(ra[0]); - Real ao_gbuffer = decode_01_from_u8(ra[1]); - - Vec3 accum(0.0f); - - for (int s = 0; s < spp; ++s) { - HitRecord surf; - surf.position_ = P; - surf.normal_ = Ns; - surf.t_ = 1.0f; - surf.material_ = are_invalid_handle; - - // Direct lighting (shadow uses robust epsilon) - Vec3 direct = compute_direct_lighting(surf); - - // AO - Real ao = 1.0f; - if (config_.enable_ao) { - ao = compute_ambient_occlusion(surf); - } - ao *= ao_gbuffer; - - // GI (simplified) - Vec3 gi(0.0f); - if (config_.enable_gi && max_depth > 1) { - Vec3 bounce_dir = rng.random_cosine_direction(Ns); - Vec3 origin = offset_ray_origin(P, Ng); - Real eps = compute_ray_epsilon(P); - Ray bounce(origin, bounce_dir, eps * 4.0f, 1e30f); - gi = trace_ray(bounce, max_depth - 1); - } - - Vec3 c = albedo * direct * ao + albedo * gi; - accum += c; - } - - Vec3 hdr = accum / static_cast(spp); - framebuffer_[idx] = tonemap_reinhard(hdr, 1.0f); - } - } - - std::vector rgba(static_cast(width_ * height_)); - for (size_t i = 0; i < rgba.size(); ++i) { - rgba[i] = Vec4(framebuffer_[i], 1.0f); - } - - glBindTexture(GL_TEXTURE_2D, output_texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_RGBA, GL_FLOAT, rgba.data()); - glBindTexture(GL_TEXTURE_2D, 0); -} - -Vec3 CPURayTracer::trace_ray(const Ray& ray, int depth) { - if (depth <= 0) { - return Vec3(0.0f); - } - - HitRecord hit; - if (!bvh_->intersect(ray, hit)) { - return Vec3(0.0f); - } - - Vec3 Ng = hit.normal_; - if (hit.triangle_index_ < bvh_->get_triangles().size()) { - Ng = bvh_->get_triangles()[hit.triangle_index_].normal(); - } - - RandomGenerator& rng = get_thread_random(); - Vec3 dir = rng.random_cosine_direction(hit.normal_); - Vec3 origin = offset_ray_origin(hit.position_, Ng); - Real eps = compute_ray_epsilon(hit.position_); - - Ray bounce(origin, dir, eps * 4.0f, 1e30f); - return trace_ray(bounce, depth - 1); -} - -Vec3 CPURayTracer::compute_direct_lighting(const HitRecord& hit) { - Vec3 lighting(0.0f); - if (!scene_) { - return lighting; - } - - const auto& lights = scene_->get_all_lights(); - for (const auto& light_ptr : lights) { - if (!light_ptr) continue; - - Vec3 L(0.0f); - Real max_distance = 1e30f; - Real attenuation = 1.0f; - - LightType type = light_ptr->get_type(); - - if (type == LightType::ARE_LIGHT_DIRECTIONAL) { - const auto* dl = static_cast(light_ptr.get()); - L = -glm::normalize(dl->get_direction()); - } else if (type == LightType::ARE_LIGHT_POINT) { - const auto* pl = static_cast(light_ptr.get()); - Vec3 to_light = pl->get_position() - hit.position_; - Real dist = glm::length(to_light); - if (dist < are_epsilon) continue; - if (!pl->affects_point(hit.position_)) continue; - L = to_light / dist; - max_distance = dist; - attenuation = pl->calculate_attenuation(dist); - } else if (type == LightType::ARE_LIGHT_SPOT) { - const auto* sl = static_cast(light_ptr.get()); - Vec3 to_light = sl->get_position() - hit.position_; - Real dist = glm::length(to_light); - if (dist < are_epsilon) continue; - if (!sl->affects_point(hit.position_)) continue; - L = to_light / dist; - max_distance = dist; - Vec3 light_to_point = glm::normalize(hit.position_ - sl->get_position()); - attenuation *= sl->calculate_spot_factor(light_to_point); - } else { - continue; - } - - if (light_ptr->get_cast_shadows()) { - Real eps = compute_ray_epsilon(hit.position_); - Vec3 origin = hit.position_ + hit.normal_ * (eps * 4.0f); - Ray shadow(origin, L, eps * 4.0f, max_distance); - if (bvh_ && bvh_->intersect_any(shadow, max_distance)) { - continue; - } - } - - Real n_dot_l = std::max(0.0f, glm::dot(hit.normal_, L)); - if (n_dot_l <= 0.0f) continue; - - Vec3 radiance = light_ptr->get_color() * light_ptr->get_intensity(); - lighting += radiance * n_dot_l * attenuation; - } - - return lighting; -} - -Real CPURayTracer::compute_ambient_occlusion(const HitRecord& hit) { - if (!bvh_) { - return 1.0f; - } - - const int ao_samples = std::max(1, config_.ao_samples); - const Real radius = std::max(are_epsilon, config_.ao_radius); - - RandomGenerator& rng = get_thread_random(); - - int occluded = 0; - for (int i = 0; i < ao_samples; ++i) { - Vec3 dir = rng.random_in_hemisphere(hit.normal_); - Real eps = compute_ray_epsilon(hit.position_); - Vec3 origin = hit.position_ + hit.normal_ * (eps * 4.0f); - Ray ao_ray(origin, dir, eps * 4.0f, radius); - if (bvh_->intersect_any(ao_ray, radius)) { - occluded++; - } - } - - Real occ = static_cast(occluded) / static_cast(ao_samples); - return 1.0f - occ; -} - -bool CPURayTracer::is_in_shadow(const Vec3& origin, const Vec3& direction, Real max_distance, uint32_t ignore_triangle) { - if (!bvh_) return false; - - Real t_max = (max_distance > 0.0f) ? max_distance : 1e30f; - Real eps = compute_ray_epsilon(origin); - Ray shadow(origin, direction, eps * 4.0f, t_max); - return bvh_->intersect_any(shadow, t_max, ignore_triangle); -} - -} // namespace are diff --git a/src/raytracer/hit_record.cpp b/src/raytracer/hit_record.cpp deleted file mode 100644 index 2952a9f..0000000 --- a/src/raytracer/hit_record.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @file hit_record.cpp - * @brief Implementation of HitRecord structure - */ - -#include -#include -#include - -namespace are { - -HitRecord::HitRecord() - : position_(0.0f) - , normal_(0.0f, 1.0f, 0.0f) - , texcoord_(0.0f) - , tangent_(1.0f, 0.0f, 0.0f) - , t_(std::numeric_limits::max()) - , material_(are_invalid_handle) - , triangle_index_(0) - , front_face_(true) { -} - -void HitRecord::set_face_normal(const Vec3& ray_direction, const Vec3& outward_normal) { - front_face_ = glm::dot(ray_direction, outward_normal) < 0.0f; - normal_ = front_face_ ? outward_normal : -outward_normal; -} - -bool HitRecord::is_valid() const { - return t_ > 0.0f && t_ < std::numeric_limits::max(); -} - -} // namespace are diff --git a/src/raytracer/ray.cpp b/src/raytracer/ray.cpp deleted file mode 100644 index 46a2392..0000000 --- a/src/raytracer/ray.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @file ray.cpp - * @brief Implementation of Ray structure - */ - -#include -#include -#include - -namespace are { - -Ray::Ray() - : origin_(0.0f) - , direction_(0.0f, 0.0f, 1.0f) - , t_min_(are_epsilon) - , t_max_(1e30f) { -} - -Ray::Ray(const Vec3& origin, const Vec3& direction, Real t_min, Real t_max) - : origin_(origin) - , t_min_(t_min) - , t_max_(t_max) { - // Normalize direction vector - Real length = glm::length(direction); - if (length < are_epsilon) { - ARE_LOG_WARN("Ray: Direction vector has zero length, using default (0,0,1)"); - direction_ = Vec3(0.0f, 0.0f, 1.0f); - } else { - direction_ = direction / length; - } -} - -Vec3 Ray::at(Real t) const { - return origin_ + direction_ * t; -} - -bool Ray::is_valid_t(Real t) const { - return t >= t_min_ && t <= t_max_; -} - -} // namespace are diff --git a/src/raytracer/raytracer.cpp b/src/raytracer/raytracer.cpp deleted file mode 100644 index e002b5d..0000000 --- a/src/raytracer/raytracer.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @file raytracer.cpp - * @brief Implementation of RayTracer interface - */ - -#include - -namespace are { - -RayTracer::RayTracer(const RayTracingConfig& config) - : config_(config) { -} - -void RayTracer::set_config(const RayTracingConfig& config) { - config_ = config; -} - -} // namespace are diff --git a/src/renderer/geometry_cache.cpp b/src/renderer/geometry_cache.cpp deleted file mode 100644 index a2a1d45..0000000 --- a/src/renderer/geometry_cache.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @file geometry_cache.cpp - * @brief Implementation of GeometryCache - */ - -#include -#include -#include - -namespace are { - -static std::vector mesh_to_triangles(const Mesh& mesh) { - std::vector tris; - if (mesh.is_empty()) { - return tris; - } - - const auto& v = mesh.get_vertices(); - const auto& idx = mesh.get_indices(); - if (idx.size() % 3 != 0) { - ARE_LOG_ERROR("GeometryCache: Mesh index count is not multiple of 3"); - return tris; - } - - MaterialHandle material = mesh.get_material(); - tris.reserve(idx.size() / 3); - - for (size_t i = 0; i < idx.size(); i += 3) { - uint32_t i0 = idx[i + 0]; - uint32_t i1 = idx[i + 1]; - uint32_t i2 = idx[i + 2]; - - if (i0 >= v.size() || i1 >= v.size() || i2 >= v.size()) { - continue; - } - - tris.emplace_back(v[i0], v[i1], v[i2], material); - } - - return tris; -} - -bool GeometryCache::build_from_scene(const SceneManager& scene, const BVHBuildConfig& bvh_config) { - ARE_PROFILE_FUNCTION(); - - triangles_.clear(); - mesh_triangle_base_.clear(); - - const auto& meshes = scene.get_all_meshes(); - mesh_triangle_base_.reserve(meshes.size()); - - uint32_t base = 0; - - for (size_t mi = 0; mi < meshes.size(); ++mi) { - mesh_triangle_base_.push_back(base); - - auto tris = mesh_to_triangles(meshes[mi]); - base += static_cast(tris.size()); - - triangles_.insert(triangles_.end(), tris.begin(), tris.end()); - } - - if (triangles_.empty()) { - ARE_LOG_WARN("GeometryCache: No triangles in scene"); - return false; - } - - if (!bvh_.build(triangles_, bvh_config)) { - ARE_LOG_ERROR("GeometryCache: BVH build failed"); - return false; - } - - ARE_LOG_INFO("GeometryCache: Built triangles=" + std::to_string(triangles_.size()) + - ", meshes=" + std::to_string(meshes.size())); - return true; -} - -uint32_t GeometryCache::get_mesh_triangle_base(size_t mesh_index) const { - if (mesh_index >= mesh_triangle_base_.size()) { - return 0; - } - return mesh_triangle_base_[mesh_index]; -} - -} // namespace are diff --git a/src/scene/camera.cpp b/src/scene/camera.cpp deleted file mode 100644 index ba11360..0000000 --- a/src/scene/camera.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/** - * @file camera.cpp - * @brief Implementation of Camera class - */ - -#include -#include -#include -#include -#include - -namespace are { - -Camera::Camera() - : position_(0.0f, 0.0f, 5.0f) - , target_(0.0f, 0.0f, 0.0f) - , up_(0.0f, 1.0f, 0.0f) - , fov_(45.0f) - , aspect_ratio_(16.0f / 9.0f) - , near_plane_(0.1f) - , far_plane_(1000.0f) - , view_matrix_(1.0f) - , projection_matrix_(1.0f) - , view_dirty_(true) - , projection_dirty_(true) - , dirty_(true) { -} - -Camera::Camera(const Vec3& position, const Vec3& target, const Vec3& up) - : position_(position) - , target_(target) - , up_(glm::normalize(up)) - , fov_(45.0f) - , aspect_ratio_(16.0f / 9.0f) - , near_plane_(0.1f) - , far_plane_(1000.0f) - , view_matrix_(1.0f) - , projection_matrix_(1.0f) - , view_dirty_(true) - , projection_dirty_(true) - , dirty_(true) { -} - -void Camera::set_position(const Vec3& position) { - position_ = position; - view_dirty_ = true; - dirty_ = true; -} - -void Camera::set_target(const Vec3& target) { - target_ = target; - view_dirty_ = true; - dirty_ = true; -} - -void Camera::set_up(const Vec3& up) { - Real length = glm::length(up); - if (length < are_epsilon) { - ARE_LOG_WARN("Camera: Invalid up vector (zero length), using default"); - up_ = Vec3(0.0f, 1.0f, 0.0f); - } else { - up_ = up / length; - } - view_dirty_ = true; - dirty_ = true; -} - -void Camera::look_at(const Vec3& position, const Vec3& target, const Vec3& up) { - position_ = position; - target_ = target; - set_up(up); -} - -void Camera::set_fov(Real fov_degrees) { - // Clamp FOV to reasonable range - fov_ = clamp(fov_degrees, 1.0f, 179.0f); - projection_dirty_ = true; - dirty_ = true; -} - -void Camera::set_aspect_ratio(Real aspect) { - if (aspect <= 0.0f) { - ARE_LOG_ERROR("Camera: Invalid aspect ratio (must be positive)"); - return; - } - aspect_ratio_ = aspect; - projection_dirty_ = true; - dirty_ = true; -} - -void Camera::set_near_plane(Real near) { - if (near <= 0.0f) { - ARE_LOG_ERROR("Camera: Invalid near plane (must be positive)"); - return; - } - near_plane_ = near; - projection_dirty_ = true; - dirty_ = true; -} - -void Camera::set_far_plane(Real far) { - if (far <= near_plane_) { - ARE_LOG_ERROR("Camera: Invalid far plane (must be greater than near plane)"); - return; - } - far_plane_ = far; - projection_dirty_ = true; - dirty_ = true; -} - -void Camera::set_perspective(Real fov_degrees, Real aspect, Real near, Real far) { - set_fov(fov_degrees); - set_aspect_ratio(aspect); - set_near_plane(near); - set_far_plane(far); -} - -Vec3 Camera::get_forward() const { - return glm::normalize(target_ - position_); -} - -Vec3 Camera::get_right() const { - return glm::normalize(glm::cross(get_forward(), up_)); -} - -const Mat4& Camera::get_view_matrix() const { - if (view_dirty_) { - update_view_matrix(); - } - return view_matrix_; -} - -const Mat4& Camera::get_projection_matrix() const { - if (projection_dirty_) { - update_projection_matrix(); - } - return projection_matrix_; -} - -Mat4 Camera::get_view_projection_matrix() const { - return get_projection_matrix() * get_view_matrix(); -} - -void Camera::generate_ray(Real u, Real v, Vec3& origin, Vec3& direction) const { - ARE_PROFILE_FUNCTION(); - - // Ray origin is camera position - origin = position_; - - // Calculate ray direction in camera space - // u, v are in [0, 1], convert to [-1, 1] - Real x = 2.0f * u - 1.0f; - Real y = 1.0f - 2.0f * v; // Flip y for screen coordinates - - // Calculate direction based on FOV and aspect ratio - Real tan_half_fov = std::tan(degrees_to_radians(fov_ * 0.5f)); - Real viewport_height = 2.0f * tan_half_fov; - Real viewport_width = viewport_height * aspect_ratio_; - - // Get camera basis vectors - Vec3 forward = get_forward(); - Vec3 right = get_right(); - Vec3 up = glm::normalize(glm::cross(right, forward)); - - // Calculate ray direction - direction = glm::normalize( - forward + - right * (x * viewport_width * 0.5f) + - up * (y * viewport_height * 0.5f) - ); -} - -void Camera::update_view_matrix() const { - ARE_PROFILE_FUNCTION(); - - // Check if camera is looking at itself - if (glm::length(target_ - position_) < are_epsilon) { - ARE_LOG_WARN("Camera: Position and target are too close, using default view"); - view_matrix_ = Mat4(1.0f); - } else { - view_matrix_ = glm::lookAt(position_, target_, up_); - } - - view_dirty_ = false; -} - -void Camera::update_projection_matrix() const { - ARE_PROFILE_FUNCTION(); - - projection_matrix_ = glm::perspective( - degrees_to_radians(fov_), - aspect_ratio_, - near_plane_, - far_plane_ - ); - - projection_dirty_ = false; -} - -} // namespace are diff --git a/src/scene/directional_light.cpp b/src/scene/directional_light.cpp deleted file mode 100644 index 784055a..0000000 --- a/src/scene/directional_light.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file directional_light.cpp - * @brief Implementation of DirectionalLight class - */ - -#include -#include -#include - -namespace are { - -DirectionalLight::DirectionalLight() - : Light(LightType::ARE_LIGHT_DIRECTIONAL) - , direction_(0.0f, -1.0f, 0.0f) { -} - -DirectionalLight::DirectionalLight(const Vec3& direction, const Vec3& color, Real intensity) - : Light(LightType::ARE_LIGHT_DIRECTIONAL) - , direction_(glm::normalize(direction)) { - set_color(color); - set_intensity(intensity); -} - -void DirectionalLight::set_direction(const Vec3& direction) { - Real length = glm::length(direction); - if (length < are_epsilon) { - ARE_LOG_WARN("DirectionalLight: Invalid direction vector (zero length), using default"); - direction_ = Vec3(0.0f, -1.0f, 0.0f); - } else { - direction_ = direction / length; - } -} - -LightData DirectionalLight::pack() const { - LightData data; - - // position_type_: xyz unused for directional, w = light type - data.position_type_ = Vec4(0.0f, 0.0f, 0.0f, - static_cast(LightType::ARE_LIGHT_DIRECTIONAL)); - - // direction_range_: xyz = direction, w = range (unused for directional) - data.direction_range_ = Vec4(direction_, 0.0f); - - // color_intensity_: xyz = color, w = intensity - data.color_intensity_ = Vec4(color_, intensity_); - - // params_: x = cast_shadows - data.params_ = Vec4(cast_shadows_ ? 1.0f : 0.0f, 0.0f, 0.0f, 0.0f); - - return data; -} - -bool DirectionalLight::affects_point(const Vec3& point) const { - // Directional light affects all points - (void)point; // Suppress unused parameter warning - return true; -} - -} // namespace are diff --git a/src/scene/light.cpp b/src/scene/light.cpp deleted file mode 100644 index f01a018..0000000 --- a/src/scene/light.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file light.cpp - * @brief Implementation of base Light class - */ - -#include -#include -#include - -namespace are { - -Light::Light(LightType type) - : type_(type) - , color_(1.0f, 1.0f, 1.0f) - , intensity_(1.0f) - , cast_shadows_(true) { -} - -void Light::set_color(const Vec3& color) { - // Clamp color to valid range [0, 1] - color_.x = clamp(color.x, 0.0f, 1.0f); - color_.y = clamp(color.y, 0.0f, 1.0f); - color_.z = clamp(color.z, 0.0f, 1.0f); -} - -void Light::set_intensity(Real intensity) { - // Intensity can be HDR, so only clamp to non-negative - intensity_ = std::max(0.0f, intensity); -} - -void Light::set_cast_shadows(bool cast) { - cast_shadows_ = cast; -} - -} // namespace are diff --git a/src/scene/material.cpp b/src/scene/material.cpp deleted file mode 100644 index cbbe9fb..0000000 --- a/src/scene/material.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file material.cpp - * @brief Implementation of PBR Material class - */ - -#include -#include -#include - -namespace are { - -Material::Material() - : albedo_(1.0f, 1.0f, 1.0f) - , metallic_(0.0f) - , roughness_(0.5f) - , emissive_(0.0f, 0.0f, 0.0f) - , albedo_tex_handle_(are_invalid_handle) - , metallic_tex_handle_(are_invalid_handle) - , roughness_tex_handle_(are_invalid_handle) - , normal_tex_handle_(are_invalid_handle) - , ao_tex_handle_(are_invalid_handle) - , emissive_tex_handle_(are_invalid_handle) { -} - -void Material::set_albedo(const Vec3& albedo) { - // Clamp albedo to valid range [0, 1] - albedo_.x = clamp(albedo.x, 0.0f, 1.0f); - albedo_.y = clamp(albedo.y, 0.0f, 1.0f); - albedo_.z = clamp(albedo.z, 0.0f, 1.0f); -} - -void Material::set_albedo_map(const std::string& path) { - albedo_map_ = path; -} - -void Material::set_metallic(Real metallic) { - metallic_ = clamp(metallic, 0.0f, 1.0f); -} - -void Material::set_metallic_map(const std::string& path) { - metallic_map_ = path; -} - -void Material::set_roughness(Real roughness) { - // Clamp roughness to avoid division by zero in BRDF calculations - roughness_ = clamp(roughness, 0.04f, 1.0f); -} - -void Material::set_roughness_map(const std::string& path) { - roughness_map_ = path; -} - -void Material::set_normal_map(const std::string& path) { - normal_map_ = path; -} - -void Material::set_ao_map(const std::string& path) { - ao_map_ = path; -} - -void Material::set_emissive(const Vec3& emissive) { - // Emissive can be HDR, so no upper clamp - emissive_.x = std::max(0.0f, emissive.x); - emissive_.y = std::max(0.0f, emissive.y); - emissive_.z = std::max(0.0f, emissive.z); -} - -void Material::set_emissive_map(const std::string& path) { - emissive_map_ = path; -} - -bool Material::is_emissive() const { - // Check if material has significant emission - const Real threshold = 0.001f; - return (emissive_.x > threshold || - emissive_.y > threshold || - emissive_.z > threshold) || - has_emissive_map(); -} - -} // namespace are diff --git a/src/scene/mesh.cpp b/src/scene/mesh.cpp deleted file mode 100644 index 763dbd5..0000000 --- a/src/scene/mesh.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @file mesh.cpp - * @brief Implementation of Mesh class - */ - -#include -#include -#include -#include -#include - -namespace are { - -Mesh::Mesh() - : material_id_(are_invalid_handle) - , vao_(0) - , vbo_(0) - , ebo_(0) { -} - -Mesh::Mesh(const std::vector& vertices, - const std::vector& indices, - MaterialHandle material_id) - : vertices_(vertices) - , indices_(indices) - , material_id_(material_id) - , vao_(0) - , vbo_(0) - , ebo_(0) { - compute_aabb(); -} - -Mesh::Mesh(const Vertex* vertices, size_t vertex_count, - const uint32_t* indices, size_t index_count, - MaterialHandle material_id) - : material_id_(material_id) - , vao_(0) - , vbo_(0) - , ebo_(0) { - if (vertices && vertex_count > 0) { - vertices_.assign(vertices, vertices + vertex_count); - } - - if (indices && index_count > 0) { - indices_.assign(indices, indices + index_count); - } - - compute_aabb(); -} - -void Mesh::set_vertices(const std::vector& vertices) { - vertices_ = vertices; - compute_aabb(); -} - -void Mesh::set_indices(const std::vector& indices) { - indices_ = indices; -} - -void Mesh::set_material(MaterialHandle material_id) { - material_id_ = material_id; -} - -void Mesh::compute_aabb() { - ARE_PROFILE_FUNCTION(); - - if (vertices_.empty()) { - aabb_ = AABB::invalid(); - return; - } - - aabb_ = AABB(vertices_[0].position_); - - for (size_t i = 1; i < vertices_.size(); ++i) { - aabb_.expand(vertices_[i].position_); - } -} - -void Mesh::compute_tangents() { - ARE_PROFILE_FUNCTION(); - - if (vertices_.empty() || indices_.empty()) { - ARE_LOG_WARN("Mesh: Cannot compute tangents for empty mesh"); - return; - } - - if (indices_.size() % 3 != 0) { - ARE_LOG_ERROR("Mesh: Index count is not a multiple of 3"); - return; - } - - // Initialize tangents to zero - std::vector tangents(vertices_.size(), Vec3(0.0f)); - std::vector bitangents(vertices_.size(), Vec3(0.0f)); - - // Calculate tangents for each triangle - for (size_t i = 0; i < indices_.size(); i += 3) { - uint32_t i0 = indices_[i]; - uint32_t i1 = indices_[i + 1]; - uint32_t i2 = indices_[i + 2]; - - if (i0 >= vertices_.size() || i1 >= vertices_.size() || i2 >= vertices_.size()) { - ARE_LOG_ERROR("Mesh: Invalid index in compute_tangents"); - continue; - } - - const Vertex& v0 = vertices_[i0]; - const Vertex& v1 = vertices_[i1]; - const Vertex& v2 = vertices_[i2]; - - // Calculate edges - Vec3 edge1 = v1.position_ - v0.position_; - Vec3 edge2 = v2.position_ - v0.position_; - - Vec2 delta_uv1 = v1.texcoord_ - v0.texcoord_; - Vec2 delta_uv2 = v2.texcoord_ - v0.texcoord_; - - // Calculate tangent and bitangent - Real f = delta_uv1.x * delta_uv2.y - delta_uv2.x * delta_uv1.y; - - if (std::abs(f) < are_epsilon) { - // Degenerate UV coordinates, use arbitrary tangent - Vec3 tangent, bitangent; - create_orthonormal_basis(v0.normal_, tangent, bitangent); - - tangents[i0] += tangent; - tangents[i1] += tangent; - tangents[i2] += tangent; - continue; - } - - f = 1.0f / f; - - Vec3 tangent; - tangent.x = f * (delta_uv2.y * edge1.x - delta_uv1.y * edge2.x); - tangent.y = f * (delta_uv2.y * edge1.y - delta_uv1.y * edge2.y); - tangent.z = f * (delta_uv2.y * edge1.z - delta_uv1.y * edge2.z); - - Vec3 bitangent; - bitangent.x = f * (-delta_uv2.x * edge1.x + delta_uv1.x * edge2.x); - bitangent.y = f * (-delta_uv2.x * edge1.y + delta_uv1.x * edge2.y); - bitangent.z = f * (-delta_uv2.x * edge1.z + delta_uv1.x * edge2.z); - - // Accumulate tangents for each vertex - tangents[i0] += tangent; - tangents[i1] += tangent; - tangents[i2] += tangent; - - bitangents[i0] += bitangent; - bitangents[i1] += bitangent; - bitangents[i2] += bitangent; - } - - // Orthogonalize and normalize tangents (Gram-Schmidt) - for (size_t i = 0; i < vertices_.size(); ++i) { - const Vec3& n = vertices_[i].normal_; - const Vec3& t = tangents[i]; - - // Gram-Schmidt orthogonalize - Vec3 tangent = t - n * glm::dot(n, t); - - Real length = glm::length(tangent); - if (length < are_epsilon) { - // If tangent is parallel to normal, create arbitrary tangent - create_orthonormal_basis(n, tangent, bitangents[i]); - } else { - tangent /= length; - } - - // Check handedness - Real handedness = glm::dot(glm::cross(n, t), bitangents[i]); - if (handedness < 0.0f) { - tangent = -tangent; - } - - vertices_[i].tangent_ = tangent; - } -} - -bool Mesh::get_triangle(size_t triangle_index, Vertex& v0, Vertex& v1, Vertex& v2) const { - if (triangle_index >= get_triangle_count()) { - return false; - } - - size_t base_index = triangle_index * 3; - uint32_t i0 = indices_[base_index]; - uint32_t i1 = indices_[base_index + 1]; - uint32_t i2 = indices_[base_index + 2]; - - if (i0 >= vertices_.size() || i1 >= vertices_.size() || i2 >= vertices_.size()) { - ARE_LOG_ERROR("Mesh: Invalid indices in get_triangle"); - return false; - } - - v0 = vertices_[i0]; - v1 = vertices_[i1]; - v2 = vertices_[i2]; - - return true; -} - -} // namespace are diff --git a/src/scene/point_light.cpp b/src/scene/point_light.cpp deleted file mode 100644 index 5a51b24..0000000 --- a/src/scene/point_light.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file point_light.cpp - * @brief Implementation of PointLight class - */ - -#include -#include -#include - -namespace are { - -PointLight::PointLight() - : Light(LightType::ARE_LIGHT_POINT) - , position_(0.0f) - , range_(10.0f) - , attenuation_constant_(1.0f) - , attenuation_linear_(0.09f) - , attenuation_quadratic_(0.032f) { -} - -PointLight::PointLight(const Vec3& position, const Vec3& color, Real intensity, Real range) - : Light(LightType::ARE_LIGHT_POINT) - , position_(position) - , range_(range) - , attenuation_constant_(1.0f) - , attenuation_linear_(0.09f) - , attenuation_quadratic_(0.032f) { - set_color(color); - set_intensity(intensity); - set_range(range); -} - -void PointLight::set_position(const Vec3& position) { - position_ = position; -} - -void PointLight::set_range(Real range) { - if (range <= 0.0f) { - ARE_LOG_WARN("PointLight: Invalid range (must be positive), using default"); - range_ = 10.0f; - } else { - range_ = range; - } -} - -void PointLight::set_attenuation(Real constant, Real linear, Real quadratic) { - attenuation_constant_ = std::max(0.0f, constant); - attenuation_linear_ = std::max(0.0f, linear); - attenuation_quadratic_ = std::max(0.0f, quadratic); - - // Ensure at least some attenuation to avoid division issues - if (attenuation_constant_ < are_epsilon && - attenuation_linear_ < are_epsilon && - attenuation_quadratic_ < are_epsilon) { - ARE_LOG_WARN("PointLight: All attenuation factors near zero, setting constant to 1.0"); - attenuation_constant_ = 1.0f; - } -} - -Real PointLight::calculate_attenuation(Real distance) const { - // Standard attenuation formula: 1 / (constant + linear*d + quadratic*d^2) - Real attenuation = attenuation_constant_ + - attenuation_linear_ * distance + - attenuation_quadratic_ * distance * distance; - return 1.0f / std::max(attenuation, are_epsilon); -} - -LightData PointLight::pack() const { - LightData data; - - // position_type_: xyz = position, w = light type - data.position_type_ = Vec4(position_, - static_cast(LightType::ARE_LIGHT_POINT)); - - // direction_range_: xyz unused for point light, w = range - data.direction_range_ = Vec4(0.0f, 0.0f, 0.0f, range_); - - // color_intensity_: xyz = color, w = intensity - data.color_intensity_ = Vec4(color_, intensity_); - - // params_: x = cast_shadows, y = constant, z = linear, w = quadratic - data.params_ = Vec4( - cast_shadows_ ? 1.0f : 0.0f, - attenuation_constant_, - attenuation_linear_, - attenuation_quadratic_ - ); - - return data; -} - -bool PointLight::affects_point(const Vec3& point) const { - Real distance = glm::length(point - position_); - return distance <= range_; -} - -} // namespace are diff --git a/src/scene/scene_manager.cpp b/src/scene/scene_manager.cpp deleted file mode 100644 index c198af3..0000000 --- a/src/scene/scene_manager.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/** - * @file scene_manager.cpp - * @brief Implementation of SceneManager class - */ - -#include -#include -#include - -namespace are { - -SceneManager::SceneManager() - : next_mesh_handle_(1) - , next_material_handle_(1) - , next_light_handle_(1) - , dirty_(false) { -} - -SceneManager::~SceneManager() { - clear(); -} - -MeshHandle SceneManager::add_mesh(const Mesh &mesh) { - ARE_PROFILE_FUNCTION(); - - if (mesh.is_empty()) { - ARE_LOG_WARN("SceneManager: Attempting to add empty mesh"); - return are_invalid_handle; - } - - MeshHandle handle = next_mesh_handle_++; - meshes_.push_back(mesh); - mesh_handle_map_[handle] = meshes_.size() - 1; - - dirty_ = true; - - ARE_LOG_DEBUG("SceneManager: Added mesh with handle " + std::to_string(handle)); - return handle; -} - -void SceneManager::remove_mesh(MeshHandle handle) { - ARE_PROFILE_FUNCTION(); - - auto it = mesh_handle_map_.find(handle); - if (it == mesh_handle_map_.end()) { - ARE_LOG_WARN("SceneManager: Attempting to remove invalid mesh handle"); - return; - } - - size_t index = it->second; - - // Swap with last element and pop - if (index < meshes_.size() - 1) { - meshes_[index] = meshes_.back(); - - // Update handle map for swapped element - for (auto &pair : mesh_handle_map_) { - if (pair.second == meshes_.size() - 1) { - pair.second = index; - break; - } - } - } - - meshes_.pop_back(); - mesh_handle_map_.erase(it); - - dirty_ = true; - - ARE_LOG_DEBUG("SceneManager: Removed mesh with handle " + std::to_string(handle)); -} - -void SceneManager::update_mesh(MeshHandle handle, const Mesh &mesh) { - ARE_PROFILE_FUNCTION(); - - Mesh *existing = get_mesh(handle); - if (!existing) { - ARE_LOG_WARN("SceneManager: Attempting to update invalid mesh handle"); - return; - } - - *existing = mesh; - dirty_ = true; -} - -Mesh *SceneManager::get_mesh(MeshHandle handle) { - auto it = mesh_handle_map_.find(handle); - if (it == mesh_handle_map_.end()) { - return nullptr; - } - - size_t index = it->second; - if (index >= meshes_.size()) { - ARE_LOG_ERROR("SceneManager: Mesh handle map corrupted"); - return nullptr; - } - - return &meshes_[index]; -} - -const Mesh *SceneManager::get_mesh(MeshHandle handle) const { - auto it = mesh_handle_map_.find(handle); - if (it == mesh_handle_map_.end()) { - return nullptr; - } - - size_t index = it->second; - if (index >= meshes_.size()) { - ARE_LOG_ERROR("SceneManager: Mesh handle map corrupted"); - return nullptr; - } - - return &meshes_[index]; -} - -MaterialHandle SceneManager::add_material(const Material &material) { - ARE_PROFILE_FUNCTION(); - - MaterialHandle handle = next_material_handle_++; - materials_.push_back(material); - material_handle_map_[handle] = materials_.size() - 1; - - ARE_LOG_DEBUG("SceneManager: Added material with handle " + std::to_string(handle)); - return handle; -} - -void SceneManager::remove_material(MaterialHandle handle) { - ARE_PROFILE_FUNCTION(); - - auto it = material_handle_map_.find(handle); - if (it == material_handle_map_.end()) { - ARE_LOG_WARN("SceneManager: Attempting to remove invalid material handle"); - return; - } - - size_t index = it->second; - - // Swap with last element and pop - if (index < materials_.size() - 1) { - materials_[index] = materials_.back(); - - // Update handle map for swapped element - for (auto &pair : material_handle_map_) { - if (pair.second == materials_.size() - 1) { - pair.second = index; - break; - } - } - } - - materials_.pop_back(); - material_handle_map_.erase(it); - - ARE_LOG_DEBUG("SceneManager: Removed material with handle " + std::to_string(handle)); -} - -void SceneManager::update_material(MaterialHandle handle, const Material &material) { - ARE_PROFILE_FUNCTION(); - - Material *existing = get_material(handle); - if (!existing) { - ARE_LOG_WARN("SceneManager: Attempting to update invalid material handle"); - return; - } - - *existing = material; -} - -Material *SceneManager::get_material(MaterialHandle handle) { - auto it = material_handle_map_.find(handle); - if (it == material_handle_map_.end()) { - return nullptr; - } - - size_t index = it->second; - if (index >= materials_.size()) { - ARE_LOG_ERROR("SceneManager: Material handle map corrupted"); - return nullptr; - } - - return &materials_[index]; -} - -const Material *SceneManager::get_material(MaterialHandle handle) const { - auto it = material_handle_map_.find(handle); - if (it == material_handle_map_.end()) { - return nullptr; - } - - size_t index = it->second; - if (index >= materials_.size()) { - ARE_LOG_ERROR("SceneManager: Material handle map corrupted"); - return nullptr; - } - - return &materials_[index]; -} - -LightHandle SceneManager::add_light(const std::shared_ptr &light) { - ARE_PROFILE_FUNCTION(); - - if (!light) { - ARE_LOG_WARN("SceneManager: Attempting to add null light"); - return are_invalid_handle; - } - - LightHandle handle = next_light_handle_++; - lights_.push_back(light); - light_handle_map_[handle] = lights_.size() - 1; - - dirty_ = true; - - ARE_LOG_DEBUG("SceneManager: Added light with handle " + std::to_string(handle)); - return handle; -} - -void SceneManager::remove_light(LightHandle handle) { - ARE_PROFILE_FUNCTION(); - - auto it = light_handle_map_.find(handle); - if (it == light_handle_map_.end()) { - ARE_LOG_WARN("SceneManager: Attempting to remove invalid light handle"); - return; - } - - size_t index = it->second; - - // Swap with last element and pop - if (index < lights_.size() - 1) { - lights_[index] = lights_.back(); - - // Update handle map for swapped element - for (auto &pair : light_handle_map_) { - if (pair.second == lights_.size() - 1) { - pair.second = index; - break; - } - } - } - - lights_.pop_back(); - light_handle_map_.erase(it); - - dirty_ = true; - - ARE_LOG_DEBUG("SceneManager: Removed light with handle " + std::to_string(handle)); -} - -std::shared_ptr SceneManager::get_light(LightHandle handle) { - auto it = light_handle_map_.find(handle); - if (it == light_handle_map_.end()) { - return nullptr; - } - - size_t index = it->second; - if (index >= lights_.size()) { - ARE_LOG_ERROR("SceneManager: Light handle map corrupted"); - return nullptr; - } - - return lights_[index]; -} - -size_t SceneManager::get_total_triangle_count() const { - ARE_PROFILE_FUNCTION(); - - size_t total = 0; - for (const auto &mesh : meshes_) { - total += mesh.get_triangle_count(); - } - return total; -} - -void SceneManager::clear() { - ARE_PROFILE_FUNCTION(); - - meshes_.clear(); - materials_.clear(); - lights_.clear(); - - mesh_handle_map_.clear(); - material_handle_map_.clear(); - light_handle_map_.clear(); - - next_mesh_handle_ = 1; - next_material_handle_ = 1; - next_light_handle_ = 1; - - dirty_ = true; - - ARE_LOG_INFO("SceneManager: Cleared all scene data"); -} - -void SceneManager::compact() { - ARE_PROFILE_FUNCTION(); - - // Remove invalid entries (this is a placeholder for future optimization) - // Currently, the handle-based system ensures no invalid entries exist - - ARE_LOG_DEBUG("SceneManager: Compacted scene data"); -} - -} // namespace are diff --git a/src/scene/spot_light.cpp b/src/scene/spot_light.cpp deleted file mode 100644 index 2adab35..0000000 --- a/src/scene/spot_light.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @file spot_light.cpp - * @brief Implementation of SpotLight class - */ - -#include -#include -#include -#include - -namespace are { - -SpotLight::SpotLight() - : Light(LightType::ARE_LIGHT_SPOT) - , position_(0.0f) - , direction_(0.0f, -1.0f, 0.0f) - , inner_angle_(30.0f) - , outer_angle_(45.0f) - , range_(10.0f) - , cos_inner_(std::cos(degrees_to_radians(30.0f))) - , cos_outer_(std::cos(degrees_to_radians(45.0f))) { -} - -SpotLight::SpotLight(const Vec3& position, const Vec3& direction, - Real inner_angle, Real outer_angle, - const Vec3& color, Real intensity) - : Light(LightType::ARE_LIGHT_SPOT) - , position_(position) - , range_(10.0f) { - set_direction(direction); - set_inner_angle(inner_angle); - set_outer_angle(outer_angle); - set_color(color); - set_intensity(intensity); -} - -void SpotLight::set_position(const Vec3& position) { - position_ = position; -} - -void SpotLight::set_direction(const Vec3& direction) { - Real length = glm::length(direction); - if (length < are_epsilon) { - ARE_LOG_WARN("SpotLight: Invalid direction vector (zero length), using default"); - direction_ = Vec3(0.0f, -1.0f, 0.0f); - } else { - direction_ = direction / length; - } -} - -void SpotLight::set_inner_angle(Real angle) { - // Clamp to valid range [0, 90] degrees - inner_angle_ = clamp(angle, 0.0f, 90.0f); - cos_inner_ = std::cos(degrees_to_radians(inner_angle_)); - - // Ensure inner angle is not larger than outer angle - if (inner_angle_ > outer_angle_) { - ARE_LOG_WARN("SpotLight: Inner angle larger than outer angle, adjusting outer angle"); - outer_angle_ = inner_angle_; - cos_outer_ = cos_inner_; - } -} - -void SpotLight::set_outer_angle(Real angle) { - // Clamp to valid range [0, 90] degrees - outer_angle_ = clamp(angle, 0.0f, 90.0f); - cos_outer_ = std::cos(degrees_to_radians(outer_angle_)); - - // Ensure outer angle is not smaller than inner angle - if (outer_angle_ < inner_angle_) { - ARE_LOG_WARN("SpotLight: Outer angle smaller than inner angle, adjusting inner angle"); - inner_angle_ = outer_angle_; - cos_inner_ = cos_outer_; - } -} - -void SpotLight::set_range(Real range) { - if (range <= 0.0f) { - ARE_LOG_WARN("SpotLight: Invalid range (must be positive), using default"); - range_ = 10.0f; - } else { - range_ = range; - } -} - -Real SpotLight::calculate_spot_factor(const Vec3& to_point) const { - // Calculate angle between light direction and direction to point - Real cos_angle = glm::dot(direction_, glm::normalize(to_point)); - - // Outside outer cone - if (cos_angle < cos_outer_) { - return 0.0f; - } - - // Inside inner cone - if (cos_angle > cos_inner_) { - return 1.0f; - } - - // Smooth transition between inner and outer cone - Real delta = cos_inner_ - cos_outer_; - if (delta < are_epsilon) { - return 1.0f; - } - - return (cos_angle - cos_outer_) / delta; -} - -LightData SpotLight::pack() const { - LightData data; - - // position_type_: xyz = position, w = light type - data.position_type_ = Vec4(position_, - static_cast(LightType::ARE_LIGHT_SPOT)); - - // direction_range_: xyz = direction, w = range - data.direction_range_ = Vec4(direction_, range_); - - // color_intensity_: xyz = color, w = intensity - data.color_intensity_ = Vec4(color_, intensity_); - - // params_: x = cast_shadows, y = cos_inner, z = cos_outer, w unused - data.params_ = Vec4( - cast_shadows_ ? 1.0f : 0.0f, - cos_inner_, - cos_outer_, - 0.0f - ); - - return data; -} - -bool SpotLight::affects_point(const Vec3& point) const { - // Check if point is within range - Vec3 to_point = point - position_; - Real distance = glm::length(to_point); - - if (distance > range_) { - return false; - } - - // Check if point is within spotlight cone - if (distance > are_epsilon) { - to_point /= distance; - Real cos_angle = glm::dot(direction_, to_point); - return cos_angle >= cos_outer_; - } - - return true; -} - -} // namespace are diff --git a/src/utils/file_utils.cpp b/src/utils/file_utils.cpp deleted file mode 100644 index 343c3ed..0000000 --- a/src/utils/file_utils.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/** - * @file file_utils.cpp - * @brief Implementation of file system utilities - */ - -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 - #include - #define MKDIR(path) _mkdir(path) -#else - #include - #define MKDIR(path) mkdir(path, 0755) -#endif - -namespace are { - -std::string read_file_to_string(const std::string& filepath) { - std::ifstream file(filepath, std::ios::in | std::ios::binary); - - if (!file.is_open()) { - ARE_LOG_ERROR("Failed to open file: " + filepath); - return ""; - } - - std::stringstream buffer; - buffer << file.rdbuf(); - file.close(); - - return buffer.str(); -} - -std::vector read_file_to_bytes(const std::string& filepath) { - std::ifstream file(filepath, std::ios::in | std::ios::binary); - - if (!file.is_open()) { - ARE_LOG_ERROR("Failed to open file: " + filepath); - return {}; - } - - // Get file size - file.seekg(0, std::ios::end); - size_t size = file.tellg(); - file.seekg(0, std::ios::beg); - - // Read data - std::vector data(size); - file.read(reinterpret_cast(data.data()), size); - file.close(); - - return data; -} - -bool write_string_to_file(const std::string& filepath, const std::string& content) { - std::ofstream file(filepath, std::ios::out | std::ios::binary); - - if (!file.is_open()) { - ARE_LOG_ERROR("Failed to open file for writing: " + filepath); - return false; - } - - file << content; - file.close(); - - return true; -} - -bool write_bytes_to_file(const std::string& filepath, const void* data, size_t size) { - std::ofstream file(filepath, std::ios::out | std::ios::binary); - - if (!file.is_open()) { - ARE_LOG_ERROR("Failed to open file for writing: " + filepath); - return false; - } - - file.write(static_cast(data), size); - file.close(); - - return true; -} - -bool file_exists(const std::string& filepath) { - struct stat buffer; - return (stat(filepath.c_str(), &buffer) == 0); -} - -bool is_directory(const std::string& path) { - struct stat buffer; - if (stat(path.c_str(), &buffer) != 0) { - return false; - } - return (buffer.st_mode & S_IFDIR) != 0; -} - -bool create_directory(const std::string& path) { - if (path.empty()) { - return false; - } - - if (is_directory(path)) { - return true; - } - - // Create parent directories recursively - size_t pos = 0; - std::string current_path; - - while ((pos = path.find_first_of("/\\", pos)) != std::string::npos) { - current_path = path.substr(0, pos++); - - if (!current_path.empty() && !is_directory(current_path)) { - if (MKDIR(current_path.c_str()) != 0 && !is_directory(current_path)) { - ARE_LOG_ERROR("Failed to create directory: " + current_path); - return false; - } - } - } - - // Create final directory - if (MKDIR(path.c_str()) != 0 && !is_directory(path)) { - ARE_LOG_ERROR("Failed to create directory: " + path); - return false; - } - - return true; -} - -std::string get_file_extension(const std::string& filepath) { - size_t dot_pos = filepath.find_last_of('.'); - - if (dot_pos == std::string::npos || dot_pos == filepath.length() - 1) { - return ""; - } - - std::string ext = filepath.substr(dot_pos + 1); - - // Convert to lowercase - std::transform(ext.begin(), ext.end(), ext.begin(), - [](unsigned char c) { return std::tolower(c); }); - - return ext; -} - -std::string get_filename(const std::string& filepath) { - size_t slash_pos = filepath.find_last_of("/\\"); - - if (slash_pos == std::string::npos) { - return filepath; - } - - return filepath.substr(slash_pos + 1); -} - -std::string get_directory(const std::string& filepath) { - size_t slash_pos = filepath.find_last_of("/\\"); - - if (slash_pos == std::string::npos) { - return ""; - } - - return filepath.substr(0, slash_pos); -} - -std::string join_path(const std::vector& parts) { - if (parts.empty()) { - return ""; - } - - std::string result = parts[0]; - - for (size_t i = 1; i < parts.size(); ++i) { - if (!result.empty() && result.back() != '/' && result.back() != '\\') { - result += '/'; - } - result += parts[i]; - } - - return result; -} - -std::string normalize_path(const std::string& path) { - if (path.empty()) { - return ""; - } - - std::vector components; - std::string current; - - for (char c : path) { - if (c == '/' || c == '\\') { - if (!current.empty()) { - if (current == "..") { - if (!components.empty() && components.back() != "..") { - components.pop_back(); - } else { - components.push_back(current); - } - } else if (current != ".") { - components.push_back(current); - } - current.clear(); - } - } else { - current += c; - } - } - - if (!current.empty()) { - if (current == "..") { - if (!components.empty() && components.back() != "..") { - components.pop_back(); - } else { - components.push_back(current); - } - } else if (current != ".") { - components.push_back(current); - } - } - - return join_path(components); -} - -} // namespace are diff --git a/src/utils/image_io.cpp b/src/utils/image_io.cpp deleted file mode 100644 index 1372697..0000000 --- a/src/utils/image_io.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/** - * @file image_io.cpp - * @brief Implementation of image I/O utilities - */ - -#include -#include -#include -#include -#include -#include - -#define STB_IMAGE_IMPLEMENTATION -#include - -#define STB_IMAGE_WRITE_IMPLEMENTATION -#include - -namespace are { - -bool ImageData::is_valid() const { - return width_ > 0 && height_ > 0 && channels_ > 0 && !data_.empty(); -} - -const uint8_t* ImageData::get_pixel(int x, int y) const { - if (x < 0 || x >= width_ || y < 0 || y >= height_) { - return nullptr; - } - - size_t index = (y * width_ + x) * channels_; - return &data_[index]; -} - -void ImageData::set_pixel(int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - if (x < 0 || x >= width_ || y < 0 || y >= height_) { - return; - } - - size_t index = (y * width_ + x) * channels_; - - data_[index + 0] = r; - data_[index + 1] = g; - data_[index + 2] = b; - - if (channels_ == 4) { - data_[index + 3] = a; - } -} - -ImageData load_image(const std::string& filename, bool flip_vertically) { - ImageData image; - - // Set flip flag - stbi_set_flip_vertically_on_load(flip_vertically ? 1 : 0); - - // Load image - int width, height, channels; - unsigned char* data = stbi_load(filename.c_str(), &width, &height, &channels, 0); - - if (!data) { - ARE_LOG_ERROR("Failed to load image: " + filename + " - " + stbi_failure_reason()); - return image; - } - - // Copy data to ImageData - image.width_ = width; - image.height_ = height; - image.channels_ = channels; - - size_t data_size = width * height * channels; - image.data_.resize(data_size); - std::memcpy(image.data_.data(), data, data_size); - - // Free stb_image data - stbi_image_free(data); - - ARE_LOG_INFO("Loaded image: " + filename + " (" + - std::to_string(width) + "x" + std::to_string(height) + - ", " + std::to_string(channels) + " channels)"); - - return image; -} - -ImageFormat detect_format(const std::string& filename) { - std::string ext; - size_t dot_pos = filename.find_last_of('.'); - - if (dot_pos != std::string::npos) { - ext = filename.substr(dot_pos + 1); - - // Convert to lowercase - std::transform(ext.begin(), ext.end(), ext.begin(), - [](unsigned char c) { return std::tolower(c); }); - } - - if (ext == "ppm") return ImageFormat::ARE_IMAGE_FORMAT_PPM; - if (ext == "bmp") return ImageFormat::ARE_IMAGE_FORMAT_BMP; - if (ext == "png") return ImageFormat::ARE_IMAGE_FORMAT_PNG; - if (ext == "jpg" || ext == "jpeg") return ImageFormat::ARE_IMAGE_FORMAT_JPG; - - // Default to PNG - return ImageFormat::ARE_IMAGE_FORMAT_PNG; -} - -bool save_image(const std::string& filename, const ImageData& data, ImageFormat format) { - if (!data.is_valid()) { - ARE_LOG_ERROR("Cannot save invalid image data"); - return false; - } - - // Auto-detect format if not specified - if (format == ImageFormat::ARE_IMAGE_FORMAT_PNG) { - format = detect_format(filename); - } - - int result = 0; - - switch (format) { - case ImageFormat::ARE_IMAGE_FORMAT_PPM: { - // Write PPM manually (stb doesn't support it) - std::ofstream file(filename, std::ios::binary); - if (!file.is_open()) { - ARE_LOG_ERROR("Failed to open file for writing: " + filename); - return false; - } - - file << "P6\n" << data.width_ << " " << data.height_ << "\n255\n"; - - for (int i = 0; i < data.width_ * data.height_; ++i) { - int idx = i * data.channels_; - file.put(data.data_[idx + 0]); // R - file.put(data.data_[idx + 1]); // G - file.put(data.data_[idx + 2]); // B - } - - file.close(); - result = 1; - break; - } - - case ImageFormat::ARE_IMAGE_FORMAT_BMP: - result = stbi_write_bmp(filename.c_str(), data.width_, data.height_, - data.channels_, data.data_.data()); - break; - - case ImageFormat::ARE_IMAGE_FORMAT_PNG: - result = stbi_write_png(filename.c_str(), data.width_, data.height_, - data.channels_, data.data_.data(), - data.width_ * data.channels_); - break; - - case ImageFormat::ARE_IMAGE_FORMAT_JPG: - result = stbi_write_jpg(filename.c_str(), data.width_, data.height_, - data.channels_, data.data_.data(), 90); - break; - } - - if (result == 0) { - ARE_LOG_ERROR("Failed to save image: " + filename); - return false; - } - - ARE_LOG_INFO("Saved image: " + filename); - return true; -} - -bool save_image(const std::string& filename, const uint8_t* pixels, - int width, int height, int channels, ImageFormat format) { - ImageData data; - data.width_ = width; - data.height_ = height; - data.channels_ = channels; - - size_t data_size = width * height * channels; - data.data_.resize(data_size); - std::memcpy(data.data_.data(), pixels, data_size); - - return save_image(filename, data, format); -} - -} // namespace are diff --git a/src/utils/math_utils.cpp b/src/utils/math_utils.cpp deleted file mode 100644 index d0685e5..0000000 --- a/src/utils/math_utils.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @file math_utils.cpp - * @brief Implementation of mathematical utility functions - */ - -#include -#include -#include - -namespace are { - -void compute_barycentric(const Vec3& p, const Vec3& a, const Vec3& b, const Vec3& c, - Real& u, Real& v, Real& w) { - Vec3 v0 = b - a; - Vec3 v1 = c - a; - Vec3 v2 = p - a; - - Real d00 = glm::dot(v0, v0); - Real d01 = glm::dot(v0, v1); - Real d11 = glm::dot(v1, v1); - Real d20 = glm::dot(v2, v0); - Real d21 = glm::dot(v2, v1); - - Real denom = d00 * d11 - d01 * d01; - - if (std::abs(denom) < are_epsilon) { - // Degenerate triangle - u = v = w = 1.0f / 3.0f; - return; - } - - v = (d11 * d20 - d01 * d21) / denom; - w = (d00 * d21 - d01 * d20) / denom; - u = 1.0f - v - w; -} - -Vec3 reflect(const Vec3& incident, const Vec3& normal) { - return incident - 2.0f * glm::dot(incident, normal) * normal; -} - -bool refract(const Vec3& incident, const Vec3& normal, Real eta, Vec3& refracted) { - Real cos_theta = glm::dot(-incident, normal); - Real sin_theta_sq = 1.0f - cos_theta * cos_theta; - Real sin_theta_t_sq = eta * eta * sin_theta_sq; - - // Total internal reflection - if (sin_theta_t_sq > 1.0f) { - return false; - } - - Real cos_theta_t = std::sqrt(1.0f - sin_theta_t_sq); - refracted = eta * incident + (eta * cos_theta - cos_theta_t) * normal; - - return true; -} - -Real fresnel_schlick(Real cos_theta, Real f0) { - Real f = 1.0f - cos_theta; - Real f2 = f * f; - Real f5 = f2 * f2 * f; - return f0 + (1.0f - f0) * f5; -} - -void create_orthonormal_basis(const Vec3& normal, Vec3& tangent, Vec3& bitangent) { - // Choose a vector not parallel to normal - Vec3 up = (std::abs(normal.y) < 0.999f) ? Vec3(0, 1, 0) : Vec3(1, 0, 0); - - tangent = glm::normalize(glm::cross(up, normal)); - bitangent = glm::cross(normal, tangent); -} - -Vec3 tangent_to_world(const Vec3& tangent_dir, const Vec3& normal, - const Vec3& tangent, const Vec3& bitangent) { - return tangent_dir.x * tangent + - tangent_dir.y * bitangent + - tangent_dir.z * normal; -} - -} // namespace are diff --git a/src/utils/random.cpp b/src/utils/random.cpp deleted file mode 100644 index a3e7594..0000000 --- a/src/utils/random.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file random.cpp - * @brief Implementation of random number generation - */ - -#include -#include -#include -#include - -namespace are { - -RandomGenerator::RandomGenerator(uint64_t seed) - : dist_(0.0f, 1.0f) { - if (seed == 0) { - std::random_device rd; - seed = rd(); - } - rng_.seed(seed); -} - -Real RandomGenerator::random_float() { - return dist_(rng_); -} - -Real RandomGenerator::random_float(Real min, Real max) { - return min + (max - min) * random_float(); -} - -int RandomGenerator::random_int(int min, int max) { - std::uniform_int_distribution int_dist(min, max); - return int_dist(rng_); -} - -Vec3 RandomGenerator::random_in_unit_disk() { - while (true) { - Vec3 p(random_float(-1.0f, 1.0f), random_float(-1.0f, 1.0f), 0.0f); - if (glm::dot(p, p) < 1.0f) { - return p; - } - } -} - -Vec3 RandomGenerator::random_in_unit_sphere() { - while (true) { - Vec3 p(random_float(-1.0f, 1.0f), - random_float(-1.0f, 1.0f), - random_float(-1.0f, 1.0f)); - if (glm::dot(p, p) < 1.0f) { - return p; - } - } -} - -Vec3 RandomGenerator::random_unit_vector() { - return glm::normalize(random_in_unit_sphere()); -} - -Vec3 RandomGenerator::random_in_hemisphere(const Vec3& normal) { - Vec3 in_unit_sphere = random_in_unit_sphere(); - if (glm::dot(in_unit_sphere, normal) > 0.0f) { - return in_unit_sphere; - } else { - return -in_unit_sphere; - } -} - -Vec3 RandomGenerator::random_cosine_direction(const Vec3& normal) { - // Generate random direction with cosine-weighted distribution - Real r1 = random_float(); - Real r2 = random_float(); - - Real phi = 2.0f * glm::pi() * r1; - Real cos_theta = std::sqrt(r2); - Real sin_theta = std::sqrt(1.0f - r2); - - Vec3 local_dir( - std::cos(phi) * sin_theta, - std::sin(phi) * sin_theta, - cos_theta - ); - - // Transform to world space - Vec3 tangent, bitangent; - Vec3 up = (std::abs(normal.y) < 0.999f) ? Vec3(0, 1, 0) : Vec3(1, 0, 0); - tangent = glm::normalize(glm::cross(up, normal)); - bitangent = glm::cross(normal, tangent); - - return local_dir.x * tangent + local_dir.y * bitangent + local_dir.z * normal; -} - -void RandomGenerator::set_seed(uint64_t seed) { - rng_.seed(seed); -} - -// Thread-local random generator -RandomGenerator& get_thread_random() { - thread_local RandomGenerator generator; - return generator; -} - -} // namespace are diff --git a/write.sh b/write.sh deleted file mode 100644 index b622c6c..0000000 --- a/write.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -# query.sh - 遍历指定文件夹中的 .h 文件并生成 all_headers.md - -# 检查是否提供了目录参数 -if [ $# -ne 1 ]; then - echo "用法: $0 <目标文件夹路径>" - exit 1 -fi - -TARGET_DIR="$1" - -# 检查提供的路径是否为一个存在的目录 -if [ ! -d "$TARGET_DIR" ]; then - echo "错误: 目录 '$TARGET_DIR' 不存在。" - exit 1 -fi - -# 输出文件 -OUTPUT_FILE="all_headers.md" - -# 清空或创建输出文件 -> "$OUTPUT_FILE" - -echo "正在扫描目录: $TARGET_DIR" -# 使用 find 命令查找所有 .h 文件 -H_FILES=$(find "$TARGET_DIR" -type f -name "*.h") - -# 检查是否找到了 .h 文件 -if [ -z "$H_FILES" ]; then - echo "在目录 '$TARGET_DIR' 及其子目录中未找到任何 .h 文件。" - exit 0 -fi - -# 遍历找到的每个 .h 文件 -for header_file in $H_FILES; do - # 获取相对于脚本执行位置的相对路径 - RELATIVE_PATH=$(realpath --relative-to=. "$header_file") - - # 写入分隔符和文件名 - { - echo "### 文件:$RELATIVE_PATH" - echo "" - echo '```cpp' - cat "$header_file" - echo '```' - echo "" # 添加一个空行,使文件之间有分隔 - } >> "$OUTPUT_FILE" - - echo "已处理: $RELATIVE_PATH" -done - -echo "" -echo "处理完成!所有头文件内容已合并到 $OUTPUT_FILE 中。"