Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ project(plush
# options

option(PLUSH_BUILD_EXAMPLES "Build Plush Examples" ON)
option(PLUSH_BUILD_EDITOR "Build Plush Editor" ON)
option(PLUSH_USE_ASAN "Use Address Sanitizer" OFF)
set(PLUSH_MAX_LIGHTS "32" CACHE STRING "Maximum number of lights in a single render pass")
set(PLUSH_MAX_TRIANGLES "16384" CACHE STRING "Maximum number of triangles in a single render pass")
Expand Down Expand Up @@ -77,6 +78,17 @@ endif()

target_link_libraries(plush PUBLIC $<$<BOOL:${PLUSH_USE_ASAN}>:ASAN::ASAN>)

# editor

if(PLUSH_BUILD_EDITOR)
find_package(SDL3 CONFIG COMPONENTS SDL3)
if(SDL3_FOUND)
add_subdirectory(editor)
else()
message(WARNING "SDL3 not found, cannot build editor")
endif()
endif()

# examples

if(PLUSH_BUILD_EXAMPLES)
Expand Down
33 changes: 33 additions & 0 deletions editor/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
project(plush-editor LANGUAGES C CXX)

include(FetchContent)

FetchContent_Declare(
imgui
GIT_REPOSITORY https://github.com/ocornut/imgui.git
GIT_TAG v1.92.3
)

FetchContent_MakeAvailable(imgui)

add_library(imgui STATIC
${imgui_SOURCE_DIR}/imgui_demo.cpp
${imgui_SOURCE_DIR}/imgui_draw.cpp
${imgui_SOURCE_DIR}/imgui_tables.cpp
${imgui_SOURCE_DIR}/imgui_widgets.cpp
${imgui_SOURCE_DIR}/imgui.cpp
${imgui_SOURCE_DIR}/backends/imgui_impl_sdl3.cpp
${imgui_SOURCE_DIR}/backends/imgui_impl_sdlrenderer3.cpp
)

target_include_directories(imgui PUBLIC
${imgui_SOURCE_DIR}
${imgui_SOURCE_DIR}/backends
)

add_executable(plush-editor)
target_sources(plush-editor PRIVATE
${PROJECT_SOURCE_DIR}/main.cpp
)

target_link_libraries(plush-editor PUBLIC plush SDL3::SDL3 imgui)
196 changes: 196 additions & 0 deletions editor/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@

#include <vector>
#include <string>
#include <cstdlib>
#include <stdexcept>

#include <SDL3/SDL.h>
#include <plush/plush.h>

#include "imgui.h"
#include "imgui_impl_sdl3.h"
#include "imgui_impl_sdlrenderer3.h"

#define SDL_MAIN_USE_CALLBACKS 1
#include <SDL3/SDL_main.h>

static void quit()
{
SDL_Event event;
event.quit.type = SDL_EVENT_QUIT;
event.quit.timestamp = SDL_GetTicksNS();
SDL_PushEvent(&event);
}

static SDL_AppResult die(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_CRITICAL, fmt, ap);
va_end(ap);

SDL_Event event;
event.quit.type = SDL_EVENT_QUIT;
event.quit.timestamp = SDL_GetTicksNS();
SDL_PushEvent(&event);

return SDL_APP_FAILURE;
}

class app_t {
public:
void EditorMain()
{
// setup flags
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;

// setup size
int screen_w, screen_h;
SDL_GetRenderOutputSize(renderer, &screen_w, &screen_h);
ImGui::SetNextWindowSize(ImVec2(screen_w, screen_h), ImGuiCond_Always);
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);

// do it
if (ImGui::Begin("Main Menu", nullptr, window_flags))
{
// main menu bar
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("File"))
{
if (ImGui::MenuItem("Load"))
;

if (ImGui::MenuItem("Save", "Ctrl+S"))
;

if (ImGui::MenuItem("Save As"))
;

if (ImGui::MenuItem("Quit", "Alt+F4"))
quit();

ImGui::EndMenu();
}

ImGui::EndMenuBar();
}

ImGui::End();
}

