Add backends
- Renamed GfxOpenGL to GfxOPenGL2 - Added GfxOpenGL3 backend for OpenGL 3.3+ - Added WIP DirectX9 backend - Added structure for Citro3D - Added linear Allocator
This commit is contained in:
115
CMakeLists.txt
115
CMakeLists.txt
@@ -14,110 +14,115 @@ option(PD_BUILD_SHARED "Build Shared Library" OFF)
|
||||
option(PD_BUILD_TOOLS "Build Palladium Tools" OFF)
|
||||
|
||||
if(${PD_BUILD_TOOLS})
|
||||
add_subdirectory(tools)
|
||||
add_subdirectory(tools)
|
||||
endif()
|
||||
|
||||
add_subdirectory(vendor)
|
||||
|
||||
# # Include Library Source
|
||||
set(PD_SOURCES
|
||||
# Common
|
||||
source/common.cpp
|
||||
# Common
|
||||
source/common.cpp
|
||||
|
||||
# Core
|
||||
source/core/bits.cpp
|
||||
source/core/color.cpp
|
||||
source/core/mat.cpp
|
||||
source/core/strings.cpp
|
||||
# Core
|
||||
source/core/bits.cpp
|
||||
source/core/color.cpp
|
||||
source/core/mat.cpp
|
||||
source/core/strings.cpp
|
||||
|
||||
# Drivers
|
||||
source/drivers/os.cpp
|
||||
source/drivers/gfx.cpp
|
||||
# Drivers
|
||||
source/drivers/os.cpp
|
||||
source/drivers/gfx.cpp
|
||||
|
||||
# Lithium
|
||||
source/lithium/pools.cpp
|
||||
# Lithium
|
||||
source/lithium/pools.cpp
|
||||
)
|
||||
|
||||
if(${PD_BUILD_SHARED})
|
||||
add_library(palladium SHARED ${PD_SOURCES})
|
||||
target_compile_definitions(palladium PRIVATE -DPD_BUILD_SHARED)
|
||||
add_library(palladium SHARED ${PD_SOURCES})
|
||||
target_compile_definitions(palladium PRIVATE PD_BUILD_SHARED)
|
||||
else()
|
||||
add_library(palladium STATIC ${PD_SOURCES})
|
||||
target_compile_definitions(palladium PUBLIC -DPD_BUILD_STATIC)
|
||||
add_library(palladium STATIC ${PD_SOURCES})
|
||||
target_compile_definitions(palladium PUBLIC PD_BUILD_STATIC)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(palladium PUBLIC -DPD_DEBUG=1)
|
||||
target_compile_definitions(palladium PUBLIC PD_DEBUG)
|
||||
target_compile_options(palladium
|
||||
PUBLIC
|
||||
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source
|
||||
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/include=include
|
||||
PUBLIC
|
||||
$<$<CXX_COMPILER_ID:GNU,Clang>:
|
||||
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source
|
||||
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/include=include
|
||||
>
|
||||
)
|
||||
|
||||
add_library(palladium::palladium ALIAS palladium)
|
||||
|
||||
target_include_directories(palladium
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
|
||||
target_compile_options(palladium
|
||||
PRIVATE
|
||||
$<$<CONFIG:Debug>:-O0 -g>
|
||||
$<$<CONFIG:Release>:-O3>
|
||||
PRIVATE
|
||||
$<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:GNU,Clang>>:-O0 -g>
|
||||
$<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:GNU,Clang>>:-O3>
|
||||
|
||||
$<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:MSVC>>:/Od /Zi>
|
||||
$<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:MSVC>>:/O2>
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS palladium
|
||||
EXPORT palladiumTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
TARGETS palladium
|
||||
EXPORT palladiumTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
install(
|
||||
DIRECTORY include/
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
DIRECTORY include/
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
install(EXPORT palladiumTargets
|
||||
FILE palladiumTargets.cmake
|
||||
NAMESPACE palladium::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium
|
||||
FILE palladiumTargets.cmake
|
||||
NAMESPACE palladium::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium
|
||||
)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
configure_package_config_file(
|
||||
cmake/palladiumConfig.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake
|
||||
INSTALL_DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}/cmake/palladium
|
||||
cmake/palladiumConfig.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake
|
||||
INSTALL_DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}/cmake/palladium
|
||||
)
|
||||
|
||||
write_basic_package_version_file(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake
|
||||
VERSION
|
||||
${PROJECT_VERSION}
|
||||
COMPATIBILITY
|
||||
SameMajorVersion
|
||||
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake
|
||||
VERSION
|
||||
${PROJECT_VERSION}
|
||||
COMPATIBILITY
|
||||
SameMajorVersion
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium
|
||||
)
|
||||
|
||||
find_program(CLANG_FORMAT clang-format)
|
||||
|
||||
file(GLOB_RECURSE PD_FMTFILES
|
||||
CONFIGURE_DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp
|
||||
CONFIGURE_DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp
|
||||
)
|
||||
|
||||
add_custom_target(pd-clang-format
|
||||
COMMAND ${CLANG_FORMAT} --style=file -i ${PD_FMTFILES}
|
||||
COMMENT "Formatting Project Sources"
|
||||
COMMAND ${CLANG_FORMAT} --style=file -i ${PD_FMTFILES}
|
||||
COMMENT "Formatting Project Sources"
|
||||
)
|
||||
|
||||
add_subdirectory(backends)
|
||||
|
||||
@@ -4,26 +4,60 @@ project(pd-system)
|
||||
|
||||
option(PD_ENABLE_OPENGL2 "Enable OpenGL 2.1 (On Supported Hardware)" ON)
|
||||
option(PD_ENABLE_OPENGL3 "Enable OpenGL 3.3 (On Supported Hardware)" ON)
|
||||
option(PD_ENABLE_DIRECTX9 "Enable DirectX9 Support" ON)
|
||||
option(PD_ENABLE_CITRO3D "Enable Citro3D Support (3DS)" OFF)
|
||||
option(PD_ENABLE_VULKAN "Not implemented yet" OFF)
|
||||
|
||||
if(NOT WIN32) # cause we are not on windows...
|
||||
set(PD_ENABLE_DIRECTX9 OFF)
|
||||
endif()
|
||||
|
||||
add_library(pd-system STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_opengl.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gl-helper.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_opengl2.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_opengl3.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_directx9.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_citro3d.cpp
|
||||
)
|
||||
|
||||
target_include_directories(pd-system
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
|
||||
target_compile_options(pd-system
|
||||
PUBLIC
|
||||
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source
|
||||
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/include=include
|
||||
target_compile_options(palladium
|
||||
PUBLIC
|
||||
$<$<CXX_COMPILER_ID:GNU,Clang>:
|
||||
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source
|
||||
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/include=include
|
||||
>
|
||||
)
|
||||
|
||||
target_link_libraries(pd-system
|
||||
PUBLIC
|
||||
palladium::palladium
|
||||
glad
|
||||
)
|
||||
target_compile_definitions(pd-system
|
||||
PUBLIC
|
||||
$<$<BOOL:${PD_ENABLE_OPENGL2}>:PD_ENABLE_OPENGL2>
|
||||
$<$<BOOL:${PD_ENABLE_OPENGL3}>:PD_ENABLE_OPENGL3>
|
||||
$<$<BOOL:${PD_ENABLE_VULKAN}>:PD_ENABLE_VULKAN>
|
||||
$<$<BOOL:${PD_ENABLE_DIRECTX9}>:PD_ENABLE_DIRECTX9>
|
||||
)
|
||||
|
||||
# Palladium
|
||||
target_link_libraries(pd-system PUBLIC palladium::palladium)
|
||||
|
||||
# glad (if we have any OpenGL version included)
|
||||
if(PD_ENABLE_OPENGL2 OR PD_ENABLE_OPENGL3)
|
||||
target_link_libraries(pd-system
|
||||
PUBLIC
|
||||
glad
|
||||
)
|
||||
endif()
|
||||
|
||||
# DirectX9
|
||||
if(PD_ENABLE_DIRECTX9)
|
||||
target_link_libraries(pd-system
|
||||
PUBLIC
|
||||
d3d9
|
||||
d3dcompiler
|
||||
)
|
||||
endif()
|
||||
|
||||
67
backends/include/pd_system/ctr-linear-allocator.hpp
Normal file
67
backends/include/pd_system/ctr-linear-allocator.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __3DS__
|
||||
#include <3ds.h>
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
// Custom C++ Allocator class to interface with libctru linear heap memory
|
||||
// based on this guide:
|
||||
// https://johnfarrier.com/custom-allocators-in-c-high-performance-memory-management/
|
||||
|
||||
namespace PD {
|
||||
template <typename T>
|
||||
class LinearAllocator {
|
||||
public:
|
||||
using value_type = T;
|
||||
LinearAllocator() noexcept = default;
|
||||
template <typename U>
|
||||
constexpr LinearAllocator(const LinearAllocator<U>&) noexcept {}
|
||||
|
||||
T* allocate(std::size_t n) {
|
||||
if (n > max_size()) {
|
||||
throw std::runtime_error("[PD] LinearAllocator: Bad alloc!");
|
||||
}
|
||||
#ifdef __3DS__
|
||||
return static_cast<T*>(linearAlloc(n * sizeof(T)));
|
||||
#else
|
||||
return static_cast<T*>(malloc(n * sizeof(T)));
|
||||
#endif
|
||||
}
|
||||
#ifdef __3DS__
|
||||
void deallocate(T* p, std::size_t) noexcept { linearFree(p); }
|
||||
#else
|
||||
void deallocate(T* p, std::size_t) noexcept { free(p); }
|
||||
#endif
|
||||
|
||||
template <class U, class... Args>
|
||||
void construct(U* p, Args&&... args) {
|
||||
::new ((void*)p) U(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
void destroy(U* p) {
|
||||
p->~U();
|
||||
}
|
||||
|
||||
friend bool operator==(const LinearAllocator, const LinearAllocator) {
|
||||
return true;
|
||||
}
|
||||
friend bool operator!=(const LinearAllocator, const LinearAllocator) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __3DS__
|
||||
// Use linearSpace free as max_size to not allocate out of bounds
|
||||
// or to b eable to see a crash report screen.
|
||||
size_t max_size() const noexcept { return linearSpaceFree(); }
|
||||
#else
|
||||
size_t max_size() const noexcept {
|
||||
return std::numeric_limits<size_t>::max();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
} // namespace PD
|
||||
38
backends/include/pd_system/gfx_citro3d.hpp
Normal file
38
backends/include/pd_system/gfx_citro3d.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/drivers/gfx.hpp>
|
||||
#include <pd_system/ctr-linear-allocator.hpp>
|
||||
|
||||
namespace PD {
|
||||
struct GfxCitro3DConfig {
|
||||
// Vertex Allocator
|
||||
template <typename T>
|
||||
using VertexAlloc = LinearAllocator<T>;
|
||||
// Index Allocator
|
||||
template <typename T>
|
||||
using IndexAlloc = LinearAllocator<T>;
|
||||
|
||||
static constexpr size_t NumVertices = 32768; // 8192*4
|
||||
static constexpr size_t NumIndices = 49152; // 8192*6
|
||||
};
|
||||
|
||||
class GfxCitro3D : public GfxDriverBase<GfxCitro3DConfig> {
|
||||
public:
|
||||
GfxCitro3D() : GfxDriverBase("Citro3D") {}
|
||||
~GfxCitro3D() {}
|
||||
|
||||
void SysInit() override;
|
||||
void SysDeinit() override;
|
||||
void Submit(size_t count, size_t start) override;
|
||||
void BindTexture(TextureID id) override;
|
||||
void SysReset() override;
|
||||
TextureID LoadTexture(const std::vector<PD::u8>& pixels, int w, int h,
|
||||
TextureFormat type = TextureFormat::RGBA32,
|
||||
TextureFilter filter = TextureFilter::Linear) override;
|
||||
void DeleteTexture(const TextureID& tex) override;
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
Impl* impl = nullptr;
|
||||
};
|
||||
} // namespace PD
|
||||
39
backends/include/pd_system/gfx_directx9.hpp
Normal file
39
backends/include/pd_system/gfx_directx9.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/drivers/gfx.hpp>
|
||||
|
||||
namespace PD {
|
||||
struct GfxDirectX9Config {
|
||||
// Vertex Allocator
|
||||
template <typename T>
|
||||
using VertexAlloc = std::allocator<T>;
|
||||
// Index Allocator
|
||||
template <typename T>
|
||||
using IndexAlloc = std::allocator<T>;
|
||||
|
||||
static constexpr size_t NumVertices = 32768; // 8192*4
|
||||
static constexpr size_t NumIndices = 49152; // 8192*6
|
||||
};
|
||||
|
||||
class GfxDirectX9 : public GfxDriverBase<GfxDirectX9Config> {
|
||||
public:
|
||||
GfxDirectX9(void* device = nullptr)
|
||||
: GfxDriverBase("DirectX9"), pDevice(device) {}
|
||||
~GfxDirectX9() {}
|
||||
|
||||
void SysInit() override;
|
||||
void SysDeinit() override;
|
||||
void Submit(size_t count, size_t start) override;
|
||||
void BindTexture(TextureID id) override;
|
||||
void SysReset() override;
|
||||
TextureID LoadTexture(const std::vector<PD::u8>& pixels, int w, int h,
|
||||
TextureFormat type = TextureFormat::RGBA32,
|
||||
TextureFilter filter = TextureFilter::Linear) override;
|
||||
void DeleteTexture(const TextureID& tex) override;
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
Impl* impl = nullptr;
|
||||
void* pDevice = nullptr;
|
||||
};
|
||||
} // namespace PD
|
||||
@@ -3,22 +3,22 @@
|
||||
#include <pd/drivers/gfx.hpp>
|
||||
|
||||
namespace PD {
|
||||
struct GfxOpenGLConfig {
|
||||
struct GfxOpenGL2Config {
|
||||
// Vertex Allocator
|
||||
template <typename T>
|
||||
using VertexAlloc = std::allocator<T>;
|
||||
// Index Allocator
|
||||
template <typename T>
|
||||
using IndexAlloc = std::allocator<T>;
|
||||
using IndexType = u32; // Index Type
|
||||
|
||||
static constexpr size_t NumVertices = 32768; // 8192*4
|
||||
static constexpr size_t NumIndices = 49152; // 8192*6
|
||||
};
|
||||
class GfxOpenGL : public GfxDriverBase<GfxOpenGLConfig> {
|
||||
|
||||
class GfxOpenGL2 : public GfxDriverBase<GfxOpenGL2Config> {
|
||||
public:
|
||||
GfxOpenGL(): GfxDriverBase("OpenGL2") {}
|
||||
~GfxOpenGL() {}
|
||||
GfxOpenGL2() : GfxDriverBase("OpenGL2") {}
|
||||
~GfxOpenGL2() {}
|
||||
|
||||
void SysInit() override;
|
||||
void SysDeinit() override;
|
||||
@@ -38,5 +38,7 @@ class GfxOpenGL : public GfxDriverBase<GfxOpenGLConfig> {
|
||||
int pLocTex = 0;
|
||||
int pLocAlfa = 0;
|
||||
int pLocProjection = 0;
|
||||
static const char* pVertCode;
|
||||
static const char* pFragCode;
|
||||
};
|
||||
} // namespace PD
|
||||
44
backends/include/pd_system/gfx_opengl3.hpp
Normal file
44
backends/include/pd_system/gfx_opengl3.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/drivers/gfx.hpp>
|
||||
|
||||
namespace PD {
|
||||
struct GfxOpenGL3Config {
|
||||
// Vertex Allocator
|
||||
template <typename T>
|
||||
using VertexAlloc = std::allocator<T>;
|
||||
// Index Allocator
|
||||
template <typename T>
|
||||
using IndexAlloc = std::allocator<T>;
|
||||
|
||||
static constexpr size_t NumVertices = 32768; // 8192*4
|
||||
static constexpr size_t NumIndices = 49152; // 8192*6
|
||||
};
|
||||
|
||||
class GfxOpenGL3 : public GfxDriverBase<GfxOpenGL3Config> {
|
||||
public:
|
||||
GfxOpenGL3() : GfxDriverBase("OpenGL3") {}
|
||||
~GfxOpenGL3() {}
|
||||
|
||||
void SysInit() override;
|
||||
void SysDeinit() override;
|
||||
void Submit(size_t count, size_t start) override;
|
||||
void BindTexture(TextureID id) override;
|
||||
void SysReset() override;
|
||||
TextureID LoadTexture(const std::vector<PD::u8>& pixels, int w, int h,
|
||||
TextureFormat type = TextureFormat::RGBA32,
|
||||
TextureFilter filter = TextureFilter::Linear) override;
|
||||
void DeleteTexture(const TextureID& tex) override;
|
||||
|
||||
private:
|
||||
u32 pShader = 0;
|
||||
u32 VBO = 0;
|
||||
u32 IBO = 0;
|
||||
u32 VAO = 0;
|
||||
int pLocTex = 0;
|
||||
int pLocAlfa = 0;
|
||||
int pLocProjection = 0;
|
||||
static const char* pVertCode;
|
||||
static const char* pFragCode;
|
||||
};
|
||||
} // namespace PD
|
||||
7
backends/include/pd_system/gl-helper.hpp
Normal file
7
backends/include/pd_system/gl-helper.hpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/common.hpp>
|
||||
|
||||
namespace PD {
|
||||
u32 CreateShaderProgram(const char* vert, const char* frag);
|
||||
}
|
||||
6
backends/include/pdsystem
Normal file
6
backends/include/pdsystem
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd_system/gfx_citro3d.hpp>
|
||||
#include <pd_system/gfx_directx9.hpp>
|
||||
#include <pd_system/gfx_opengl2.hpp>
|
||||
#include <pd_system/gfx_opengl3.hpp>
|
||||
69
backends/source/gfx_citro3d.cpp
Normal file
69
backends/source/gfx_citro3d.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
// Well yes, i finally try it
|
||||
|
||||
#include <pd_system/gfx_citro3d.hpp>
|
||||
|
||||
#if defined(PD_ENABLE_CITRO3D) // && defined(__3DS__)
|
||||
|
||||
#include <3ds.h>
|
||||
#include <citro3d.h>
|
||||
|
||||
#include <pd/drivers/drivers.hpp>
|
||||
|
||||
namespace PD {
|
||||
struct GfxCitro3D::Impl {};
|
||||
|
||||
void GfxCitro3D::SysInit() {
|
||||
if (impl) return;
|
||||
PDLOG("GfxCitro3D::SysInit();");
|
||||
impl = new Impl();
|
||||
}
|
||||
|
||||
void GfxCitro3D::SysDeinit() {
|
||||
if (!impl) return;
|
||||
delete impl;
|
||||
impl = nullptr;
|
||||
PDLOG("GfxCitro3D::SysDeinit()");
|
||||
}
|
||||
|
||||
void GfxCitro3D::Submit(size_t count, size_t start) {
|
||||
if (!impl) return;
|
||||
}
|
||||
|
||||
void GfxCitro3D::BindTexture(TextureID id) {
|
||||
if (!impl) return;
|
||||
}
|
||||
|
||||
void GfxCitro3D::SysReset() {
|
||||
if (!impl) return;
|
||||
}
|
||||
|
||||
TextureID GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||
int h, TextureFormat type,
|
||||
TextureFilter filter) {
|
||||
if (!impl) return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GfxCitro3D::DeleteTexture(const TextureID& tex) {
|
||||
if (!tex) return;
|
||||
}
|
||||
} // namespace PD
|
||||
#else
|
||||
namespace PD {
|
||||
void GfxCitro3D::SysInit() {
|
||||
PDLOG(
|
||||
"GfxCitro3D::SysInit: Citro3D Driver is not included in "
|
||||
"palladium-system");
|
||||
}
|
||||
void GfxCitro3D::SysDeinit() {}
|
||||
void GfxCitro3D::Submit(size_t count, size_t start) {}
|
||||
void GfxCitro3D::BindTexture(TextureID id) {}
|
||||
void GfxCitro3D::SysReset() {}
|
||||
TextureID GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||
int h, TextureFormat type,
|
||||
TextureFilter filter) {
|
||||
return 0;
|
||||
}
|
||||
void GfxCitro3D::DeleteTexture(const TextureID& tex) {}
|
||||
} // namespace PD
|
||||
#endif
|
||||
267
backends/source/gfx_directx9.cpp
Normal file
267
backends/source/gfx_directx9.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
// Well yes, i finally try it
|
||||
|
||||
#include <pd_system/gfx_directx9.hpp>
|
||||
|
||||
// Sicher ist sicher
|
||||
#if defined(PD_ENABLE_DIRECTX9) && defined(_WIN32)
|
||||
#include <d3d9.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#include <pd/drivers/drivers.hpp>
|
||||
|
||||
namespace PD {
|
||||
static const char* g_vsCode = R"(
|
||||
float4x4 projection;
|
||||
|
||||
struct VS_IN {
|
||||
float2 pos : POSITION0;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 col : COLOR0;
|
||||
};
|
||||
|
||||
struct VS_OUT {
|
||||
float4 pos : POSITION0;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 col : COLOR0;
|
||||
};
|
||||
|
||||
VS_OUT main(VS_IN input) {
|
||||
VS_OUT o;
|
||||
o.pos = mul(projection, float4(input.pos, 0.0, 1.0));
|
||||
o.uv = input.uv;
|
||||
o.col = input.col;
|
||||
return o;
|
||||
}
|
||||
)";
|
||||
|
||||
static const char* g_psCode = R"(
|
||||
sampler2D tex : register(s0);
|
||||
bool alfa;
|
||||
|
||||
struct PS_IN {
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 col : COLOR0;
|
||||
};
|
||||
|
||||
float4 main(PS_IN input) : COLOR0 {
|
||||
float4 tc = tex2D(tex, input.uv);
|
||||
if (alfa)
|
||||
return float4(input.col.rgb, tc.a * input.col.a);
|
||||
else
|
||||
return tc * input.col;
|
||||
}
|
||||
)";
|
||||
|
||||
struct GfxDirectX9::Impl {
|
||||
IDirect3DDevice9* Device = nullptr;
|
||||
IDirect3DVertexBuffer9* VBO = nullptr;
|
||||
IDirect3DIndexBuffer9* IBO = nullptr;
|
||||
IDirect3DVertexDeclaration9* Decl = nullptr;
|
||||
IDirect3DVertexShader9* VS = nullptr;
|
||||
IDirect3DPixelShader9* FS = nullptr;
|
||||
IDirect3DTexture9* CurrentTex = nullptr;
|
||||
};
|
||||
|
||||
void GfxDirectX9::SysInit() {
|
||||
if (impl) return;
|
||||
PDLOG("GfxDirectX9::SysInit();");
|
||||
impl = new Impl();
|
||||
impl->Device = (IDirect3DDevice9*)pDevice;
|
||||
if (impl->Device) {
|
||||
D3DVERTEXELEMENT9 elements[]{
|
||||
{0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,
|
||||
0},
|
||||
{0, 8, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,
|
||||
0},
|
||||
{0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,
|
||||
0},
|
||||
D3DDECL_END()};
|
||||
impl->Device->CreateVertexDeclaration(elements, &impl->Decl);
|
||||
impl->Device->CreateVertexBuffer(
|
||||
GfxDirectX9Config::NumVertices * sizeof(PD::Li::Vertex),
|
||||
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &impl->VBO,
|
||||
nullptr);
|
||||
impl->Device->CreateIndexBuffer(GfxDirectX9Config::NumIndices * sizeof(u16),
|
||||
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
|
||||
D3DFMT_INDEX16, D3DPOOL_DEFAULT, &impl->IBO,
|
||||
nullptr);
|
||||
ID3DBlob* vsBlob = nullptr;
|
||||
ID3DBlob* errBlob = nullptr;
|
||||
HRESULT hr = D3DCompile(g_vsCode, strlen(g_vsCode), nullptr, nullptr,
|
||||
nullptr, "main", "vs_2_0", 0, 0, &vsBlob, &errBlob);
|
||||
if (FAILED(hr)) {
|
||||
PDLOG("Vertex Shader compile error: {}",
|
||||
errBlob ? (char*)errBlob->GetBufferPointer() : "");
|
||||
} else {
|
||||
impl->Device->CreateVertexShader((DWORD*)vsBlob->GetBufferPointer(),
|
||||
&impl->VS);
|
||||
}
|
||||
if (vsBlob) vsBlob->Release();
|
||||
if (errBlob) errBlob->Release();
|
||||
|
||||
ID3DBlob* psBlob = nullptr;
|
||||
errBlob = nullptr;
|
||||
hr = D3DCompile(g_psCode, strlen(g_psCode), nullptr, nullptr, nullptr,
|
||||
"main", "ps_2_0", 0, 0, &psBlob, &errBlob);
|
||||
if (FAILED(hr)) {
|
||||
PDLOG("Pixel Shader compile error: {}",
|
||||
errBlob ? (char*)errBlob->GetBufferPointer() : "");
|
||||
} else {
|
||||
impl->Device->CreatePixelShader((DWORD*)psBlob->GetBufferPointer(),
|
||||
&impl->FS);
|
||||
}
|
||||
if (psBlob) psBlob->Release();
|
||||
if (errBlob) errBlob->Release();
|
||||
} else {
|
||||
PDLOG(
|
||||
"GfxDirectX9::SysInit Error: pDevice is not set!\nYOu need to include "
|
||||
"your D3D9 Device as "
|
||||
"folowing:\nPD::Gfx::UseDriver<PD::GfxDirectX9>(D3D9Device);");
|
||||
}
|
||||
}
|
||||
|
||||
void GfxDirectX9::SysDeinit() {
|
||||
if (!impl || !impl->Device) return;
|
||||
if (impl->VBO) impl->VBO->Release();
|
||||
if (impl->IBO) impl->IBO->Release();
|
||||
if (impl->Decl) impl->Decl->Release();
|
||||
if (impl->VS) impl->VS->Release();
|
||||
if (impl->FS) impl->FS->Release();
|
||||
delete impl;
|
||||
impl = nullptr;
|
||||
PDLOG("GfxDirectX9::SysDeinit()");
|
||||
}
|
||||
|
||||
void GfxDirectX9::Submit(size_t count, size_t start) {
|
||||
if (!impl || !impl->Device || !impl->VBO || !impl->IBO) return;
|
||||
|
||||
impl->Device->SetVertexShaderConstantF(
|
||||
0, reinterpret_cast<const float*>(&Projection), 4);
|
||||
|
||||
void* vptr;
|
||||
impl->VBO->Lock(0, 0, &vptr, D3DLOCK_DISCARD);
|
||||
memcpy(vptr, GetVertexBufPtr(0), CurrentVertex * sizeof(PD::Li::Vertex));
|
||||
impl->VBO->Unlock();
|
||||
|
||||
void* iptr;
|
||||
impl->IBO->Lock(0, 0, &iptr, D3DLOCK_DISCARD);
|
||||
memcpy(iptr, GetIndexBufPtr(0), CurrentIndex * sizeof(u16));
|
||||
impl->IBO->Unlock();
|
||||
|
||||
impl->Device->SetStreamSource(0, impl->VBO, 0, sizeof(PD::Li::Vertex));
|
||||
impl->Device->SetIndices(impl->IBO);
|
||||
impl->Device->SetVertexDeclaration(impl->Decl);
|
||||
impl->Device->SetVertexShader(impl->VS);
|
||||
impl->Device->SetPixelShader(impl->FS);
|
||||
|
||||
impl->Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, CurrentVertex,
|
||||
start, count / 3);
|
||||
}
|
||||
|
||||
void GfxDirectX9::BindTexture(TextureID id) {
|
||||
if (!impl || !impl->Device) return;
|
||||
impl->CurrentTex = (IDirect3DTexture9*)id;
|
||||
impl->Device->SetTexture(0, impl->CurrentTex);
|
||||
|
||||
bool a8 = false;
|
||||
if (impl->CurrentTex) {
|
||||
D3DSURFACE_DESC desc;
|
||||
impl->CurrentTex->GetLevelDesc(0, &desc);
|
||||
a8 = (desc.Format == D3DFMT_A8);
|
||||
}
|
||||
|
||||
float v = a8 ? 1.0f : 0.0f;
|
||||
impl->Device->SetPixelShaderConstantF(0, &v, 1);
|
||||
}
|
||||
|
||||
void GfxDirectX9::SysReset() {
|
||||
if (!impl || !impl->Device) return;
|
||||
|
||||
impl->Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
impl->Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
impl->Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
}
|
||||
|
||||
TextureID GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||
int h, TextureFormat type,
|
||||
TextureFilter filter) {
|
||||
if (!impl || !impl->Device) return 0;
|
||||
IDirect3DTexture9* tex = nullptr;
|
||||
D3DFORMAT fmt = D3DFMT_A8R8G8B8;
|
||||
if (type == TextureFormat::RGB24)
|
||||
fmt = D3DFMT_X8R8G8B8;
|
||||
else if (type == TextureFormat::A8)
|
||||
fmt = D3DFMT_A8;
|
||||
|
||||
HRESULT hr = impl->Device->CreateTexture(w, h, 1, 0, fmt, D3DPOOL_MANAGED,
|
||||
&tex, nullptr);
|
||||
if (FAILED(hr) || !tex) return 0;
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
tex->LockRect(0, &rect, nullptr, 0);
|
||||
|
||||
if (type == TextureFormat::RGB24) {
|
||||
u8* dstRow = reinterpret_cast<u8*>(rect.pBits);
|
||||
for (int y = 0; y < h; ++y) {
|
||||
u32* dst = reinterpret_cast<u32*>(dstRow);
|
||||
for (int x = 0; x < w; ++x) {
|
||||
u8 r = pixels[(y * w + x) * 3 + 0];
|
||||
u8 g = pixels[(y * w + x) * 3 + 1];
|
||||
u8 b = pixels[(y * w + x) * 3 + 2];
|
||||
dst[x] = (0xFF << 24) | (r << 16) | (g << 8) | b; // X8R8G8B8
|
||||
}
|
||||
dstRow += rect.Pitch;
|
||||
}
|
||||
} else if (type == TextureFormat::RGBA32) {
|
||||
u8* dstRow = reinterpret_cast<u8*>(rect.pBits);
|
||||
for (int y = 0; y < h; ++y) {
|
||||
u32* dst = reinterpret_cast<u32*>(dstRow);
|
||||
for (int x = 0; x < w; ++x) {
|
||||
u8 r = pixels[(y * w + x) * 4 + 0];
|
||||
u8 g = pixels[(y * w + x) * 4 + 1];
|
||||
u8 b = pixels[(y * w + x) * 4 + 2];
|
||||
u8 a = pixels[(y * w + x) * 4 + 3];
|
||||
dst[x] = (a << 24) | (r << 16) | (g << 8) | b; // A8R8G8B8
|
||||
}
|
||||
dstRow += rect.Pitch;
|
||||
}
|
||||
} else if (type == TextureFormat::A8) {
|
||||
u8* dstRow = reinterpret_cast<u8*>(rect.pBits);
|
||||
for (int y = 0; y < h; ++y) {
|
||||
memcpy(dstRow, &pixels[y * w], w);
|
||||
dstRow += rect.Pitch;
|
||||
}
|
||||
}
|
||||
|
||||
tex->UnlockRect(0);
|
||||
|
||||
PDLOG("GfxDirectX9::LoadTexture -> [{}] 0x{:X}, [{}, {}]", PD::ivec2(w, h),
|
||||
(TextureID)tex, type, filter);
|
||||
return (TextureID)tex;
|
||||
}
|
||||
|
||||
void GfxDirectX9::DeleteTexture(const TextureID& tex) {
|
||||
if (!tex) return;
|
||||
IDirect3DTexture9* t = (IDirect3DTexture9*)tex;
|
||||
t->Release();
|
||||
}
|
||||
} // namespace PD
|
||||
#else
|
||||
namespace PD {
|
||||
void GfxDirectX9::SysInit() {
|
||||
PDLOG(
|
||||
"GfxDirectX9::SysInit: DirectX9 Driver is not included in "
|
||||
"palladium-system");
|
||||
}
|
||||
void GfxDirectX9::SysDeinit() {}
|
||||
void GfxDirectX9::Submit(size_t count, size_t start) {}
|
||||
void GfxDirectX9::BindTexture(TextureID id) {}
|
||||
void GfxDirectX9::SysReset() {}
|
||||
TextureID GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||
int h, TextureFormat type,
|
||||
TextureFilter filter) {
|
||||
return 0;
|
||||
}
|
||||
void GfxDirectX9::DeleteTexture(const TextureID& tex) {}
|
||||
} // namespace PD
|
||||
#endif
|
||||
@@ -1,56 +1,13 @@
|
||||
#include <pd_system/gfx_opengl2.hpp>
|
||||
|
||||
#if defined(PD_ENABLE_OPENGL2)
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <gfx_opengl.hpp>
|
||||
|
||||
#include "pd/common.hpp"
|
||||
#include "pd/drivers/gfx.hpp"
|
||||
#include <pd/drivers/drivers.hpp>
|
||||
#include <pd_system/gl-helper.hpp>
|
||||
|
||||
namespace PD {
|
||||
GLuint compileShader(const std::string& source, GLenum type) {
|
||||
GLuint shader = glCreateShader(type);
|
||||
const char* src = source.c_str();
|
||||
glShaderSource(shader, 1, &src, nullptr);
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint success;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
char infoLog[512];
|
||||
glGetShaderInfoLog(shader, 512, nullptr, infoLog);
|
||||
std::cerr << "Shader Compilation Error: " << infoLog << std::endl;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
GLuint createShaderProgram(const std::string& vertexShaderSource,
|
||||
const std::string& fragmentShaderSource) {
|
||||
GLuint vertexShader = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
|
||||
GLuint fragmentShader =
|
||||
compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
|
||||
|
||||
GLuint shaderProgram = glCreateProgram();
|
||||
glAttachShader(shaderProgram, vertexShader);
|
||||
glAttachShader(shaderProgram, fragmentShader);
|
||||
glLinkProgram(shaderProgram);
|
||||
|
||||
GLint success;
|
||||
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
char infoLog[512];
|
||||
glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
|
||||
std::cerr << "Shader Program Linking Error: " << infoLog << std::endl;
|
||||
}
|
||||
|
||||
glDeleteShader(vertexShader);
|
||||
glDeleteShader(fragmentShader);
|
||||
|
||||
if (success) PDLOG("Shader [{}] compiled sucessfully", shaderProgram);
|
||||
|
||||
return shaderProgram;
|
||||
}
|
||||
|
||||
const char* vertex_shader = R"(
|
||||
const char* GfxOpenGL2::pVertCode = R"(
|
||||
#version 120
|
||||
|
||||
attribute vec2 pos;
|
||||
@@ -71,7 +28,7 @@ const char* vertex_shader = R"(
|
||||
}
|
||||
)";
|
||||
|
||||
const char* frag_shader = R"(
|
||||
const char* GfxOpenGL2::pFragCode = R"(
|
||||
#version 120
|
||||
|
||||
varying vec2 oUV;
|
||||
@@ -90,7 +47,7 @@ const char* frag_shader = R"(
|
||||
}
|
||||
)";
|
||||
|
||||
void GfxOpenGL::pSetupShaderAttribs(u32 shader) {
|
||||
void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {
|
||||
GLint _pos = glGetAttribLocation(shader, "pos");
|
||||
GLint _uv = glGetAttribLocation(shader, "uv");
|
||||
GLint _color = glGetAttribLocation(shader, "color");
|
||||
@@ -108,15 +65,15 @@ void GfxOpenGL::pSetupShaderAttribs(u32 shader) {
|
||||
glEnableVertexAttribArray(_color);
|
||||
}
|
||||
|
||||
void GfxOpenGL::SysInit() {
|
||||
pShader = createShaderProgram(vertex_shader, frag_shader);
|
||||
void GfxOpenGL2::SysInit() {
|
||||
pShader = CreateShaderProgram(pVertCode, pFragCode);
|
||||
glUseProgram(pShader);
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
pSetupShaderAttribs(pShader);
|
||||
glGenBuffers(1, &IBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||
|
||||
pSetupShaderAttribs(pShader);
|
||||
pLocTex = glGetUniformLocation(pShader, "tex");
|
||||
pLocAlfa = glGetUniformLocation(pShader, "alfa");
|
||||
pLocProjection = glGetUniformLocation(pShader, "projection");
|
||||
@@ -124,21 +81,20 @@ void GfxOpenGL::SysInit() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
PDLOG(
|
||||
"GfxOpenGL::SysInit():\n pShader = {}\n pLocTex = {}\n pLocAlfa = "
|
||||
"GfxOpenGL2::SysInit():\n pShader = {}\n pLocTex = {}\n pLocAlfa = "
|
||||
"{}\n pLocProjection = {}\n VBO = {}\n IBO = {}",
|
||||
pShader, pLocTex, pLocAlfa, pLocProjection, VBO, IBO);
|
||||
}
|
||||
|
||||
void GfxOpenGL::SysDeinit() {
|
||||
void GfxOpenGL2::SysDeinit() {
|
||||
glDeleteBuffers(1, &VBO);
|
||||
glDeleteBuffers(1, &IBO);
|
||||
PDLOG("GfxOpenGL::SysDeinit()");
|
||||
PDLOG("GfxOpenGL2::SysDeinit()");
|
||||
}
|
||||
|
||||
void GfxOpenGL::Submit(size_t count, size_t start) {
|
||||
void GfxOpenGL2::Submit(size_t count, size_t start) {
|
||||
BindTexture(CurrentTex);
|
||||
glUseProgram(pShader);
|
||||
pSetupShaderAttribs(pShader);
|
||||
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
|
||||
@@ -148,14 +104,17 @@ void GfxOpenGL::Submit(size_t count, size_t start) {
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(PD::u16),
|
||||
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT,
|
||||
pSetupShaderAttribs(pShader);
|
||||
GLint ibo = 0;
|
||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &ibo);
|
||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
|
||||
reinterpret_cast<void*>(start * sizeof(u16)));
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
BindTexture(0);
|
||||
}
|
||||
|
||||
void GfxOpenGL::BindTexture(TextureID id) {
|
||||
void GfxOpenGL2::BindTexture(TextureID id) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)id);
|
||||
glUniform1i(pLocTex, 0);
|
||||
@@ -164,25 +123,25 @@ void GfxOpenGL::BindTexture(TextureID id) {
|
||||
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
|
||||
}
|
||||
|
||||
void GfxOpenGL::SysReset() {
|
||||
void GfxOpenGL2::SysReset() {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
TextureID GfxOpenGL::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||
int h, TextureFormat type,
|
||||
TextureFilter filter) {
|
||||
TextureID GfxOpenGL2::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||
int h, TextureFormat type,
|
||||
TextureFilter filter) {
|
||||
GLuint texID;
|
||||
glGenTextures(1, &texID);
|
||||
glBindTexture(GL_TEXTURE_2D, texID);
|
||||
|
||||
// Set base format (Always using RGBA as base)
|
||||
GLenum fmt = GL_RGBA;
|
||||
/*if (type == PD::Li::Texture::Type::RGB24) {
|
||||
if (type == TextureFormat::RGB24) {
|
||||
fmt = GL_RGB;
|
||||
} else if (type == PD::Li::Texture::Type::A8) {
|
||||
} else if (type == TextureFormat::A8) {
|
||||
fmt = GL_ALPHA;
|
||||
}*/
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE,
|
||||
pixels.data());
|
||||
if (filter == TextureFilter::Linear) {
|
||||
@@ -193,12 +152,33 @@ TextureID GfxOpenGL::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
PDLOG("GfxOpenGL::LoadTexture -> [{}] {}", PD::ivec2(w, h), texID);
|
||||
PDLOG("GfxOpenGL2::LoadTexture -> [{}] {}, [{}, {}]", PD::ivec2(w, h), texID,
|
||||
type, filter);
|
||||
return texID;
|
||||
}
|
||||
|
||||
void GfxOpenGL::DeleteTexture(const TextureID& tex) {
|
||||
void GfxOpenGL2::DeleteTexture(const TextureID& tex) {
|
||||
GLuint tex_ = tex;
|
||||
glDeleteTextures(1, &tex_);
|
||||
}
|
||||
} // namespace PD
|
||||
} // namespace PD
|
||||
#else
|
||||
namespace PD {
|
||||
void GfxOpenGL2::SysInit() {
|
||||
PDLOG(
|
||||
"GfxOpenGL2::SysInit: OpenGL2 Driver is not included in "
|
||||
"palladium-system");
|
||||
}
|
||||
void GfxOpenGL2::SysDeinit() {}
|
||||
void GfxOpenGL2::Submit(size_t count, size_t start) {}
|
||||
void GfxOpenGL2::BindTexture(TextureID id) {}
|
||||
void GfxOpenGL2::SysReset() {}
|
||||
TextureID GfxOpenGL2::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||
int h, TextureFormat type,
|
||||
TextureFilter filter) {
|
||||
return 0;
|
||||
}
|
||||
void GfxOpenGL2::DeleteTexture(const TextureID& tex) {}
|
||||
void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {}
|
||||
} // namespace PD
|
||||
#endif
|
||||
180
backends/source/gfx_opengl3.cpp
Normal file
180
backends/source/gfx_opengl3.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
#include <pd_system/gfx_opengl3.hpp>
|
||||
#if defined(PD_ENABLE_OPENGL3)
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <pd/drivers/drivers.hpp>
|
||||
#include <pd_system/gl-helper.hpp>
|
||||
|
||||
namespace PD {
|
||||
const char* GfxOpenGL3::pVertCode = R"(
|
||||
#version 330 core
|
||||
|
||||
layout(location = 0) in vec2 pos;
|
||||
layout(location = 1) in vec2 uv;
|
||||
layout(location = 2) in vec4 color;
|
||||
|
||||
out vec2 oUV;
|
||||
out vec4 oColor;
|
||||
|
||||
// Probably forgot about this matrix and
|
||||
// searched hours for why the rendering isn't working :/
|
||||
uniform mat4 projection;
|
||||
|
||||
void main() {
|
||||
gl_Position = projection*vec4(pos, 0.0, 1.0);
|
||||
oUV = uv;
|
||||
oColor = color;
|
||||
}
|
||||
)";
|
||||
|
||||
const char* GfxOpenGL3::pFragCode = R"(
|
||||
#version 330 core
|
||||
|
||||
in vec2 oUV;
|
||||
in vec4 oColor;
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform bool alfa;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
vec4 tc = texture(tex, oUV);
|
||||
if (alfa) {
|
||||
FragColor = vec4(oColor.rgb, tc.a * oColor.a);
|
||||
} else {
|
||||
FragColor = tc * oColor;
|
||||
}
|
||||
}
|
||||
)";
|
||||
|
||||
void GfxOpenGL3::SysInit() {
|
||||
pShader = CreateShaderProgram(pVertCode, pFragCode);
|
||||
glUseProgram(pShader);
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glBindVertexArray(VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(PD::Li::Vertex),
|
||||
(void*)offsetof(PD::Li::Vertex, pos));
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(PD::Li::Vertex),
|
||||
(void*)offsetof(PD::Li::Vertex, uv));
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(PD::Li::Vertex),
|
||||
(void*)offsetof(PD::Li::Vertex, color));
|
||||
|
||||
glGenBuffers(1, &IBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||
|
||||
pLocTex = glGetUniformLocation(pShader, "tex");
|
||||
pLocAlfa = glGetUniformLocation(pShader, "alfa");
|
||||
pLocProjection = glGetUniformLocation(pShader, "projection");
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
PDLOG(
|
||||
"GfxOpenGL3::SysInit():\n pShader = {}\n pLocTex = {}\n pLocAlfa = "
|
||||
"{}\n pLocProjection = {}\n VBO = {}\n IBO = {}, VAO = {}",
|
||||
pShader, pLocTex, pLocAlfa, pLocProjection, VBO, IBO, VAO);
|
||||
}
|
||||
|
||||
void GfxOpenGL3::SysDeinit() {
|
||||
glDeleteBuffers(1, &VBO);
|
||||
glDeleteBuffers(1, &IBO);
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
PDLOG("GfxOpenGL3::SysDeinit()");
|
||||
}
|
||||
|
||||
void GfxOpenGL3::Submit(size_t count, size_t start) {
|
||||
BindTexture(CurrentTex);
|
||||
glUseProgram(pShader);
|
||||
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
|
||||
GetVertexBufPtr(0), GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(u16),
|
||||
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
|
||||
reinterpret_cast<void*>(start * sizeof(u16)));
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
BindTexture(0);
|
||||
}
|
||||
|
||||
void GfxOpenGL3::BindTexture(TextureID id) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)id);
|
||||
glUniform1i(pLocTex, 0);
|
||||
GLint fmt = 0;
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
|
||||
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
|
||||
}
|
||||
|
||||
void GfxOpenGL3::SysReset() {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
TextureID GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||
int h, TextureFormat type,
|
||||
TextureFilter filter) {
|
||||
GLuint texID;
|
||||
glGenTextures(1, &texID);
|
||||
glBindTexture(GL_TEXTURE_2D, texID);
|
||||
|
||||
// Set base format (Always using RGBA as base)
|
||||
GLenum fmt = GL_RGBA;
|
||||
if (type == TextureFormat::RGB24) {
|
||||
fmt = GL_RGB;
|
||||
} else if (type == TextureFormat::A8) {
|
||||
fmt = GL_ALPHA;
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE,
|
||||
pixels.data());
|
||||
if (filter == TextureFilter::Linear) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
} else if (filter == TextureFilter::Nearest) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
PDLOG("GfxOpenGL3::LoadTexture -> [{}] {}, [{}, {}]", PD::ivec2(w, h), texID,
|
||||
type, filter);
|
||||
return texID;
|
||||
}
|
||||
|
||||
void GfxOpenGL3::DeleteTexture(const TextureID& tex) {
|
||||
GLuint tex_ = tex;
|
||||
glDeleteTextures(1, &tex_);
|
||||
}
|
||||
} // namespace PD
|
||||
#else
|
||||
namespace PD {
|
||||
void GfxOpenGL3::SysInit() {
|
||||
PDLOG(
|
||||
"GfxOpenGL3::SysInit: OpenGL3 Driver is not included in "
|
||||
"palladium-system");
|
||||
}
|
||||
void GfxOpenGL3::SysDeinit() {}
|
||||
void GfxOpenGL3::Submit(size_t count, size_t start) {}
|
||||
void GfxOpenGL3::BindTexture(TextureID id) {}
|
||||
void GfxOpenGL3::SysReset() {}
|
||||
TextureID GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||
int h, TextureFormat type,
|
||||
TextureFilter filter) {
|
||||
return 0;
|
||||
}
|
||||
void GfxOpenGL3::DeleteTexture(const TextureID& tex) {}
|
||||
void GfxOpenGL3::pSetupShaderAttribs(u32 shader) {}
|
||||
} // namespace PD
|
||||
#endif
|
||||
46
backends/source/gl-helper.cpp
Normal file
46
backends/source/gl-helper.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <pd_system/gl-helper.hpp>
|
||||
|
||||
namespace PD {
|
||||
GLuint compileShader(const char* src, GLenum type) {
|
||||
GLuint shader = glCreateShader(type);
|
||||
glShaderSource(shader, 1, &src, nullptr);
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint success;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
char infoLog[512];
|
||||
glGetShaderInfoLog(shader, 512, nullptr, infoLog);
|
||||
std::cerr << "Shader Compilation Error: " << infoLog << std::endl;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
u32 CreateShaderProgram(const char* vert, const char* frag) {
|
||||
GLuint vertexShader = compileShader(vert, GL_VERTEX_SHADER);
|
||||
GLuint fragmentShader = compileShader(frag, GL_FRAGMENT_SHADER);
|
||||
|
||||
GLuint shaderProgram = glCreateProgram();
|
||||
glAttachShader(shaderProgram, vertexShader);
|
||||
glAttachShader(shaderProgram, fragmentShader);
|
||||
glLinkProgram(shaderProgram);
|
||||
|
||||
GLint success;
|
||||
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
char infoLog[512];
|
||||
glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
|
||||
std::cerr << "Shader Program Linking Error: " << infoLog << std::endl;
|
||||
}
|
||||
|
||||
glDeleteShader(vertexShader);
|
||||
glDeleteShader(fragmentShader);
|
||||
|
||||
if (success) PDLOG("Shader [{}] compiled sucessfully", shaderProgram);
|
||||
|
||||
return shaderProgram;
|
||||
}
|
||||
} // namespace PD
|
||||
@@ -23,6 +23,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
@@ -43,7 +44,7 @@ using u16 = unsigned short;
|
||||
using u32 = unsigned int;
|
||||
using u64 = unsigned long long;
|
||||
using ptr = uintptr_t;
|
||||
void Log(const std::string& txt);
|
||||
PD_API void Log(const std::string& txt);
|
||||
template <typename... Args>
|
||||
void Log(std::format_string<Args...> fmt, Args&&... args) {
|
||||
std::string msg = std::format(fmt, std::forward<Args>(args)...);
|
||||
|
||||
@@ -93,6 +93,6 @@ struct std::formatter<PD::Color> : std::formatter<std::string> {
|
||||
std::format_parse_context::const_iterator end,
|
||||
size_t len, const char* what) {
|
||||
return (end - it >= static_cast<std::ptrdiff_t>(len) &&
|
||||
std::string_view(it, len) == what);
|
||||
std::string_view(&*it, len) == what); // msvc things...
|
||||
}
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/drivers/formatters.hpp>
|
||||
#include <pd/drivers/gfx.hpp>
|
||||
#include <pd/drivers/os.hpp>
|
||||
#include <pd/drivers/gfx.hpp>
|
||||
44
include/pd/drivers/formatters.hpp
Normal file
44
include/pd/drivers/formatters.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/drivers/gfx.hpp>
|
||||
|
||||
template <>
|
||||
struct std::formatter<PD::TextureFilter> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const PD::TextureFilter& value, FormatContext& ctx) const {
|
||||
std::string_view ret = "Unknown";
|
||||
switch (value) {
|
||||
case PD::TextureFilter::Linear:
|
||||
ret = "Linear";
|
||||
break;
|
||||
case PD::TextureFilter::Nearest:
|
||||
ret = "Nearest";
|
||||
break;
|
||||
}
|
||||
return std::format_to(ctx.out(), "{}", ret);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std::formatter<PD::TextureFormat> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const PD::TextureFormat& value, FormatContext& ctx) const {
|
||||
std::string_view ret = "Unknown";
|
||||
switch (value) {
|
||||
case PD::TextureFormat::RGBA32:
|
||||
ret = "RGBA32";
|
||||
break;
|
||||
case PD::TextureFormat::RGB24:
|
||||
ret = "RGB24";
|
||||
break;
|
||||
case PD::TextureFormat::A8:
|
||||
ret = "A8";
|
||||
break;
|
||||
}
|
||||
return std::format_to(ctx.out(), "{}", ret);
|
||||
}
|
||||
};
|
||||
@@ -19,6 +19,7 @@ enum class TextureFilter {
|
||||
|
||||
enum class TextureFormat {
|
||||
RGBA32,
|
||||
RGB24,
|
||||
A8,
|
||||
};
|
||||
|
||||
@@ -69,20 +70,17 @@ struct DefaultGfxConfig {
|
||||
// Index Allocator
|
||||
template <typename T>
|
||||
using IndexAlloc = std::allocator<T>;
|
||||
using IndexType = u16; // Index Type
|
||||
|
||||
static constexpr size_t NumVertices = 32768; // 8192*4
|
||||
static constexpr size_t NumIndices = 49152; // 8192*6
|
||||
};
|
||||
|
||||
template <typename Config = DefaultGfxConfig>
|
||||
class PD_API GfxDriverBase : public GfxDriver {
|
||||
class GfxDriverBase : public GfxDriver {
|
||||
public:
|
||||
using IndexType = Config::IndexType;
|
||||
using VtxPool =
|
||||
Pool<Li::Vertex, typename Config::template VertexAlloc<Li::Vertex>>;
|
||||
using IdxPool =
|
||||
Pool<IndexType, typename Config::template VertexAlloc<IndexType>>;
|
||||
using IdxPool = Pool<u16, typename Config::template VertexAlloc<u16>>;
|
||||
GfxDriverBase(std::string_view name = "Default") : GfxDriver(name) {}
|
||||
virtual ~GfxDriverBase() {}
|
||||
|
||||
@@ -111,17 +109,19 @@ class PD_API GfxDriverBase : public GfxDriver {
|
||||
for (size_t i = 0; i < c.IndexCount; i++) {
|
||||
pIdx[i] = CurrentVertex + c.FirstIndex[i];
|
||||
}
|
||||
CurrentIndex += c.IndexCount;
|
||||
CurrentVertex += c.VertexCount;
|
||||
for (size_t i = 0; i < c.VertexCount; i++) {
|
||||
pVtx[i] = c.FirstVertex[i];
|
||||
}
|
||||
index++;
|
||||
}
|
||||
Submit(index - startidx, startidx);
|
||||
Submit(CurrentIndex - startidx, startidx);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
IndexType* GetIndexBufPtr(size_t start) { return &pIdxPool[start]; }
|
||||
u16* GetIndexBufPtr(size_t start) { return &pIdxPool[start]; }
|
||||
Li::Vertex* GetVertexBufPtr(size_t start) { return &pVtxPool[start]; }
|
||||
void ResetPools() override {
|
||||
pVtxPool.Reset();
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
namespace PD {
|
||||
namespace Li {
|
||||
void InitPools(size_t max_vertices = 32768);
|
||||
Vertex* AllocateVertices(size_t count);
|
||||
u16* AllocateIndices(size_t count);
|
||||
PD_API void InitPools(size_t max_vertices = 32768);
|
||||
PD_API Vertex* AllocateVertices(size_t count);
|
||||
PD_API u16* AllocateIndices(size_t count);
|
||||
} // namespace Li
|
||||
} // namespace PD
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <iostream>
|
||||
#include <pd/common.hpp>
|
||||
|
||||
void PD::Log(const std::string& txt) {
|
||||
PD_API void PD::Log(const std::string& txt) {
|
||||
std::cout << "[PD] " << txt << std::endl;
|
||||
}
|
||||
@@ -3,19 +3,20 @@
|
||||
namespace PD {
|
||||
PD_API std::unique_ptr<GfxDriver> Gfx::driver;
|
||||
|
||||
GfxDriver::GfxDriver(std::string_view name) : DriverInterface(name) {}
|
||||
PD_API GfxDriver::GfxDriver(std::string_view name) : DriverInterface(name) {}
|
||||
|
||||
void GfxDriver::SetViewPort(const ivec2& size) {
|
||||
PD_API void GfxDriver::SetViewPort(const ivec2& size) {
|
||||
ViewPort = size;
|
||||
Projection = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f);
|
||||
}
|
||||
void GfxDriver::SetViewPort(int x, int y) {
|
||||
|
||||
PD_API void GfxDriver::SetViewPort(int x, int y) {
|
||||
ViewPort.x = x;
|
||||
ViewPort.y = y;
|
||||
Projection = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f);
|
||||
}
|
||||
|
||||
void GfxDriver::Reset() {
|
||||
PD_API void GfxDriver::Reset() {
|
||||
CurrentVertex = 0;
|
||||
CurrentIndex = 0;
|
||||
ResetPools();
|
||||
|
||||
@@ -9,16 +9,16 @@ namespace Li {
|
||||
PD::Pool<Vertex> pVtxPool;
|
||||
PD::Pool<u16> pIdxPool;
|
||||
|
||||
void InitPools(size_t max_vertices) {
|
||||
PD_API void InitPools(size_t max_vertices) {
|
||||
pVtxPool.Init(max_vertices);
|
||||
pIdxPool.Init(max_vertices * 2);
|
||||
}
|
||||
|
||||
Vertex* AllocateVertices(size_t count) { return pVtxPool.Allocate(count); }
|
||||
PD_API Vertex* AllocateVertices(size_t count) { return pVtxPool.Allocate(count); }
|
||||
|
||||
u16* AllocateIndices(size_t count) { return pIdxPool.Allocate(count); }
|
||||
PD_API u16* AllocateIndices(size_t count) { return pIdxPool.Allocate(count); }
|
||||
|
||||
void ResetPools() {
|
||||
PD_API void ResetPools() {
|
||||
pVtxPool.Reset();
|
||||
pIdxPool.Reset();
|
||||
}
|
||||
|
||||
@@ -3,4 +3,4 @@ cmake_minimum_required(VERSION 3.22)
|
||||
project(gfx-tests)
|
||||
|
||||
add_executable(gfx-tests ${CMAKE_CURRENT_SOURCE_DIR}/source/main.cpp)
|
||||
target_link_libraries(gfx-tests PRIVATE palladium::palladium pd-system glfw)
|
||||
target_link_libraries(gfx-tests PRIVATE palladium::palladium pd-system glfw stb)
|
||||
|
||||
@@ -3,42 +3,98 @@
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <format>
|
||||
#include <gfx_opengl.hpp>
|
||||
#include <iostream>
|
||||
#include <palladium>
|
||||
#include <pdsystem>
|
||||
|
||||
#include "pd/core/vec2.hpp"
|
||||
#include "pd/lithium/pools.hpp"
|
||||
#include "pd/lithium/vertex.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <d3d9.h>
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
#include <GLFW/glfw3native.h>
|
||||
#endif
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
|
||||
enum class Driver {
|
||||
Unknown = 0,
|
||||
OpenGL2 = 1,
|
||||
OpenGL3 = 2,
|
||||
DirectX9 = 3,
|
||||
};
|
||||
|
||||
PD::TextureID LoadTex(const std::string& path) {
|
||||
int w, h, c;
|
||||
stbi_uc* buf = stbi_load(path.c_str(), &w, &h, &c, 4);
|
||||
return PD::Gfx::LoadTexture(std::vector<PD::u8>(buf, buf + (w * h * 4)), w,
|
||||
h);
|
||||
}
|
||||
|
||||
class App {
|
||||
public:
|
||||
App() {
|
||||
App(Driver d = Driver::OpenGL3) : pDriver(d) {
|
||||
PD::Os::UseDriver<PD::OsDriver>();
|
||||
PD::Gfx::UseDriver<PD::GfxOpenGL>();
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
||||
window = glfwCreateWindow(1280, 720, "gfx_tests", nullptr, nullptr);
|
||||
std::string winname = "gfx_test";
|
||||
if (d == Driver::OpenGL2) {
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
||||
PD::Gfx::UseDriver<PD::GfxOpenGL2>();
|
||||
winname += " (OpenGL2)";
|
||||
} else if (d == Driver::OpenGL3) {
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
PD::Gfx::UseDriver<PD::GfxOpenGL3>();
|
||||
winname += " (OpenGL3)";
|
||||
} else if (d == Driver::DirectX9) {
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
winname += " (DirectX9)";
|
||||
}
|
||||
window = glfwCreateWindow(1280, 720, winname.c_str(), nullptr, nullptr);
|
||||
glfwMakeContextCurrent(window);
|
||||
gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress));
|
||||
if (d == Driver::OpenGL2 || d == Driver::OpenGL3) {
|
||||
gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress));
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if (d == Driver::DirectX9) {
|
||||
d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
auto hwnd = glfwGetWin32Window(window);
|
||||
D3DPRESENT_PARAMETERS d3dpp = {};
|
||||
d3dpp.Windowed = TRUE;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3dpp.hDeviceWindow = hwnd;
|
||||
|
||||
HRESULT hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
&d3dpp, &dx9_device);
|
||||
if (FAILED(hr)) {
|
||||
MessageBoxW(nullptr, L"Failed to create D3D9 device", L"Error", MB_OK);
|
||||
std::abort();
|
||||
}
|
||||
PD::Gfx::UseDriver<PD::GfxDirectX9>(dx9_device);
|
||||
}
|
||||
#endif
|
||||
glfwSwapInterval(1);
|
||||
PD::Gfx::Init();
|
||||
PD::Li::InitPools(8192);
|
||||
std::vector<PD::u8> img(16 * 16 * 4, 0xff);
|
||||
pTex = PD::Gfx::LoadTexture(img, 16, 16);
|
||||
pTex = LoadTex("icon.png");
|
||||
/*std::vector<PD::u8> img(16 * 16 * 4, 0xff);
|
||||
pTex = PD::Gfx::LoadTexture(img, 16, 16);*/
|
||||
std::cout << "GfxDriver: " << PD::Gfx::GetDriverName() << std::endl;
|
||||
pPool.Init(10);
|
||||
auto cmd = pPool.Allocate(1);
|
||||
cmd->Reserve(4, 6);
|
||||
cmd->Add(PD::Li::Vertex(PD::fvec2(0, 0), PD::fvec2(0, 0), 0xffffffff));
|
||||
cmd->Add(PD::Li::Vertex(PD::fvec2(50, 0), PD::fvec2(1, 0), 0xffffffff));
|
||||
cmd->Add(PD::Li::Vertex(PD::fvec2(50, 50), PD::fvec2(1, 1), 0xffffffff));
|
||||
cmd->Add(PD::Li::Vertex(PD::fvec2(0, 50), PD::fvec2(0, 1), 0xffffffff));
|
||||
cmd->Add(0, 1, 2);
|
||||
cmd->Add(0, 2, 3);
|
||||
cmd->Add(PD::Li::Vertex(PD::fvec2(0, 0), PD::fvec2(0, 0), 0xffffffff));
|
||||
cmd->Add(PD::Li::Vertex(PD::fvec2(256, 0), PD::fvec2(1, 0), 0xffffffff));
|
||||
cmd->Add(PD::Li::Vertex(PD::fvec2(256, 256), PD::fvec2(1, 1), 0xffffffff));
|
||||
cmd->Add(PD::Li::Vertex(PD::fvec2(0, 256), PD::fvec2(0, 1), 0xffffffff));
|
||||
cmd->Tex = pTex;
|
||||
}
|
||||
~App() {
|
||||
@@ -49,14 +105,33 @@ class App {
|
||||
|
||||
void Run() {
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
glViewport(0, 0, 1280, 720);
|
||||
glClearColor(0.1, 0.1, 0.1, 0.1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (pDriver == Driver::OpenGL2 || pDriver == Driver::OpenGL3) {
|
||||
glClearColor(0.1, 0.1, 0.1, 0.1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glViewport(0, 0, 1280, 720);
|
||||
} else if (pDriver == Driver::DirectX9) {
|
||||
#ifdef _WIN32
|
||||
if (dx9_device) {
|
||||
dx9_device->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
|
||||
D3DCOLOR_XRGB(25, 25, 25), 1.0f, 0);
|
||||
dx9_device->BeginScene();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
PD::Gfx::Reset();
|
||||
PD::Gfx::SetViewPort(1280, 720);
|
||||
PD::Gfx::Draw(pPool);
|
||||
glfwPollEvents();
|
||||
glfwSwapBuffers(window);
|
||||
if (pDriver == Driver::DirectX9) {
|
||||
#ifdef _WIN32
|
||||
if (dx9_device) {
|
||||
dx9_device->EndScene();
|
||||
dx9_device->Present(nullptr, nullptr, nullptr, nullptr);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,10 +139,25 @@ class App {
|
||||
GLFWwindow* window = nullptr;
|
||||
PD::Pool<PD::Li::Command> pPool;
|
||||
PD::ptr pTex = 0;
|
||||
Driver pDriver;
|
||||
#ifdef _WIN32
|
||||
IDirect3D9* d3d = nullptr;
|
||||
IDirect3DDevice9* dx9_device = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
int main() {
|
||||
App app;
|
||||
int main(int argc, char** argv) {
|
||||
Driver drv = Driver::OpenGL3;
|
||||
if (argc == 2) {
|
||||
if (std::string(argv[1]) == "gl2") {
|
||||
drv = Driver::OpenGL2;
|
||||
} else if (std::string(argv[1]) == "gl3") {
|
||||
drv = Driver::OpenGL3;
|
||||
} else if (std::string(argv[1]) == "dx9") {
|
||||
drv = Driver::DirectX9;
|
||||
}
|
||||
}
|
||||
App app(drv);
|
||||
app.Run();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user