Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vk-shadertoy rework #1

Merged
merged 1 commit into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cmake/glsl_compile.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ macro(append_glsl_to_target target sources version)

get_filename_component(FILE_NAME ${GLSL} NAME)

set(SPIRV "${CMAKE_CURRENT_BINARY_DIR}/shaders/${FILE_NAME}.spv")
set(SPIRV "${CMAKE_CURRENT_BINARY_DIR}/shaders//spv/${FILE_NAME}.spv")

if (NOT EXISTS "${GLSL}")
set(GLSL "${CMAKE_CURRENT_SOURCE_DIR}/${GLSL}")
endif ()

add_custom_command(
OUTPUT ${SPIRV}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/shaders
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/shaders/spv
COMMAND ${GLSL_VALIDATOR} -V${version} ${GLSL} -o ${SPIRV}
DEPENDS ${GLSL}
)
Expand All @@ -44,7 +44,7 @@ macro(append_glsl_to_target target sources version)
add_dependencies(${target} Shaders)

add_custom_command(TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${target}>/shaders/"
COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${target}>/shaders"
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_BINARY_DIR}/shaders" "$<TARGET_FILE_DIR:${target}>/shaders"
)
endmacro()
8 changes: 3 additions & 5 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,10 @@ add_sanitizers(agl-capture)
#
# Vulkan
#
if (FALSE)
find_package(Vulkan)
find_package(Vulkan)

if (VULKAN_FOUND)
add_subdirectory(vk-shadertoy)
endif ()
if (VULKAN_FOUND)
add_subdirectory(vk-shadertoy)
endif ()

