Skip to content

Commit

Permalink
sokol: Add imgui introspection support
Browse files Browse the repository at this point in the history
  • Loading branch information
IonAgorria committed Oct 21, 2024
1 parent a0841b7 commit 551267a
Show file tree
Hide file tree
Showing 15 changed files with 197 additions and 58 deletions.
15 changes: 12 additions & 3 deletions Source/Render/inc/IRenderDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ class cInterfaceRenderDevice : public cUnknownClass
std::unordered_map<uint64_t, class DrawBuffer*> drawBuffers;
Mat4f orthoVP;
eCullMode CameraCullMode = CULL_NONE;
bool debugUIEnabled = false;

virtual void DrawFieldDispatcher(class FieldDispatcher* ffd, uint8_t transparent);

Expand Down Expand Up @@ -268,6 +269,16 @@ class cInterfaceRenderDevice : public cUnknownClass
virtual void DrawPoint(const Vect3f &v1, const sColor4c& color);
virtual void FlushPrimitive3D();

virtual void DebugUISetEnable(bool enabled);
virtual bool DebugUIIsEnabled();
virtual bool DebugUIMouseMove(const Vect2f& pos);
virtual bool DebugUIMousePress(const Vect2f& pos, uint8_t button, bool pressed);
virtual bool DebugUIKeyPress(struct sKey* key, bool pressed);

#ifdef PERIMETER_DEBUG
virtual void StartCaptureFrame();
#endif

// Decl only methods

virtual eRenderDeviceSelection GetRenderSelection() const = 0;
Expand Down Expand Up @@ -333,9 +344,7 @@ class cInterfaceRenderDevice : public cUnknownClass
virtual cTexture* GetShadowMap() = 0;
virtual cTexture* GetLightMap() = 0;

#ifdef PERIMETER_DEBUG
virtual void StartCaptureFrame();
#endif
// Decl only methods end
};

cInterfaceRenderDevice* CreateIRenderDevice(eRenderDeviceSelection selection);
Expand Down
78 changes: 44 additions & 34 deletions Source/Render/sokol/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,26 @@ OPTION(OPTION_PROCESS_SHADERS "Re-Process game shaders" OFF)
#Include Sokol
FetchContent_Declare(sokol
GIT_REPOSITORY https://github.com/floooh/sokol
GIT_TAG "67339198b75a7d04da3676db2b56514bf363d4b1"
GIT_TAG "4bda1469d3b311af03a34dd956460776c920dc2e"
GIT_SHALLOW OFF
)
)
FetchContent_MakeAvailable(sokol)

#Include ImGui
FetchContent_Declare(imgui
GIT_REPOSITORY https://github.com/ocornut/imgui
GIT_TAG "cb16568fca5297512ff6a8f3b877f461c4323fbe"
GIT_SHALLOW OFF
)
FetchContent_MakeAvailable(imgui)

IF (OPTION_PROCESS_SHADERS)
#Download precompiled sokol-shdc
FetchContent_Declare(sokol-tools-bin
GIT_REPOSITORY https://github.com/floooh/sokol-tools-bin
GIT_TAG "9a54e8ea68807733d82f4b169a8752a8fcad2040"
GIT_TAG "f1af4529746b804d6c79d5a36c333aec489fab27"
GIT_SHALLOW OFF
)
)
FetchContent_MakeAvailable(sokol-tools-bin)

