@@ -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 |
@@ -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) |
@@ -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_; | |||
}; | |||
@@ -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() { |
@@ -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()); |
@@ -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) |
@@ -0,0 +1 @@ | |||
Subproject commit b9ba533ba28bd875c75b04888bdde2ab4e464122 |