25 std::cout <<
"surface: started example.\n";
26 if (!resize_canvas_to_swapchain()) {
27 throw mxvk::Exception(
"surface: failed to initialize canvas from swapchain extent");
31 void event(SDL_Event &e)
override {
33 case SDL_EVENT_KEY_DOWN:
34 if (e.key.key == SDLK_ESCAPE) {
45 SDL_Surface *canvas = bg.get();
46 if (canvas ==
nullptr || !SDL_LockSurface(canvas)) {
49 auto *pixels =
static_cast<Uint8 *
>(canvas->pixels);
50 for (
int y = 0; y < canvas->h; ++y) {
51 Uint8 *row = pixels + y * canvas->pitch;
52 for (
int x = 0; x < canvas->w; ++x) {
53 const std::uint32_t color = random_color(random_engine);
54 Uint8 *p = row + x * 4;
55 p[0] =
static_cast<Uint8
>(color & 0xFFU);
56 p[1] =
static_cast<Uint8
>((color >> 8U) & 0xFFU);
57 p[2] =
static_cast<Uint8
>((color >> 16U) & 0xFFU);
58 p[3] =
static_cast<Uint8
>(255);
61 SDL_UnlockSurface(canvas);
62 surf->updateTexture(canvas);
63 surf->drawSpriteRect(0, 0, target_width, target_height);
67 resize_canvas_to_swapchain();
71 bool resize_canvas_to_swapchain() {
76 if (extent.width == 0U || extent.height == 0U) {
79 resize_canvas(
static_cast<int>(extent.width),
static_cast<int>(extent.height));
83 void resize_canvas(
int width,
int height) {
84 if (width <= 0 || height <= 0 || (bg !=
nullptr && bg->w == width && bg->h == height)) {
87 bg.reset(SDL_CreateSurface(width, height, SDL_PIXELFORMAT_RGBA32));
89 throw mxvk::Exception(
"Failed to create surface canvas: " + std::string(SDL_GetError()));
91 SDL_FillSurfaceRect(bg.get(),
nullptr, SDL_MapSurfaceRGBA(bg.get(), 0, 0, 0, 255));
93 target_height = height;
96 mxvk::VK_Sprite *surf =
nullptr;
97 std::unique_ptr<SDL_Surface, surface::SurfaceDeleter> bg;
98 int target_width = 1280;
99 int target_height = 720;
100 std::mt19937 random_engine{std::random_device{}()};
101 std::uniform_int_distribution<std::uint32_t> random_color{0U, 0x00FFFFFFU};
105int main(
int argc,
char **argv) {
111 std::cerr << std::format(
"mxvk: Exception: {}\n", e.
text());
114 std::cerr << std::format(
"mxvk: Argument Exception: {}\n", e.
text());
Lightweight, header-only, template command-line argument parser.
Arguments proc_args(int &argc, char **argv)
Parse standard libmx2 command-line options from main()'s argv.
Exception thrown by Argz::proc() on unrecognised or malformed options.
Main Vulkan window wrapper for MXVK.
VkExtent2D getSwapchainExtent() const noexcept
Get the current swapchain extent.
void loop()
Run the main event/render loop.
VK_Sprite * createSprite(const std::string &pngPath, const std::string &vertexShaderPath="", const std::string &fragmentShaderPath="")
Create a sprite from a PNG file and register it with this window.
void exit()
Request loop termination.
bool ensureRenderResources()
Ensure deferred render resources are initialized.
VK_Window()=default
Construct an empty window object.
void onSwapchainRecreated() override
Called after swapchain and render resources are recreated.
SurfaceWindow(std::string shader_path, int width, int height, bool full, bool enable_vsync)
void proc() override
Execute one processing/update step.
void event(SDL_Event &e) override
Handle one SDL event.
Utilities for loading and saving PNG images.
Plain data structure returned by proc_args() with all common libmx2 CLI options.
bool fullscreen
Whether fullscreen mode was requested.
bool enable_vsync
Enable FIFO present mode / v-sync (--enable-vsync).
int height
Viewport height in pixels (default: 720).
std::string filename
Optional input filename (--filename).
int width
Viewport width in pixels (default: 1280).
void operator()(SDL_Surface *surface) const