if(NOT DEFINED ENV{PERIMETER_SHADER_LANG})
Expand Down Expand Up @@ -74,64 +82,58 @@ if (MACOS)
#Required for compiling some glue as Obj-C
set(RenderSokol_SokolImpl sokol/SokolImpl.mm)
if(OPTION_SOKOL_API MATCHES "GLCORE")
message("Sokol API: OpenGL Core")
add_definitions(-DSOKOL_GLCORE)
set(SOKOL_GL ON)
set(RenderSokol_LINK_LIBS "-framework OpenGL")
elseif(OPTION_SOKOL_API MATCHES "METAL")
message("Sokol API: Metal")
add_definitions(-DSOKOL_METAL)
set(RenderSokol_LINK_LIBS "-framework Foundation -framework QuartzCore -framework Metal -framework MetalKit")
#set(RenderSokol_LINK_LIBS "${RenderSokol_LINK_LIBS} -fobjc-arc -framework AudioToolbox")
#You may wanna use UIKit here instead when porting to iOS in far far future
set(RenderSokol_LINK_LIBS "${RenderSokol_LINK_LIBS} -framework Cocoa")
else()
message(SEND_ERROR "Unknown Sokol API selected: ${OPTION_SOKOL_API}")
endif()
elseif(PERIMETER_WINDOWS)
if(NOT OPTION_SOKOL_API)
set(OPTION_SOKOL_API "D3D11")
endif ()
if(OPTION_SOKOL_API MATCHES "D3D11")
message("Sokol API: DirectX 11")
add_definitions(-DSOKOL_D3D11)
set(RenderSokol_LINK_LIBS d3d11)
elseif(OPTION_SOKOL_API MATCHES "GLCORE")
message("Sokol API: OpenGL Core")
add_definitions(-DSOKOL_GLCORE)
set(SOKOL_GL ON)
set(RenderSokol_LINK_LIBS opengl32)
else()
message(SEND_ERROR "Unknown Sokol API selected: ${OPTION_SOKOL_API}")
endif()
else()
if(NOT OPTION_SOKOL_API)
set(OPTION_SOKOL_API "GLCORE")
endif ()
if(OPTION_SOKOL_API MATCHES "GLES3")
message("Sokol API: OpenGLES 3.0")
add_definitions(-DSOKOL_GLES3)
set(SOKOL_GL ON)
set(RenderSokol_LINK_LIBS GL)
elseif(OPTION_SOKOL_API MATCHES "GLCORE")
message("Sokol API: OpenGL Core")
add_definitions(-DSOKOL_GLCORE)
set(SOKOL_GL ON)
elseif(OPTION_SOKOL_API MATCHES "D3D11")
message("Sokol API: D3D11")
add_definitions(-DSOKOL_D3D11)
#The rest done after add_library()
else()
message(SEND_ERROR "Unknown Sokol API selected: ${OPTION_SOKOL_API}")
endif()
if (SOKOL_GL)
set(RenderSokol_LINK_LIBS GL)
endif ()
endif()
endif()
message(${OPTION_SOKOL_API})
if(OPTION_SOKOL_API MATCHES "GLES3")
message("Sokol API: OpenGLES 3.0")
add_definitions(-DSOKOL_GLES3)
set(SOKOL_GL ON)
set(RenderSokol_ImguiBackend ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp)
elseif(OPTION_SOKOL_API MATCHES "GLCORE")
message("Sokol API: OpenGL Core")
add_definitions(-DSOKOL_GLCORE)
set(RenderSokol_ImguiBackend ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp)
elseif(OPTION_SOKOL_API MATCHES "D3D11")
message("Sokol API: D3D11")
add_definitions(-DSOKOL_D3D11)
set(RenderSokol_ImguiBackend ${imgui_SOURCE_DIR}/backends/imgui_impl_dx11.cpp)
elseif(OPTION_SOKOL_API MATCHES "METAL")
message("Sokol API: Metal")
add_definitions(-DSOKOL_METAL)
set(RenderSokol_ImguiBackend ${imgui_SOURCE_DIR}/backends/imgui_impl_metal.mm)
else()
message(SEND_ERROR "Unknown Sokol API selected: ${OPTION_SOKOL_API}")
endif()

#Required for SDL_GL_* and SDL_SetHint/SDL_GetHint funcs called during render init
set(RenderSokol_LINK_LIBS ${RenderSokol_LINK_LIBS} ${SDL2_LIBRARY})

