diff --git a/README.md b/README.md index 100324b..2a0fd14 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,16 @@ -# ougge +# OUGGE A game engine or something, idk. ## Installation -1. Clone the repository +1. Clone the repository. ```sh git clone --recurse-submodules https://timerix.ddns.net:3322/Timerix/ougge.git ``` -2. Install [cbuild](https://timerix.ddns.net:3322/Timerix/cbuild.git) -3. Install **SDL2** from package manager or compile it from source. - **If you are using msys, switch to mingw64 sh.** - ```sh - git clone https://github.com/libsdl-org/SDL.git - cd SDL - ./configure - make -j [number of cpu threads] - ``` - Then you can install it systemwide (on **Linux**): - ```sh - sudo make install - ``` - or copy to ./dependencies/precompiled/ (on **Windows**): - ```sh - mkdir -p ../ougge/dependencies/precompiled/ - cp ./build/.libs/SDL2.dll ../ougge/dependencies/precompiled/ - ``` - If it doesn't work, read [SDL/INSTALL.txt](https://github.com/libsdl-org/SDL/blob/SDL2/INSTALL.txt) and [SDL/docs/README.md](https://github.com/libsdl-org/SDL/blob/SDL2/docs/README.md). -4. Symlink SDL headers directory to `dependencies/include` +2. Install [cbuild](https://timerix.ddns.net:3322/Timerix/cbuild.git). +3. Install [SDL2](https://github.com/libsdl-org/SDL) and [SDL2_image](https://github.com/libsdl-org/SDL_image). + - On **Linux** install shared libraries from a package manager or compile them from source. + - On **Windows** download pre-built dll's from github releases and put them into `dependencies/precompiled/`. +4. Symlink SDL headers directory to `dependencies/include`. ```sh cd ../ougge ln -s SDL2_HEADERS_DIRECTORY_ABSOLUTE_PATH -T dependencies/include/SDL2 diff --git a/dependencies/imgui.project.config b/dependencies/imgui.project.config index 861ddfe..a767416 100644 --- a/dependencies/imgui.project.config +++ b/dependencies/imgui.project.config @@ -16,7 +16,7 @@ SRC_CPP="imgui.cpp imgui_tables.cpp imgui_widgets.cpp backends/imgui_impl_sdl2.cpp - backends/imgui_impl_opengl3.cpp" + backends/imgui_impl_sdlrenderer2.cpp" # Directory with dependency configs. # See cbuild/example_dependency_configs diff --git a/embedded_resources/tutel.png b/embedded_resources/tutel.png new file mode 100644 index 0000000..b62d636 Binary files /dev/null and b/embedded_resources/tutel.png differ diff --git a/project.config b/project.config index f2768be..ee7dc2b 100644 --- a/project.config +++ b/project.config @@ -35,12 +35,12 @@ case "$OS" in WINDOWS) EXEC_FILE="$PROJECT.exe" SHARED_LIB_FILE="$PROJECT.dll" - LINKER_LIBS="-lopengl32 -lpthread" + LINKER_LIBS="" ;; LINUX) EXEC_FILE="$PROJECT" SHARED_LIB_FILE="$PROJECT.so" - LINKER_LIBS="-lSDL2 -lGL" + LINKER_LIBS="-lSDL2 -lSDL2_image" ;; *) error "operating system $OS has no configuration variants" diff --git a/src/GUI/MainWindow.cpp b/src/GUI/MainWindow.cpp index 12ddf4a..533e44a 100644 --- a/src/GUI/MainWindow.cpp +++ b/src/GUI/MainWindow.cpp @@ -1,16 +1,17 @@ #include -#include +#include #include #include "MainWindow.hpp" #include "../exceptions.hpp" #include "../format.hpp" #include "../Resources/fonts.hpp" +#include "../Resources/textures.hpp" namespace ougge::GUI { f32 MainWindow::getDPI(){ int w=0, h=0; - SDL_GL_GetDrawableSize(sdl_window, &w, &h); + SDL_GetRendererOutputSize(sdl_renderer, &w, &h); int sim_w=0, sim_h=0; SDL_GetWindowSize(sdl_window, &sim_w, &sim_h); f32 wdpi=(f32)w / sim_w; @@ -20,40 +21,35 @@ f32 MainWindow::getDPI(){ } void MainWindow::init(const char* window_title){ - SDL_TRY(SDL_Init(SDL_INIT_VIDEO)); + SDL_TRY(SDL_Init(SDL_INIT_EVERYTHING)); SDL_version v; SDL_GetVersion(&v); std::cout<0) { draw_frame(); frame_updates_requested--; - } + } } // Cleanup @@ -228,10 +218,10 @@ void MainWindow::close(){ } void MainWindow::destroy(){ - ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplSDLRenderer2_Shutdown(); ImGui_ImplSDL2_Shutdown(); ImGui::DestroyContext(); - SDL_GL_DeleteContext(gl_context); + SDL_DestroyRenderer(sdl_renderer); SDL_DestroyWindow(sdl_window); SDL_Quit(); } diff --git a/src/GUI/MainWindow.hpp b/src/GUI/MainWindow.hpp index c4c8c20..7e375b6 100644 --- a/src/GUI/MainWindow.hpp +++ b/src/GUI/MainWindow.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include "../std.hpp" @@ -27,7 +26,7 @@ private: bool show_demo_window = false; bool show_metrics_window = false; SDL_Window* sdl_window = nullptr; - SDL_GLContext gl_context = nullptr; + SDL_Renderer* sdl_renderer = nullptr; public: void init(const char* window_title); diff --git a/src/Resources/Resources.cpp b/src/Resources/Resources.cpp index 6c9b014..1767e48 100644 --- a/src/Resources/Resources.cpp +++ b/src/Resources/Resources.cpp @@ -1,7 +1,7 @@ #include #include #include -#include "../UsefulException.hpp" +#include "../exceptions.hpp" #include "../format.hpp" #include "Resources.hpp" #include "embedded_resources.h" @@ -19,16 +19,27 @@ MemoryStreamBuf::MemoryStreamBuf(void* _p, const std::size_t n){ setp(p, p + n); } -class MemoryStreamRead : public std::istream { -public: - MemoryStreamRead(const void* p, const std::size_t n) - : std::istream(new MemoryStreamBuf((void*)p, n)) - {} +std::istream::pos_type MemoryStreamBuf::seekoff( + std::istream::off_type off, + std::ios_base::seekdir dir, + std::ios_base::openmode which) +{ + if (dir == std::ios_base::cur) + gbump(off); + else if (dir == std::ios_base::end) + setg(eback(), egptr() + off, egptr()); + else if (dir == std::ios_base::beg) + setg(eback(), eback() + off, egptr()); + return gptr() - eback(); +} - virtual ~MemoryStreamRead(){ - delete rdbuf(); - } -}; +MemoryStreamRead::MemoryStreamRead(const void* p, const std::size_t n) + : std::istream(new MemoryStreamBuf((void*)p, n)) +{} + +MemoryStreamRead::~MemoryStreamRead(){ + delete rdbuf(); +} static std::unordered_map* _resourceMap = nullptr; diff --git a/src/Resources/Resources.hpp b/src/Resources/Resources.hpp index f54056d..65c73bf 100644 --- a/src/Resources/Resources.hpp +++ b/src/Resources/Resources.hpp @@ -27,8 +27,19 @@ public: class MemoryStreamBuf : public std::streambuf { public: MemoryStreamBuf(void* p, const std::size_t n); + + virtual std::istream::pos_type seekoff( + std::istream::off_type off, + std::ios_base::seekdir dir, + std::ios_base::openmode which); }; +class MemoryStreamRead : public std::istream { +public: + MemoryStreamRead(const void* p, const std::size_t n); + + virtual ~MemoryStreamRead(); +}; Resource& getResource(const std::string& path); diff --git a/src/Resources/textures.cpp b/src/Resources/textures.cpp new file mode 100644 index 0000000..a469cc6 --- /dev/null +++ b/src/Resources/textures.cpp @@ -0,0 +1,105 @@ +#include "textures.hpp" +#include +#include "../exceptions.hpp" + +namespace ougge::Resources { + +Texture::Texture(SDL_Renderer* renderer) + : renderer(renderer), texture(nullptr), w(0), h(0) +{} + +Texture::~Texture(){ + SDL_DestroyTexture(texture); +} + +void Texture::loadFrom(const Resource& r){ + auto s = r.openStream(); + loadFrom(*s, r.size); +} + +void Texture::loadFrom(std::istream& s, size_t size){ + if(texture) + throw UsefulException("texture has been loaded already"); + SDL_RWops* sdl_stream = SDL_RWFromIStream(s, size); + if(!sdl_stream) + throw SDLException(); + texture = IMG_LoadTexture_RW(renderer, sdl_stream, 1); + if(!texture) + throw IMGException(); + SDL_TRY(SDL_QueryTexture(texture, nullptr, nullptr, &w, &h)); +} + +SDL_RenderCopyExF_Params::SDL_RenderCopyExF_Params() + : rotation_angle(0), flip(SDL_FLIP_NONE) +{} + +void Texture::render(const SDL_FRect& target_section){ + SDL_TRY( + SDL_RenderCopyF(renderer, texture, nullptr, &target_section) + ); +} + +void Texture::render(const SDL_FRect& target_section, const SDL_Rect& texture_section){ + SDL_TRY( + SDL_RenderCopyF(renderer, texture, &texture_section, &target_section) + ); +} + +void Texture::render(const SDL_RenderCopyExF_Params& p){ + SDL_TRY( + SDL_RenderCopyExF(renderer, texture, + optional_value_ptr_or_null(p.texture_section), + optional_value_ptr_or_null(p.target_section), + p.rotation_angle, + optional_value_ptr_or_null(p.rotation_center), + p.flip + ) + ) +} + +static Sint64 istream_size(SDL_RWops* context){ + return (Sint64)(size_t)context->hidden.unknown.data2; +} + +static Sint64 istream_seek(SDL_RWops* context, Sint64 offset, int whence){ + std::istream* stream = (std::istream*)context->hidden.unknown.data1; + switch(whence){ + case SEEK_SET: stream->seekg(offset, std::ios::beg); break; + case SEEK_CUR: stream->seekg(offset, std::ios::cur); break; + case SEEK_END: stream->seekg(offset, std::ios::end); break; + default: break; + } + return stream->fail() ? -1 : (Sint64)stream->tellg(); +} + +static size_t istream_read(SDL_RWops* context, void *ptr, size_t size, size_t maxnum){ + if(size == 0) + return -1; + std::istream* stream = (std::istream*)context->hidden.unknown.data1; + stream->read((char*)ptr, size * maxnum); + + return stream->bad() ? -1 : stream->gcount() / size; +} + +static int istream_close(SDL_RWops* context){ + if (context) + SDL_FreeRW(context); + return 0; +} + +SDL_RWops* SDL_RWFromIStream(std::istream& stream, size_t size){ + SDL_RWops* rwops = SDL_AllocRW(); + if(rwops) { + rwops->size = istream_size; + rwops->seek = istream_seek; + rwops->read = istream_read; + rwops->write = nullptr; + rwops->close = istream_close; + rwops->hidden.unknown.data1 = &stream; + rwops->hidden.unknown.data2 = (void*)size; + rwops->type = SDL_RWOPS_UNKNOWN; + } + return rwops; +} + +} diff --git a/src/Resources/textures.hpp b/src/Resources/textures.hpp new file mode 100644 index 0000000..37b0dd5 --- /dev/null +++ b/src/Resources/textures.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include +#include +#include "Resources.hpp" + +namespace ougge::Resources { + +#define SDL_RectConstruct(X, Y, W, H) (SDL_Rect){X, Y, W, H} +#define SDL_FRectConstruct(X, Y, W, H) (SDL_FRect){X, Y, W, H} +#define SDL_PointConstruct(X, Y) (SDL_Point){X, Y, W, H} +#define SDL_FPointConstruct(X, Y) (SDL_FPoint){X, Y, W, H} + +#define optional_value_ptr_or_null(OPT) (OPT ? &(*OPT) : nullptr) + +SDL_RWops* SDL_RWFromIStream(std::istream& stream, size_t size); + +struct SDL_RenderCopyExF_Params { + std::optional texture_section; + std::optional target_section; + std::optional rotation_center; + double rotation_angle; + SDL_RendererFlip flip; + + SDL_RenderCopyExF_Params(); +}; + +struct Texture { + SDL_Renderer* renderer; + SDL_Texture* texture; + int w; + int h; + + Texture(SDL_Renderer* renderer); + ~Texture(); + + void loadFrom(const Resource& r); + void loadFrom(std::istream& s, size_t size); + + void render(const SDL_FRect& target_section); + void render(const SDL_FRect& target_section, const SDL_Rect& texture_section); + void render(const SDL_RenderCopyExF_Params& params); +}; + +} diff --git a/src/main.cpp b/src/main.cpp index 08fa535..540b7ea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,8 @@ #include "std.hpp" #include "GUI/MainWindow.hpp" #include "Resources/Resources.hpp" +#include "format.hpp" +#include "exceptions.hpp" using namespace ougge;