2016-02-16 15:07:25 +01:00
|
|
|
/*
|
|
|
|
|
* Vulkan Example base class
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
|
|
|
|
|
*
|
|
|
|
|
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
#pragma comment(linker, "/subsystem:windows")
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <io.h>
|
2016-03-20 14:55:46 +01:00
|
|
|
#elif defined(__ANDROID__)
|
|
|
|
|
#include <android/native_activity.h>
|
2016-03-20 15:45:40 +01:00
|
|
|
#include <android/asset_manager.h>
|
|
|
|
|
#include <android_native_app_glue.h>
|
2016-03-20 14:55:46 +01:00
|
|
|
#include "vulkanandroid.h"
|
|
|
|
|
#elif defined(__linux__)
|
2016-02-16 15:07:25 +01:00
|
|
|
#include <xcb/xcb.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <chrono>
|
|
|
|
|
|
|
|
|
|
#define GLM_FORCE_RADIANS
|
2016-03-08 21:52:40 +01:00
|
|
|
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
2016-02-16 15:07:25 +01:00
|
|
|
#include <glm/glm.hpp>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <array>
|
|
|
|
|
|
|
|
|
|
#include "vulkan/vulkan.h"
|
|
|
|
|
|
2016-08-03 21:44:04 +02:00
|
|
|
#include "keycodes.hpp"
|
2016-02-16 15:07:25 +01:00
|
|
|
#include "vulkantools.h"
|
|
|
|
|
#include "vulkandebug.h"
|
|
|
|
|
|
2017-01-06 22:48:37 +01:00
|
|
|
#include "VulkanInitializers.hpp"
|
2016-07-16 17:36:35 +02:00
|
|
|
#include "vulkandevice.hpp"
|
2016-02-16 15:07:25 +01:00
|
|
|
#include "vulkanswapchain.hpp"
|
|
|
|
|
#include "vulkanTextureLoader.hpp"
|
|
|
|
|
#include "vulkanMeshLoader.hpp"
|
2016-05-15 18:31:31 +02:00
|
|
|
#include "vulkantextoverlay.hpp"
|
2016-06-11 15:54:16 +02:00
|
|
|
#include "camera.hpp"
|
2016-02-16 15:07:25 +01:00
|
|
|
|
|
|
|
|
class VulkanExampleBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2016-03-13 16:51:00 +01:00
|
|
|
// fps timer (one second interval)
|
|
|
|
|
float fpsTimer = 0.0f;
|
|
|
|
|
// Get window title with example name, device, et.
|
|
|
|
|
std::string getWindowTitle();
|
2016-07-31 12:41:50 +02:00
|
|
|
/** brief Indicates that the view (position, rotation) has changed and */
|
|
|
|
|
bool viewUpdated = false;
|
2016-04-10 11:12:04 +02:00
|
|
|
// Destination dimensions for resizing the window
|
|
|
|
|
uint32_t destWidth;
|
|
|
|
|
uint32_t destHeight;
|
2016-10-16 17:39:30 +02:00
|
|
|
bool resizing = false;
|
2016-04-10 11:12:04 +02:00
|
|
|
// Called if the window is resized and some resources have to be recreatesd
|
|
|
|
|
void windowResize();
|
2016-02-16 15:07:25 +01:00
|
|
|
protected:
|
|
|
|
|
// Last frame time, measured using a high performance timer (if available)
|
|
|
|
|
float frameTimer = 1.0f;
|
2016-03-13 16:51:00 +01:00
|
|
|
// Frame counter to display fps
|
|
|
|
|
uint32_t frameCounter = 0;
|
2016-05-14 21:19:52 +02:00
|
|
|
uint32_t lastFPS = 0;
|
2016-02-16 15:07:25 +01:00
|
|
|
// Vulkan instance, stores all per-application states
|
|
|
|
|
VkInstance instance;
|
|
|
|
|
// Physical device (GPU) that Vulkan will ise
|
|
|
|
|
VkPhysicalDevice physicalDevice;
|
2016-03-13 16:51:00 +01:00
|
|
|
// Stores physical device properties (for e.g. checking device limits)
|
|
|
|
|
VkPhysicalDeviceProperties deviceProperties;
|
2016-12-14 21:38:45 +01:00
|
|
|
// Stores the features available on the selected physical device (for e.g. checking if a feature is available)
|
2016-04-24 10:28:27 +02:00
|
|
|
VkPhysicalDeviceFeatures deviceFeatures;
|
2016-02-16 15:07:25 +01:00
|
|
|
// Stores all available memory (type) properties for the physical device
|
|
|
|
|
VkPhysicalDeviceMemoryProperties deviceMemoryProperties;
|
2016-12-14 21:38:45 +01:00
|
|
|
/**
|
|
|
|
|
* Set of physical device features to be enabled for this example (must be set in the derived constructor)
|
|
|
|
|
*
|
|
|
|
|
* @note By default no phyiscal device features are enabled
|
|
|
|
|
*/
|
|
|
|
|
VkPhysicalDeviceFeatures enabledFeatures{};
|
2016-07-16 17:36:35 +02:00
|
|
|
/** @brief Logical device, application's view of the physical device (GPU) */
|
|
|
|
|
// todo: getter? should always point to VulkanDevice->device
|
2016-02-16 15:07:25 +01:00
|
|
|
VkDevice device;
|
2016-07-16 17:36:35 +02:00
|
|
|
/** @brief Encapsulated physical and logical vulkan device */
|
2016-07-22 20:45:48 +02:00
|
|
|
vk::VulkanDevice *vulkanDevice;
|
2016-02-16 15:07:25 +01:00
|
|
|
// Handle to the device graphics queue that command buffers are submitted to
|
|
|
|
|
VkQueue queue;
|
|
|
|
|
// Color buffer format
|
|
|
|
|
VkFormat colorformat = VK_FORMAT_B8G8R8A8_UNORM;
|
|
|
|
|
// Depth buffer format
|
|
|
|
|
// Depth format is selected during Vulkan initialization
|
|
|
|
|
VkFormat depthFormat;
|
|
|
|
|
// Command buffer pool
|
|
|
|
|
VkCommandPool cmdPool;
|
2016-08-11 19:29:40 +02:00
|
|
|
/** @brief Pipeline stages used to wait at for graphics queue submissions */
|
|
|
|
|
VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
2016-03-06 19:22:41 +01:00
|
|
|
// Contains command buffers and semaphores to be presented to the queue
|
|
|
|
|
VkSubmitInfo submitInfo;
|
2016-02-16 15:07:25 +01:00
|
|
|
// Command buffers used for rendering
|
|
|
|
|
std::vector<VkCommandBuffer> drawCmdBuffers;
|
|
|
|
|
// Global render pass for frame buffer writes
|
|
|
|
|
VkRenderPass renderPass;
|
|
|
|
|
// List of available frame buffers (same as number of swap chain images)
|
|
|
|
|
std::vector<VkFramebuffer>frameBuffers;
|
|
|
|
|
// Active frame buffer index
|
|
|
|
|
uint32_t currentBuffer = 0;
|
|
|
|
|
// Descriptor set pool
|
2016-04-02 12:47:08 +02:00
|
|
|
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
|
2016-02-16 15:07:25 +01:00
|
|
|
// List of shader modules created (stored for cleanup)
|
|
|
|
|
std::vector<VkShaderModule> shaderModules;
|
|
|
|
|
// Pipeline cache object
|
|
|
|
|
VkPipelineCache pipelineCache;
|
|
|
|
|
// Wraps the swap chain to present images (framebuffers) to the windowing system
|
|
|
|
|
VulkanSwapChain swapChain;
|
2016-03-06 19:22:41 +01:00
|
|
|
// Synchronization semaphores
|
|
|
|
|
struct {
|
|
|
|
|
// Swap chain image presentation
|
|
|
|
|
VkSemaphore presentComplete;
|
|
|
|
|
// Command buffer submission and execution
|
|
|
|
|
VkSemaphore renderComplete;
|
2016-05-15 18:31:31 +02:00
|
|
|
// Text overlay submission and execution
|
|
|
|
|
VkSemaphore textOverlayComplete;
|
2016-03-06 19:22:41 +01:00
|
|
|
} semaphores;
|
2016-02-16 15:07:25 +01:00
|
|
|
// Simple texture loader
|
|
|
|
|
vkTools::VulkanTextureLoader *textureLoader = nullptr;
|
2016-03-21 20:10:09 +01:00
|
|
|
// Returns the base asset path (for shaders, models, textures) depending on the os
|
|
|
|
|
const std::string getAssetPath();
|
2016-02-16 15:07:25 +01:00
|
|
|
public:
|
|
|
|
|
bool prepared = false;
|
|
|
|
|
uint32_t width = 1280;
|
|
|
|
|
uint32_t height = 720;
|
|
|
|
|
|
2017-01-22 13:38:57 +01:00
|
|
|
/** @brief Example settings that can be changed e.g. by command line arguments */
|
|
|
|
|
struct Settings {
|
|
|
|
|
/** @brief Activates validation layers (and message output) when set to true */
|
|
|
|
|
bool validation = false;
|
|
|
|
|
/** @brief Set to true if fullscreen mode has been requested via command line */
|
|
|
|
|
bool fullscreen = false;
|
|
|
|
|
/** @brief Set to true if v-sync will be forced for the swapchain */
|
|
|
|
|
bool vsync = false;
|
|
|
|
|
} settings;
|
|
|
|
|
|
2016-02-16 15:07:25 +01:00
|
|
|
VkClearColorValue defaultClearColor = { { 0.025f, 0.025f, 0.025f, 1.0f } };
|
|
|
|
|
|
|
|
|
|
float zoom = 0;
|
|
|
|
|
|
2016-11-10 22:56:15 +01:00
|
|
|
static std::vector<const char*> args;
|
2016-11-10 22:29:55 +01:00
|
|
|
|
2016-02-16 15:07:25 +01:00
|
|
|
// Defines a frame rate independent timer value clamped from -1.0...1.0
|
|
|
|
|
// For use in animations, rotations, etc.
|
|
|
|
|
float timer = 0.0f;
|
|
|
|
|
// Multiplier for speeding up (or slowing down) the global timer
|
|
|
|
|
float timerSpeed = 0.25f;
|
|
|
|
|
|
|
|
|
|
bool paused = false;
|
|
|
|
|
|
2016-05-15 18:31:31 +02:00
|
|
|
bool enableTextOverlay = false;
|
|
|
|
|
VulkanTextOverlay *textOverlay;
|
|
|
|
|
|
2016-02-16 15:07:25 +01:00
|
|
|
// Use to adjust mouse rotation speed
|
|
|
|
|
float rotationSpeed = 1.0f;
|
|
|
|
|
// Use to adjust mouse zoom speed
|
|
|
|
|
float zoomSpeed = 1.0f;
|
|
|
|
|
|
2016-06-11 15:54:16 +02:00
|
|
|
Camera camera;
|
|
|
|
|
|
2016-02-16 15:07:25 +01:00
|
|
|
glm::vec3 rotation = glm::vec3();
|
2016-03-30 22:48:58 +02:00
|
|
|
glm::vec3 cameraPos = glm::vec3();
|
2016-02-16 15:07:25 +01:00
|
|
|
glm::vec2 mousePos;
|
|
|
|
|
|
|
|
|
|
std::string title = "Vulkan Example";
|
|
|
|
|
std::string name = "vulkanExample";
|
|
|
|
|
|
|
|
|
|
struct
|
|
|
|
|
{
|
|
|
|
|
VkImage image;
|
|
|
|
|
VkDeviceMemory mem;
|
|
|
|
|
VkImageView view;
|
|
|
|
|
} depthStencil;
|
|
|
|
|
|
2016-05-15 11:13:14 +02:00
|
|
|
// Gamepad state (only one pad supported)
|
2016-03-20 21:46:49 +01:00
|
|
|
struct
|
|
|
|
|
{
|
2016-06-20 22:08:50 +02:00
|
|
|
glm::vec2 axisLeft = glm::vec2(0.0f);
|
|
|
|
|
glm::vec2 axisRight = glm::vec2(0.0f);
|
2016-03-20 21:46:49 +01:00
|
|
|
} gamePadState;
|
2016-05-15 11:13:14 +02:00
|
|
|
|
|
|
|
|
// OS specific
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
|
HWND window;
|
|
|
|
|
HINSTANCE windowInstance;
|
|
|
|
|
#elif defined(__ANDROID__)
|
|
|
|
|
// true if application has focused, false if moved to background
|
|
|
|
|
bool focused = false;
|
2016-03-20 14:55:46 +01:00
|
|
|
#elif defined(__linux__)
|
2016-02-16 15:07:25 +01:00
|
|
|
struct {
|
|
|
|
|
bool left = false;
|
|
|
|
|
bool right = false;
|
2016-03-30 22:48:58 +02:00
|
|
|
bool middle = false;
|
2016-02-16 15:07:25 +01:00
|
|
|
} mouseButtons;
|
2016-07-18 20:43:41 +02:00
|
|
|
bool quit = false;
|
2016-02-16 15:07:25 +01:00
|
|
|
xcb_connection_t *connection;
|
|
|
|
|
xcb_screen_t *screen;
|
|
|
|
|
xcb_window_t window;
|
|
|
|
|
xcb_intern_atom_reply_t *atom_wm_delete_window;
|
2016-03-20 14:55:46 +01:00
|
|
|
#endif
|
2016-02-16 15:07:25 +01:00
|
|
|
|
2016-05-30 20:57:38 +02:00
|
|
|
// Default ctor
|
2016-12-14 20:17:15 +01:00
|
|
|
VulkanExampleBase(bool enableValidation);
|
2016-05-30 20:57:38 +02:00
|
|
|
|
|
|
|
|
// dtor
|
2016-02-16 15:07:25 +01:00
|
|
|
~VulkanExampleBase();
|
|
|
|
|
|
|
|
|
|
// Setup the vulkan instance, enable required extensions and connect to the physical device (GPU)
|
2016-12-13 19:59:15 +01:00
|
|
|
void initVulkan();
|
2016-02-16 15:07:25 +01:00
|
|
|
|
2016-03-20 14:55:46 +01:00
|
|
|
#if defined(_WIN32)
|
2016-02-16 15:07:25 +01:00
|
|
|
void setupConsole(std::string title);
|
|
|
|
|
HWND setupWindow(HINSTANCE hinstance, WNDPROC wndproc);
|
|
|
|
|
void handleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
2016-03-20 14:55:46 +01:00
|
|
|
#elif defined(__ANDROID__)
|
2016-03-20 21:46:49 +01:00
|
|
|
static int32_t handleAppInput(struct android_app* app, AInputEvent* event);
|
2016-03-20 17:35:54 +01:00
|
|
|
static void handleAppCommand(android_app* app, int32_t cmd);
|
2016-03-20 14:55:46 +01:00
|
|
|
#elif defined(__linux__)
|
2016-02-16 15:07:25 +01:00
|
|
|
xcb_window_t setupWindow();
|
|
|
|
|
void initxcbConnection();
|
|
|
|
|
void handleEvent(const xcb_generic_event_t *event);
|
|
|
|
|
#endif
|
2016-12-13 19:59:15 +01:00
|
|
|
/**
|
|
|
|
|
* Create the application wide Vulkan instance
|
|
|
|
|
*
|
|
|
|
|
* @note Virtual, can be overriden by derived example class for custom instance creation
|
|
|
|
|
*/
|
|
|
|
|
virtual VkResult createInstance(bool enableValidation);
|
|
|
|
|
|
2016-02-16 15:07:25 +01:00
|
|
|
// Pure virtual render function (override in derived class)
|
|
|
|
|
virtual void render() = 0;
|
|
|
|
|
// Called when view change occurs
|
|
|
|
|
// Can be overriden in derived class to e.g. update uniform buffers
|
|
|
|
|
// Containing view dependant matrices
|
|
|
|
|
virtual void viewChanged();
|
2016-03-03 16:41:57 +01:00
|
|
|
// Called if a key is pressed
|
2016-03-28 21:43:31 +02:00
|
|
|
// Can be overriden in derived class to do custom key handling
|
2016-03-03 16:41:57 +01:00
|
|
|
virtual void keyPressed(uint32_t keyCode);
|
2016-04-10 11:12:04 +02:00
|
|
|
// Called when the window has been resized
|
|
|
|
|
// Can be overriden in derived class to recreate or rebuild resources attached to the frame buffer / swapchain
|
|
|
|
|
virtual void windowResized();
|
|
|
|
|
// Pure virtual function to be overriden by the dervice class
|
|
|
|
|
// Called in case of an event where e.g. the framebuffer has to be rebuild and thus
|
|
|
|
|
// all command buffers that may reference this
|
|
|
|
|
virtual void buildCommandBuffers();
|
2016-02-16 15:07:25 +01:00
|
|
|
|
|
|
|
|
// Creates a new (graphics) command pool object storing command buffers
|
|
|
|
|
void createCommandPool();
|
|
|
|
|
// Setup default depth and stencil views
|
2016-06-03 13:15:55 +02:00
|
|
|
virtual void setupDepthStencil();
|
2016-02-16 15:07:25 +01:00
|
|
|
// Create framebuffers for all requested swap chain images
|
2016-03-28 21:43:31 +02:00
|
|
|
// Can be overriden in derived class to setup a custom framebuffer (e.g. for MSAA)
|
|
|
|
|
virtual void setupFrameBuffer();
|
2016-02-16 15:07:25 +01:00
|
|
|
// Setup a default render pass
|
2016-03-28 21:43:31 +02:00
|
|
|
// Can be overriden in derived class to setup a custom render pass (e.g. for MSAA)
|
|
|
|
|
virtual void setupRenderPass();
|
2016-02-16 15:07:25 +01:00
|
|
|
|
|
|
|
|
// Connect and prepare the swap chain
|
|
|
|
|
void initSwapchain();
|
|
|
|
|
// Create swap chain images
|
|
|
|
|
void setupSwapChain();
|
|
|
|
|
|
|
|
|
|
// Check if command buffers are valid (!= VK_NULL_HANDLE)
|
|
|
|
|
bool checkCommandBuffers();
|
|
|
|
|
// Create command buffers for drawing commands
|
|
|
|
|
void createCommandBuffers();
|
|
|
|
|
// Destroy all command buffers and set their handles to VK_NULL_HANDLE
|
|
|
|
|
// May be necessary during runtime if options are toggled
|
|
|
|
|
void destroyCommandBuffers();
|
|
|
|
|
|
2016-04-16 14:42:41 +02:00
|
|
|
// Command buffer creation
|
|
|
|
|
// Creates and returns a new command buffer
|
|
|
|
|
VkCommandBuffer createCommandBuffer(VkCommandBufferLevel level, bool begin);
|
|
|
|
|
// End the command buffer, submit it to the queue and free (if requested)
|
|
|
|
|
// Note : Waits for the queue to become idle
|
|
|
|
|
void flushCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue, bool free);
|
|
|
|
|
|
2016-02-16 15:07:25 +01:00
|
|
|
// Create a cache pool for rendering pipelines
|
|
|
|
|
void createPipelineCache();
|
|
|
|
|
|
|
|
|
|
// Prepare commonly used Vulkan functions
|
2016-03-20 17:35:54 +01:00
|
|
|
virtual void prepare();
|
2016-02-16 15:07:25 +01:00
|
|
|
|
|
|
|
|
// Load a SPIR-V shader
|
2016-03-21 20:10:09 +01:00
|
|
|
VkPipelineShaderStageCreateInfo loadShader(std::string fileName, VkShaderStageFlagBits stage);
|
2016-03-06 20:15:56 +01:00
|
|
|
|
2016-02-16 15:07:25 +01:00
|
|
|
// Load a mesh (using ASSIMP) and create vulkan vertex and index buffers with given vertex layout
|
|
|
|
|
void loadMesh(
|
2016-07-03 21:09:20 +02:00
|
|
|
std::string fiename,
|
|
|
|
|
vkMeshLoader::MeshBuffer *meshBuffer,
|
|
|
|
|
std::vector<vkMeshLoader::VertexLayout> vertexLayout,
|
2016-02-16 15:07:25 +01:00
|
|
|
float scale);
|
2016-07-03 21:09:20 +02:00
|
|
|
void loadMesh(
|
|
|
|
|
std::string filename,
|
|
|
|
|
vkMeshLoader::MeshBuffer *meshBuffer,
|
|
|
|
|
std::vector<vkMeshLoader::VertexLayout>
|
|
|
|
|
vertexLayout,
|
|
|
|
|
vkMeshLoader::MeshCreateInfo *meshCreateInfo);
|
2016-03-22 13:41:30 +01:00
|
|
|
|
2016-02-16 15:07:25 +01:00
|
|
|
// Start the main render loop
|
|
|
|
|
void renderLoop();
|
|
|
|
|
|
2016-05-15 18:31:31 +02:00
|
|
|
void updateTextOverlay();
|
2016-05-15 20:11:28 +02:00
|
|
|
|
2016-05-18 19:33:15 +02:00
|
|
|
// Called when the text overlay is updating
|
|
|
|
|
// Can be overriden in derived class to add custom text to the overlay
|
|
|
|
|
virtual void getOverlayText(VulkanTextOverlay * textOverlay);
|
|
|
|
|
|
2016-05-15 20:11:28 +02:00
|
|
|
// Prepare the frame for workload submission
|
|
|
|
|
// - Acquires the next image from the swap chain
|
|
|
|
|
// - Sets the default wait and signal semaphores
|
|
|
|
|
void prepareFrame();
|
|
|
|
|
|
|
|
|
|
// Submit the frames' workload
|
|
|
|
|
// - Submits the text overlay (if enabled)
|
|
|
|
|
void submitFrame();
|
|
|
|
|
|
2016-02-16 15:07:25 +01:00
|
|
|
};
|
|
|
|
|
|
2016-06-25 23:01:09 +02:00
|
|
|
// OS specific macros for the example main entry points
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
|
// Windows entry point
|
2016-06-27 22:28:21 +02:00
|
|
|
#define VULKAN_EXAMPLE_MAIN() \
|
2016-06-26 00:04:13 +02:00
|
|
|
VulkanExample *vulkanExample; \
|
|
|
|
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) \
|
|
|
|
|
{ \
|
|
|
|
|
if (vulkanExample != NULL) \
|
|
|
|
|
{ \
|
|
|
|
|
vulkanExample->handleMessages(hWnd, uMsg, wParam, lParam); \
|
|
|
|
|
} \
|
|
|
|
|
return (DefWindowProc(hWnd, uMsg, wParam, lParam)); \
|
|
|
|
|
} \
|
2016-06-25 23:01:09 +02:00
|
|
|
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) \
|
|
|
|
|
{ \
|
2016-11-10 22:29:55 +01:00
|
|
|
for (size_t i = 0; i < __argc; i++) { VulkanExample::args.push_back(__argv[i]); }; \
|
2016-06-26 00:04:13 +02:00
|
|
|
vulkanExample = new VulkanExample(); \
|
2016-12-13 19:59:15 +01:00
|
|
|
vulkanExample->initVulkan(); \
|
2016-06-26 00:04:13 +02:00
|
|
|
vulkanExample->setupWindow(hInstance, WndProc); \
|
|
|
|
|
vulkanExample->initSwapchain(); \
|
|
|
|
|
vulkanExample->prepare(); \
|
|
|
|
|
vulkanExample->renderLoop(); \
|
|
|
|
|
delete(vulkanExample); \
|
2016-06-25 23:01:09 +02:00
|
|
|
return 0; \
|
2016-06-26 00:04:13 +02:00
|
|
|
}
|
2016-06-25 23:01:09 +02:00
|
|
|
#elif defined(__ANDROID__)
|
|
|
|
|
// Android entry point
|
|
|
|
|
// A note on app_dummy(): This is required as the compiler may otherwise remove the main entry point of the application
|
2016-06-27 22:28:21 +02:00
|
|
|
#define VULKAN_EXAMPLE_MAIN() \
|
2016-06-26 00:04:13 +02:00
|
|
|
VulkanExample *vulkanExample; \
|
2016-06-25 23:01:09 +02:00
|
|
|
void android_main(android_app* state) \
|
|
|
|
|
{ \
|
|
|
|
|
app_dummy(); \
|
2016-06-26 00:04:13 +02:00
|
|
|
vulkanExample = new VulkanExample(); \
|
2016-06-25 23:01:09 +02:00
|
|
|
state->userData = vulkanExample; \
|
|
|
|
|
state->onAppCmd = VulkanExample::handleAppCommand; \
|
|
|
|
|
state->onInputEvent = VulkanExample::handleAppInput; \
|
2017-01-18 19:21:40 +01:00
|
|
|
androidApp = state; \
|
2016-06-26 00:04:13 +02:00
|
|
|
vulkanExample->renderLoop(); \
|
|
|
|
|
delete(vulkanExample); \
|
2016-06-25 23:01:09 +02:00
|
|
|
}
|
2016-11-04 13:32:58 -07:00
|
|
|
#elif defined(_DIRECT2DISPLAY)
|
|
|
|
|
// Linux entry point with direct to display wsi
|
|
|
|
|
// todo: extract command line arguments
|
|
|
|
|
#define VULKAN_EXAMPLE_MAIN() \
|
|
|
|
|
VulkanExample *vulkanExample; \
|
|
|
|
|
static void handleEvent() \
|
|
|
|
|
{ \
|
|
|
|
|
} \
|
|
|
|
|
int main(const int argc, const char *argv[]) \
|
|
|
|
|
{ \
|
2016-11-10 22:56:15 +01:00
|
|
|
vulkanExample = new VulkanExample(); \
|
2016-12-13 19:59:15 +01:00
|
|
|
vulkanExample->initVulkan(); \
|
2016-11-04 13:32:58 -07:00
|
|
|
vulkanExample->initSwapchain(); \
|
|
|
|
|
vulkanExample->prepare(); \
|
|
|
|
|
vulkanExample->renderLoop(); \
|
|
|
|
|
delete(vulkanExample); \
|
|
|
|
|
return 0; \
|
|
|
|
|
}
|
2016-06-25 23:01:09 +02:00
|
|
|
#elif defined(__linux__)
|
|
|
|
|
// Linux entry point
|
|
|
|
|
// todo: extract command line arguments
|
2016-06-27 22:28:21 +02:00
|
|
|
#define VULKAN_EXAMPLE_MAIN() \
|
2016-06-26 00:04:13 +02:00
|
|
|
VulkanExample *vulkanExample; \
|
|
|
|
|
static void handleEvent(const xcb_generic_event_t *event) \
|
|
|
|
|
{ \
|
|
|
|
|
if (vulkanExample != NULL) \
|
|
|
|
|
{ \
|
|
|
|
|
vulkanExample->handleEvent(event); \
|
|
|
|
|
} \
|
2016-07-04 19:12:30 +02:00
|
|
|
} \
|
2016-06-25 23:01:09 +02:00
|
|
|
int main(const int argc, const char *argv[]) \
|
|
|
|
|
{ \
|
2016-11-10 22:29:55 +01:00
|
|
|
for (size_t i = 0; i < argc; i++) { VulkanExample::args.push_back(argv[i]); }; \
|
2016-06-26 00:04:13 +02:00
|
|
|
vulkanExample = new VulkanExample(); \
|
2016-12-13 19:59:15 +01:00
|
|
|
vulkanExample->initVulkan(); \
|
2016-06-26 00:04:13 +02:00
|
|
|
vulkanExample->setupWindow(); \
|
|
|
|
|
vulkanExample->initSwapchain(); \
|
|
|
|
|
vulkanExample->prepare(); \
|
|
|
|
|
vulkanExample->renderLoop(); \
|
|
|
|
|
delete(vulkanExample); \
|
2016-06-25 23:01:09 +02:00
|
|
|
return 0; \
|
|
|
|
|
}
|
|
|
|
|
#endif
|