Add app library
This commit is contained in:
parent
0d4563638b
commit
f69fb7299e
7 changed files with 313 additions and 1 deletions
8
libs/app/CMakeLists.txt
Normal file
8
libs/app/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
find_package(SDL2 REQUIRED)
|
||||
|
||||
file(GLOB_RECURSE PSEMEK_APP_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "include/*.hpp")
|
||||
file(GLOB_RECURSE PSEMEK_APP_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "source/*.cpp")
|
||||
|
||||
add_library(app ${PSEMEK_APP_HEADERS} ${PSEMEK_APP_SOURCES})
|
||||
target_include_directories(app PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${SDL2_INCLUDE_DIRS}")
|
||||
target_link_libraries(app PUBLIC log util gfx ${SDL2_LIBRARIES})
|
||||
44
libs/app/include/psemek/app/app.hpp
Normal file
44
libs/app/include/psemek/app/app.hpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
#include <SDL2/SDL_keycode.h>
|
||||
#include <psemek/util/pimpl.hpp>
|
||||
|
||||
namespace psemek::app
|
||||
{
|
||||
|
||||
struct app
|
||||
: util::pimpl::dynamic<app>
|
||||
{
|
||||
app(std::string const & name);
|
||||
virtual ~app();
|
||||
|
||||
virtual bool running() const;
|
||||
|
||||
virtual void on_resize(int width, int height);
|
||||
virtual void on_focus_gained();
|
||||
virtual void on_focus_lost();
|
||||
virtual void on_quit();
|
||||
|
||||
virtual void on_mouse_move(int x, int y);
|
||||
virtual void on_mouse_wheel(int delta);
|
||||
virtual void on_left_button_down();
|
||||
virtual void on_left_button_up();
|
||||
virtual void on_middle_button_down();
|
||||
virtual void on_middle_button_up();
|
||||
virtual void on_right_button_down();
|
||||
virtual void on_right_button_up();
|
||||
|
||||
virtual void on_key_down(SDL_Keycode key);
|
||||
virtual void on_key_up(SDL_Keycode key);
|
||||
|
||||
void poll_events();
|
||||
|
||||
virtual void update();
|
||||
virtual void draw();
|
||||
|
||||
void run();
|
||||
|
||||
void show_cursor(bool show);
|
||||
};
|
||||
|
||||
}
|
||||
32
libs/app/include/psemek/app/main.hpp
Normal file
32
libs/app/include/psemek/app/main.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/log/log.hpp>
|
||||
|
||||
namespace psemek::app
|
||||
{
|
||||
|
||||
template <typename App>
|
||||
int main() try
|
||||
{
|
||||
log::register_thread("main");
|
||||
|
||||
App app;
|
||||
|
||||
log::info() << "Running";
|
||||
app.run();
|
||||
log::info() << "Quitting";
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
catch (std::exception const & e)
|
||||
{
|
||||
log::error() << e.what();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::error() << "unknown exception";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
215
libs/app/source/app.cpp
Normal file
215
libs/app/source/app.cpp
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
#include <psemek/app/app.hpp>
|
||||
#include <psemek/gfx/gl.hpp>
|
||||
#include <psemek/log/log.hpp>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
[[noreturn]] void sdl_fail(std::string const & message)
|
||||
{
|
||||
throw std::runtime_error(message + SDL_GetError());
|
||||
}
|
||||
|
||||
struct sdl_initializer
|
||||
{
|
||||
sdl_initializer()
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||
sdl_fail("Failed to initialize SDL2: ");
|
||||
}
|
||||
|
||||
~sdl_initializer()
|
||||
{
|
||||
SDL_Quit();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace psemek::util::pimpl
|
||||
{
|
||||
|
||||
template <>
|
||||
struct impl<app::app>
|
||||
{
|
||||
sdl_initializer init;
|
||||
SDL_Window * window = nullptr;
|
||||
SDL_GLContext gl_context = nullptr;
|
||||
|
||||
bool running = false;
|
||||
|
||||
~impl()
|
||||
{
|
||||
if (gl_context) SDL_GL_DeleteContext(gl_context);
|
||||
if (window) SDL_DestroyWindow(window);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace psemek::app
|
||||
{
|
||||
|
||||
|
||||
app::app(std::string const & name)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, gl::sys::GetLeastMajorVersion());
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, gl::sys::GetLeastMinorVersion());
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
||||
|
||||
impl().window = SDL_CreateWindow(name.data(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_MAXIMIZED);
|
||||
if (!impl().window)
|
||||
sdl_fail("Failed to create window: ");
|
||||
|
||||
impl().gl_context = SDL_GL_CreateContext(impl().window);
|
||||
if (!impl().gl_context)
|
||||
sdl_fail("Failed to create OpenGL context: ");
|
||||
|
||||
SDL_GL_MakeCurrent(impl().window, impl().gl_context);
|
||||
|
||||
if (!gl::sys::LoadFunctions())
|
||||
throw std::runtime_error("Failed to load OpenGL functions");
|
||||
|
||||
log::info() << "Initialized OpenGL " << gl::sys::GetMajorVersion() << '.' << gl::sys::GetMinorVersion();
|
||||
}
|
||||
|
||||
app::~app()
|
||||
{}
|
||||
|
||||
bool app::running() const
|
||||
{
|
||||
return impl().running;
|
||||
}
|
||||
|
||||
void app::on_resize(int width, int height)
|
||||
{
|
||||
gl::Viewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void app::on_focus_gained() {}
|
||||
|
||||
void app::on_focus_lost() {}
|
||||
|
||||
void app::on_quit()
|
||||
{
|
||||
impl().running = false;
|
||||
}
|
||||
|
||||
void app::on_mouse_move(int, int) {}
|
||||
|
||||
void app::on_mouse_wheel(int) {}
|
||||
|
||||
void app::on_left_button_down() {}
|
||||
|
||||
void app::on_left_button_up() {}
|
||||
|
||||
void app::on_middle_button_down() {}
|
||||
|
||||
void app::on_middle_button_up() {}
|
||||
|
||||
void app::on_right_button_down() {}
|
||||
|
||||
void app::on_right_button_up() {}
|
||||
|
||||
void app::on_key_down(SDL_Keycode) {}
|
||||
|
||||
void app::on_key_up(SDL_Keycode) {}
|
||||
|
||||
void app::poll_events()
|
||||
{
|
||||
for (SDL_Event e; SDL_PollEvent(&e);) switch (e.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
on_quit();
|
||||
break;
|
||||
case SDL_WINDOWEVENT: switch (e.window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
on_resize(e.window.data1, e.window.data2);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
on_focus_gained();
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
on_focus_lost();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
on_mouse_move(e.motion.x, e.motion.y);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
on_mouse_wheel(e.wheel.y);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
switch (e.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
on_left_button_down();
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
on_middle_button_down();
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
on_right_button_down();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
switch (e.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
on_left_button_up();
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
on_middle_button_up();
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
on_right_button_up();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
on_key_down(e.key.keysym.sym);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
on_key_up(e.key.keysym.sym);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void app::update()
|
||||
{}
|
||||
|
||||
void app::draw()
|
||||
{
|
||||
gl::ClearColor(0.7f, 0.7f, 1.f, 1.f);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void app::run()
|
||||
{
|
||||
impl().running = true;
|
||||
while (running())
|
||||
{
|
||||
poll_events();
|
||||
if (!running()) break;
|
||||
update();
|
||||
draw();
|
||||
|
||||
SDL_GL_SwapWindow(impl().window);
|
||||
}
|
||||
}
|
||||
|
||||
void app::show_cursor(bool show)
|
||||
{
|
||||
SDL_ShowCursor(show ? SDL_TRUE : SDL_FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1733,6 +1733,9 @@ namespace gl
|
|||
|
||||
exts::LoadTest LoadFunctions();
|
||||
|
||||
int GetLeastMinorVersion();
|
||||
int GetLeastMajorVersion();
|
||||
|
||||
int GetMinorVersion();
|
||||
int GetMajorVersion();
|
||||
bool IsVersionGEQ(int majorVersion, int minorVersion);
|
||||
|
|
|
|||
|
|
@ -1579,6 +1579,16 @@ namespace gl
|
|||
return exts::LoadTest(true, numFailed);
|
||||
}
|
||||
|
||||
int GetLeastMinorVersion()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
int GetLeastMajorVersion()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int g_major_version = 0;
|
||||
static int g_minor_version = 0;
|
||||
|
||||
|
|
|
|||
2
todo.md
2
todo.md
|
|
@ -1,6 +1,6 @@
|
|||
* Remove gfx::vertex, setup mesh using attributes directly
|
||||
* Design affine transforms in geom & use them instead of matrices when appropriate
|
||||
* Create an 'app' module that simplifies application creation
|
||||
* Implement pixmap font rendering
|
||||
* Create a simple generic primive painter
|
||||
* Design ui system
|
||||
* Add platform deployment tools
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue