WIP: Rewrite with LLGL
This commit is contained in:
parent
002d97ee27
commit
f337ff9f0d
24 changed files with 377 additions and 390 deletions
|
@ -1,15 +1,23 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
project(cigui
|
||||
VERSION 0.0.1
|
||||
LANGUAGES CXX)
|
||||
LANGUAGES CXX C)
|
||||
|
||||
# Options
|
||||
option(CIGUI_BUILD_SHARED "Build CIGUI as a shared library" ON)
|
||||
option(CIGUI_BUILD_SHARED "Build CIGUI as a shared library" OFF)
|
||||
option(CIGUI_BUILD_EXAMPLES "Build example applications" ON)
|
||||
option(CIGUI_BUILD_TESTS "Build tests" OFF)
|
||||
option(CIGUI_ENABLE_ASAN "Enable Address Sanitizer (Debug)" OFF)
|
||||
option(CIGUI_ENABLE_UBSAN "Enable Undefined Behavior Sanitizer (Debug)" OFF)
|
||||
option(CIGUI_ENABLE_WARNINGS "Enable additional compiler warnings" ON)
|
||||
|
||||
option(CIGUI_ENABLE_ASAN "Enable Address Sanitizer (Debug)" ON)
|
||||
option(CIGUI_ENABLE_UBSAN "Enable Undefined Behavior Sanitizer (Debug)" ON)
|
||||
option(CIGUI_ENABLE_WARNINGS "Enable additional compiler warnings" OFF)
|
||||
|
||||
option(CIGUI_RENDERER_VULKAN "Use Vulkan renderer (if available)" ON)
|
||||
option(CIGUI_RENDERER_OPENGL "Use OpenGL renderer (if available)" ON)
|
||||
option(CIGUI_RENDERER_DIRECT3D11 "Use Direct3D 11 renderer (if available on Windows)" OFF)
|
||||
option(CIGUI_RENDERER_DIRECT3D12 "Use Direct3D 12 renderer (if available on Windows)" ON)
|
||||
option(CIGUI_RENDERER_METAL "Use Metal renderer (if available on macOS)" ON)
|
||||
|
||||
|
||||
|
||||
# Set C++ standard
|
||||
|
@ -60,19 +68,62 @@ if(CIGUI_BUILD_SHARED)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
# Include CPM.cmake for dependency management
|
||||
include(cmake/CPM.cmake)
|
||||
# Function to find all libraries in a directory
|
||||
function(link_libraries_in_directory target directory)
|
||||
# Find all library files based on platform
|
||||
if(WIN32)
|
||||
file(GLOB LIBRARIES "${directory}/*.lib")
|
||||
elseif(APPLE)
|
||||
file(GLOB LIBRARIES "${directory}/*.dylib" "${directory}/*.a")
|
||||
else() # Linux and others
|
||||
file(GLOB LIBRARIES "${directory}/*.so" "${directory}/*.a")
|
||||
endif()
|
||||
|
||||
# Link each found library
|
||||
foreach(LIB ${LIBRARIES})
|
||||
target_link_libraries(${target} PRIVATE ${LIB})
|
||||
message(STATUS "Linking with library: ${LIB}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# Add SFML dependency using CPM
|
||||
CPMAddPackage(
|
||||
NAME SFML
|
||||
GITHUB_REPOSITORY SFML/SFML
|
||||
GIT_TAG 3.0.0 # Adjust to actual SFML 3 version/tag
|
||||
OPTIONS
|
||||
"SFML_BUILD_AUDIO OFF"
|
||||
"SFML_BUILD_NETWORK OFF"
|
||||
"CMAKE_DEBUG_POSTFIX -d" # Add debug postfix for debug builds
|
||||
)
|
||||
|
||||
set(LIB_LLGL_PATH "W:/Jann/aLibs/LLGLVD" CACHE STRING "The path to the LLGL installation")
|
||||
|
||||
set(LLGL_PATH "${LIB_LLGL_PATH}/lib/cmake/LLGL")
|
||||
|
||||
set(LLGL_LIB_PATH "${LIB_LLGL_PATH}/lib")
|
||||
set(LLGL_BIN_PATH "${LIB_LLGL_PATH}/bin")
|
||||
set(LLGL_INCLUDE_PATH "${LIB_LLGL_PATH}/include")
|
||||
set(LLGL_CMAKE_PATH "${LIB_LLGL_PATH}/lib/cmake/LLGL")
|
||||
|
||||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "${LLGL_PATH}")
|
||||
|
||||
# Add LLGL dependency
|
||||
find_package(LLGL REQUIRED HINTS ${LLGL_CMAKE_PATH})
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
# Configure renderer backends based on platform and options
|
||||
if(WIN32)
|
||||
if(CIGUI_RENDERER_DIRECT3D11)
|
||||
add_definitions(-DCIGUI_RENDERER_D3D11)
|
||||
endif()
|
||||
if(CIGUI_RENDERER_DIRECT3D12)
|
||||
add_definitions(-DCIGUI_RENDERER_D3D12)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CIGUI_RENDERER_OPENGL)
|
||||
add_definitions(-DCIGUI_RENDERER_OPENGL)
|
||||
endif()
|
||||
|
||||
if(CIGUI_RENDERER_VULKAN)
|
||||
add_definitions(-DCIGUI_RENDERER_VULKAN)
|
||||
endif()
|
||||
|
||||
if(APPLE AND CIGUI_RENDERER_METAL)
|
||||
add_definitions(-DCIGUI_RENDERER_METAL)
|
||||
endif()
|
||||
|
||||
# Generate export macros
|
||||
include(GenerateExportHeader)
|
||||
|
@ -88,15 +139,15 @@ else()
|
|||
add_library(cigui STATIC)
|
||||
endif()
|
||||
|
||||
link_libraries_in_directory(cigui ${LLGL_LIB_PATH})
|
||||
target_include_directories(cigui PUBLIC ${LLGL_INCLUDE_PATH})
|
||||
|
||||
# Enable precompiled headers for faster builds
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16)
|
||||
target_precompile_headers(cigui PRIVATE
|
||||
<string>
|
||||
<memory>
|
||||
<functional>
|
||||
<SFML/Graphics.hpp>
|
||||
<SFML/Window.hpp>
|
||||
<SFML/System.hpp>
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -116,9 +167,6 @@ target_include_directories(cigui
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Link with SFML
|
||||
target_link_libraries(cigui PUBLIC sfml-graphics sfml-window sfml-system)
|
||||
|
||||
# Define installation
|
||||
include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
@ -175,6 +223,6 @@ endif()
|
|||
|
||||
# Add tests directory
|
||||
if(CIGUI_BUILD_TESTS)
|
||||
include(CTest)
|
||||
include(CTest)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
# Import targets created by CIGUITargets.cmake
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/CIGUITargets.cmake")
|
||||
|
||||
# Ensure SFML is available
|
||||
# Ensure LLGL is available
|
||||
include(CMakeFindDependencyMacro)
|
||||
find_dependency(SFML 3 COMPONENTS graphics window system)
|
||||
find_dependency(LLGL REQUIRED)
|
||||
|
||||
# Define convenient imported target if it doesn't exist
|
||||
if(NOT TARGET cigui::cigui)
|
||||
|
|
|
@ -6,20 +6,33 @@ function(add_cigui_example NAME)
|
|||
find_files(EXAMPLE_${NAME}_SOURCES "${NAME}/src" cpp c cxx hpp h hxx inl)
|
||||
add_executable(EXAMPLE_${NAME} ${EXAMPLE_${NAME}_SOURCES})
|
||||
target_link_libraries(EXAMPLE_${NAME} PRIVATE cigui)
|
||||
link_libraries_in_directory(EXAMPLE_${NAME} ${LLGL_LIB_PATH})
|
||||
target_include_directories(EXAMPLE_${NAME} PRIVATE ${LLGL_INCLUDE_PATH})
|
||||
|
||||
set_target_properties(EXAMPLE_${NAME} PROPERTIES OUTPUT_NAME "${NAME}")
|
||||
|
||||
# Copy SFML DLLs to output directory on Windows when building shared
|
||||
if(WIN32 AND CIGUI_BUILD_SHARED)
|
||||
add_custom_command(TARGET EXAMPLE_${NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:sfml-graphics>
|
||||
$<TARGET_FILE:sfml-window>
|
||||
$<TARGET_FILE:sfml-system>
|
||||
$<TARGET_FILE:cigui>
|
||||
$<TARGET_FILE_DIR:EXAMPLE_${NAME}>
|
||||
)
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET EXAMPLE_${NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${LLGL_BIN_PATH}
|
||||
$<TARGET_FILE_DIR:EXAMPLE_${NAME}>
|
||||
COMMENT "Coppied LLGL binaries to example directory"
|
||||
)
|
||||
|
||||
add_custom_command(TARGET EXAMPLE_${NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${NAME}/src/shader
|
||||
$<TARGET_FILE_DIR:EXAMPLE_${NAME}>/shader
|
||||
COMMENT "Coppied shaders to example directory"
|
||||
)
|
||||
|
||||
# Copy DLLs to output directory on Windows when building shared
|
||||
if(WIN32 AND CIGUI_BUILD_SHARED)
|
||||
add_custom_command(TARGET EXAMPLE_${NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:cigui>
|
||||
$<TARGET_FILE_DIR:EXAMPLE_${NAME}>
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Basic example
|
||||
|
|
|
@ -1,73 +1,6 @@
|
|||
//
|
||||
// Created by n0ffie on 08/04/25.
|
||||
//
|
||||
#include <cigui/core/App.hpp>
|
||||
|
||||
#include <iostream>
|
||||
int main() {
|
||||
cig::App::GetInstance().Run();
|
||||
}
|
||||
|
||||
#include <cigui/cigui.hpp>
|
||||
#include <cigui/utils/List.hpp>
|
||||
|
||||
// WIP - not working yet
|
||||
// Layout unsupported
|
||||
struct HStack final : cig::View {
|
||||
using Stack = cig::List<View*>;
|
||||
Stack views;
|
||||
|
||||
void append(View* view) { views.push_back(view); }
|
||||
|
||||
bool update() override {
|
||||
bool needs_redraw = false;
|
||||
views.iterate([this, &needs_redraw](View*& view) { if (view->update()) needs_redraw = true; });
|
||||
return needs_redraw;
|
||||
}
|
||||
|
||||
View* body() override {
|
||||
views.iterate<>([this](View*& view) { view->draw(); });
|
||||
views.iterate([this](View*& view) {
|
||||
this->m_RenderCalls.expand(view->renderCalls());
|
||||
});
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct NewView final : cig::View {
|
||||
View* body() override {
|
||||
auto List = new HStack();
|
||||
|
||||
auto view = new cig::Rectangle({400, 400});
|
||||
view->setBorderColor(sf::Color::Red)->setBorderThickness(5)->setColor(sf::Color::Green);
|
||||
List->append(view);
|
||||
|
||||
view = new cig::Rectangle({100, 100});
|
||||
view->setBorderColor(sf::Color::Blue)->setBorderThickness(5)->setColor(sf::Color::Yellow);
|
||||
List->append(view);
|
||||
|
||||
return List;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
sf::RenderWindow window(sf::VideoMode({800, 600}), "Hello World!");
|
||||
|
||||
const auto view = new NewView();
|
||||
const cig::Renderer renderer(view);
|
||||
|
||||
while (window.isOpen()) {
|
||||
|
||||
while (const std::optional event = window.pollEvent())
|
||||
{
|
||||
if (event->is<sf::Event::Closed>())
|
||||
{
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
|
||||
renderer.update();
|
||||
|
||||
window.clear();
|
||||
renderer.render(window, sf::RenderStates());
|
||||
window.display();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
18
examples/Full/General/src/shader/MyShader.frag
Normal file
18
examples/Full/General/src/shader/MyShader.frag
Normal file
|
@ -0,0 +1,18 @@
|
|||
// GLSL shader version 1.30 (for OpenGL 3.1)
|
||||
#version 130
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
// Fragment input from the vertex shader
|
||||
in vec3 vertexColor;
|
||||
|
||||
// Fragment output color
|
||||
out vec4 fragColor;
|
||||
|
||||
// Fragment shader main function
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(vertexColor, 1);
|
||||
}
|
28
examples/Full/General/src/shader/MyShader.hlsl
Normal file
28
examples/Full/General/src/shader/MyShader.hlsl
Normal file
|
@ -0,0 +1,28 @@
|
|||
// HLSL shader version 4.0 (for Direct3D 11/ 12)
|
||||
|
||||
struct InputVS
|
||||
{
|
||||
float2 position : POSITION;
|
||||
float3 color : COLOR;
|
||||
};
|
||||
|
||||
struct OutputVS
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float3 color : COLOR;
|
||||
};
|
||||
|
||||
// Vertex shader main function
|
||||
OutputVS VS(InputVS inp)
|
||||
{
|
||||
OutputVS outp;
|
||||
outp.position = float4(inp.position, 0, 1);
|
||||
outp.color = inp.color;
|
||||
return outp;
|
||||
}
|
||||
|
||||
// Pixel shader main function
|
||||
float4 PS(OutputVS inp) : SV_Target
|
||||
{
|
||||
return float4(inp.color, 1);
|
||||
};
|
20
examples/Full/General/src/shader/MyShader.vert
Normal file
20
examples/Full/General/src/shader/MyShader.vert
Normal file
|
@ -0,0 +1,20 @@
|
|||
// GLSL shader version 1.30 (for OpenGL 3.1)
|
||||
#version 130
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
// Vertex attributes (these names must match our vertex format attributes)
|
||||
in vec2 position;
|
||||
in vec3 color;
|
||||
|
||||
// Vertex output to the fragment shader
|
||||
out vec3 vertexColor;
|
||||
|
||||
// Vertex shader main function
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(position, 0, 1);
|
||||
vertexColor = color;
|
||||
}
|
|
@ -2,11 +2,9 @@
|
|||
|
||||
|
||||
#include <cigui/config.h>
|
||||
#include <cigui/core/Renderer.hpp>
|
||||
#include <cigui/core/View.hpp>
|
||||
#include <cigui/views/views.hpp>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cigui/App.hpp>
|
||||
|
||||
namespace cig {
|
||||
constexpr unsigned int VERSION_MAJOR = CIGUI_VERSION_MAJOR;
|
||||
|
|
|
@ -34,4 +34,11 @@
|
|||
#define CIGUI_TEMPLATE_API
|
||||
|
||||
// Special macro for template instantiations
|
||||
#define CIGUI_TEMPLATE_INST extern template class CIGUI_API
|
||||
#define CIGUI_TEMPLATE_INST extern template class CIGUI_API
|
||||
|
||||
// Supported LLGL rendering backends - defined by CMake
|
||||
// #cmakedefine CIGUI_RENDERER_OPENGL
|
||||
// #cmakedefine CIGUI_RENDERER_VULKAN
|
||||
// #cmakedefine CIGUI_RENDERER_D3D11
|
||||
// #cmakedefine CIGUI_RENDERER_D3D12
|
||||
// #cmakedefine CIGUI_RENDERER_METAL
|
39
include/cigui/core/App.hpp
Normal file
39
include/cigui/core/App.hpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include <cigui/config.h>
|
||||
#include <LLGL/LLGL.h>
|
||||
|
||||
#include <cigui/utils/List.hpp>
|
||||
|
||||
namespace cig
|
||||
{
|
||||
struct Vertex
|
||||
{
|
||||
float position[2]; // 2D vector for X and Y coordinates
|
||||
uint8_t color[4]; // 4D vector for red, green, blue, and alpha components
|
||||
};
|
||||
|
||||
class App
|
||||
{
|
||||
protected:
|
||||
App();
|
||||
~App();
|
||||
|
||||
LLGL::RenderSystemPtr m_RenderSystem;
|
||||
LLGL::SwapChain* m_SwapChain;
|
||||
|
||||
std::pair<LLGL::Shader*, LLGL::Shader*> m_ShaderPack;
|
||||
LLGL::PipelineState* m_Pipeline;
|
||||
LLGL::Buffer* m_VertexBuffer;
|
||||
LLGL::CommandBuffer* m_CmdBuffer;
|
||||
LLGL::Window* m_Window;
|
||||
|
||||
bool ShaderLanguageIsSupported(LLGL::ShadingLanguage lang);
|
||||
|
||||
List<Vertex> m_Vertices;
|
||||
public:
|
||||
static App& GetInstance();
|
||||
|
||||
void Run();
|
||||
};
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <cigui/utils/Vectors.hpp>
|
||||
|
||||
|
||||
namespace cig
|
||||
{
|
||||
enum class LayoutSizes : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
Min,
|
||||
Max,
|
||||
Fixed,
|
||||
};
|
||||
|
||||
enum class LayoutAlignment : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
Left,
|
||||
Right,
|
||||
Top,
|
||||
Bottom,
|
||||
Center,
|
||||
};
|
||||
|
||||
enum class LayoutDirection : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
LeftToRight,
|
||||
RightToLeft,
|
||||
TopToBottom,
|
||||
BottomToTop,
|
||||
};
|
||||
|
||||
enum class LayoutPosition : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
Absolute,
|
||||
Left,
|
||||
Right,
|
||||
Top,
|
||||
Bottom,
|
||||
Center,
|
||||
};
|
||||
|
||||
struct Layout
|
||||
{
|
||||
struct
|
||||
{
|
||||
LayoutSizes rule = LayoutSizes::None;
|
||||
vec2f minSize = {0.f, 0.f};
|
||||
vec2f maxSize = {0.f, 0.f};
|
||||
} size;
|
||||
|
||||
struct
|
||||
{
|
||||
LayoutAlignment rule = LayoutAlignment::None;
|
||||
vec4f padding = {0.f, 0.f, 0.f, 0.f};
|
||||
vec4f margin = {0.f, 0.f, 0.f, 0.f};
|
||||
} alignment;
|
||||
|
||||
struct
|
||||
{
|
||||
LayoutDirection rule = LayoutDirection::None;
|
||||
vec2f spacing = {0.f, 0.f};
|
||||
} direction;
|
||||
|
||||
struct
|
||||
{
|
||||
LayoutPosition rule = LayoutPosition::None;
|
||||
vec2f position = {0.f, 0.f};
|
||||
} position;
|
||||
};
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace sf {
|
||||
class Drawable;
|
||||
class RenderTarget;
|
||||
struct RenderStates;
|
||||
}
|
||||
|
||||
namespace cig
|
||||
{
|
||||
class RenderCall
|
||||
{
|
||||
std::shared_ptr<sf::Drawable> drawable;
|
||||
sf::RenderStates states;
|
||||
|
||||
public:
|
||||
explicit RenderCall(const sf::RenderStates& rstates, sf::Drawable* ptr);
|
||||
|
||||
void draw(sf::RenderTarget& target, const sf::RenderStates& rstates) const;
|
||||
};
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace sf {
|
||||
class RenderTarget;
|
||||
class RenderStates;
|
||||
}
|
||||
|
||||
namespace cig {
|
||||
class View;
|
||||
class RenderCall;
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
explicit Renderer(View *_view);
|
||||
|
||||
std::unique_ptr<View> view;
|
||||
|
||||
void update() const;
|
||||
|
||||
void render(sf::RenderTarget &target, const sf::RenderStates &states) const;
|
||||
};
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <cigui/core/Layout.hpp>
|
||||
#include <cigui/utils/List.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace cig
|
||||
{
|
||||
class RenderCall;
|
||||
|
||||
class View {
|
||||
protected:
|
||||
List<RenderCall> m_RenderCalls;
|
||||
Layout m_Layout;
|
||||
|
||||
public:
|
||||
virtual ~View() = default;
|
||||
|
||||
[[nodiscard]] const List<RenderCall>& renderCalls() const;
|
||||
std::unique_ptr<View> content;
|
||||
|
||||
virtual bool update();
|
||||
|
||||
void draw();
|
||||
|
||||
virtual View *body() = 0;
|
||||
};
|
||||
}
|
|
@ -43,6 +43,9 @@ namespace cig
|
|||
|
||||
template <typename Lambda>
|
||||
void iterate(Lambda&& lambda) const;
|
||||
|
||||
const T* data() const;
|
||||
|
||||
};
|
||||
}
|
||||
#include <cigui/utils/List.inl>
|
|
@ -1,8 +1,8 @@
|
|||
#include <cigui/utils/List.hpp>
|
||||
#pragma once
|
||||
|
||||
#define LIST_FUNC_DEFINE(rtt) \
|
||||
template <typename T, size_t growth_scalar, size_t growth_summand> \
|
||||
rtt List<T, growth_scalar, growth_summand>
|
||||
#define LIST_FUNC_DEFINE(rtt) \
|
||||
template <typename T, size_t growth_scalar, size_t growth_summand> \
|
||||
rtt List<T, growth_scalar, growth_summand>
|
||||
|
||||
|
||||
namespace cig
|
||||
|
@ -21,7 +21,7 @@ namespace cig
|
|||
m_Capacity = capacity;
|
||||
}
|
||||
|
||||
LIST_FUNC_DEFINE()::List(const size_t capacity) : m_Capacity(capacity) { reserve(capacity); }
|
||||
LIST_FUNC_DEFINE( )::List(const size_t capacity) : m_Capacity(capacity) { reserve(capacity); }
|
||||
|
||||
LIST_FUNC_DEFINE(void)::own(T* data, const size_t size) {
|
||||
m_Data = data;
|
||||
|
@ -64,7 +64,6 @@ namespace cig
|
|||
m_Data.get()[m_Size++] = value;
|
||||
}
|
||||
|
||||
|
||||
LIST_FUNC_DEFINE(template <typename... Args> void)::emplace_back(Args&&... args) {
|
||||
if (m_Size >= m_Capacity)
|
||||
reserve(m_Capacity * growth_scalar + growth_summand);
|
||||
|
@ -82,6 +81,10 @@ namespace cig
|
|||
for (size_t i = 0; i < m_Size; i++)
|
||||
lambda(m_Data.get()[i]);
|
||||
}
|
||||
|
||||
LIST_FUNC_DEFINE(const T *)::data() const {
|
||||
return m_Data.get();
|
||||
}
|
||||
}
|
||||
|
||||
#undef LIST_FUNC_DEFINE
|
|
@ -23,9 +23,12 @@
|
|||
TYPEDEF_VECTOR(NAME, unsigned long long, N, ull)
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define UNNAMED_STRUCT __extension__ struct
|
||||
#define UNNAMED_STRUCT __extension__ struct
|
||||
#else
|
||||
#defien UNNAMED_STRUCT struct
|
||||
#define UNNAMED_STRUCT struct
|
||||
// Disable warning for anonymous structs and unions
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4201)
|
||||
#endif
|
||||
|
||||
#if CIGUI_DLL
|
||||
|
@ -104,3 +107,15 @@ namespace cig
|
|||
|
||||
TYPEDEF_VECTORS(Vector4, 4)
|
||||
}
|
||||
|
||||
#if !defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#undef UNNAMED_STRUCT
|
||||
#undef TYPEDEF_VECTOR
|
||||
#undef TYPEDEF_VECTORS
|
||||
#if CIGUI_DLL
|
||||
#undef VECTOR_TEMPLATE_INST
|
||||
#endif
|
||||
#undef VECTOR_INSTANTIATION
|
|
@ -1,48 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <cigui/core/View.hpp>
|
||||
#include <SFML/Graphics/Color.hpp>
|
||||
|
||||
namespace sf {
|
||||
class RectangleShape;
|
||||
}
|
||||
|
||||
namespace cig {
|
||||
struct Rectangle : View {
|
||||
sf::Color m_Color;
|
||||
sf::Color m_BorderColor;
|
||||
float m_BorderThickness = 0;
|
||||
|
||||
Rectangle *setBorderColor(const sf::Color &color) {
|
||||
m_BorderColor = color;
|
||||
return this;
|
||||
}
|
||||
Rectangle *setBorderThickness(float thickness) {
|
||||
m_BorderThickness = thickness;
|
||||
return this;
|
||||
}
|
||||
Rectangle *setColor(const sf::Color &color) {
|
||||
m_Color = color;
|
||||
return this;
|
||||
}
|
||||
Rectangle *setSize(const vec2f &size) {
|
||||
m_Layout.size.minSize = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
View *body() override {
|
||||
auto m_Shape = new sf::RectangleShape(sf::Vector2f{m_Layout.size.minSize.x, m_Layout.size.minSize.y});
|
||||
m_Shape->setFillColor(m_Color);
|
||||
if (m_BorderThickness > 0) {
|
||||
m_Shape->setOutlineThickness(m_BorderThickness);
|
||||
m_Shape->setOutlineColor(m_BorderColor);
|
||||
}
|
||||
m_RenderCalls.emplace_back(sf::RenderStates(), m_Shape);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
explicit Rectangle(const vec2f &size) {
|
||||
m_Layout.size.minSize = size;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <cigui/views/Rectangle.hpp>
|
129
src/core/App.cpp
Normal file
129
src/core/App.cpp
Normal file
|
@ -0,0 +1,129 @@
|
|||
#include <cigui/core/App.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <LLGL/Utils/VertexFormat.h>
|
||||
|
||||
namespace cig
|
||||
{
|
||||
App::App()
|
||||
{
|
||||
// Rectangle
|
||||
m_Vertices.emplace_back(Vertex{ { 0.5f, -0.5f }, { 0, 255, 0, 255 } });
|
||||
m_Vertices.emplace_back(Vertex{ { -0.5f, -0.5f }, { 255, 0, 0, 255 } });
|
||||
m_Vertices.emplace_back(Vertex{ { -0.5f, 0.5f }, { 0, 0, 255, 255 } });
|
||||
m_Vertices.emplace_back(Vertex{ { 0.5f, 0.5f }, { 255, 0, 0, 255 } });
|
||||
m_Vertices.emplace_back(Vertex{ { -0.5f, -0.5f }, { 0, 255, 0, 255 } });
|
||||
m_Vertices.emplace_back(Vertex{ { -0.5f, 0.5f }, { 0, 0, 255, 255 } });
|
||||
|
||||
for (const char* module : { "Direct3D12", "Direct3D11", "Vulkan", "OpenGL" }) {
|
||||
LLGL::Report report;
|
||||
m_RenderSystem = LLGL::RenderSystem::Load(module, &report);
|
||||
if (m_RenderSystem == nullptr) {
|
||||
LLGL::Log::Errorf("%s", report.GetText());
|
||||
}
|
||||
}
|
||||
if (m_RenderSystem == nullptr) {
|
||||
std::cout << "No renderer found!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
LLGL::SwapChainDescriptor swapChainDesc;
|
||||
swapChainDesc.resolution = { 800, 600 }; // Framebuffer resolution of 800x600 pixels
|
||||
swapChainDesc.fullscreen = false; // No fullscreen, use windowed mode
|
||||
swapChainDesc.samples = 8; // 8 samples for anti-aliasing
|
||||
m_SwapChain = m_RenderSystem->CreateSwapChain(swapChainDesc);
|
||||
|
||||
LLGL::VertexFormat vertexFormat;
|
||||
vertexFormat.AppendAttribute({ "position", LLGL::Format::RG32Float });
|
||||
vertexFormat.AppendAttribute({ "color", LLGL::Format::RGBA8UNorm });
|
||||
|
||||
LLGL::BufferDescriptor VBufferDesc;
|
||||
VBufferDesc.size = sizeof(Vertex) * m_Vertices.size(); // Size (in bytes) of the buffer
|
||||
VBufferDesc.bindFlags = LLGL::BindFlags::VertexBuffer; // Use for vertex buffer binding
|
||||
VBufferDesc.vertexAttribs = vertexFormat.attributes; // Vertex buffer attributes
|
||||
m_VertexBuffer = m_RenderSystem->CreateBuffer(VBufferDesc, m_Vertices.data());
|
||||
|
||||
LLGL::ShaderDescriptor VSDesc, FSDesc;
|
||||
if (ShaderLanguageIsSupported(LLGL::ShadingLanguage::HLSL)) {
|
||||
VSDesc = { LLGL::ShaderType::Vertex, "shader/MyShader.hlsl", "VMain", "vs_4_0" };
|
||||
FSDesc = { LLGL::ShaderType::Fragment, "shader/MyShader.hlsl", "PMain", "ps_4_0" };
|
||||
} else if (ShaderLanguageIsSupported(LLGL::ShadingLanguage::GLSL)) {
|
||||
VSDesc = { LLGL::ShaderType::Vertex, "shader/MyShader.vert" };
|
||||
FSDesc = { LLGL::ShaderType::Fragment, "shader/MyShader.frag" };
|
||||
} else {
|
||||
std::cout << "Shading language not supported!" << std::endl;
|
||||
return;
|
||||
}
|
||||
VSDesc.vertex.inputAttribs = vertexFormat.attributes;
|
||||
|
||||
m_ShaderPack.first = m_RenderSystem->CreateShader(VSDesc);
|
||||
m_ShaderPack.second = m_RenderSystem->CreateShader(FSDesc);
|
||||
|
||||
for (LLGL::Shader* shader : { m_ShaderPack.first, m_ShaderPack.second }) {
|
||||
if (const LLGL::Report* report = shader->GetReport()) {
|
||||
if (report->HasErrors()) {
|
||||
LLGL::Log::Errorf("Shader compile errors:\n%s", report->GetText());
|
||||
} else {
|
||||
LLGL::Log::Printf("Shader compile warnings:\n%s", report->GetText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLGL::GraphicsPipelineDescriptor pipelineDesc;
|
||||
pipelineDesc.vertexShader = m_ShaderPack.first;
|
||||
pipelineDesc.fragmentShader = m_ShaderPack.second;
|
||||
pipelineDesc.rasterizer.multiSampleEnabled = swapChainDesc.samples > 1;
|
||||
|
||||
m_Pipeline = m_RenderSystem->CreatePipelineState(pipelineDesc);
|
||||
|
||||
m_CmdBuffer = m_RenderSystem->CreateCommandBuffer(LLGL::CommandBufferFlags::ImmediateSubmit);
|
||||
}
|
||||
|
||||
App::~App() {}
|
||||
|
||||
|
||||
bool App::ShaderLanguageIsSupported(LLGL::ShadingLanguage lang)
|
||||
{
|
||||
const auto& supportedLangs = m_RenderSystem->GetRenderingCaps().shadingLanguages;
|
||||
return std::find(supportedLangs.begin(), supportedLangs.end(), lang) != supportedLangs.end();
|
||||
}
|
||||
|
||||
App& App::GetInstance()
|
||||
{
|
||||
static App instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void App::Run()
|
||||
{
|
||||
if (!m_RenderSystem)
|
||||
return;
|
||||
m_Window = &LLGL::CastTo<LLGL::Window>(m_SwapChain->GetSurface());
|
||||
m_Window->SetTitle("Hello Triangle");
|
||||
m_Window->Show();
|
||||
|
||||
while (!m_Window->HasQuit()) {
|
||||
m_Window->ProcessEvents();
|
||||
|
||||
m_CmdBuffer->Begin();
|
||||
m_CmdBuffer->SetVertexBuffer(*m_VertexBuffer);
|
||||
|
||||
m_CmdBuffer->BeginRenderPass(*m_SwapChain);
|
||||
|
||||
m_CmdBuffer->SetViewport(m_SwapChain->GetResolution());
|
||||
|
||||
m_CmdBuffer->Clear(LLGL::ClearFlags::Color);
|
||||
|
||||
m_CmdBuffer->SetPipelineState(*m_Pipeline);
|
||||
|
||||
m_CmdBuffer->Draw(m_Vertices.size(), 0);
|
||||
|
||||
m_CmdBuffer->EndRenderPass();
|
||||
|
||||
m_CmdBuffer->End();
|
||||
|
||||
|
||||
m_SwapChain->Present();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#include <cigui/core/RenderCall.hpp>
|
||||
#include <sfml/Graphics.hpp>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace cig {
|
||||
RenderCall::RenderCall(const sf::RenderStates& rstates, sf::Drawable* ptr) : drawable(ptr), states(rstates) {
|
||||
if (!drawable) { throw std::runtime_error("RenderCall::RenderCall(): Drawable is null"); }
|
||||
}
|
||||
|
||||
void RenderCall::draw(sf::RenderTarget& target, const sf::RenderStates& rstates) const {
|
||||
target.draw(*drawable, rstates);
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#include <cigui/core/Renderer.hpp>
|
||||
|
||||
#include <cigui/core/View.hpp>
|
||||
#include <cigui/core/RenderCall.hpp>
|
||||
#include <sfml/Graphics.hpp>
|
||||
|
||||
namespace cig {
|
||||
Renderer::Renderer(View *_view) : view(_view) { view->draw(); }
|
||||
|
||||
void Renderer::update() const {
|
||||
if (view->update())
|
||||
view->draw();
|
||||
}
|
||||
|
||||
void Renderer::render(sf::RenderTarget &target, const sf::RenderStates &states) const {
|
||||
auto lambda = [&target, &states](const RenderCall &renderCall) { renderCall.draw(target, states); };
|
||||
view->renderCalls().iterate(lambda);
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#include <cigui/core/View.hpp>
|
||||
|
||||
#include <cigui/core/RenderCall.hpp>
|
||||
|
||||
namespace cig {
|
||||
const List<RenderCall>& View::renderCalls() const
|
||||
{
|
||||
return m_RenderCalls;
|
||||
}
|
||||
|
||||
void View::draw() {
|
||||
if (!m_RenderCalls.empty()) {
|
||||
m_RenderCalls.clear();
|
||||
}
|
||||
content = std::unique_ptr<View>(body());
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
content->draw();
|
||||
auto &contentRenderCalls = content->renderCalls();
|
||||
m_RenderCalls.expand(contentRenderCalls);
|
||||
}
|
||||
|
||||
bool View::update() {
|
||||
if (content)
|
||||
return content->update();
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -35,9 +35,7 @@ function(add_cigui_test TEST_NAME)
|
|||
if(WIN32 AND CIGUI_BUILD_SHARED)
|
||||
add_custom_command(TARGET ${TEST_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:sfml-graphics>
|
||||
$<TARGET_FILE:sfml-window>
|
||||
$<TARGET_FILE:sfml-system>
|
||||
$<TARGET_FILE:LLGL>
|
||||
$<TARGET_FILE:cigui>
|
||||
$<TARGET_FILE_DIR:${TEST_NAME}>
|
||||
)
|
||||
|
@ -73,9 +71,7 @@ add_test(NAME cigui_tests COMMAND cigui_tests)
|
|||
if(WIN32 AND CIGUI_BUILD_SHARED)
|
||||
add_custom_command(TARGET cigui_tests POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:sfml-graphics>
|
||||
$<TARGET_FILE:sfml-window>
|
||||
$<TARGET_FILE:sfml-system>
|
||||
$<TARGET_FILE:LLGL>
|
||||
$<TARGET_FILE:cigui>
|
||||
$<TARGET_FILE_DIR:cigui_tests>
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue