Browse Source

basic imgui integration (now with SDL)

opengl-renderer-broken
Martin Dørum 4 years ago
parent
commit
c6ffa3c7d5
7 changed files with 79 additions and 16 deletions
  1. 3
    0
      .gitmodules
  2. 5
    1
      CMakeLists.txt
  3. 11
    8
      libswan/include/swan/Win.h
  4. 2
    2
      libswan/src/Game.cc
  5. 51
    4
      src/main.cc
  6. 6
    1
      third_party/CMakeLists.txt
  7. 1
    0
      third_party/imgui_sdl

+ 3
- 0
.gitmodules View File

@@ -4,3 +4,6 @@
[submodule "third_party/PerlinNoise"]
path = third_party/PerlinNoise
url = https://github.com/Reputeless/PerlinNoise.git
[submodule "third_party/imgui_sdl"]
path = third_party/imgui_sdl
url = https://github.com/mortie/imgui_sdl

+ 5
- 1
CMakeLists.txt View File

@@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 3.0)
project(swan)

find_package(SDL2 REQUIRED)

option(USE_CLANG_TIDY "Use clang-tidy for additional checks" ON)
if(USE_CLANG_TIDY)
set(CMAKE_CXX_CLANG_TIDY
@@ -9,6 +11,7 @@ if(USE_CLANG_TIDY)
--checks=-*,bugprone-*,cert-*,performance-*,clang-analyzer-*,-cert-dcl16-c,-cert-err58-cpp,-clang-analyzer-optin.cplusplus.VirtualCall)
endif()


add_compile_options(-std=c++2a -Wall -Wextra -Wpedantic -Wno-unused-parameter)
if(CMAKE_BUILD_TYPE STREQUAL Sanitize OR CMAKE_BUILD_TYPE STREQUAL "")
message(STATUS "Build mode: Sanitize")
@@ -39,7 +42,8 @@ set(libraries imgui SDL2 SDL2_image dl z)
add_compile_options(-Wno-c99-extensions)

include_directories(
${PROJECT_SOURCE_DIR}/third_party)
${PROJECT_SOURCE_DIR}/third_party
${SDL2_INCLUDE_DIRS})
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib;${CMAKE_INSTALL_PREFIX}/lib64;${CMAKE_INSTALL_PREFIX}/swan/libswan;${CMAKE_INSTALL_PREFIX}/swan/third_party")

add_subdirectory(libswan)

+ 11
- 8
libswan/include/swan/Win.h View File

@@ -10,7 +10,9 @@ namespace Swan {

class Win {
public:
Win(SDL_Window *window, SDL_Renderer *renderer): window_(window), renderer_(renderer) {
Win(SDL_Window *window, SDL_Renderer *renderer, float scale):
window_(window), renderer_(renderer), scale_(scale) {

if (SDL_GetRendererInfo(renderer_, &rinfo_) < 0) {
panic << "GetRenedrerInfo failed: " << SDL_GetError();
abort();
@@ -19,7 +21,7 @@ public:
// For HiDPI, we must set the renderer's logical size.
int w, h;
SDL_GetWindowSize(window_, &w, &h);
SDL_RenderSetLogicalSize(renderer_, w, h);
SDL_RenderSetLogicalSize(renderer_, w / scale_, h / scale_);

info << "Using renderer: " << rinfo_.name;
}
@@ -27,18 +29,18 @@ public:
Vec2 getSize() {
int w, h;
SDL_GetWindowSize(window_, &w, &h);
return Vec2(((float)w / scale_) / TILE_SIZE, ((float)h / scale_) / TILE_SIZE);
return Vec2(((float)w / (scale_ * zoom_)) / TILE_SIZE, ((float)h / (scale_ * zoom_)) / TILE_SIZE);
}

void onResize(int w, int h) {
SDL_RenderSetLogicalSize(renderer_, w, h);
SDL_RenderSetLogicalSize(renderer_, w / scale_, h / scale_);
}

SDL_Rect createDestRect(Vec2 pos, Vec2 pixsize) {
return SDL_Rect{
(int)((pos.x - cam_.x) * TILE_SIZE * scale_),
(int)((pos.y - cam_.y) * TILE_SIZE * scale_),
(int)(pixsize.x * scale_), (int)(pixsize.y * scale_),
(int)((pos.x - cam_.x) * TILE_SIZE * zoom_),
(int)((pos.y - cam_.y) * TILE_SIZE * zoom_),
(int)(pixsize.x * zoom_), (int)(pixsize.y * zoom_),
};
}

@@ -74,10 +76,11 @@ public:
warn << "RenderDrawRect failed: " << SDL_GetError();
}

float scale_ = 2;
Vec2 cam_;
float zoom_ = 1;
SDL_Window *window_;
SDL_Renderer *renderer_;
float scale_;
SDL_RendererInfo rinfo_;
};


+ 2
- 2
libswan/src/Game.cc View File

@@ -39,8 +39,8 @@ void Game::createWorld(const std::string &worldgen, std::vector<std::unique_ptr<
TilePos Game::getMouseTile() {
auto mousePos = getMousePos();
return TilePos(
(int)floor(win_.cam_.x + mousePos.x / (Swan::TILE_SIZE * win_.scale_)),
(int)floor(win_.cam_.y + mousePos.y / (Swan::TILE_SIZE * win_.scale_)));
(int)floor(win_.cam_.x + mousePos.x / (Swan::TILE_SIZE * win_.zoom_)),
(int)floor(win_.cam_.y + mousePos.y / (Swan::TILE_SIZE * win_.zoom_)));
}

void Game::draw() {

+ 51
- 4
src/main.cc View File

@@ -8,6 +8,8 @@
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <string.h>
#include <imgui.h>
#include <imgui_sdl/imgui_sdl.h>

#include <swan/swan.h>

@@ -23,8 +25,24 @@ using namespace Swan;
#define sdlassert(expr, str) errassert(expr, str, SDL_GetError);
#define imgassert(expr, str) errassert(expr, str, IMG_GetError);

template<typename T>
using DeleteFunc = void (*)(T *);
// ImGUI and SDL have different numbers for mouse buttons
int sdlButtonToImGuiButton(uint8_t button) {
switch (button) {
case SDL_BUTTON_LEFT:
return 0;
case SDL_BUTTON_RIGHT:
return 1;
case SDL_BUTTON_MIDDLE:
return 2;
case SDL_BUTTON_X1:
return 3;
case SDL_BUTTON_X2:
return 4;
default:
warn << "Unknown mouse button: " << button;
return 4; // Let's call that X2?
}
}

int main(int argc, char **argv) {
uint32_t winflags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
@@ -54,6 +72,7 @@ int main(int argc, char **argv) {
imgassert(IMG_Init(imgflags) == imgflags, "Could not initialize SDL_Image");
auto sdl_image = makeDeferred([] { IMG_Quit(); });

// Create the window
auto window = makeRaiiPtr(
SDL_CreateWindow(
"Project: SWAN",
@@ -73,8 +92,20 @@ int main(int argc, char **argv) {
SDL_DestroyRenderer);
sdlassert(renderer, "Could not create renderer");

Win win(window.get(), renderer.get());
Win win(window.get(), renderer.get(), 2);

// Init ImGUI and ImGUI_SDL
IMGUI_CHECKVERSION();
ImGui::CreateContext();
auto imgui = makeDeferred([] { ImGui::DestroyContext(); });
ImGuiSDL::Initialize(renderer.get(), 640, 480);
auto imgui_sdl = makeDeferred([] { ImGuiSDL::Deinitialize(); });

// ImGuiIO is to glue SDL and ImGUI together
ImGuiIO& imgui_io = ImGui::GetIO();
imgui_io.BackendPlatformName = "imgui_sdl + Project: SWAN";

// Create a world
Game game(win);
std::vector<std::unique_ptr<Mod>> mods;
mods.push_back(game.loadMod("core.mod"));
@@ -100,8 +131,11 @@ int main(int argc, char **argv) {
break;

case SDL_WINDOWEVENT:
if (evt.window.event == SDL_WINDOWEVENT_RESIZED)
if (evt.window.event == SDL_WINDOWEVENT_RESIZED) {
imgui_io.DisplaySize.x = (float)evt.window.data1;
imgui_io.DisplaySize.y = (float)evt.window.data2;
win.onResize(evt.window.data1, evt.window.data2);
}
break;

case SDL_KEYDOWN:
@@ -113,14 +147,18 @@ int main(int argc, char **argv) {
break;

case SDL_MOUSEMOTION:
imgui_io.MousePos.x = (float)evt.motion.x;
imgui_io.MousePos.y = (float)evt.motion.y;
game.onMouseMove(evt.motion.x, evt.motion.y);
break;

case SDL_MOUSEBUTTONDOWN:
imgui_io.MouseDown[sdlButtonToImGuiButton(evt.button.button)] = true;
game.onMouseDown(evt.button.x, evt.button.y, evt.button.button);
break;

case SDL_MOUSEBUTTONUP:
imgui_io.MouseDown[sdlButtonToImGuiButton(evt.button.button)] = false;
game.onMouseUp(evt.button.x, evt.button.y, evt.button.button);
break;
}
@@ -184,12 +222,21 @@ int main(int argc, char **argv) {

SDL_RenderClear(renderer.get());

// ImGUI
imgui_io.DeltaTime = dt;
ImGui::NewFrame();
ImGui::ShowDemoWindow();

RTClock draw_clock;
game.draw();
pcounter.countGameDraw(draw_clock.duration());

pcounter.countFrameTime(total_frame_clock.duration());

// Render ImGUI
ImGui::Render();
ImGuiSDL::Render(ImGui::GetDrawData());

RTClock present_clock;
SDL_RenderPresent(renderer.get());
pcounter.countRenderPresent(present_clock.duration());

+ 6
- 1
third_party/CMakeLists.txt View File

@@ -2,7 +2,12 @@ add_library(imgui SHARED
${PROJECT_SOURCE_DIR}/third_party/imgui/imgui_demo.cpp
${PROJECT_SOURCE_DIR}/third_party/imgui/imgui_draw.cpp
${PROJECT_SOURCE_DIR}/third_party/imgui/imgui_widgets.cpp
${PROJECT_SOURCE_DIR}/third_party/imgui/imgui.cpp)
${PROJECT_SOURCE_DIR}/third_party/imgui/imgui.cpp
${PROJECT_SOURCE_DIR}/third_party/imgui_sdl/imgui_sdl.cpp)
set_target_properties(imgui PROPERTIES CXX_CLANG_TIDY "")
target_include_directories(imgui PUBLIC
${PROJECT_SOURCE_DIR}/third_party/imgui
${PROJECT_SOURCE_DIR}/third_party/imgui/examples
${SDL2_INCLUDE_DIRS})

install(TARGETS imgui DESTINATION swan/third_party)

+ 1
- 0
third_party/imgui_sdl

@@ -0,0 +1 @@
Subproject commit b9ba533ba28bd875c75b04888bdde2ab4e464122

Loading…
Cancel
Save