From cf965d29b9092ea6b56847028dc885b67b1603e0 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bruyère Date: Fri, 26 Oct 2018 18:59:06 +0200 Subject: some renames for c++ --- include/vke.h | 186 --------------- include/vke.hpp | 186 +++++++++++++++ src/VkEngine.cpp | 591 ------------------------------------------------ src/VkEngine.h | 0 src/VulkanBuffer.hpp | 52 ----- src/VulkanDevice.cpp | 2 +- src/VulkanDevice.hpp | 4 +- src/VulkanSwapChain.cpp | 2 +- src/VulkanSwapChain.hpp | 2 +- src/VulkanTexture.hpp | 263 --------------------- src/VulkanglTFModel.hpp | 7 +- src/buffer.cpp | 4 +- src/buffer.hpp | 52 +++++ src/macros.h | 51 ----- src/macros.hpp | 51 +++++ src/pbrrenderer2.cpp | 2 +- src/pbrrenderer2.h | 50 ---- src/pbrrenderer2.hpp | 50 ++++ src/phyInfos.h | 102 --------- src/phyInfos.hpp | 102 +++++++++ src/rendertarget.cpp | 4 +- src/rendertarget.hpp | 2 +- src/resource.hpp | 2 +- src/shadingcontext.cpp | 2 +- src/shadingcontext.hpp | 2 +- src/texture.cpp | 4 +- src/texture.hpp | 245 +++++++++++++++++++- src/vke.cpp | 591 ++++++++++++++++++++++++++++++++++++++++++++++++ src/vkrenderer.cpp | 6 +- src/vkrenderer.h | 69 ------ src/vkrenderer.hpp | 69 ++++++ tests/test1.cpp | 19 +- 32 files changed, 1379 insertions(+), 1395 deletions(-) delete mode 100644 include/vke.h create mode 100644 include/vke.hpp delete mode 100644 src/VkEngine.cpp delete mode 100644 src/VkEngine.h delete mode 100644 src/VulkanBuffer.hpp delete mode 100644 src/VulkanTexture.hpp create mode 100644 src/buffer.hpp delete mode 100644 src/macros.h create mode 100644 src/macros.hpp delete mode 100644 src/pbrrenderer2.h create mode 100644 src/pbrrenderer2.hpp delete mode 100644 src/phyInfos.h create mode 100644 src/phyInfos.hpp create mode 100644 src/vke.cpp delete mode 100644 src/vkrenderer.h create mode 100644 src/vkrenderer.hpp diff --git a/include/vke.h b/include/vke.h deleted file mode 100644 index b6656f8..0000000 --- a/include/vke.h +++ /dev/null @@ -1,186 +0,0 @@ -/* -* 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 - -#include -#include - -#define GLM_FORCE_RADIANS -#define GLM_FORCE_DEPTH_ZERO_TO_ONE -#define GLM_ENABLE_EXPERIMENTAL -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vulkan/vulkan.h" - -#include "GLFW/glfw3.h" - -namespace vke { - class engine_t; - class swap_chain_t; - struct device_t; - struct Texture; - struct render_target_t; - struct buffer_t; - class ShadingContext; - struct Resource; - class Camera; - struct vkPhyInfo; -} - -#if defined(__linux__) -#define KEY_ESCAPE 0x9 -#define KEY_F1 0x43 -#define KEY_F2 0x44 -#define KEY_F3 0x45 -#define KEY_F4 0x46 -#define KEY_W 0x19 -#define KEY_A 0x26 -#define KEY_S 0x27 -#define KEY_D 0x28 -#define KEY_P 0x21 -#define KEY_SPACE 0x41 -#define KEY_KPADD 0x56 -#define KEY_KPSUB 0x52 -#define KEY_B 0x38 -#define KEY_F 0x29 -#define KEY_L 0x2E -#define KEY_N 0x39 -#define KEY_O 0x20 -#define KEY_T 0x1C -#endif - -// AngelCode .fnt format structs and classes -struct bmchar { - uint32_t x, y; - uint32_t width; - uint32_t height; - int32_t xoffset; - int32_t yoffset; - int32_t xadvance; - uint32_t page; -}; -std::array parsebmFont(const std::string& fileName); - -namespace vke { - - class engine_t - { - private: - float fpsTimer = 0.0f; - uint32_t frameCounter = 0; - - bool viewUpdated = false; - - std::string getWindowTitle(); - -#if DEBUG - PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallback; - PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback; - VkDebugReportCallbackEXT debugReportCallback; -#endif - - void _createInstance (const std::string& app_name, std::vector& extentions); - protected: - vkPhyInfo* phyInfos; - GLFWwindow* window; - - swap_chain_t* swapChain; - render_target_t* renderTarget; - std::string title = "Vulkan Example"; - std::string name = "vulkanExample"; - - virtual void windowResize(); - public: - static std::vector args; - - VkInstance instance; - device_t* device; - VkSurfaceKHR surface; - - - uint32_t lastFPS = 0; - float frameTimer = 1.0f; - bool prepared = false; - uint32_t width, height; - Camera* camera; - glm::vec2 mousePos; - bool paused = false; - - struct Settings { - bool validation = false; - bool fullscreen = false; - bool vsync = false; - bool multiSampling = true; - VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT; - } settings; - - struct UniformBuffers { - buffer_t* matrices; - buffer_t* params; - } sharedUBOs; - - struct MVPMatrices { - glm::mat4 projection; - glm::mat4 view3; - glm::mat4 view; - glm::vec3 camPos; - } mvpMatrices; - - struct LightingParams { - glm::vec4 lightDir = glm::vec4(0.0f, -0.5f, -0.5f, 1.0f); - float exposure = 4.5f; - float gamma = 1.0f; - float prefilteredCubeMipLevels; - } lightingParams; - - glm::vec3 rotation = glm::vec3(0.0f, 135.0f, 0.0f); - - struct GamePadState { - glm::vec2 axisLeft = glm::vec2(0.0f); - glm::vec2 axisRight = glm::vec2(0.0f); - } gamePadState; - - bool mouseButtons[3] = {false,false,false}; - - - engine_t(uint32_t width, uint32_t height, - VkPhysicalDeviceType preferedGPU = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU); - virtual ~engine_t(); - - virtual void start(); - - virtual void render() = 0; - virtual void viewChanged(); - virtual void keyDown(uint32_t key); - virtual void keyUp(uint32_t key); - virtual void keyPressed(uint32_t key); - virtual void handleMouseMove(int32_t x, int32_t y); - virtual void handleMouseButtonDown(int buttonIndex); - virtual void handleMouseButtonUp(int buttonIndex); - virtual void prepare(); - - void prepareUniformBuffers(); - void updateUniformBuffers(); - void updateParams(); - - void prepareFrame(); - }; -} diff --git a/include/vke.hpp b/include/vke.hpp new file mode 100644 index 0000000..b6656f8 --- /dev/null +++ b/include/vke.hpp @@ -0,0 +1,186 @@ +/* +* 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 + +#include +#include + +#define GLM_FORCE_RADIANS +#define GLM_FORCE_DEPTH_ZERO_TO_ONE +#define GLM_ENABLE_EXPERIMENTAL +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vulkan/vulkan.h" + +#include "GLFW/glfw3.h" + +namespace vke { + class engine_t; + class swap_chain_t; + struct device_t; + struct Texture; + struct render_target_t; + struct buffer_t; + class ShadingContext; + struct Resource; + class Camera; + struct vkPhyInfo; +} + +#if defined(__linux__) +#define KEY_ESCAPE 0x9 +#define KEY_F1 0x43 +#define KEY_F2 0x44 +#define KEY_F3 0x45 +#define KEY_F4 0x46 +#define KEY_W 0x19 +#define KEY_A 0x26 +#define KEY_S 0x27 +#define KEY_D 0x28 +#define KEY_P 0x21 +#define KEY_SPACE 0x41 +#define KEY_KPADD 0x56 +#define KEY_KPSUB 0x52 +#define KEY_B 0x38 +#define KEY_F 0x29 +#define KEY_L 0x2E +#define KEY_N 0x39 +#define KEY_O 0x20 +#define KEY_T 0x1C +#endif + +// AngelCode .fnt format structs and classes +struct bmchar { + uint32_t x, y; + uint32_t width; + uint32_t height; + int32_t xoffset; + int32_t yoffset; + int32_t xadvance; + uint32_t page; +}; +std::array parsebmFont(const std::string& fileName); + +namespace vke { + + class engine_t + { + private: + float fpsTimer = 0.0f; + uint32_t frameCounter = 0; + + bool viewUpdated = false; + + std::string getWindowTitle(); + +#if DEBUG + PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallback; + PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback; + VkDebugReportCallbackEXT debugReportCallback; +#endif + + void _createInstance (const std::string& app_name, std::vector& extentions); + protected: + vkPhyInfo* phyInfos; + GLFWwindow* window; + + swap_chain_t* swapChain; + render_target_t* renderTarget; + std::string title = "Vulkan Example"; + std::string name = "vulkanExample"; + + virtual void windowResize(); + public: + static std::vector args; + + VkInstance instance; + device_t* device; + VkSurfaceKHR surface; + + + uint32_t lastFPS = 0; + float frameTimer = 1.0f; + bool prepared = false; + uint32_t width, height; + Camera* camera; + glm::vec2 mousePos; + bool paused = false; + + struct Settings { + bool validation = false; + bool fullscreen = false; + bool vsync = false; + bool multiSampling = true; + VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT; + } settings; + + struct UniformBuffers { + buffer_t* matrices; + buffer_t* params; + } sharedUBOs; + + struct MVPMatrices { + glm::mat4 projection; + glm::mat4 view3; + glm::mat4 view; + glm::vec3 camPos; + } mvpMatrices; + + struct LightingParams { + glm::vec4 lightDir = glm::vec4(0.0f, -0.5f, -0.5f, 1.0f); + float exposure = 4.5f; + float gamma = 1.0f; + float prefilteredCubeMipLevels; + } lightingParams; + + glm::vec3 rotation = glm::vec3(0.0f, 135.0f, 0.0f); + + struct GamePadState { + glm::vec2 axisLeft = glm::vec2(0.0f); + glm::vec2 axisRight = glm::vec2(0.0f); + } gamePadState; + + bool mouseButtons[3] = {false,false,false}; + + + engine_t(uint32_t width, uint32_t height, + VkPhysicalDeviceType preferedGPU = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU); + virtual ~engine_t(); + + virtual void start(); + + virtual void render() = 0; + virtual void viewChanged(); + virtual void keyDown(uint32_t key); + virtual void keyUp(uint32_t key); + virtual void keyPressed(uint32_t key); + virtual void handleMouseMove(int32_t x, int32_t y); + virtual void handleMouseButtonDown(int buttonIndex); + virtual void handleMouseButtonUp(int buttonIndex); + virtual void prepare(); + + void prepareUniformBuffers(); + void updateUniformBuffers(); + void updateParams(); + + void prepareFrame(); + }; +} diff --git a/src/VkEngine.cpp b/src/VkEngine.cpp deleted file mode 100644 index e6d12ab..0000000 --- a/src/VkEngine.cpp +++ /dev/null @@ -1,591 +0,0 @@ -/* -* Vulkan Example base class, stripped down version -* -* Copyright (C) 2016-2018 by Sascha Willems - www.saschawillems.de -* -* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) -*/ - -#define TINYGLTF_IMPLEMENTATION -#define STB_IMAGE_IMPLEMENTATION -#include "tiny_gltf.h" - -#include "vke.h" -#include "macros.h" - -#define ENGINE_NAME "vke" -#define ENGINE_VERSION 1 - -#include "VulkanDevice.hpp" - -#include "resource.hpp" -#include "VulkanBuffer.hpp" -#include "texture.hpp" - -#include "shadingcontext.hpp" -#include "rendertarget.hpp" - -#include "VulkanSwapChain.hpp" -#include "camera.hpp" - -int32_t nextValuePair(std::stringstream *stream) -{ - std::string pair; - *stream >> pair; - uint32_t spos = pair.find("="); - std::string value = pair.substr(spos + 1); - int32_t val = std::stoi(value); - return val; -} -// Basic parser fpr AngelCode bitmap font format files -// See http://www.angelcode.com/products/bmfont/doc/file_format.html for details -std::array parsebmFont(const std::string& fileName) -{ - std::array fontChars; - -#if defined(__ANDROID__) - // Font description file is stored inside the apk - // So we need to load it using the asset manager - AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, fileName.c_str(), AASSET_MODE_STREAMING); - assert(asset); - size_t size = AAsset_getLength(asset); - - assert(size > 0); - - void *fileData = malloc(size); - AAsset_read(asset, fileData, size); - AAsset_close(asset); - - std::stringbuf sbuf((const char*)fileData); - std::istream istream(&sbuf); -#else - std::filebuf fileBuffer; - fileBuffer.open(fileName, std::ios::in); - std::istream istream(&fileBuffer); -#endif - - assert(istream.good()); - - while (!istream.eof()) - { - std::string line; - std::stringstream lineStream; - std::getline(istream, line); - lineStream << line; - - std::string info; - lineStream >> info; - - if (info == "char") - { - // char id - uint32_t charid = nextValuePair(&lineStream); - // Char properties - fontChars[charid].x = nextValuePair(&lineStream); - fontChars[charid].y = nextValuePair(&lineStream); - fontChars[charid].width = nextValuePair(&lineStream); - fontChars[charid].height = nextValuePair(&lineStream); - fontChars[charid].xoffset = nextValuePair(&lineStream); - fontChars[charid].yoffset = nextValuePair(&lineStream); - fontChars[charid].xadvance = nextValuePair(&lineStream); - fontChars[charid].page = nextValuePair(&lineStream); - } - } - return fontChars; -} - -std::vector vke::engine_t::args; - -VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char * pLayerPrefix, const char * pMsg, void * pUserData) -{ - std::string prefix(""); - if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { - prefix += "ERROR:"; - }; - if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { - prefix += "WARNING:"; - }; - if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { - prefix += "DEBUG:"; - } - std::stringstream debugMessage; - debugMessage << prefix << " [" << pLayerPrefix << "] Code " << msgCode << " : " << pMsg; -#if defined(__ANDROID__) - LOGD("%s", debugMessage.str().c_str()); -#else - std::cout << debugMessage.str() << "\n"; -#endif - fflush(stdout); - return VK_FALSE; -} - -std::string vke::engine_t::getWindowTitle() -{ - std::string device(this->device->properties.deviceName); - std::string windowTitle; - windowTitle = title + " - " + device + " - " + std::to_string(lastFPS) + " fps"; - return windowTitle; -} - -static void onkey_callback (GLFWwindow* window, int key, int scanCode, int action ,int mods){ - vke::engine_t* e = (vke::engine_t*)glfwGetWindowUserPointer(window); - if (action == GLFW_PRESS) - e->keyDown(key); - else - e->keyUp(key); -} -static void char_callback (GLFWwindow* window, uint32_t c){ - vke::engine_t* e = (vke::engine_t*)glfwGetWindowUserPointer(window); -} -static void mouse_move_callback(GLFWwindow* window, double x, double y){ - vke::engine_t* e = (vke::engine_t*)glfwGetWindowUserPointer(window); - e->handleMouseMove((int32_t)x, (int32_t)y); -} -static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){ - vke::engine_t* e = (vke::engine_t*)glfwGetWindowUserPointer(window); - if (state == GLFW_PRESS){ - e->mouseButtons[but] = true; - e->handleMouseButtonDown(but); - }else{ - e->mouseButtons[but] = false; - e->handleMouseButtonUp(but); - } -} - -vke::engine_t::engine_t (uint32_t _width, uint32_t _height, - VkPhysicalDeviceType preferedGPU) -{ - width = _width; - height = _height; - - char* numConvPtr; - // Parse command line arguments - for (size_t i = 0; i < args.size(); i++) - { - if (args[i] == std::string("-validation")) { - settings.validation = true; - } - if (args[i] == std::string("-vsync")) { - settings.vsync = true; - } - if ((args[i] == std::string("-f")) || (args[i] == std::string("--fullscreen"))) { - settings.fullscreen = true; - } - if ((args[i] == std::string("-w")) || (args[i] == std::string("--width"))) { - uint32_t w = strtol(args[i + 1], &numConvPtr, 10); - if (numConvPtr != args[i + 1]) { width = w; }; - } - if ((args[i] == std::string("-h")) || (args[i] == std::string("--height"))) { - uint32_t h = strtol(args[i + 1], &numConvPtr, 10); - if (numConvPtr != args[i + 1]) { height = h; }; - } - } - - glfwInit(); - assert (glfwVulkanSupported()==GLFW_TRUE); - - uint32_t enabledExtsCount = 0, phyCount = 0; - const char ** enabledExts = glfwGetRequiredInstanceExtensions (&enabledExtsCount); - std::vector enabledExtentions; - enabledExtentions.assign(enabledExts, enabledExts + enabledExtsCount); - - _createInstance ("vkChess", enabledExtentions); - - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); - glfwWindowHint(GLFW_FLOATING, GLFW_FALSE); - glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); - - window = glfwCreateWindow (width, height, "Window Title", NULL, NULL); - - glfwSetWindowUserPointer (window, this); - - glfwSetKeyCallback (window, onkey_callback); - glfwSetCharCallback (window, char_callback); - glfwSetMouseButtonCallback (window, mouse_button_callback); - glfwSetCursorPosCallback (window, mouse_move_callback); - //glfwSetScrollCallback (e->window, onScroll); - - VK_CHECK_RESULT(glfwCreateWindowSurface(instance, window, NULL, &surface)); - - VK_CHECK_RESULT(vkEnumeratePhysicalDevices(instance, &phyCount, nullptr)); - assert(phyCount > 0); - std::vector physicalDevices(phyCount); - VK_CHECK_RESULT(vkEnumeratePhysicalDevices(instance, &phyCount, physicalDevices.data())); - - for (uint i=0; iproperties.deviceType == preferedGPU) - break; - } - - camera = new Camera(); -} - - -vke::engine_t::~engine_t() -{ - delete sharedUBOs.matrices; - delete sharedUBOs.params; - delete phyInfos; - delete camera; - - delete renderTarget; - delete swapChain; - - if (surface != VK_NULL_HANDLE) - vkDestroySurfaceKHR(instance, surface, nullptr); - - surface = VK_NULL_HANDLE; - - delete device; - - //if (settings.validation) - // vkDestroyDebugReportCallback(instance, debugReportCallback, nullptr); - - vkDestroyInstance (instance, VK_NULL_HANDLE); -} - -void vke::engine_t::start () { - std::vector devLayers; - -#if DEBUG - if (settings.validation) - devLayers.push_back ("VK_LAYER_LUNARG_standard_validation"); -#endif - - device = new vke::device_t (phyInfos, devLayers); - - swapChain = new swap_chain_t (this, false); - swapChain->create (width, height); - - renderTarget = new render_target_t(device, settings.sampleCount); - renderTarget->createDefaultPresentableTarget (swapChain); - - prepareUniformBuffers(); - - prepare(); - - prepared = true; - - while (!glfwWindowShouldClose (window)) { - glfwPollEvents(); - auto tStart = std::chrono::high_resolution_clock::now(); - if (viewUpdated) - { - viewUpdated = false; - viewChanged(); - } - - render(); - - frameCounter++; - auto tEnd = std::chrono::high_resolution_clock::now(); - auto tDiff = std::chrono::duration(tEnd - tStart).count(); - frameTimer = tDiff / 1000.0f; - camera->update(frameTimer); - if (camera->moving()) - viewUpdated = true; - fpsTimer += (float)tDiff; - if (fpsTimer > 1000.0f) - { - glfwSetWindowTitle(window, getWindowTitle().c_str()); - lastFPS = (float)frameCounter * (1000.0f / fpsTimer); - fpsTimer = 0.0f; - frameCounter = 0; - } - } -} - -void vke::engine_t::prepare(){} - -void vke::engine_t::prepareFrame() -{ - VkResult err = swapChain->acquireNextImage (device->dev); - if ((err == VK_ERROR_OUT_OF_DATE_KHR) || (err == VK_SUBOPTIMAL_KHR)) { - windowResize(); - } else { - VK_CHECK_RESULT(err); - } -} - -void vke::engine_t::_createInstance (const std::string& app_name, std::vector& extentions) { - VkApplicationInfo infos = {VK_STRUCTURE_TYPE_APPLICATION_INFO}; - infos.pApplicationName = app_name.c_str(); - infos.applicationVersion= 1; - infos.pEngineName = ENGINE_NAME; - infos.engineVersion = ENGINE_VERSION; - infos.apiVersion = VK_API_VERSION_1_0; - - - std::vector enabledLayers; - -#if DEBUG - if (settings.validation) - enabledLayers.push_back ("VK_LAYER_LUNARG_standard_validation"); -#endif - - VkInstanceCreateInfo inst_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO}; - inst_info.pApplicationInfo = &infos; - inst_info.enabledExtensionCount = extentions.size(); - inst_info.ppEnabledExtensionNames = extentions.data(); - inst_info.enabledLayerCount = enabledLayers.size(); - inst_info.ppEnabledLayerNames = enabledLayers.data(); - - VK_CHECK_RESULT(vkCreateInstance (&inst_info, NULL, &instance)); - -} - - -//void vks::VkEngine::handleEvent(const xcb_generic_event_t *event) -//{ -// switch (event->response_type & 0x7f) -// { -// case XCB_CLIENT_MESSAGE: -// if ((*(xcb_client_message_event_t*)event).data.data32[0] == -// (*atom_wm_delete_window).atom) { -// quit = true; -// } -// break; -// case XCB_MOTION_NOTIFY: -// { -// xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)event; -// handleMouseMove((int32_t)motion->event_x, (int32_t)motion->event_y); -// break; -// } -// break; -// case XCB_BUTTON_PRESS: -// { -// xcb_button_press_event_t *press = (xcb_button_press_event_t *)event; -// switch (press->detail) { -// case XCB_BUTTON_INDEX_1: -// mouseButtons.left = true; -// break; -// case XCB_BUTTON_INDEX_2: -// mouseButtons.middle = true; -// break; -// case XCB_BUTTON_INDEX_3: -// mouseButtons.right = true; -// break; -// case XCB_BUTTON_INDEX_4://wheel scroll up -// camera.translate(glm::vec3(0.0f, 0.0f, camera.zoomSpeed)); -// viewUpdated = true; -// break; -// case XCB_BUTTON_INDEX_5://wheel scroll down -// camera.translate(glm::vec3(0.0f, 0.0f, -camera.zoomSpeed)); -// viewUpdated = true; -// break; -// } -// handleMouseButtonDown(press->detail); -// } -// break; -// case XCB_BUTTON_RELEASE: -// { -// xcb_button_press_event_t *press = (xcb_button_press_event_t *)event; -// if (press->detail == XCB_BUTTON_INDEX_1) -// mouseButtons.left = false; -// if (press->detail == XCB_BUTTON_INDEX_2) -// mouseButtons.middle = false; -// if (press->detail == XCB_BUTTON_INDEX_3) -// mouseButtons.right = false; -// handleMouseButtonUp(press->detail); -// } -// break; -// case XCB_KEY_PRESS: -// { -// const xcb_key_release_event_t *keyEvent = (const xcb_key_release_event_t *)event; -// switch (keyEvent->detail) -// { -// case KEY_W: -// camera.keys.up = true; -// break; -// case KEY_S: -// camera.keys.down = true; -// break; -// case KEY_A: -// camera.keys.left = true; -// break; -// case KEY_D: -// camera.keys.right = true; -// break; -// case KEY_P: -// paused = !paused; -// break; -// } -// keyDown(keyEvent->detail); -// } -// break; -// case XCB_KEY_RELEASE: -// { -// const xcb_key_release_event_t *keyEvent = (const xcb_key_release_event_t *)event; -// switch (keyEvent->detail) -// { -// case KEY_W: -// camera.keys.up = false; -// break; -// case KEY_S: -// camera.keys.down = false; -// break; -// case KEY_A: -// camera.keys.left = false; -// break; -// case KEY_D: -// camera.keys.right = false; -// break; -// case KEY_ESCAPE: -// quit = true; -// break; -// } -// keyUp(keyEvent->detail); -// keyPressed(keyEvent->detail); -// } -// break; -// case XCB_DESTROY_NOTIFY: -// quit = true; -// break; -// case XCB_CONFIGURE_NOTIFY: -// { -// const xcb_configure_notify_event_t *cfgEvent = (const xcb_configure_notify_event_t *)event; -// if ((prepared) && ((cfgEvent->width != width) || (cfgEvent->height != height))) -// { -// destWidth = cfgEvent->width; -// destHeight = cfgEvent->height; -// if ((destWidth > 0) && (destHeight > 0)) -// { -// windowResize(); -// } -// } -// } -// break; -// default: -// break; -// } -//} - - -void vke::engine_t::viewChanged() { - updateUniformBuffers(); -} - -void vke::engine_t::prepareUniformBuffers() -{ - // Objact vertex shader uniform buffer - sharedUBOs.matrices = new buffer_t(device, - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - sizeof(mvpMatrices)); - - // Shared parameter uniform buffer - sharedUBOs.params = new buffer_t(device, - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - sizeof(lightingParams)); - - // Map persistent - sharedUBOs.matrices->map(); - sharedUBOs.params->map(); - - updateUniformBuffers(); - updateParams(); -} -void vke::engine_t::updateUniformBuffers() -{ - // 3D object - mvpMatrices.projection = camera->matrices.perspective; - mvpMatrices.view = camera->matrices.view; - mvpMatrices.view3 = glm::mat4(glm::mat3(camera->matrices.view)); - mvpMatrices.camPos = camera->position * -1.0f; - sharedUBOs.matrices->copyTo (&mvpMatrices, sizeof(mvpMatrices)); -} -void vke::engine_t::updateParams() -{ - lightingParams.lightDir = glm::vec4(-10.0f, 150.f, -10.f, 1.0f); - sharedUBOs.params->copyTo(&lightingParams, sizeof(lightingParams)); -} - -void vke::engine_t::windowResize() -{ - if (!prepared) - return; - prepared = false; - - vkDeviceWaitIdle(device->dev); - - swapChain->create (width, height); - - vkDeviceWaitIdle(device->dev); - - camera->updateAspectRatio((float)width / (float)height); - viewChanged(); - - prepared = true; -} - -void vke::engine_t::keyDown(uint32_t key) { - switch (key) { - case GLFW_KEY_ESCAPE : - glfwSetWindowShouldClose(window, GLFW_TRUE); - break; - } - -} -void vke::engine_t::keyUp(uint32_t key) { - keyPressed (key); -} -void vke::engine_t::keyPressed(uint32_t key) { - switch (key) { - case GLFW_KEY_F1: - if (lightingParams.exposure > 0.1f) { - lightingParams.exposure -= 0.1f; - updateParams(); - std::cout << "Exposure: " << lightingParams.exposure << std::endl; - } - break; - case GLFW_KEY_F2: - if (lightingParams.exposure < 10.0f) { - lightingParams.exposure += 0.1f; - updateParams(); - std::cout << "Exposure: " << lightingParams.exposure << std::endl; - } - break; - case GLFW_KEY_F3: - if (lightingParams.gamma > 0.1f) { - lightingParams.gamma -= 0.1f; - updateParams(); - std::cout << "Gamma: " << lightingParams.gamma << std::endl; - } - break; - case GLFW_KEY_F4: - if (lightingParams.gamma < 10.0f) { - lightingParams.gamma += 0.1f; - updateParams(); - std::cout << "Gamma: " << lightingParams.gamma << std::endl; - } - break; - } -} -void vke::engine_t::handleMouseMove(int32_t x, int32_t y) -{ - int32_t dx = (int32_t)mousePos.x - x; - int32_t dy = (int32_t)mousePos.y - y; - - bool handled = false; - - if (handled) { - mousePos = glm::vec2((float)x, (float)y); - return; - } - - if (mouseButtons[GLFW_MOUSE_BUTTON_RIGHT]) { - camera->rotate(glm::vec3(-dy * camera->rotationSpeed, -dx * camera->rotationSpeed, 0.0f)); - viewUpdated = true; - } - if (mouseButtons[GLFW_MOUSE_BUTTON_MIDDLE]) { - camera->translate(glm::vec3(-dx * 0.01f, -dy * 0.01f, 0.0f)); - viewUpdated = true; - } - mousePos = glm::vec2((float)x, (float)y); -} -void vke::engine_t::handleMouseButtonDown(int buttonIndex) {} -void vke::engine_t::handleMouseButtonUp(int buttonIndex) {} - diff --git a/src/VkEngine.h b/src/VkEngine.h deleted file mode 100644 index e69de29..0000000 diff --git a/src/VulkanBuffer.hpp b/src/VulkanBuffer.hpp deleted file mode 100644 index ed667bf..0000000 --- a/src/VulkanBuffer.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* -* Vulkan buffer class -* -* Encapsulates a Vulkan buffer -* -* 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 - -#include "vke.h" -#include "resource.hpp" - -namespace vke -{ - struct buffer_t : public Resource - { - VkBuffer buffer = VK_NULL_HANDLE; - - VkBufferCreateInfo infos = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; - - VkDescriptorBufferInfo descriptor; - VkDeviceSize size = 0; - VkDeviceSize alignment = 0; - VkBufferUsageFlags usageFlags; - VkMemoryPropertyFlags memoryPropertyFlags; - void* mapped = nullptr; - - buffer_t(device_t* _device, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags _memoryPropertyFlags, VkDeviceSize size, void *data = nullptr); - ~buffer_t(); - - VkResult map(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0); - void unmap(); - - VkResult bind(VkDeviceSize offset = 0); - - void setupDescriptor(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0); - - virtual VkWriteDescriptorSet getWriteDescriptorSet(VkDescriptorSet ds, uint32_t binding, VkDescriptorType descriptorType); - - void copyTo(void* data, VkDeviceSize size); - - VkResult flush(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0); - - VkResult invalidate(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0); - - void destroy(); - - }; -} diff --git a/src/VulkanDevice.cpp b/src/VulkanDevice.cpp index 16d5aae..27f0db5 100644 --- a/src/VulkanDevice.cpp +++ b/src/VulkanDevice.cpp @@ -1,5 +1,5 @@ #include "VulkanDevice.hpp" -#include "macros.h" +#include "macros.hpp" namespace vke { device_t::device_t(vkPhyInfo *phyInfos, const std::vector& devLayers) diff --git a/src/VulkanDevice.hpp b/src/VulkanDevice.hpp index 7c3783b..d4aff6c 100644 --- a/src/VulkanDevice.hpp +++ b/src/VulkanDevice.hpp @@ -10,8 +10,8 @@ #pragma once -#include "vke.h" -#include "phyInfos.h" +#include "vke.hpp" +#include "phyInfos.hpp" namespace vke { diff --git a/src/VulkanSwapChain.cpp b/src/VulkanSwapChain.cpp index 59aac45..e4190fe 100644 --- a/src/VulkanSwapChain.cpp +++ b/src/VulkanSwapChain.cpp @@ -13,7 +13,7 @@ #include "VulkanSwapChain.hpp" #include "VulkanDevice.hpp" #include "rendertarget.hpp" -#include "macros.h" +#include "macros.hpp" vke::swap_chain_t::swap_chain_t(engine_t *_vke, bool vsync) { vke = _vke; diff --git a/src/VulkanSwapChain.hpp b/src/VulkanSwapChain.hpp index d4e4424..49b07c2 100644 --- a/src/VulkanSwapChain.hpp +++ b/src/VulkanSwapChain.hpp @@ -10,7 +10,7 @@ #pragma once -#include "vke.h" +#include "vke.hpp" namespace vke { diff --git a/src/VulkanTexture.hpp b/src/VulkanTexture.hpp deleted file mode 100644 index 44eea90..0000000 --- a/src/VulkanTexture.hpp +++ /dev/null @@ -1,263 +0,0 @@ -/* -* Vulkan texture loader -* -* Copyright(C) 2016-2017 by Sascha Willems - www.saschawillems.de -* -* This code is licensed under the MIT license(MIT) (http://opensource.org/licenses/MIT) -*/ - -#pragma once - -#include -#include -#include -#include - -#include "vulkan/vulkan.h" -#include "macros.h" -#include "VulkanDevice.hpp" -#include "texture.hpp" - -#include - -#include "tiny_gltf.h" - -#if defined(__ANDROID__) -#include -#endif - -#include "VulkanBuffer.hpp" - -namespace vke -{ - class Texture2D : public Texture { - public: - void loadFromFile( - std::string filename, - VkFormat format, - vke::device_t *_device, - VkQueue copyQueue, - VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, - VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - { -#if defined(__ANDROID__) - // Textures are stored inside the apk on Android (compressed) - // So they need to be loaded via the asset manager - AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, filename.c_str(), AASSET_MODE_STREAMING); - if (!asset) { - LOGE("Could not load texture %s", filename.c_str()); - exit(-1); - } - size_t size = AAsset_getLength(asset); - assert(size > 0); - - void *textureData = malloc(size); - AAsset_read(asset, textureData, size); - AAsset_close(asset); - - gli::texture2d tex2D(gli::load((const char*)textureData, size)); - - free(textureData); -#else - gli::texture2d tex2D(gli::load(filename.c_str())); -#endif - assert(!tex2D.empty()); - - create(_device, VK_IMAGE_TYPE_2D, format, - static_cast(tex2D[0].extent().x),static_cast(tex2D[0].extent().y), - imageUsageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - VK_IMAGE_TILING_OPTIMAL,static_cast(tex2D.levels())); - - copyTo(copyQueue, (unsigned char*)tex2D.data(), tex2D.size()); - - createView(VK_IMAGE_VIEW_TYPE_2D); - createSampler(VK_FILTER_LINEAR,VK_SAMPLER_ADDRESS_MODE_REPEAT,VK_SAMPLER_MIPMAP_MODE_LINEAR); - - updateDescriptor(); - } - }; - - class TextureCubeMap : public Texture { - public: - void buildFromImages(const std::vector& mapDic, uint32_t textureSize, - VkFormat _format, - vke::device_t *_device, - VkQueue copyQueue, - VkImageUsageFlags _imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, - VkImageLayout _imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL){ - - create(_device, VK_IMAGE_TYPE_2D, _format, - textureSize, textureSize, - _imageUsageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT| VK_IMAGE_USAGE_TRANSFER_SRC_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_IMAGE_TILING_OPTIMAL, - (uint32_t)floor(log2(textureSize)) + 1, 6, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT); - - imageLayout = _imageLayout; - - for (int l = 0; l < mapDic.size(); l++) { - Texture inTex; - inTex.loadStbLinearNoSampling(mapDic[l].c_str(), device); - - VkCommandBuffer blitFirstMipCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - - VkImageBlit firstMipBlit{}; - firstMipBlit.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, l, 1}; - firstMipBlit.srcOffsets[1] = {inTex.infos.extent.width,inTex.infos.extent.height,1}; - firstMipBlit.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, l, 1}; - firstMipBlit.dstOffsets[1] = {infos.extent.width,infos.extent.height,1}; - - VkImageSubresourceRange firstMipSubRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, l, 1}; - - setImageLayout(blitFirstMipCmd, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - firstMipSubRange, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - - // Blit from source texture - vkCmdBlitImage(blitFirstMipCmd, inTex.image, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &firstMipBlit, VK_FILTER_CUBIC_IMG); - - setImageLayout(blitFirstMipCmd, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - firstMipSubRange, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - - device->flushCommandBuffer(blitFirstMipCmd, copyQueue, true); - - inTex.destroy(); - - VkCommandBuffer blitCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - - // mipmap generation - // Copy down mips from n-1 to n - for (int32_t i = 1; i < infos.mipLevels; i++) - { - VkImageBlit imageBlit{}; - imageBlit.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, i-1, l, 1}; - imageBlit.srcOffsets[1] = {infos.extent.width >> (i - 1),infos.extent.height >> (i - 1),1}; - imageBlit.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, i, l, 1}; - imageBlit.dstOffsets[1] = {infos.extent.width >> i,infos.extent.height >> i, 1}; - - VkImageSubresourceRange mipSubRange = {VK_IMAGE_ASPECT_COLOR_BIT, i, 1, l, 1}; - - setImageLayout(blitCmd, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - mipSubRange, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - - // Blit from previous level - vkCmdBlitImage(blitCmd, - image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, &imageBlit, VK_FILTER_LINEAR); - - setImageLayout(blitCmd, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - mipSubRange, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - } - firstMipSubRange.levelCount = infos.mipLevels; - setImageLayout(blitCmd, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageLayout, - firstMipSubRange, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - device->flushCommandBuffer(blitCmd, copyQueue, true); - } - - createView(VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_ASPECT_COLOR_BIT,infos.mipLevels,6); - createSampler(VK_FILTER_CUBIC_IMG,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,VK_SAMPLER_MIPMAP_MODE_LINEAR); - //samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER; - - updateDescriptor(); - - } - void loadFromFile( - std::string filename, - VkFormat format, - vke::device_t *_device, - VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, - VkImageLayout _imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - { -#if defined(__ANDROID__) - // Textures are stored inside the apk on Android (compressed) - // So they need to be loaded via the asset manager - AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, filename.c_str(), AASSET_MODE_STREAMING); - if (!asset) { - LOGE("Could not load texture %s", filename.c_str()); - exit(-1); - } - size_t size = AAsset_getLength(asset); - assert(size > 0); - - void *textureData = malloc(size); - AAsset_read(asset, textureData, size); - AAsset_close(asset); - - gli::texture_cube texCube(gli::load((const char*)textureData, size)); - - free(textureData); -#else - gli::texture_cube texCube(gli::load(filename)); -#endif - assert(!texCube.empty()); - - create(_device, VK_IMAGE_TYPE_2D, format, - static_cast(texCube.extent().x),static_cast(texCube[0].extent().y), - imageUsageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - VK_IMAGE_TILING_OPTIMAL,static_cast(texCube.levels()), 6, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT); - - imageLayout = _imageLayout; - - vke::buffer_t stagingBuffer (device, - VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - texCube.size(), texCube.data()); - - descriptor.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - - size_t offset = 0; - - std::vector bufferCopyRegions; - for (uint32_t face = 0; face < 6; face++) { - for (uint32_t level = 0; level < infos.mipLevels; level++) { - VkBufferImageCopy bufferCopyRegion = {}; - bufferCopyRegion.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, level, face, 1}; - bufferCopyRegion.imageExtent = {(uint32_t)texCube[face][level].extent().x,(uint32_t)texCube[face][level].extent().y,1}; - bufferCopyRegion.bufferOffset = offset; - - bufferCopyRegions.push_back(bufferCopyRegion); - offset += texCube[face][level].size(); - } - } - VkImageSubresourceRange subresourceRange = {}; - subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.baseMipLevel = 0; - subresourceRange.levelCount = infos.mipLevels; - subresourceRange.layerCount = 6; - - setImageLayout (copyCmd, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - subresourceRange, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); - - vkCmdCopyBufferToImage(copyCmd, stagingBuffer.buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - static_cast(bufferCopyRegions.size()), bufferCopyRegions.data()); - - setImageLayout(copyCmd, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageLayout, - subresourceRange, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - - device->flushCommandBuffer(copyCmd, device->queue, true); - - createView(VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_ASPECT_COLOR_BIT,infos.mipLevels,6); - createSampler(VK_FILTER_LINEAR,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,VK_SAMPLER_MIPMAP_MODE_LINEAR); - - updateDescriptor(); - } - }; - -} diff --git a/src/VulkanglTFModel.hpp b/src/VulkanglTFModel.hpp index dede000..052efe0 100644 --- a/src/VulkanglTFModel.hpp +++ b/src/VulkanglTFModel.hpp @@ -14,9 +14,10 @@ #include #include -#include +#include "vke.hpp" +#include "macros.hpp" -#include "vkrenderer.h" +#include "vkrenderer.hpp" #include "shadingcontext.hpp" #include @@ -31,7 +32,7 @@ //when mipLevels is set to 0 => mipmaps with be generated #define AUTOGEN_MIPMAPS 0 -#include "VulkanBuffer.hpp" +#include "buffer.hpp" namespace vkglTF { diff --git a/src/buffer.cpp b/src/buffer.cpp index 1974cfa..d3e45b6 100644 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -1,8 +1,8 @@ -#include "VulkanBuffer.hpp" +#include "buffer.hpp" #include "VulkanDevice.hpp" #include "resource.hpp" -#include "macros.h" +#include "macros.hpp" namespace vke { diff --git a/src/buffer.hpp b/src/buffer.hpp new file mode 100644 index 0000000..58ed5dd --- /dev/null +++ b/src/buffer.hpp @@ -0,0 +1,52 @@ +/* +* Vulkan buffer class +* +* Encapsulates a Vulkan buffer +* +* 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 + +#include "vke.hpp" +#include "resource.hpp" + +namespace vke +{ + struct buffer_t : public Resource + { + VkBuffer buffer = VK_NULL_HANDLE; + + VkBufferCreateInfo infos = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}; + + VkDescriptorBufferInfo descriptor; + VkDeviceSize size = 0; + VkDeviceSize alignment = 0; + VkBufferUsageFlags usageFlags; + VkMemoryPropertyFlags memoryPropertyFlags; + void* mapped = nullptr; + + buffer_t(device_t* _device, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags _memoryPropertyFlags, VkDeviceSize size, void *data = nullptr); + ~buffer_t(); + + VkResult map(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0); + void unmap(); + + VkResult bind(VkDeviceSize offset = 0); + + void setupDescriptor(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0); + + virtual VkWriteDescriptorSet getWriteDescriptorSet(VkDescriptorSet ds, uint32_t binding, VkDescriptorType descriptorType); + + void copyTo(void* data, VkDeviceSize size); + + VkResult flush(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0); + + VkResult invalidate(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0); + + void destroy(); + + }; +} diff --git a/src/macros.h b/src/macros.h deleted file mode 100644 index 4c1ddf1..0000000 --- a/src/macros.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* Global macros -* -* Copyright (C) 2018 by Sascha Willems - www.saschawillems.de -* -* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) -*/ - -#pragma once - -#include "vulkan/vulkan.h" - -#if defined(__ANDROID__) -#define VK_CHECK_RESULT(f) \ -{ \ - VkResult res = (f); \ - if (res != VK_SUCCESS) \ - { \ - LOGE("Fatal : VkResult is \" %d \" in %s at line %d", res, __FILE__, __LINE__); \ - assert(res == VK_SUCCESS); \ - } \ -} -#else -#define VK_CHECK_RESULT(f) \ -{ \ - VkResult res = (f); \ - if (res != VK_SUCCESS) \ - { \ - std::cout << "Fatal : VkResult is \"" << res << "\" in " << __FILE__ << " at line " << __LINE__ << std::endl; \ - assert(res == VK_SUCCESS); \ - } \ -} -#endif - -#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \ -{ \ - fp##entrypoint = reinterpret_cast(vkGetInstanceProcAddr(inst, "vk"#entrypoint)); \ - if (fp##entrypoint == NULL) \ - { \ - exit(1); \ - } \ -} - -#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \ -{ \ - fp##entrypoint = reinterpret_cast(vkGetDeviceProcAddr(dev, "vk"#entrypoint)); \ - if (fp##entrypoint == NULL) \ - { \ - exit(1); \ - } \ -} \ No newline at end of file diff --git a/src/macros.hpp b/src/macros.hpp new file mode 100644 index 0000000..4c1ddf1 --- /dev/null +++ b/src/macros.hpp @@ -0,0 +1,51 @@ +/* +* Global macros +* +* Copyright (C) 2018 by Sascha Willems - www.saschawillems.de +* +* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +*/ + +#pragma once + +#include "vulkan/vulkan.h" + +#if defined(__ANDROID__) +#define VK_CHECK_RESULT(f) \ +{ \ + VkResult res = (f); \ + if (res != VK_SUCCESS) \ + { \ + LOGE("Fatal : VkResult is \" %d \" in %s at line %d", res, __FILE__, __LINE__); \ + assert(res == VK_SUCCESS); \ + } \ +} +#else +#define VK_CHECK_RESULT(f) \ +{ \ + VkResult res = (f); \ + if (res != VK_SUCCESS) \ + { \ + std::cout << "Fatal : VkResult is \"" << res << "\" in " << __FILE__ << " at line " << __LINE__ << std::endl; \ + assert(res == VK_SUCCESS); \ + } \ +} +#endif + +#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \ +{ \ + fp##entrypoint = reinterpret_cast(vkGetInstanceProcAddr(inst, "vk"#entrypoint)); \ + if (fp##entrypoint == NULL) \ + { \ + exit(1); \ + } \ +} + +#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \ +{ \ + fp##entrypoint = reinterpret_cast(vkGetDeviceProcAddr(dev, "vk"#entrypoint)); \ + if (fp##entrypoint == NULL) \ + { \ + exit(1); \ + } \ +} \ No newline at end of file diff --git a/src/pbrrenderer2.cpp b/src/pbrrenderer2.cpp index 29df3ef..79b7110 100644 --- a/src/pbrrenderer2.cpp +++ b/src/pbrrenderer2.cpp @@ -1,4 +1,4 @@ -#include "pbrrenderer2.h" +#include "pbrrenderer2.hpp" #include "rendertarget.hpp" pbrRenderer::pbrRenderer () : vkRenderer() diff --git a/src/pbrrenderer2.h b/src/pbrrenderer2.h deleted file mode 100644 index 71342b4..0000000 --- a/src/pbrrenderer2.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "VkEngine.h" -#include "vkrenderer.h" -#include "VulkanTexture.hpp" -#include "VulkanglTFModel.hpp" - - -class pbrRenderer : public vke::vkRenderer -{ - void generateBRDFLUT(); - void generateCubemaps(); -protected: - virtual void configurePipelineLayout(); - virtual void loadRessources(); - virtual void freeRessources(); - virtual void prepareDescriptors(); - virtual void preparePipeline(); -public: - struct Pipelines { - VkPipeline skybox; - VkPipeline pbr; - VkPipeline pbrAlphaBlend; - } pipelines; - - VkDescriptorSet dsScene; - - struct Textures { - vke::TextureCubeMap environmentCube; - vke::Texture2D lutBrdf; - vke::TextureCubeMap irradianceCube; - vke::TextureCubeMap prefilteredCube; - } textures; - - vkglTF::Model skybox; - std::vector models; - - pbrRenderer (); - virtual ~pbrRenderer(); - - virtual void destroy(); - - void renderPrimitive(vkglTF::Primitive &primitive, VkCommandBuffer commandBuffer); - - void prepareModels(); - - virtual void draw(VkCommandBuffer cmdBuff); - - -}; diff --git a/src/pbrrenderer2.hpp b/src/pbrrenderer2.hpp new file mode 100644 index 0000000..1124737 --- /dev/null +++ b/src/pbrrenderer2.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "vke.hpp" +#include "vkrenderer.hpp" +#include "texture.hpp" +#include "VulkanglTFModel.hpp" + + +class pbrRenderer : public vke::vkRenderer +{ + void generateBRDFLUT(); + void generateCubemaps(); +protected: + virtual void configurePipelineLayout(); + virtual void loadRessources(); + virtual void freeRessources(); + virtual void prepareDescriptors(); + virtual void preparePipeline(); +public: + struct Pipelines { + VkPipeline skybox; + VkPipeline pbr; + VkPipeline pbrAlphaBlend; + } pipelines; + + VkDescriptorSet dsScene; + + struct Textures { + vke::TextureCubeMap environmentCube; + vke::Texture2D lutBrdf; + vke::TextureCubeMap irradianceCube; + vke::TextureCubeMap prefilteredCube; + } textures; + + vkglTF::Model skybox; + std::vector models; + + pbrRenderer (); + virtual ~pbrRenderer(); + + virtual void destroy(); + + void renderPrimitive(vkglTF::Primitive &primitive, VkCommandBuffer commandBuffer); + + void prepareModels(); + + virtual void draw(VkCommandBuffer cmdBuff); + + +}; diff --git a/src/phyInfos.h b/src/phyInfos.h deleted file mode 100644 index db89cbd..0000000 --- a/src/phyInfos.h +++ /dev/null @@ -1,102 +0,0 @@ -#pragma once - -#include "vke.h" - -namespace vke -{ - struct vkPhyInfo{ - VkPhysicalDevice phy; - VkPhysicalDeviceMemoryProperties memProps; - VkPhysicalDeviceProperties properties; - VkPhysicalDeviceFeatures features; - VkPhysicalDeviceFeatures enabledFeatures; - VkQueueFamilyProperties* queues; - uint32_t queueCount; - std::vector cQueues;//compute, dedicated first - std::vector gQueues;//graphic, idem - std::vector tQueues;//transfer, idem - int pQueue;//presentation - - std::vector pQueueInfos; - std::vector> qPriorities; - - vkPhyInfo (){} - vkPhyInfo (VkPhysicalDevice _phy, VkSurfaceKHR surface = VK_NULL_HANDLE) { - phy = _phy; -// cQueues.clear(); -// gQueues.clear(); -// tQueues.clear(); - pQueue = -1; -// pQueueInfos.clear(); -// qPriorities.clear(); - - vkGetPhysicalDeviceProperties (phy, &properties); - vkGetPhysicalDeviceMemoryProperties (phy, &memProps); - vkGetPhysicalDeviceFeatures (phy, &features); - - vkGetPhysicalDeviceQueueFamilyProperties (phy, &queueCount, NULL); - queues = (VkQueueFamilyProperties*)malloc(queueCount * sizeof(VkQueueFamilyProperties)); - vkGetPhysicalDeviceQueueFamilyProperties (phy, &queueCount, queues); - - //identify dedicated queues - //try to find dedicated queues first - VkBool32 present = VK_FALSE; - for (uint j=0; j cQueues;//compute, dedicated first + std::vector gQueues;//graphic, idem + std::vector tQueues;//transfer, idem + int pQueue;//presentation + + std::vector pQueueInfos; + std::vector> qPriorities; + + vkPhyInfo (){} + vkPhyInfo (VkPhysicalDevice _phy, VkSurfaceKHR surface = VK_NULL_HANDLE) { + phy = _phy; +// cQueues.clear(); +// gQueues.clear(); +// tQueues.clear(); + pQueue = -1; +// pQueueInfos.clear(); +// qPriorities.clear(); + + vkGetPhysicalDeviceProperties (phy, &properties); + vkGetPhysicalDeviceMemoryProperties (phy, &memProps); + vkGetPhysicalDeviceFeatures (phy, &features); + + vkGetPhysicalDeviceQueueFamilyProperties (phy, &queueCount, NULL); + queues = (VkQueueFamilyProperties*)malloc(queueCount * sizeof(VkQueueFamilyProperties)); + vkGetPhysicalDeviceQueueFamilyProperties (phy, &queueCount, queues); + + //identify dedicated queues + //try to find dedicated queues first + VkBool32 present = VK_FALSE; + for (uint j=0; j + #include "resource.hpp" +#include "buffer.hpp" +#include "VulkanDevice.hpp" namespace vke { @@ -78,4 +91,234 @@ namespace vke VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, bool flipY = true); }; + class Texture2D : public Texture { + public: + void loadFromFile( + std::string filename, + VkFormat format, + vke::device_t *_device, + VkQueue copyQueue, + VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, + VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + { +#if defined(__ANDROID__) + // Textures are stored inside the apk on Android (compressed) + // So they need to be loaded via the asset manager + AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, filename.c_str(), AASSET_MODE_STREAMING); + if (!asset) { + LOGE("Could not load texture %s", filename.c_str()); + exit(-1); + } + size_t size = AAsset_getLength(asset); + assert(size > 0); + + void *textureData = malloc(size); + AAsset_read(asset, textureData, size); + AAsset_close(asset); + + gli::texture2d tex2D(gli::load((const char*)textureData, size)); + + free(textureData); +#else + gli::texture2d tex2D(gli::load(filename.c_str())); +#endif + assert(!tex2D.empty()); + + create(_device, VK_IMAGE_TYPE_2D, format, + static_cast(tex2D[0].extent().x),static_cast(tex2D[0].extent().y), + imageUsageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + VK_IMAGE_TILING_OPTIMAL,static_cast(tex2D.levels())); + + copyTo(copyQueue, (unsigned char*)tex2D.data(), tex2D.size()); + + createView(VK_IMAGE_VIEW_TYPE_2D); + createSampler(VK_FILTER_LINEAR,VK_SAMPLER_ADDRESS_MODE_REPEAT,VK_SAMPLER_MIPMAP_MODE_LINEAR); + + updateDescriptor(); + } + }; + + class TextureCubeMap : public Texture { + public: + void buildFromImages(const std::vector& mapDic, uint32_t textureSize, + VkFormat _format, + vke::device_t *_device, + VkQueue copyQueue, + VkImageUsageFlags _imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, + VkImageLayout _imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL){ + + create(_device, VK_IMAGE_TYPE_2D, _format, + textureSize, textureSize, + _imageUsageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT| VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_IMAGE_TILING_OPTIMAL, + (uint32_t)floor(log2(textureSize)) + 1, 6, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT); + + imageLayout = _imageLayout; + + for (int l = 0; l < mapDic.size(); l++) { + Texture inTex; + inTex.loadStbLinearNoSampling(mapDic[l].c_str(), device); + + VkCommandBuffer blitFirstMipCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); + + VkImageBlit firstMipBlit{}; + firstMipBlit.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, l, 1}; + firstMipBlit.srcOffsets[1] = {inTex.infos.extent.width,inTex.infos.extent.height,1}; + firstMipBlit.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, l, 1}; + firstMipBlit.dstOffsets[1] = {infos.extent.width,infos.extent.height,1}; + + VkImageSubresourceRange firstMipSubRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, l, 1}; + + setImageLayout(blitFirstMipCmd, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + firstMipSubRange, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + + // Blit from source texture + vkCmdBlitImage(blitFirstMipCmd, inTex.image, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &firstMipBlit, VK_FILTER_CUBIC_IMG); + + setImageLayout(blitFirstMipCmd, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + firstMipSubRange, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + + device->flushCommandBuffer(blitFirstMipCmd, copyQueue, true); + + inTex.destroy(); + + VkCommandBuffer blitCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); + + // mipmap generation + // Copy down mips from n-1 to n + for (int32_t i = 1; i < infos.mipLevels; i++) + { + VkImageBlit imageBlit{}; + imageBlit.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, i-1, l, 1}; + imageBlit.srcOffsets[1] = {infos.extent.width >> (i - 1),infos.extent.height >> (i - 1),1}; + imageBlit.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, i, l, 1}; + imageBlit.dstOffsets[1] = {infos.extent.width >> i,infos.extent.height >> i, 1}; + + VkImageSubresourceRange mipSubRange = {VK_IMAGE_ASPECT_COLOR_BIT, i, 1, l, 1}; + + setImageLayout(blitCmd, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + mipSubRange, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + + // Blit from previous level + vkCmdBlitImage(blitCmd, + image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, &imageBlit, VK_FILTER_LINEAR); + + setImageLayout(blitCmd, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + mipSubRange, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + } + firstMipSubRange.levelCount = infos.mipLevels; + setImageLayout(blitCmd, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageLayout, + firstMipSubRange, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + device->flushCommandBuffer(blitCmd, copyQueue, true); + } + + createView(VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_ASPECT_COLOR_BIT,infos.mipLevels,6); + createSampler(VK_FILTER_CUBIC_IMG,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,VK_SAMPLER_MIPMAP_MODE_LINEAR); + //samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER; + + updateDescriptor(); + + } + void loadFromFile( + std::string filename, + VkFormat format, + vke::device_t *_device, + VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, + VkImageLayout _imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + { +#if defined(__ANDROID__) + // Textures are stored inside the apk on Android (compressed) + // So they need to be loaded via the asset manager + AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, filename.c_str(), AASSET_MODE_STREAMING); + if (!asset) { + LOGE("Could not load texture %s", filename.c_str()); + exit(-1); + } + size_t size = AAsset_getLength(asset); + assert(size > 0); + + void *textureData = malloc(size); + AAsset_read(asset, textureData, size); + AAsset_close(asset); + + gli::texture_cube texCube(gli::load((const char*)textureData, size)); + + free(textureData); +#else + gli::texture_cube texCube(gli::load(filename)); +#endif + assert(!texCube.empty()); + + create(_device, VK_IMAGE_TYPE_2D, format, + static_cast(texCube.extent().x),static_cast(texCube[0].extent().y), + imageUsageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + VK_IMAGE_TILING_OPTIMAL,static_cast(texCube.levels()), 6, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT); + + imageLayout = _imageLayout; + + vke::buffer_t stagingBuffer (device, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + texCube.size(), texCube.data()); + + descriptor.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); + + size_t offset = 0; + + std::vector bufferCopyRegions; + for (uint32_t face = 0; face < 6; face++) { + for (uint32_t level = 0; level < infos.mipLevels; level++) { + VkBufferImageCopy bufferCopyRegion = {}; + bufferCopyRegion.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, level, face, 1}; + bufferCopyRegion.imageExtent = {(uint32_t)texCube[face][level].extent().x,(uint32_t)texCube[face][level].extent().y,1}; + bufferCopyRegion.bufferOffset = offset; + + bufferCopyRegions.push_back(bufferCopyRegion); + offset += texCube[face][level].size(); + } + } + VkImageSubresourceRange subresourceRange = {}; + subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + subresourceRange.baseMipLevel = 0; + subresourceRange.levelCount = infos.mipLevels; + subresourceRange.layerCount = 6; + + setImageLayout (copyCmd, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + subresourceRange, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + + vkCmdCopyBufferToImage(copyCmd, stagingBuffer.buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + static_cast(bufferCopyRegions.size()), bufferCopyRegions.data()); + + setImageLayout(copyCmd, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageLayout, + subresourceRange, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + + device->flushCommandBuffer(copyCmd, device->queue, true); + + createView(VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_ASPECT_COLOR_BIT,infos.mipLevels,6); + createSampler(VK_FILTER_LINEAR,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,VK_SAMPLER_MIPMAP_MODE_LINEAR); + + updateDescriptor(); + } + }; + } diff --git a/src/vke.cpp b/src/vke.cpp new file mode 100644 index 0000000..6e3ed3a --- /dev/null +++ b/src/vke.cpp @@ -0,0 +1,591 @@ +/* +* Vulkan Example base class, stripped down version +* +* Copyright (C) 2016-2018 by Sascha Willems - www.saschawillems.de +* +* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +*/ + +#define TINYGLTF_IMPLEMENTATION +#define STB_IMAGE_IMPLEMENTATION +#include "tiny_gltf.h" + +#include "vke.hpp" +#include "macros.hpp" + +#define ENGINE_NAME "vke" +#define ENGINE_VERSION 1 + +#include "VulkanDevice.hpp" + +#include "resource.hpp" +#include "buffer.hpp" +#include "texture.hpp" + +#include "shadingcontext.hpp" +#include "rendertarget.hpp" + +#include "VulkanSwapChain.hpp" +#include "camera.hpp" + +int32_t nextValuePair(std::stringstream *stream) +{ + std::string pair; + *stream >> pair; + uint32_t spos = pair.find("="); + std::string value = pair.substr(spos + 1); + int32_t val = std::stoi(value); + return val; +} +// Basic parser fpr AngelCode bitmap font format files +// See http://www.angelcode.com/products/bmfont/doc/file_format.html for details +std::array parsebmFont(const std::string& fileName) +{ + std::array fontChars; + +#if defined(__ANDROID__) + // Font description file is stored inside the apk + // So we need to load it using the asset manager + AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, fileName.c_str(), AASSET_MODE_STREAMING); + assert(asset); + size_t size = AAsset_getLength(asset); + + assert(size > 0); + + void *fileData = malloc(size); + AAsset_read(asset, fileData, size); + AAsset_close(asset); + + std::stringbuf sbuf((const char*)fileData); + std::istream istream(&sbuf); +#else + std::filebuf fileBuffer; + fileBuffer.open(fileName, std::ios::in); + std::istream istream(&fileBuffer); +#endif + + assert(istream.good()); + + while (!istream.eof()) + { + std::string line; + std::stringstream lineStream; + std::getline(istream, line); + lineStream << line; + + std::string info; + lineStream >> info; + + if (info == "char") + { + // char id + uint32_t charid = nextValuePair(&lineStream); + // Char properties + fontChars[charid].x = nextValuePair(&lineStream); + fontChars[charid].y = nextValuePair(&lineStream); + fontChars[charid].width = nextValuePair(&lineStream); + fontChars[charid].height = nextValuePair(&lineStream); + fontChars[charid].xoffset = nextValuePair(&lineStream); + fontChars[charid].yoffset = nextValuePair(&lineStream); + fontChars[charid].xadvance = nextValuePair(&lineStream); + fontChars[charid].page = nextValuePair(&lineStream); + } + } + return fontChars; +} + +std::vector vke::engine_t::args; + +VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char * pLayerPrefix, const char * pMsg, void * pUserData) +{ + std::string prefix(""); + if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { + prefix += "ERROR:"; + }; + if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { + prefix += "WARNING:"; + }; + if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { + prefix += "DEBUG:"; + } + std::stringstream debugMessage; + debugMessage << prefix << " [" << pLayerPrefix << "] Code " << msgCode << " : " << pMsg; +#if defined(__ANDROID__) + LOGD("%s", debugMessage.str().c_str()); +#else + std::cout << debugMessage.str() << "\n"; +#endif + fflush(stdout); + return VK_FALSE; +} + +std::string vke::engine_t::getWindowTitle() +{ + std::string device(this->device->properties.deviceName); + std::string windowTitle; + windowTitle = title + " - " + device + " - " + std::to_string(lastFPS) + " fps"; + return windowTitle; +} + +static void onkey_callback (GLFWwindow* window, int key, int scanCode, int action ,int mods){ + vke::engine_t* e = (vke::engine_t*)glfwGetWindowUserPointer(window); + if (action == GLFW_PRESS) + e->keyDown(key); + else + e->keyUp(key); +} +static void char_callback (GLFWwindow* window, uint32_t c){ + vke::engine_t* e = (vke::engine_t*)glfwGetWindowUserPointer(window); +} +static void mouse_move_callback(GLFWwindow* window, double x, double y){ + vke::engine_t* e = (vke::engine_t*)glfwGetWindowUserPointer(window); + e->handleMouseMove((int32_t)x, (int32_t)y); +} +static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){ + vke::engine_t* e = (vke::engine_t*)glfwGetWindowUserPointer(window); + if (state == GLFW_PRESS){ + e->mouseButtons[but] = true; + e->handleMouseButtonDown(but); + }else{ + e->mouseButtons[but] = false; + e->handleMouseButtonUp(but); + } +} + +vke::engine_t::engine_t (uint32_t _width, uint32_t _height, + VkPhysicalDeviceType preferedGPU) +{ + width = _width; + height = _height; + + char* numConvPtr; + // Parse command line arguments + for (size_t i = 0; i < args.size(); i++) + { + if (args[i] == std::string("-validation")) { + settings.validation = true; + } + if (args[i] == std::string("-vsync")) { + settings.vsync = true; + } + if ((args[i] == std::string("-f")) || (args[i] == std::string("--fullscreen"))) { + settings.fullscreen = true; + } + if ((args[i] == std::string("-w")) || (args[i] == std::string("--width"))) { + uint32_t w = strtol(args[i + 1], &numConvPtr, 10); + if (numConvPtr != args[i + 1]) { width = w; }; + } + if ((args[i] == std::string("-h")) || (args[i] == std::string("--height"))) { + uint32_t h = strtol(args[i + 1], &numConvPtr, 10); + if (numConvPtr != args[i + 1]) { height = h; }; + } + } + + glfwInit(); + assert (glfwVulkanSupported()==GLFW_TRUE); + + uint32_t enabledExtsCount = 0, phyCount = 0; + const char ** enabledExts = glfwGetRequiredInstanceExtensions (&enabledExtsCount); + std::vector enabledExtentions; + enabledExtentions.assign(enabledExts, enabledExts + enabledExtsCount); + + _createInstance ("vkChess", enabledExtentions); + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); + glfwWindowHint(GLFW_FLOATING, GLFW_FALSE); + glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); + + window = glfwCreateWindow (width, height, "Window Title", NULL, NULL); + + glfwSetWindowUserPointer (window, this); + + glfwSetKeyCallback (window, onkey_callback); + glfwSetCharCallback (window, char_callback); + glfwSetMouseButtonCallback (window, mouse_button_callback); + glfwSetCursorPosCallback (window, mouse_move_callback); + //glfwSetScrollCallback (e->window, onScroll); + + VK_CHECK_RESULT(glfwCreateWindowSurface(instance, window, NULL, &surface)); + + VK_CHECK_RESULT(vkEnumeratePhysicalDevices(instance, &phyCount, nullptr)); + assert(phyCount > 0); + std::vector physicalDevices(phyCount); + VK_CHECK_RESULT(vkEnumeratePhysicalDevices(instance, &phyCount, physicalDevices.data())); + + for (uint i=0; iproperties.deviceType == preferedGPU) + break; + } + + camera = new Camera(); +} + + +vke::engine_t::~engine_t() +{ + delete sharedUBOs.matrices; + delete sharedUBOs.params; + delete phyInfos; + delete camera; + + delete renderTarget; + delete swapChain; + + if (surface != VK_NULL_HANDLE) + vkDestroySurfaceKHR(instance, surface, nullptr); + + surface = VK_NULL_HANDLE; + + delete device; + + //if (settings.validation) + // vkDestroyDebugReportCallback(instance, debugReportCallback, nullptr); + + vkDestroyInstance (instance, VK_NULL_HANDLE); +} + +void vke::engine_t::start () { + std::vector devLayers; + +#if DEBUG + if (settings.validation) + devLayers.push_back ("VK_LAYER_LUNARG_standard_validation"); +#endif + + device = new vke::device_t (phyInfos, devLayers); + + swapChain = new swap_chain_t (this, false); + swapChain->create (width, height); + + renderTarget = new render_target_t(device, settings.sampleCount); + renderTarget->createDefaultPresentableTarget (swapChain); + + prepareUniformBuffers(); + + prepare(); + + prepared = true; + + while (!glfwWindowShouldClose (window)) { + glfwPollEvents(); + auto tStart = std::chrono::high_resolution_clock::now(); + if (viewUpdated) + { + viewUpdated = false; + viewChanged(); + } + + render(); + + frameCounter++; + auto tEnd = std::chrono::high_resolution_clock::now(); + auto tDiff = std::chrono::duration(tEnd - tStart).count(); + frameTimer = tDiff / 1000.0f; + camera->update(frameTimer); + if (camera->moving()) + viewUpdated = true; + fpsTimer += (float)tDiff; + if (fpsTimer > 1000.0f) + { + glfwSetWindowTitle(window, getWindowTitle().c_str()); + lastFPS = (float)frameCounter * (1000.0f / fpsTimer); + fpsTimer = 0.0f; + frameCounter = 0; + } + } +} + +void vke::engine_t::prepare(){} + +void vke::engine_t::prepareFrame() +{ + VkResult err = swapChain->acquireNextImage (device->dev); + if ((err == VK_ERROR_OUT_OF_DATE_KHR) || (err == VK_SUBOPTIMAL_KHR)) { + windowResize(); + } else { + VK_CHECK_RESULT(err); + } +} + +void vke::engine_t::_createInstance (const std::string& app_name, std::vector& extentions) { + VkApplicationInfo infos = {VK_STRUCTURE_TYPE_APPLICATION_INFO}; + infos.pApplicationName = app_name.c_str(); + infos.applicationVersion= 1; + infos.pEngineName = ENGINE_NAME; + infos.engineVersion = ENGINE_VERSION; + infos.apiVersion = VK_API_VERSION_1_0; + + + std::vector enabledLayers; + +#if DEBUG + if (settings.validation) + enabledLayers.push_back ("VK_LAYER_LUNARG_standard_validation"); +#endif + + VkInstanceCreateInfo inst_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO}; + inst_info.pApplicationInfo = &infos; + inst_info.enabledExtensionCount = extentions.size(); + inst_info.ppEnabledExtensionNames = extentions.data(); + inst_info.enabledLayerCount = enabledLayers.size(); + inst_info.ppEnabledLayerNames = enabledLayers.data(); + + VK_CHECK_RESULT(vkCreateInstance (&inst_info, NULL, &instance)); + +} + + +//void vks::VkEngine::handleEvent(const xcb_generic_event_t *event) +//{ +// switch (event->response_type & 0x7f) +// { +// case XCB_CLIENT_MESSAGE: +// if ((*(xcb_client_message_event_t*)event).data.data32[0] == +// (*atom_wm_delete_window).atom) { +// quit = true; +// } +// break; +// case XCB_MOTION_NOTIFY: +// { +// xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)event; +// handleMouseMove((int32_t)motion->event_x, (int32_t)motion->event_y); +// break; +// } +// break; +// case XCB_BUTTON_PRESS: +// { +// xcb_button_press_event_t *press = (xcb_button_press_event_t *)event; +// switch (press->detail) { +// case XCB_BUTTON_INDEX_1: +// mouseButtons.left = true; +// break; +// case XCB_BUTTON_INDEX_2: +// mouseButtons.middle = true; +// break; +// case XCB_BUTTON_INDEX_3: +// mouseButtons.right = true; +// break; +// case XCB_BUTTON_INDEX_4://wheel scroll up +// camera.translate(glm::vec3(0.0f, 0.0f, camera.zoomSpeed)); +// viewUpdated = true; +// break; +// case XCB_BUTTON_INDEX_5://wheel scroll down +// camera.translate(glm::vec3(0.0f, 0.0f, -camera.zoomSpeed)); +// viewUpdated = true; +// break; +// } +// handleMouseButtonDown(press->detail); +// } +// break; +// case XCB_BUTTON_RELEASE: +// { +// xcb_button_press_event_t *press = (xcb_button_press_event_t *)event; +// if (press->detail == XCB_BUTTON_INDEX_1) +// mouseButtons.left = false; +// if (press->detail == XCB_BUTTON_INDEX_2) +// mouseButtons.middle = false; +// if (press->detail == XCB_BUTTON_INDEX_3) +// mouseButtons.right = false; +// handleMouseButtonUp(press->detail); +// } +// break; +// case XCB_KEY_PRESS: +// { +// const xcb_key_release_event_t *keyEvent = (const xcb_key_release_event_t *)event; +// switch (keyEvent->detail) +// { +// case KEY_W: +// camera.keys.up = true; +// break; +// case KEY_S: +// camera.keys.down = true; +// break; +// case KEY_A: +// camera.keys.left = true; +// break; +// case KEY_D: +// camera.keys.right = true; +// break; +// case KEY_P: +// paused = !paused; +// break; +// } +// keyDown(keyEvent->detail); +// } +// break; +// case XCB_KEY_RELEASE: +// { +// const xcb_key_release_event_t *keyEvent = (const xcb_key_release_event_t *)event; +// switch (keyEvent->detail) +// { +// case KEY_W: +// camera.keys.up = false; +// break; +// case KEY_S: +// camera.keys.down = false; +// break; +// case KEY_A: +// camera.keys.left = false; +// break; +// case KEY_D: +// camera.keys.right = false; +// break; +// case KEY_ESCAPE: +// quit = true; +// break; +// } +// keyUp(keyEvent->detail); +// keyPressed(keyEvent->detail); +// } +// break; +// case XCB_DESTROY_NOTIFY: +// quit = true; +// break; +// case XCB_CONFIGURE_NOTIFY: +// { +// const xcb_configure_notify_event_t *cfgEvent = (const xcb_configure_notify_event_t *)event; +// if ((prepared) && ((cfgEvent->width != width) || (cfgEvent->height != height))) +// { +// destWidth = cfgEvent->width; +// destHeight = cfgEvent->height; +// if ((destWidth > 0) && (destHeight > 0)) +// { +// windowResize(); +// } +// } +// } +// break; +// default: +// break; +// } +//} + + +void vke::engine_t::viewChanged() { + updateUniformBuffers(); +} + +void vke::engine_t::prepareUniformBuffers() +{ + // Objact vertex shader uniform buffer + sharedUBOs.matrices = new buffer_t(device, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + sizeof(mvpMatrices)); + + // Shared parameter uniform buffer + sharedUBOs.params = new buffer_t(device, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + sizeof(lightingParams)); + + // Map persistent + sharedUBOs.matrices->map(); + sharedUBOs.params->map(); + + updateUniformBuffers(); + updateParams(); +} +void vke::engine_t::updateUniformBuffers() +{ + // 3D object + mvpMatrices.projection = camera->matrices.perspective; + mvpMatrices.view = camera->matrices.view; + mvpMatrices.view3 = glm::mat4(glm::mat3(camera->matrices.view)); + mvpMatrices.camPos = camera->position * -1.0f; + sharedUBOs.matrices->copyTo (&mvpMatrices, sizeof(mvpMatrices)); +} +void vke::engine_t::updateParams() +{ + lightingParams.lightDir = glm::vec4(-10.0f, 150.f, -10.f, 1.0f); + sharedUBOs.params->copyTo(&lightingParams, sizeof(lightingParams)); +} + +void vke::engine_t::windowResize() +{ + if (!prepared) + return; + prepared = false; + + vkDeviceWaitIdle(device->dev); + + swapChain->create (width, height); + + vkDeviceWaitIdle(device->dev); + + camera->updateAspectRatio((float)width / (float)height); + viewChanged(); + + prepared = true; +} + +void vke::engine_t::keyDown(uint32_t key) { + switch (key) { + case GLFW_KEY_ESCAPE : + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + } + +} +void vke::engine_t::keyUp(uint32_t key) { + keyPressed (key); +} +void vke::engine_t::keyPressed(uint32_t key) { + switch (key) { + case GLFW_KEY_F1: + if (lightingParams.exposure > 0.1f) { + lightingParams.exposure -= 0.1f; + updateParams(); + std::cout << "Exposure: " << lightingParams.exposure << std::endl; + } + break; + case GLFW_KEY_F2: + if (lightingParams.exposure < 10.0f) { + lightingParams.exposure += 0.1f; + updateParams(); + std::cout << "Exposure: " << lightingParams.exposure << std::endl; + } + break; + case GLFW_KEY_F3: + if (lightingParams.gamma > 0.1f) { + lightingParams.gamma -= 0.1f; + updateParams(); + std::cout << "Gamma: " << lightingParams.gamma << std::endl; + } + break; + case GLFW_KEY_F4: + if (lightingParams.gamma < 10.0f) { + lightingParams.gamma += 0.1f; + updateParams(); + std::cout << "Gamma: " << lightingParams.gamma << std::endl; + } + break; + } +} +void vke::engine_t::handleMouseMove(int32_t x, int32_t y) +{ + int32_t dx = (int32_t)mousePos.x - x; + int32_t dy = (int32_t)mousePos.y - y; + + bool handled = false; + + if (handled) { + mousePos = glm::vec2((float)x, (float)y); + return; + } + + if (mouseButtons[GLFW_MOUSE_BUTTON_RIGHT]) { + camera->rotate(glm::vec3(-dy * camera->rotationSpeed, -dx * camera->rotationSpeed, 0.0f)); + viewUpdated = true; + } + if (mouseButtons[GLFW_MOUSE_BUTTON_MIDDLE]) { + camera->translate(glm::vec3(-dx * 0.01f, -dy * 0.01f, 0.0f)); + viewUpdated = true; + } + mousePos = glm::vec2((float)x, (float)y); +} +void vke::engine_t::handleMouseButtonDown(int buttonIndex) {} +void vke::engine_t::handleMouseButtonUp(int buttonIndex) {} + diff --git a/src/vkrenderer.cpp b/src/vkrenderer.cpp index 7bde5b7..e9c9640 100644 --- a/src/vkrenderer.cpp +++ b/src/vkrenderer.cpp @@ -1,11 +1,11 @@ -#include "vkrenderer.h" +#include "vkrenderer.hpp" //#include "pbrrenderer2.h" #include "VulkanDevice.hpp" #include "rendertarget.hpp" #include "VulkanSwapChain.hpp" #include "shadingcontext.hpp" -#include "VulkanBuffer.hpp" -#include "macros.h" +#include "buffer.hpp" +#include "macros.hpp" const VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; diff --git a/src/vkrenderer.h b/src/vkrenderer.h deleted file mode 100644 index 4c7c7e7..0000000 --- a/src/vkrenderer.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once - -#include "vke.h" - -#define DRAW_FENCE_TIMEOUT 99900000 - -namespace vke { - - class vkRenderer - { - protected: - - bool prepared = false; - - vke::device_t* device; - vke::render_target_t* renderTarget; - vke::engine_t::UniformBuffers sharedUBOs; - - vke::ShadingContext* shadingCtx; - - VkCommandPool commandPool = VK_NULL_HANDLE; - std::vectorcmdBuffers; - - VkDescriptorSet descriptorSet = VK_NULL_HANDLE; - - std::vector fences; - VkSubmitInfo submitInfo; - - VkPipeline pipeline = VK_NULL_HANDLE; - VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; - - std::vector vertices; - vke::buffer_t* vertexBuff; - uint32_t vBufferSize = 10000 * sizeof(float) * 6; - - virtual void prepare(); - virtual void prepareRendering(); - virtual void configurePipelineLayout(); - virtual void loadRessources(); - virtual void freeRessources(); - virtual void prepareDescriptors(); - virtual void preparePipeline(); - - public: - VkSemaphore drawComplete = VK_NULL_HANDLE; - uint32_t vertexCount = 0; - uint32_t sdffVertexCount = 0; - - vkRenderer (); - virtual ~vkRenderer(); - - virtual void create (device_t *_device, vke::render_target_t* _renderTarget, - engine_t::UniformBuffers& _sharedUbos); - virtual void destroy(); - - virtual void buildCommandBuffer (); - virtual void rebuildCommandBuffer (); - virtual void draw(VkCommandBuffer cmdBuff); - - void submit (VkQueue queue, VkSemaphore *waitSemaphore, uint32_t waitSemaphoreCount); - - void drawLine(const glm::vec3& from,const glm::vec3& to,const glm::vec3& fromColor, const glm::vec3& toColor); - void drawLine(const glm::vec3& from,const glm::vec3& to,const glm::vec3& color); - - virtual void flush(); - virtual void clear(); - }; -} - diff --git a/src/vkrenderer.hpp b/src/vkrenderer.hpp new file mode 100644 index 0000000..ea85115 --- /dev/null +++ b/src/vkrenderer.hpp @@ -0,0 +1,69 @@ +#pragma once + +#include "vke.hpp" + +#define DRAW_FENCE_TIMEOUT 99900000 + +namespace vke { + + class vkRenderer + { + protected: + + bool prepared = false; + + vke::device_t* device; + vke::render_target_t* renderTarget; + vke::engine_t::UniformBuffers sharedUBOs; + + vke::ShadingContext* shadingCtx; + + VkCommandPool commandPool = VK_NULL_HANDLE; + std::vectorcmdBuffers; + + VkDescriptorSet descriptorSet = VK_NULL_HANDLE; + + std::vector fences; + VkSubmitInfo submitInfo; + + VkPipeline pipeline = VK_NULL_HANDLE; + VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; + + std::vector vertices; + vke::buffer_t* vertexBuff; + uint32_t vBufferSize = 10000 * sizeof(float) * 6; + + virtual void prepare(); + virtual void prepareRendering(); + virtual void configurePipelineLayout(); + virtual void loadRessources(); + virtual void freeRessources(); + virtual void prepareDescriptors(); + virtual void preparePipeline(); + + public: + VkSemaphore drawComplete = VK_NULL_HANDLE; + uint32_t vertexCount = 0; + uint32_t sdffVertexCount = 0; + + vkRenderer (); + virtual ~vkRenderer(); + + virtual void create (device_t *_device, vke::render_target_t* _renderTarget, + engine_t::UniformBuffers& _sharedUbos); + virtual void destroy(); + + virtual void buildCommandBuffer (); + virtual void rebuildCommandBuffer (); + virtual void draw(VkCommandBuffer cmdBuff); + + void submit (VkQueue queue, VkSemaphore *waitSemaphore, uint32_t waitSemaphoreCount); + + void drawLine(const glm::vec3& from,const glm::vec3& to,const glm::vec3& fromColor, const glm::vec3& toColor); + void drawLine(const glm::vec3& from,const glm::vec3& to,const glm::vec3& color); + + virtual void flush(); + virtual void clear(); + }; +} + diff --git a/tests/test1.cpp b/tests/test1.cpp index efd6090..2b8d17d 100644 --- a/tests/test1.cpp +++ b/tests/test1.cpp @@ -1,7 +1,7 @@ -#include "vke.h" +#include "vke.hpp" #include "camera.hpp" -#include "phyInfos.h" -#include "pbrrenderer2.h" +#include "phyInfos.hpp" +#include "pbrrenderer2.hpp" #include "VulkanSwapChain.hpp" class Test : public vke::engine_t @@ -16,9 +16,10 @@ public: camera->type = vke::Camera::CameraType::firstperson; camera->movementSpeed = 8.0f; camera->rotationSpeed = 0.25f; - camera->setPerspective(50.0f, (float)width / (float)height, 0.1f, 50.0f); - camera->setRotation({ 42.0f, 0.0f, 0.0f }); - camera->setPosition({ .0f, -12.f, -15.f }); + camera->setPerspective(45.0f, (float)width / (float)height, 0.1f, 256.0f); + camera->setRotation({ .0f, 0.0f, 2.5f }); + camera->setPosition({ .0f, .0f, 0.f }); + settings.validation = true; @@ -40,9 +41,11 @@ public: sceneRenderer->models.resize(1); mod = &sceneRenderer->models[0]; - mod->loadFromFile ("data/models/chess.gltf", device, true); + //mod->loadFromFile ("data/models/chess.gltf", device, true); + mod->loadFromFile ("data/models/DamagedHelmet/glTF-Embedded/DamagedHelmet.gltf", device, true); - mod->addInstance("frame", glm::translate(glm::mat4(1.0), glm::vec3( 0,0,0))); + //mod->addInstance("frame", glm::translate(glm::mat4(1.0), glm::vec3( 0,0,0))); + mod->addOneInstanceOfEach(); sceneRenderer->prepareModels(); sceneRenderer->buildCommandBuffer(); -- cgit v1.3.1-4-g156e