ImGui::ShowDemoWindow(nullptr);
}

SDL_AppResult Iterate()
{
ImGui_ImplSDLRenderer3_NewFrame();
ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame();

EditorMain();

ImGui::Render();
ImGuiIO &io = ImGui::GetIO();
SDL_SetRenderScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
SDL_SetRenderDrawColorFloat(renderer, clear_color.x, clear_color.y, clear_color.z, clear_color.w);
SDL_RenderClear(renderer);
ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), renderer);
SDL_RenderPresent(renderer);

return SDL_APP_CONTINUE;
}

SDL_AppResult Event(SDL_Event *event)
{
if ((event->type == SDL_EVENT_QUIT) || (event->type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event->window.windowID == SDL_GetWindowID(window)))
return SDL_APP_SUCCESS;

ImGui_ImplSDL3_ProcessEvent(event);

return SDL_APP_CONTINUE;
}

app_t(const char *title, int w=1280, int h=720) : windowTitle(title), windowWidth(w), windowHeight(h)
{
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
throw std::runtime_error(SDL_GetError());

if (!SDL_CreateWindowAndRenderer(windowTitle.c_str(), windowWidth, windowHeight, SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_MAXIMIZED, &window, &renderer))
throw std::runtime_error(SDL_GetError());

IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO &io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
io.IniFilename = nullptr;
io.LogFilename = nullptr;

ImGui::StyleColorsDark();

ImGui_ImplSDL3_InitForSDLRenderer(window, renderer);
ImGui_ImplSDLRenderer3_Init(renderer);

SDL_ShowWindow(window);
}

~app_t()
{
ImGui_ImplSDLRenderer3_Shutdown();
ImGui_ImplSDL3_Shutdown();
ImGui::DestroyContext();

if (renderer) SDL_DestroyRenderer(renderer);
if (window) SDL_DestroyWindow(window);

SDL_Quit();
}
private:
// SDL video state
SDL_Window *window;
SDL_Renderer *renderer;

int windowWidth;
int windowHeight;
std::string windowTitle;

ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
};

SDLMAIN_DECLSPEC SDL_AppResult SDLCALL SDL_AppInit(void **appstate, SDL_UNUSED int argc, SDL_UNUSED char *argv[])
{
app_t *app = NULL;

try {
app = new app_t("Plush Scene Editor");
} catch (const std::runtime_error &error) {
return die("%s", error.what());
}

*appstate = reinterpret_cast<void*>(app);

return SDL_APP_CONTINUE;
}

SDLMAIN_DECLSPEC SDL_AppResult SDLCALL SDL_AppIterate(void *appstate)
{
app_t *app = reinterpret_cast<app_t*>(appstate);

return app->Iterate();
}

SDLMAIN_DECLSPEC SDL_AppResult SDLCALL SDL_AppEvent(void *appstate, SDL_Event *event)
{
app_t *app = reinterpret_cast<app_t*>(appstate);

return app->Event(event);
}

SDLMAIN_DECLSPEC void SDLCALL SDL_AppQuit(void *appstate, SDL_UNUSED SDL_AppResult result)
{
app_t *app = reinterpret_cast<app_t*>(appstate);

delete app;
}
54 changes: 54 additions & 0 deletions editor/scenefmt.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Namespace = "Plush";
Name = "Test Scene";
DefaultCamera = 0;

// palette 0
palette
{
FirstColor = 0;
LastColor = 255;
File = "palette.pcx";
}

// camera 0
camera
{
Width = 640;
Height = 480;
Fov = 90;
zBuffer = true;

Origin = [64, 64, -384];
Angles = [15, 10, 0];

Palette = 0;
}

// material 0
material
{
Name = "Fallback Material";
Fallback = true;

Ambient = [44, 8, 8];
Diffuse = [156, 25, 25];
Specular = [185, 159, 159];
}

// mesh 0
mesh
{
Name = "Polyrobo";

File = "polyrobo.obj";

Material = 0;
}

// object 0
object
{
Name = "Polyrobo";

Mesh = 0;
}