This commit is contained in:
Hartmut Seichter 2024-07-25 23:04:57 +02:00
parent 49f8fbf187
commit 4be1393295
10 changed files with 233 additions and 301 deletions

View file

@ -3,13 +3,13 @@ add_subdirectory(deps)
# build internal core
add_subdirectory(core)
# add_subdirectory(scene)
# add_subdirectory(system)
# add_subdirectory(io)
add_subdirectory(scene)
add_subdirectory(system)
add_subdirectory(io)
#add_subdirectory(ui)
add_subdirectory(binding)
add_subdirectory(visual)
# add_subdirectory(geometry)
# add_subdirectory(runtime)
add_subdirectory(runtime)

View file

@ -38,8 +38,7 @@ class image {
enum pixel_layout { RGB8, RGBA8, LUM, DEPTH, HDR };
image(const size_type& s, pixel_layout t,
const data_t* ptr = nullptr);
image(const size_type& s, pixel_layout t, const data_t* ptr = nullptr);
bool create(const size_type& s, pixel_layout t,
const data_t* ptr = nullptr);
@ -70,7 +69,6 @@ class image {
bool is_valid() const;
protected:
size_type _size{.width = 0, .height = 0};
pixel_layout _layout{pixel_layout::RGB8};
uint64_t _change_count{0};

View file

@ -222,7 +222,7 @@ constexpr double matrix<double, 1, 1>::determinant() const noexcept {
return (*this)[0][0];
}
template <typename Scalar, unsigned int Ra, unsigned int CaRb, unsigned int Cb>
template <typename Scalar, std::size_t Ra, std::size_t CaRb, std::size_t Cb>
constexpr auto operator*(const matrix<Scalar, Ra, CaRb>& A,
const matrix<Scalar, CaRb, Cb>& B) noexcept {
matrix<Scalar, Ra, Cb> result{};
@ -242,7 +242,7 @@ constexpr auto operator*(const matrix<Scalar, Ra, CaRb>& A,
return result;
}
template <typename ScalarA, typename ScalarB, unsigned int Ra, unsigned int Ca>
template <typename ScalarA, typename ScalarB, std::size_t Ra, std::size_t Ca>
constexpr auto operator*(const matrix<ScalarA, Ra, Ca>& A,
const vector<ScalarB, Ca>& B) noexcept {
// first step - should move to concepts to allow for std::array and

View file

@ -194,8 +194,11 @@ template <std::floating_point Scalar> struct quaternion final {
};
// deduction guide for quaternion
template <class T, class... U, class CT = std::common_type_t<T, U...>>
quaternion(T, U...) -> quaternion<CT>;
template <std::floating_point... U, class CT = std::common_type_t<U...>>
quaternion(U...) -> quaternion<CT>;
using quaternionf = quaternion<float>;
using quaterniond = quaternion<double>;
#if 0
constexpr quaternion_ operator*(const quaternion_& rhs) const {

View file

@ -23,7 +23,6 @@
#ifndef PW_CORE_SIZE_HPP
#define PW_CORE_SIZE_HPP
#include <asm-generic/errno.h>
#include <pw/core/globals.hpp>
#include <type_traits>
@ -54,6 +53,10 @@ template <typename Scalar> struct size {
}
};
// deduction guide for size
template <class... U, class CT = std::common_type_t<U...>>
size(U...) -> size<CT>;
} // namespace pw
#endif

View file

@ -6,77 +6,66 @@
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#include "stb_image_write.h"
#include <future>
namespace pw {
struct image_io::impl
{
struct image_io::impl {
image read_impl(const std::string& uri,uint32_t flags)
{
int x{ 0 }, y{ 0 }, n{ 0 };
image read_impl(const std::string& uri, uint32_t flags) {
int x{0}, y{0}, n{0};
const auto data = stbi_load(uri.c_str(), &x, &y, &n, 4);
if (data) {
image r;
image r;
r.create(size(x,y),image::pixel_layout::RGBA8,reinterpret_cast<image::data_t*>(data));
r.create(size{x, y}.cast<image::size_type::value_type>(),
image::pixel_layout::RGBA8,
reinterpret_cast<image::data_t*>(data));
stbi_image_free(data);
stbi_image_free(data);
return r;
} else {
} else {
debug::e() << stbi_failure_reason();
}
debug::e() << stbi_failure_reason();
}
return image();
}
bool write(const std::string& uri, const image& img, uint32_t flags)
{
auto res = stbi_write_png(uri.c_str(),img.size().width,img.size().height,
image::components(img.layout()),
img.data(),
img.size().width * image::components(img.layout()));
bool write(const std::string& uri, const image& img, uint32_t flags) {
auto res =
stbi_write_png(uri.c_str(), img.size().width, img.size().height,
image::components(img.layout()), img.data(),
img.size().width * image::components(img.layout()));
return 0 == res;
}
};
image_io &image_io::get()
{
image_io& image_io::get() {
static image_io instance;
return instance;
}
image image_io::read(const std::string &uri, uint32_t flags)
{
return _impl->read_impl(uri,flags);
image image_io::read(const std::string& uri, uint32_t flags) {
return _impl->read_impl(uri, flags);
}
bool image_io::write(const std::string &uri, const image& img, uint32_t flags)
{
return _impl->write(uri,img,flags);
bool image_io::write(const std::string& uri, const image& img, uint32_t flags) {
return _impl->write(uri, img, flags);
}
//
//
//
image_io::image_io()
{
_impl = make_unique<impl>();
}
image_io::image_io() { _impl = make_unique<impl>(); }
image_io::~image_io()
{
}
image_io::~image_io() {}
}
} // namespace pw

View file

@ -7,65 +7,64 @@
namespace pw {
struct transform {
struct transform final {
transform() = default;
transform(const transform&) = default;
inline const matrix4x4& local() const { return _local; }
void set_local(const matrix4x4 &local)
{
_local = local;
}
inline const matrix4x4& global() const { return _global; }
void set_global(const matrix4x4 &global)
{
matrix4x4 diff = _global.inverse() * global;
_local = _local * diff;
void set_global(const matrix4x4f& global) {
matrix4x4f diff = _global.inverse() * global;
_local = _local * diff;
_global = global;
}
inline transform& translate(const real_t &x, const real_t &y, const real_t &z) {
_local(0,3) += x;_local(1,3) += y;_local(2,3) += z;
return *this;
}
inline transform& translate(const float& x, const float& y,
const float& z) {
_local[0][3] += x;
_local[1][3] += y;
_local[2][3] += z;
return *this;
}
inline transform& set_translation(const real_t &x, const real_t &y, const real_t &z) {
_local(0,3) = x;_local(1,3) = y;_local(2,3) = z;
return *this;
}
inline transform& set_translation(const float& x, const float& y,
const float& z) {
_local[0][3] = x;
_local[1][3] = y;
_local[2][3] = z;
return *this;
}
inline transform& rotate(const quaternion& q) {
inline transform& rotate(const quaternionf& q) {
_local = _local * q.to_matrix();
return *this;
}
return *this;
}
inline transform& set_rotation(const quaternion& q) {
_local = q.to_matrix();
return *this;
}
inline transform& set_rotation(const quaternionf& q) {
_local = q.to_matrix();
return *this;
}
inline transform& scale(const real_t &sx, const real_t &sy, const real_t &sz) {
_local(0,0) *= sx; _local(1,1) *= sy; _local(2,2) *= sz;
return *this;
}
inline transform& scale(const float& sx, const float& sy, const float& sz) {
_local[0][0] *= sx;
_local[1][1] *= sy;
_local[2][2] *= sz;
return *this;
}
inline transform& set_scale(const real_t &sx, const real_t &sy, const real_t &sz) {
_local(0,0) = sx; _local(1,1) = sy; _local(2,2) = sz;
return *this;
}
inline transform& set_scale(const float& sx, const float& sy,
const float& sz) {
_local[0][0] = sx;
_local[1][1] = sy;
_local[2][2] = sz;
return *this;
}
inline transform& scale(const real_t& uniform_scale) {
return scale(uniform_scale,uniform_scale,uniform_scale);
}
inline transform& scale(const float& uniform_scale) {
return scale(uniform_scale, uniform_scale, uniform_scale);
}
matrix4x4 _local = matrix4x4::identity();
matrix4x4 _global = matrix4x4::identity();
matrix4x4f _local = matrix4x4f::identity();
matrix4x4f _global = matrix4x4f::identity();
};
}
} // namespace pw
#endif

View file

@ -1,54 +1,46 @@
#ifndef PW_SYSTEM_INPUT_HPP
#define PW_SYSTEM_INPUT_HPP
#include <cstdint>
#include <pw/core/globals.hpp>
#include <pw/core/point.hpp>
namespace pw {
class input {
public:
struct input {
static input& get();
point mouse_position() const { return _mouse_position; }
point<int32_t> mouse_position() const { return _mouse_position; }
bool mouse_pressed() const { return _mouse_pressed; }
int mouse_button() const { return _mouse_button; }
bool has_input() const { return !_input_string.empty();}
bool has_input() const { return !_input_string.empty(); }
std::string input_string() const { return _input_string; }
~input() = default;
~input() = default;
enum mouse_button_state {
pressed,
released
};
enum mouse_button_state { pressed, released };
void reset();
protected:
protected:
friend class window;
input() = default;
private:
point _mouse_position;
int _mouse_button;
private:
point<int32_t> _mouse_position;
int _mouse_button;
bool _mouse_pressed;
int _key_code;
bool _key_pressed;
std::string _input_string;
std::string _input_string;
};
}
} // namespace pw
#endif

View file

@ -1,33 +1,33 @@
#ifndef PW_SYSTEM_WINDOW_HPP
#define PW_SYSTEM_WINDOW_HPP
#include <cstdint>
#include <pw/core/globals.hpp>
#include <pw/core/size.hpp>
#include <pw/core/point.hpp>
#include <pw/core/size.hpp>
#include <functional>
namespace pw {
class window {
public:
struct window final {
using on_update_t = std::function<void(window&)> ;
using on_resize_t = std::function<void(window&)> ;
using on_update_t = std::function<void(window&)>;
using on_resize_t = std::function<void(window&)>;
window();
~window();
bool update();
void set_title(const std::string& title);
void set_title(const std::string& title);
void set_size(const size& s);
pw::size size() const;
pw::size client_size() const;
void set_size(const size<int32_t>& s);
pw::size<int32_t> size() const;
pw::size<int32_t> client_size() const;
void set_position(const point& p);
point position() const;
void set_position(const point<int32_t>& p);
point<int32_t> position() const;
typedef void drop_callback;
@ -39,17 +39,15 @@ public:
bool visible() const;
void set_visible(bool is_visible);
protected:
struct impl;
std::unique_ptr<impl> _impl;
protected:
struct impl;
std::unique_ptr<impl> _impl;
on_update_t _on_update;
on_resize_t _on_resize;
};
}
} // namespace pw
#endif

View file

@ -1,99 +1,102 @@
#include "pw/system/window.hpp"
// clang-format off
#include "glad/glad.h"
#include "GLFW/glfw3.h"
// clang-format on
#include "pw/visual/context.hpp"
#include "pw/system/input.hpp"
#include "pw/system/display.hpp"
#include "pw/system/input.hpp"
#include "pw/visual/context.hpp"
#include "pw/core/debug.hpp"
#include <cmath>
#include <locale>
#include <codecvt>
#include <cstdint>
#include <locale>
#include <iostream>
namespace pw {
//struct window_context : context
// struct window_context : context
//{
// virtual bool make_current() override;
// virtual void resize() override;
// // virtual context::size size() override;
// virtual void flush() override;
//};
// virtual bool make_current() override;
// virtual void resize() override;
// // virtual context::size size() override;
// virtual void flush() override;
// };
//bool window_context::make_current()
// bool window_context::make_current()
//{
//}
// }
//void window_context::resize()
// void window_context::resize()
//{
//}
// }
//void window_context::flush()
// void window_context::flush()
//{
//}
// }
struct window::impl {
window& _parent;
GLFWwindow *_window = nullptr;
GLFWwindow* _window = nullptr;
::pw::size _old_size;
pointi _old_pos;
::pw::size<int32_t> _old_size;
point<int32_t> _old_pos;
// window_context _context;
static void error_callback(int error, const char* description)
{
debug::e() << "GLFW error: " << description;
static void error_callback(int error, const char* description) {
debug::e() << "GLFW error: " << description;
}
static void drop_callback(GLFWwindow* window, int count, const char** paths)
{
static void drop_callback(GLFWwindow* window, int count,
const char** paths) {
// std::cout << __FUNCTION__ << std::endl;
// for (int i = 0; i < count; i++)
// std::cout << "\t" << paths[i] << std::endl;
}
static void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
std::cout << __FUNCTION__ << std::endl;
static void scroll_callback(GLFWwindow* window, double xoffset,
double yoffset) {
// std::cout << __FUNCTION__ << std::endl;
}
static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
static void mouse_button_callback(GLFWwindow* window, int button,
int action, int mods) {
input::get()._mouse_button = button;
std::cout << __FUNCTION__ << " " << button << " " << action << " " << mods << std::endl;
// std::cout << __FUNCTION__ << " " << button << " " << action << " "
// << mods << std::endl;
// input::get()._mouse_position
}
static void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos)
{
input::get()._mouse_position = pointd(xpos,ypos).cast<float>();
static void cursor_pos_callback(GLFWwindow* window, double xpos,
double ypos) {
input::get()._mouse_position =
point<double>(xpos, ypos).cast<int32_t>();
}
static void key_callback(GLFWwindow *window,int key, int scancode, int action, int mods)
{
input::get()._key_code = scancode;
static void key_callback(GLFWwindow* window, int key, int scancode,
int action, int mods) {
input::get()._key_code = scancode;
input::get()._key_pressed = action;
// action 0,1,2
// std::cout << __FUNCTION__ << action << std::endl;
}
// static void character_callback(GLFWwindow* window, unsigned int codepoint)
// static void character_callback(GLFWwindow* window, unsigned int
// codepoint)
// {
// std::cout << __FUNCTION__ << std::endl;
// }
static void charmods_callback(GLFWwindow* window, unsigned int codepoint, int mods)
{
static void charmods_callback(GLFWwindow* window, unsigned int codepoint,
int mods) {
// build the string from a Unicode code point
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
std::string u8str = converter.to_bytes(codepoint);
@ -101,28 +104,30 @@ struct window::impl {
input::get()._input_string = u8str;
}
static void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
window::impl* impl = static_cast<window::impl*>(glfwGetWindowUserPointer(window));
static void framebuffer_size_callback(GLFWwindow* window, int width,
int height) {
window::impl* impl =
static_cast<window::impl*>(glfwGetWindowUserPointer(window));
impl->_parent._on_resize(impl->_parent);
// debug::d() << "window::frame_buffer_size_callback " << width << "x" << height;
// debug::d() << "window::frame_buffer_size_callback " << width
// << "x" << height;
// impl->on_resize(width,height);
// std::cout << "framebuffer " << width << "x" << height << std::endl;
// glViewport(0, 0, width, height);
// std::cout << "framebuffer " << width << "x" << height <<
// std::endl;
// glViewport(0, 0, width, height);
}
void update_display_list()
{
void update_display_list() {
display::_displays.clear();
// fetch all monitors
int monitor_count = 0;
int monitor_count = 0;
GLFWmonitor** monitors = glfwGetMonitors(&monitor_count);
for (int i = 0; i < monitor_count;i++) {
for (int i = 0; i < monitor_count; i++) {
display d;
d._name = std::string(glfwGetMonitorName(monitors[i]));
@ -137,24 +142,21 @@ struct window::impl {
// glfwGetMonitorPos(
// glfwGetMonitorPhysicalSize(
// glfwGetMonitorName();
}
impl(window& w)
: _parent(w)
{
impl(window& w) : _parent(w) {
// initialize
if (!glfwInit())
{
if (!glfwInit()) {
debug::e() << "Initalization error";
}
int glfw_major, glfx_minor,glfw_rev;
glfwGetVersion(&glfw_major,&glfx_minor,&glfw_rev);
int glfw_major, glfx_minor, glfw_rev;
glfwGetVersion(&glfw_major, &glfx_minor, &glfw_rev);
// debug::d() << "GLFW " << glfw_major << "." << glfx_minor << "." << glfw_rev;
// debug::d() << "GLFW header " << GLFW_VERSION_MAJOR << "." << GLFW_VERSION_MINOR << "." << GLFW_VERSION_REVISION;
// debug::d() << "GLFW " << glfw_major << "." << glfx_minor <<
// "." << glfw_rev; debug::d() << "GLFW header " <<
// GLFW_VERSION_MAJOR << "." << GLFW_VERSION_MINOR << "." <<
// GLFW_VERSION_REVISION;
update_display_list();
@ -175,8 +177,7 @@ struct window::impl {
glfwMakeContextCurrent(_window);
// load opengl
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
debug::e() << "glad couldn't get OpenGL API";
}
@ -184,14 +185,16 @@ struct window::impl {
int major, minor, rev;
major = glfwGetWindowAttrib(_window, GLFW_CONTEXT_VERSION_MAJOR);
minor = glfwGetWindowAttrib(_window, GLFW_CONTEXT_VERSION_MINOR);
rev = glfwGetWindowAttrib(_window, GLFW_CONTEXT_REVISION);
rev = glfwGetWindowAttrib(_window, GLFW_CONTEXT_REVISION);
// maybe something to pass to the outside
// debug::d() << "OpenGL " << major << "." << minor << "." << rev;
// debug::d() << "OpenGL " << major << "." << minor << "." <<
// rev;
glfwSetWindowUserPointer(_window,this);
glfwSetWindowUserPointer(_window, this);
glfwSetFramebufferSizeCallback(_window, window::impl::framebuffer_size_callback);
glfwSetFramebufferSizeCallback(_window,
window::impl::framebuffer_size_callback);
glfwSetKeyCallback(_window, window::impl::key_callback);
// glfwSetCharCallback(_window, character_callback);
glfwSetCharModsCallback(_window, charmods_callback);
@ -203,22 +206,17 @@ struct window::impl {
glfwSetMouseButtonCallback(_window, mouse_button_callback);
glfwSetScrollCallback(_window, scroll_callback);
glfwSetErrorCallback(error_callback);
//glfwSetWindowCloseCallback(_window,close_callback);
// glfwSetWindowCloseCallback(_window,close_callback);
}
~impl()
{
glfwDestroyWindow(_window);
}
~impl() { glfwDestroyWindow(_window); }
bool update()
{
if (_window && !glfwWindowShouldClose(_window))
{
// TODO lock an unlock the current input system to allow for late events coming in
bool update() {
if (_window && !glfwWindowShouldClose(_window)) {
// TODO lock an unlock the current input system to allow for late
// events coming in
input::get().reset();
// get new events
@ -234,70 +232,60 @@ struct window::impl {
return false;
}
void set_title(const std::string& title)
{
glfwSetWindowTitle(_window,title.c_str());
void set_title(const std::string& title) {
glfwSetWindowTitle(_window, title.c_str());
}
void set_size(const ::pw::size& s)
{
glfwSetWindowSize(_window,s.width,s.height);
void set_size(const ::pw::size<int32_t>& s) {
glfwSetWindowSize(_window, s.width, s.height);
}
::pw::size size() const
{
int w,h;
glfwGetWindowSize(_window,&w,&h);
return ::pw::size(w,h);
::pw::size<int32_t> size() const {
int w, h;
glfwGetWindowSize(_window, &w, &h);
return ::pw::size<int32_t>{w, h};
}
::pw::size client_size() const
{
int w,h;
glfwGetFramebufferSize(_window,&w,&h);
return ::pw::size(w,h);
::pw::size<int32_t> client_size() const {
int w, h;
glfwGetFramebufferSize(_window, &w, &h);
return ::pw::size<int32_t>{w, h};
}
::pw::point position() const
{
int x,y;
glfwGetWindowPos(_window,&x,&y);
return ::pw::point(x,y);
::pw::point<int32_t> position() const {
int x, y;
glfwGetWindowPos(_window, &x, &y);
return ::pw::point<int32_t>(x, y);
}
void set_position(const pointi& p)
{
glfwSetWindowPos(_window,p.x,p.y);
void set_position(const point<int32_t>& p) {
glfwSetWindowPos(_window, p.x, p.y);
}
void set_fullscreen(bool use_fullscreen)
{
void set_fullscreen(bool use_fullscreen) {
if (fullscreen() == use_fullscreen)
return;
if (use_fullscreen)
{
glfwGetWindowPos( _window, &_old_pos.x, &_old_pos.y );
glfwGetWindowSize( _window, &_old_size.width, &_old_size.height );
if (use_fullscreen) {
glfwGetWindowPos(_window, &_old_pos.x, &_old_pos.y);
glfwGetWindowSize(_window, &_old_size.width, &_old_size.height);
GLFWmonitor * monitor = glfwGetPrimaryMonitor();
const GLFWvidmode * mode = glfwGetVideoMode(monitor);
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
glfwSetWindowMonitor( _window, monitor, 0, 0, mode->width, mode->height, 0 );
glfwSetWindowMonitor(_window, monitor, 0, 0, mode->width,
mode->height, 0);
} else
{
} else {
glfwSetWindowMonitor( _window, nullptr, _old_pos.x,_old_pos.y, _old_size.width,_old_size.height,0);
glfwSetWindowMonitor(_window, nullptr, _old_pos.x, _old_pos.y,
_old_size.width, _old_size.height, 0);
}
// glfwSetWindow
}
bool fullscreen() const {
return glfwGetWindowMonitor(_window) != nullptr;
}
bool fullscreen() const { return glfwGetWindowMonitor(_window) != nullptr; }
void set_visible(bool show) {
(show) ? glfwShowWindow(_window) : glfwHideWindow(_window);
@ -308,77 +296,39 @@ struct window::impl {
}
};
//
//
//
window::window()
: _impl(std::make_unique<window::impl>(*this))
, _on_update([](window&){})
, _on_resize([](window&){})
{
}
: _impl(std::make_unique<window::impl>(*this)), _on_update([](window&) {}),
_on_resize([](window&) {}) {}
window::~window()
{
}
window::~window() {}
bool window::update()
{
return _impl->update();
}
bool window::update() { return _impl->update(); }
void window::set_title(const std::string& title)
{
_impl->set_title(title);
}
void window::set_title(const std::string& title) { _impl->set_title(title); }
void window::set_size(const ::pw::size& s)
{
_impl->set_size(s.cast<int>());
}
void window::set_size(const ::pw::size<int32_t>& s) { _impl->set_size(s); }
size window::size() const
{
return _impl->size();
}
size<int32_t> window::size() const { return _impl->size(); }
size window::client_size() const
{
return _impl->client_size();
}
size<int32_t> window::client_size() const { return _impl->client_size(); }
void window::set_position(const point &p)
{
void window::set_position(const point<int32_t>& p) {
_impl->set_position(p.cast<int>());
}
point window::position() const
{
return _impl->position();
}
point<int32_t> window::position() const { return _impl->position(); }
bool window::fullscreen() const
{
return _impl->fullscreen();
}
bool window::fullscreen() const { return _impl->fullscreen(); }
void window::set_fullscreen(bool use_fullscreen)
{
void window::set_fullscreen(bool use_fullscreen) {
_impl->set_fullscreen(use_fullscreen);
}
bool window::visible() const
{
return _impl->visible();
}
bool window::visible() const { return _impl->visible(); }
void window::set_visible(bool is_visible)
{
_impl->set_visible(is_visible);
}
void window::set_visible(bool is_visible) { _impl->set_visible(is_visible); }
}
} // namespace pw