vulakn教程--Drawing a Triangle--Set up--Base code
2016-09-03 11:02
316 查看
原文地址:vulkan-tutorial
stdexception 引入异常,functional 引入lambda功能。
然后创建这个Instance:
当Instance离开有效作用域,比如,关闭了应用,VDeleter将自动使用vkDestroyInstance将Instance销毁。
以下是VDeleter的定义:
后续的所有教程都将使用VDeleter来管理我们的对象。
在
初始化:
GLFW最初是为创建OPENGL 的 context设计的,为了避免它创建OPENGL context,需要设置 :
允许窗口改变大小会引起其他的问题,后续我们再讨论,为了操作简单,这里禁止改变窗口大小:
创建窗体:
第三个参数为窗口(window)创建一个监视器,最后一个参数和OPENGL 相关。
显示 ,直到遇到错误或关闭窗口:
为了方便你对照和理解,这里所有代码:
Base code
General structure
上一章通过构建一个窗体来完成VS对Vulkan的配置,并将配置好的工程设置为模板以备后续的使用。在上一章的最后我们用这个模板创建了一个名为:Hello Triangle 的新工程,现在让我们为这个工程搭建一个框架。hljs cpp"> #include <iostream> #include <stdexcept> #include <functional> class HelloTriangleApplication { public: void run() { initVulkan(); mainLoop(); } private: void initVulkan() { } void mainLoop() { } }; int main() { HelloTriangleApplication app; try { app.run(); } catch (const std::runtime_error& e) { std::cerr << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
stdexception 引入异常,functional 引入lambda功能。
Resource management
每一个Vulkan对象不再使用后,都需要用一个清理函数来销毁,就像malloc 分配的内存要用free 销毁一样。手动来销毁每一个对象是一个非常繁杂且容易出错的任务。我们利用C++的RAII原理来创建一个包裹类,当对象离开有效作用域后自动为我们销毁对象。如下,在创建VkInstance前,用类似方法声明VkInstance对象,并告诉我们的包裹类,销毁Instance对象的方法是vkDestroyInstance:VDeleter<VkInstance> instance{vkDestroyInstance}; //VDeleter是我们的包裹类。
然后创建这个Instance:
vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
当Instance离开有效作用域,比如,关闭了应用,VDeleter将自动使用vkDestroyInstance将Instance销毁。
以下是VDeleter的定义:
template <typename T> class VDeleter { public: VDeleter() : VDeleter([](T, VkAllocationCallbacks*) {}) {} VDeleter(std::function<void(T, VkAllocationCallbacks*)> deletef) { this->deleter = [=](T obj) { deletef(obj, nullptr); }; } VDeleter(const VDeleter<VkInstance>& instance, std::function<void(VkInstance, T, VkAllocationCallbacks*)> deletef) { this->deleter = [&instance, deletef](T obj) { deletef(instance, obj, nullptr); }; } VDeleter(const VDeleter<VkDevice>& device, std::function<void(VkDevice, T, VkAllocationCallbacks*)> deletef) { this->deleter = [&device, deletef](T obj) { deletef(device, obj, nullptr); }; } ~VDeleter() { cleanup(); } T* operator &() { cleanup(); return &object; } operator T() const { return object; } private: T object{VK_NULL_HANDLE}; std::function<void(T)> deleter; void cleanup() { if (object != VK_NULL_HANDLE) { deleter(object); } object = VK_NULL_HANDLE; } };
后续的所有教程都将使用VDeleter来管理我们的对象。
Integrating GLFW
如果你只想离屏渲染(off-screen rendering),不需要创建窗口vulkan一样可以很好的工作。但是,难道你不觉得在屏幕上显示一些东西会更酷吗?首先用如如下语句取代#include <vulkan/vulkan.h>:
#define GLFW_INCLUDE_VULKAN #include <GLFW/glfw3.h>
#define GLFW_INCLUDE_VULKAN告诉glfw 在引入自己的头文件时也要引入
vulkan.h。
在
run里添加
initWindow来创建窗体:
void run() { initWindow(); initVulkan(); mainLoop(); } private: void initWindow() { }
初始化:
glfwInit() ;
GLFW最初是为创建OPENGL 的 context设计的,为了避免它创建OPENGL context,需要设置 :
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
允许窗口改变大小会引起其他的问题,后续我们再讨论,为了操作简单,这里禁止改变窗口大小:
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
创建窗体:
const int WIDTH = 800; const int HEIGHT = 600; GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
第三个参数为窗口(window)创建一个监视器,最后一个参数和OPENGL 相关。
显示 ,直到遇到错误或关闭窗口:
while (!glfwWindowShouldClose(window)) { glfwPollEvents(); }
为了方便你对照和理解,这里所有代码:
#define GLFW_INCLUDE_VULKAN #include <GLFW/glfw3.h>
#include <iostream>
#include <stdexcept>
#include <functional>
const int WIDTH = 800;
const int HEIGHT = 600;
template <typename T> class VDeleter { public: VDeleter() : VDeleter([](T, VkAllocationCallbacks*) {}) {} VDeleter(std::function<void(T, VkAllocationCallbacks*)> deletef) { this->deleter = [=](T obj) { deletef(obj, nullptr); }; } VDeleter(const VDeleter<VkInstance>& instance, std::function<void(VkInstance, T, VkAllocationCallbacks*)> deletef) { this->deleter = [&instance, deletef](T obj) { deletef(instance, obj, nullptr); }; } VDeleter(const VDeleter<VkDevice>& device, std::function<void(VkDevice, T, VkAllocationCallbacks*)> deletef) { this->deleter = [&device, deletef](T obj) { deletef(device, obj, nullptr); }; } ~VDeleter() { cleanup(); } T* operator &() { cleanup(); return &object; } operator T() const { return object; } private: T object{VK_NULL_HANDLE}; std::function<void(T)> deleter; void cleanup() { if (object != VK_NULL_HANDLE) { deleter(object); } object = VK_NULL_HANDLE; } };
class HelloTriangleApplication {
public:
void run() {
initWindow();
initVulkan();
mainLoop();
}
private:
GLFWwindow* window;
void initWindow() {
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
}
void initVulkan() {
}
void mainLoop() {
while (!glfwWindowShouldClose(window)) { glfwPollEvents(); }
}
};
int main() {
HelloTriangleApplication app;
try {
app.run();
} catch (const std::runtime_error& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
相关文章推荐
- vulakn教程--Drawing a Triangle--Set up--Logical Device
- vulakn教程--Drawing a Triangle--Set up--Physical Device and Queue Family
- vulakn教程--Drawing a Triangle--Set up--Instance
- vulakn教程--Drawing a Triangle--Set up--Validation layers
- vulakn教程--Drawing a Triangle--Draw--Render and presentation
- vulakn教程--Drawing a Triangle--Pipeline--Fixed function
- vulakn教程--Drawing a Triangle--Presentation-- Image views
- DirectX 教程: DirectX Tutorial - Direct3D: Drawing a Triangle
- vulakn教程--Drawing a Triangle--Pipeline--Shader Module
- vulakn教程--Drawing a Triangle--Draw--CommandBuffer
- vulakn教程--Drawing a Triangle--Draw--Framebuffer
- vulakn教程--Drawing a Triangle--Pipeline--Introduction
- vulakn教程--Drawing a Triangle--Presentation--Window surface
- vulakn教程--Drawing a Triangle--Presentation--SwapChain
- vulakn教程--Drawing a Triangle--Pipeline--Render passes
- NPOI 1.2.3教程 -22 画图Drawing
- CIRCOS教程翻译 5.1——Drawing Basic Links
- Android OpenGL ES 开发教程(11):绘制三角形Triangle
- Android OpenGL ES 开发教程(11):绘制三角形Triangle
- CIRCOS教程翻译 3.9——Drawing on top of data