add_library(RenderSokol STATIC
set(RenderSokol_SRCS
${RenderSokol_SokolImpl}
sokol/SokolResources.cpp
sokol/SokolRender.cpp
Expand All @@ -140,8 +142,15 @@ add_library(RenderSokol STATIC
sokol/SokolRenderDraw.cpp
sokol/SokolRenderPipeline.cpp
sokol/SokolShaders.cpp
${imgui_SOURCE_DIR}/imgui.cpp
${imgui_SOURCE_DIR}/imgui_draw.cpp
${imgui_SOURCE_DIR}/imgui_tables.cpp
${imgui_SOURCE_DIR}/imgui_widgets.cpp
${RenderSokol_ImguiBackend}
)

add_library(RenderSokol STATIC ${RenderSokol_SRCS})

if(NOT PERIMETER_WINDOWS AND OPTION_SOKOL_API MATCHES "D3D11")
#This way dxvk will be fetched and compiled before RenderSokol
add_dependencies(RenderSokol dxvk)
Expand Down Expand Up @@ -170,6 +179,7 @@ target_include_directories(RenderSokol PRIVATE
"${PROJECT_SOURCE_DIR}/Source/Render/tracker"
"${PROJECT_SOURCE_DIR}/Source/Render/tilemap"
"${sokol_SOURCE_DIR}/"
"${imgui_SOURCE_DIR}/"
)

#Render also needs headers
Expand Down
8 changes: 6 additions & 2 deletions Source/Render/sokol/SokolImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@
#define LoadLibraryA(a) (nullptr)
#define GetProcAddress(a,b) (nullptr)
#endif

#include <imgui.h>

#define SOKOL_IMPL
#define SOKOL_TRACE_HOOKS
#define SOKOL_ASSERT xassert

#ifdef __GNUG__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wextra"
#endif
#include <sokol_gfx.h>
#include <sokol_log.h>
#include "SokolIncludes.h"
#ifdef __GNUG__
#pragma GCC diagnostic pop
#endif
10 changes: 10 additions & 0 deletions Source/Render/sokol/SokolIncludes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef PERIMETER_SOKOLINCLUDES_H
#define PERIMETER_SOKOLINCLUDES_H

#include <sokol_log.h>
#include <sokol_gfx.h>
#define SOKOL_IMGUI_NO_SOKOL_APP
#include <util/sokol_imgui.h>
#include <util/sokol_gfx_imgui.h>

#endif //PERIMETER_SOKOLINCLUDES_H
16 changes: 12 additions & 4 deletions Source/Render/sokol/SokolRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
#include "StdAfxRD.h"
#include "xmath.h"
#include "Umath.h"
#include <sokol_gfx.h>
#include <sokol_log.h>
#include "SokolIncludes.h"
#include "SokolResources.h"
#include "IRenderDevice.h"
#include "SokolRender.h"
Expand Down Expand Up @@ -260,9 +259,13 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres

//Call sokol gfx setup
sg_setup(&desc);
#ifdef PERIMETER_DEBUG
printf("cSokolRender::Init sg_setup done\n");
#endif

debugUIEnabled = false;

if (check_command_line("render_debug") != nullptr) {
DebugUISetEnable(true);
}

//Create sampler
sg_sampler_desc sampler_desc = {};
Expand Down Expand Up @@ -397,6 +400,11 @@ int cSokolRender::Done() {
sdl_gl_context = nullptr;
}
#endif
if (imgui_state) {
sgimgui_discard(imgui_state);
delete imgui_state;
imgui_state = nullptr;
}
RenderSubmitEvent(RenderEvent::DONE, "Sokol done");
return ret;
}
Expand Down
7 changes: 6 additions & 1 deletion Source/Render/sokol/SokolRender.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#define PERIMETER_SOKOL_GL (1)
#endif

#include <sokol_gfx.h>
#include <SDL_video.h>

#include "SokolTypes.h"
Expand Down Expand Up @@ -92,6 +91,8 @@ class cSokolRender: public cInterfaceRenderDevice {
friend const void* sokol_d3d_render_target_view_cb();
friend const void* sokol_d3d_depth_stencil_view_cb();
#endif

struct sgimgui_t* imgui_state = nullptr;

//Stores resources for reusing
void ClearPooledResources(uint32_t max_life);
Expand Down Expand Up @@ -240,6 +241,10 @@ class cSokolRender: public cInterfaceRenderDevice {
void StartCaptureFrame() override;
#endif

void DebugUISetEnable(bool state) override;
bool DebugUIMouseMove(const Vect2f& pos) override;
bool DebugUIMousePress(const Vect2f& pos, uint8_t button, bool pressed) override;

int SetGamma(float fGamma,float fStart=0.f,float fFinish=1.f) override;

void DeleteVertexBuffer(class VertexBuffer &vb) override;
Expand Down
1 change: 1 addition & 0 deletions Source/Render/sokol/SokolRenderDraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "xmath.h"
#include "VertexFormat.h"
#include "IRenderDevice.h"
#include "SokolIncludes.h"
#include "SokolRender.h"
#include "SokolResources.h"
#include "DrawBuffer.h"
Expand Down
2 changes: 1 addition & 1 deletion Source/Render/sokol/SokolRenderPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "Umath.h"
#include "StdAfxRD.h"
#include "VertexFormat.h"
#include <sokol_gfx.h>
#include "SokolIncludes.h"
#include "SokolRender.h"
#include "SokolRenderPipeline.h"
#include "SokolShaders.h"
Expand Down
49 changes: 47 additions & 2 deletions Source/Render/sokol/SokolRenderState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
#include <array>
#include <string>
#include <vector>
#include <SDL_mouse.h>
#include "xmath.h"
#include "Umath.h"
#include "StdAfxRD.h"
#include "VertexFormat.h"
#include <sokol_gfx.h>
#include "SokolIncludes.h"
#include "SokolResources.h"
#include "IRenderDevice.h"
#include "SokolRender.h"
Expand Down Expand Up @@ -39,7 +40,6 @@ void sokol_metal_render_callback() {
#ifdef PERIMETER_DEBUG
void sokol_metal_capture_frame();
#endif

#endif

//How many frames to store the resources until freed
Expand Down Expand Up @@ -97,6 +97,18 @@ void cSokolRender::DoSokolRendering() {
}
#endif

if (debugUIEnabled) {
static int last_clock = clocki();
const simgui_frame_desc_t frame_desc = {

Check failure on line 102 in Source/Render/sokol/SokolRenderState.cpp

View workflow job for this annotation

GitHub Actions / Release x86 64 bits

'frame_desc': const object must be initialized
.width = ScreenSize.x,

Check failure on line 103 in Source/Render/sokol/SokolRenderState.cpp

View workflow job for this annotation

GitHub Actions / Release x86 64 bits

use of designated initializers requires at least '/std:c++20'
.height = ScreenSize.y,
.delta_time = clocki() - last_clock,
.dpi_scale = 1.0
};
last_clock = clocki();
simgui_new_frame(&frame_desc);
}

for (auto& target : { shadowMapRenderTarget, lightMapRenderTarget }) {
if (target != nullptr) {
ProcessRenderPass(target->render_pass, target->commands);
Expand Down Expand Up @@ -281,6 +293,13 @@ void cSokolRender::ProcessRenderPass(sg_pass& render_pass, const std::vector<Sok
sg_draw(static_cast<int>(command->base_elements), static_cast<int>(command->indices), 1);
}

//Special pass for imgui during swapchain pass
if (debugUIEnabled && render_pass.attachments.id == 0) {
sgimgui_draw(imgui_state);
sgimgui_draw_menu(imgui_state, "sokol-gfx");
simgui_render();
}

//End pass
sg_end_pass();
}
Expand Down Expand Up @@ -330,6 +349,32 @@ void cSokolRender::StartCaptureFrame() {
}
#endif

void cSokolRender::DebugUISetEnable(bool state) {
cInterfaceRenderDevice::DebugUISetEnable(state);

//If enabled and imgui_state isn't initialized, do it
if (debugUIEnabled && imgui_state == nullptr) {
const simgui_desc_t simgui_desc = {};
simgui_setup(&simgui_desc);
const sgimgui_desc_t sgimgui_desc = {};
imgui_state = new sgimgui_t {};
sgimgui_init(imgui_state, &sgimgui_desc);
}
}

bool cSokolRender::DebugUIMouseMove(const Vect2f& pos) {
simgui_add_mouse_pos_event(
(pos.x + 0.5f) * ScreenSize.x,
(pos.y + 0.5f) * ScreenSize.y
);
return false;
}

bool cSokolRender::DebugUIMousePress(const Vect2f& pos, uint8_t button, bool pressed) {
simgui_add_mouse_button_event(button - SDL_BUTTON_LEFT, pressed);
return true;
}

void cSokolRender::ClearActiveBufferAndPassAction() {
if (activeDrawBuffer) {
//Send out any active DB before we set a pass action
Expand Down
2 changes: 1 addition & 1 deletion Source/Render/sokol/SokolRenderTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "Umath.h"
#include "StdAfxRD.h"
#include "VertexFormat.h"
#include <sokol_gfx.h>
#include "SokolIncludes.h"
#include "IRenderDevice.h"
#include "SokolRender.h"
#include "FileImage.h"
Expand Down
2 changes: 1 addition & 1 deletion Source/Render/sokol/SokolResources.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "xerrhand.h"
#include "xmath.h"
#include <sokol_gfx.h>
#include "SokolIncludes.h"
#include "SokolResources.h"
#include "SokolTypes.h"

Expand Down
Loading

0 comments on commit 551267a

Please sign in to comment.