#
Expand Down
12 changes: 8 additions & 4 deletions examples/vk-shadertoy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,19 @@ set(SHADER_SOURCES

add_executable(vk-shadertoy
app.cc
handlers.cc
main.cc
vk_backend.cc
vk_image.cc
vk_buffer.cc
shader_toy.cc
vulkan/render.cc
vulkan/utils.cc
vulkan/vk_error_print.cc
)

append_glsl_to_target(vk-shadertoy "${SHADER_SOURCES}" 100)

target_compile_definitions(vk-shadertoy PUBLIC -DVK_USE_PLATFORM_WAYLAND_KHR)

target_include_directories(vk-shadertoy PRIVATE .)

target_link_libraries(vk-shadertoy PRIVATE waypp wayland-gen cxxopts::cxxopts)

if (IPO_SUPPORT_RESULT)
Expand Down
253 changes: 220 additions & 33 deletions examples/vk-shadertoy/app.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,62 +23,249 @@

#include "app.h"

#include <linux/input.h>

#include <thread>

static constexpr uint32_t kOffscreenBuffers = 4;

void App::draw_frame(void* /* data */, const uint32_t /* time */) {
// auto window = static_cast<Window *>(data);
void App::draw_frame(void *data, const uint32_t time) {
auto window = static_cast<Window *>(data);
auto shadertoy = static_cast<ShaderToy *>(window->get_user_data());
shadertoy->draw_frame(time);
}

App::App(const Configuration& config)
: handlers_(std::make_unique<Handlers>()),
logging_(std::make_unique<Logging>()) {
spdlog::info("{}", kAppTitle);

display_ = wl_display_connect(nullptr);
if (!display_) {
spdlog::critical("Unable to connect to Wayland socket.");
exit(EXIT_FAILURE);
}
App::App(const Configuration &config) : logging_(std::make_unique<Logging>()) {
spdlog::info("{}", kAppTitle);

std::thread t1([&] {
backend_ = std::make_unique<VulkanBackend>(kAppId, config.debug_enable);
});
display_ = wl_display_connect(nullptr);
if (!display_) {
spdlog::critical("Unable to connect to Wayland socket.");
exit(EXIT_FAILURE);
}

std::thread t2([&] {
shadertoy_ = std::make_unique<ShaderToy>();
wm_ = std::make_unique<XdgWindowManager>(display_, config.disable_cursor);
auto seat = wm_->get_seat();
if (seat.has_value()) {
seat.value()->register_observer(handlers_.get());
seat.value()->set_user_data(this);
seat.value()->register_observer(this);
}

spdlog::debug("XDG Window Manager Version: {}", wm_->get_version());

toplevel_ = wm_->create_top_level(
kAppTitle, kAppId, config.width, config.height, 0, 0, config.fullscreen,
config.maximized, config.fullscreen_ratio, config.tearing, draw_frame);
kAppTitle, kAppId, config.width, config.height, 0, 0, config.fullscreen,
config.maximized, true, config.tearing, draw_frame);
spdlog::debug("XDG Window Version: {}", toplevel_->get_version());
});

t1.join();
t2.join();
shadertoy_->init(config.width,
config.height,
display_,
toplevel_->get_surface(),
config.dev_index,
config.use_gpu_idx,
config.debug,
config.reload_shaders,
static_cast<VkPresentModeKHR>(config.present_mode));

backend_->CreateSurface(wm_->get_display(), toplevel_->get_surface(),
config.width, config.height, kOffscreenBuffers);
toplevel_->set_user_data(shadertoy_.get());

/// paint padding
toplevel_->set_surface_damage(0, 0, config.width, config.height);
toplevel_->start_frame_callbacks();
/// paint padding
toplevel_->set_surface_damage(0, 0, config.width, config.height);
toplevel_->start_frame_callbacks();
}

App::~App() {
toplevel_->stop_frame_callbacks();
wl_display_flush(display_);
wl_display_flush(display_);
toplevel_->stop_frame_callbacks();
wl_display_flush(display_);
wl_display_flush(display_);
}

bool App::run() {
/// display_dispatch is blocking
return (toplevel_->is_valid() && wm_->display_dispatch() != -1);
/// display_dispatch is blocking
return (toplevel_->is_valid() && wm_->display_dispatch() != -1);
}

void App::notify_seat_capabilities(Seat *seat,
wl_seat * /* seat */,
uint32_t /* caps */) {
if (seat) {
auto keyboard = seat->get_keyboard();
if (keyboard.has_value()) {
keyboard.value()->set_user_data(this);
keyboard.value()->register_observer(this);
}

auto pointer = seat->get_pointer();
if (pointer.has_value()) {
pointer.value()->set_user_data(this);
pointer.value()->register_observer(this);
}
}
}

void App::notify_seat_name(Seat * /* seat */,
wl_seat * /* seat */,
const char * /* name */) {
}

void App::notify_keyboard_enter(Keyboard * /* keyboard */,
wl_keyboard * /* wl_keyboard */,
uint32_t /* serial */,
wl_surface * /* surface */,
wl_array * /* keys */) {
}

void App::notify_keyboard_leave(Keyboard * /* keyboard */,
wl_keyboard * /* wl_keyboard */,
uint32_t /* serial */,
wl_surface * /* surface */) {
}

void App::notify_keyboard_keymap(Keyboard * /* keyboard */,
wl_keyboard * /* wl_keyboard */,
uint32_t /* format */,
int32_t /* fd */,
uint32_t /* size */) {
}

void App::notify_keyboard_xkb_v1_key(Keyboard *keyboard,
wl_keyboard * /* wl_keyboard */,
uint32_t /* serial */,
uint32_t /* time */,
uint32_t /* xkb_scancode */,
bool /* key_repeats */,
uint32_t state,
int xdg_key_symbol_count,
const xkb_keysym_t *xdg_key_symbols) {

if (xdg_key_symbol_count && state == KeyState::KEY_STATE_PRESS) {

auto app = static_cast<App *>(keyboard->get_user_data());
auto shader_toy = app->shadertoy_.get();

switch (xdg_key_symbols[0]) {
case XKB_KEY_Escape:
spdlog::info("Quit");
app->toplevel_->close();
break;
case XKB_KEY_space:
spdlog::info("Toggle Pause");
shader_toy->toggle_pause();
break;
case XKB_KEY_0:
spdlog::info("Toggle Draw Debug");
shader_toy->toggle_draw_debug();
break;
case XKB_KEY_1:
spdlog::info("Toggle FPS Lock");
shader_toy->toggle_fps_lock();
break;
case XKB_KEY_z:
spdlog::info("Screen shot");
shader_toy->screen_shot();
break;
case XKB_KEY_f:
case XKB_KEY_F11:
spdlog::info("Toggle fullscreen");
app->toggle_fullscreen();
break;
}
}
}

void App::notify_pointer_enter(Pointer *pointer,
wl_pointer * /* pointer */,
uint32_t serial,
wl_surface * /* surface */,
double /* sx */,
double /* sy */) {
pointer->set_cursor(serial);
}

void App::notify_pointer_leave(Pointer * /* pointer */,
wl_pointer * /* pointer */,
uint32_t /* serial */,
wl_surface * /* surface */) {
}

void App::notify_pointer_motion(Pointer *pointer,
wl_pointer * /* pointer */,
uint32_t /* time */,
double sx,
double sy) {
auto app = static_cast<App *>(pointer->get_user_data());
auto shader_toy = app->shadertoy_.get();
auto os_window = shader_toy->get_app_os_window();
os_window->app_data.iMouse[0] = sx;
os_window->app_data.iMouse[1] = os_window->app_data.iResolution[1] - sy;
}

void App::notify_pointer_button(Pointer *pointer,
wl_pointer * /* pointer */,
uint32_t /* serial */,
uint32_t /* time */,
uint32_t button,
uint32_t state) {
// spdlog::info("Pointer Button: pointer: {}, time: {}, button: {}, state: {}", serial, time, button, state);
auto app = static_cast<App *>(pointer->get_user_data());
auto shader_toy = app->shadertoy_.get();
auto os_window = shader_toy->get_app_os_window();

switch (button) {
case BTN_LEFT:
os_window->app_data.iMouse_click[0] = state;
if (state) {
os_window->app_data.iMouse_lclick[0] = static_cast<int>(os_window->app_data.iMouse[0]);
os_window->app_data.iMouse_lclick[1] = static_cast<int>(os_window->app_data.iResolution[1] -
os_window->app_data.iMouse[1]);
} else {
os_window->app_data.iMouse_lclick[0] = -os_window->app_data.iMouse_lclick[0];
os_window->app_data.iMouse_lclick[1] = -os_window->app_data.iMouse_lclick[1];
}
break;
case BTN_MIDDLE:
break;
case BTN_RIGHT:
os_window->app_data.iMouse_click[1] = state;
if (state) {
os_window->app_data.iMouse_rclick[0] = static_cast<int>(os_window->app_data.iMouse[0]);
os_window->app_data.iMouse_rclick[1] = static_cast<int>(os_window->app_data.iResolution[1] -
os_window->app_data.iMouse[1]);
} else {
os_window->app_data.iMouse_rclick[0] = -os_window->app_data.iMouse_rclick[0];
os_window->app_data.iMouse_rclick[1] = -os_window->app_data.iMouse_rclick[1];
}
break;
default:
break;
}
}

void App::notify_pointer_axis(Pointer * /* pointer */,
wl_pointer * /* pointer */,
uint32_t /* time */,
uint32_t /* axis */,
wl_fixed_t /* value */) {
}

void App::notify_pointer_frame(Pointer * /* pointer */,
wl_pointer * /* pointer */) {
};

void App::notify_pointer_axis_source(Pointer * /* pointer */,
wl_pointer * /* pointer */,
uint32_t /* axis_source */) {
};

void App::notify_pointer_axis_stop(Pointer * /* pointer */,
wl_pointer * /* pointer */,
uint32_t /* time */,
uint32_t /* axis */) {
};

void App::notify_pointer_axis_discrete(Pointer * /* pointer */,
wl_pointer * /*pointer */,
uint32_t /* axis */,
int32_t /* discrete */) {
}
Loading
Loading