upload 02

This commit is contained in:
ouczbs 2023-09-19 17:44:58 +08:00
parent 2d97e06a18
commit 28040e6737
4 changed files with 295 additions and 60 deletions

181
vulkanLearn/src/02.cpp Normal file
View File

@ -0,0 +1,181 @@
#include "external/vulkan.h"
#include "com/Window.h"
#include "01 Instance and Devices/03 Connecting with a Vulkan Loader library.h"
#include "01 Instance and Devices/05 Loading function exported from a Vulkan Loader library.h"
#include "01 Instance and Devices/06 Loading global-level functions.h"
#include "01 Instance and Devices/07 Checking available Instance extensions.h"
#include <01 Instance and Devices/09 Loading instance-level functions.h>
#include <01 Instance and Devices/10 Enumerating available physical devices.h>
#include <01 Instance and Devices/12 Getting features and properties of a physical device.h>
#include <01 Instance and Devices/14 Selecting index of a queue family with desired capabilities.h>
#include <01 Instance and Devices/16 Loading device-level functions.h>
#include <01 Instance and Devices/17 Getting a device queue.h>
#include <01 Instance and Devices/19 Destroying a logical device.h>
#include <01 Instance and Devices/20 Destroying a Vulkan Instance.h>
#include <01 Instance and Devices/21 Releasing a Vulkan Loader library.h>
#include "02 Image Presentation/01 Creating a Vulkan Instance with WSI extensions enabled.h"
#include "02 Image Presentation/02 Creating a presentation surface.h"
#include "02 Image Presentation/03 Selecting a queue family that supports presentation to a given surface.h"
#include <02 Image Presentation/04 Creating a logical device with WSI extensions enabled.h>
#include <02 Image Presentation/05 Selecting a desired presentation mode.h>
#include <02 Image Presentation/06 Getting capabilities of a presentation surface.h>
#include <02 Image Presentation/07 Selecting a number of swapchain images.h>
#include <02 Image Presentation/08 Choosing a size of swapchain images.h>
#include <02 Image Presentation/09 Selecting desired usage scenarios of swapchain images.h>
#include <02 Image Presentation/10 Selecting a transformation of swapchain images.h>
#include <02 Image Presentation/11 Selecting a format of swapchain images.h>
#include <02 Image Presentation/12 Creating a swapchain.h>
#include <02 Image Presentation/13 Getting handles of swapchain images.h>
#include <02 Image Presentation/14 Creating a swapchain with R8G8B8A8 format and a MAILBOX present mode.h>
#include <02 Image Presentation/15 Acquiring a swapchain image.h>
#include <02 Image Presentation/16 Presenting an image.h>
#include <02 Image Presentation/17 Destroying a swapchain.h>
#include <02 Image Presentation/18 Destroying a presentation surface.h>
#include <03 Command Buffers and Synchronization/07 Creating a semaphore.h>
#include <03 Command Buffers and Synchronization/08 Creating a fence.h>
using namespace VulkanCookbook;
Window* pWnd;
//创建窗口
WindowParameters createWindow() {
WindowParameters window_parameters{};
pWnd = new Window(600, 800, "hello Window");
window_parameters.HWnd = pWnd->GetHWnd();
window_parameters.HInstance = Window::WindowClass::GetInstance();
return window_parameters;
}
int main02() {
//加载dll
LIBRARY_TYPE vulkan_library;
ConnectWithVulkanLoaderLibrary(vulkan_library);
//加载vulkan接口
LoadFunctionExportedFromVulkanLoaderLibrary(vulkan_library);
//调用vulkan接口加载全局函数指针
LoadGlobalLevelFunctions();
{
//调用全局函数指针,检查实例扩展
std::vector<VkExtensionProperties> available_extensions;
CheckAvailableInstanceExtensions(available_extensions);
}
//调用全局接口,创建实例
std::vector<char const*> desired_extensions;
char* application_name = "hello world";
VkInstance instance;
CreateVulkanInstanceWithWsiExtensionsEnabled(desired_extensions, application_name, instance);
//调用vulkan接口加载实例函数指针
LoadInstanceLevelFunctions(instance, desired_extensions);
//调用实例接口,获取物理设备列表
std::vector<VkPhysicalDevice> available_devices;
EnumerateAvailablePhysicalDevices(instance, available_devices);
VkPhysicalDevice physical_device = available_devices[0];
//调用实例接口,检查物理设备功能
VkPhysicalDeviceFeatures device_features;
VkPhysicalDeviceProperties device_properties;
GetFeaturesAndPropertiesOfPhysicalDevice(physical_device, device_features, device_properties);
//调用实例接口,获取命令队列信息
uint32_t graphics_queue_family_index, compute_queue_family_index;
SelectIndexOfQueueFamilyWithDesiredCapabilities(physical_device, VK_QUEUE_GRAPHICS_BIT, graphics_queue_family_index);
SelectIndexOfQueueFamilyWithDesiredCapabilities(physical_device, VK_QUEUE_COMPUTE_BIT, compute_queue_family_index);
std::vector<QueueInfo> requested_queues = { { graphics_queue_family_index, { 1.0f } } };
if (graphics_queue_family_index != compute_queue_family_index) {
requested_queues.push_back({ compute_queue_family_index, { 1.0f } });
}
//调用实例接口,创建逻辑设备,并且检查是否支持交换链
VkDevice logical_device;
desired_extensions.clear();
CreateLogicalDeviceWithWsiExtensionsEnabled(physical_device, requested_queues, desired_extensions, &device_features, logical_device);
//调用vulkan接口加载设备函数指针
LoadDeviceLevelFunctions(logical_device, desired_extensions);
WindowParameters&& window_parameters = createWindow();
VkSurfaceKHR presentation_surface;
//调用实例接口,创建图像显示设备,需要传递窗口,并启用对应扩展
CreatePresentationSurface(instance, window_parameters, presentation_surface);
//调用实例接口,寻找支持与图像显示设备通信的命令队列
uint32_t queue_family_index;
SelectQueueFamilyThatSupportsPresentationToGivenSurface(physical_device, presentation_surface, queue_family_index);
//调用实例接口,查询图像显示设备的显示模式
VkPresentModeKHR present_mode;
SelectDesiredPresentationMode(physical_device, presentation_surface, VK_PRESENT_MODE_MAILBOX_KHR, present_mode);
//调用实例接口,查询图像显示设备的显示能力
VkSurfaceCapabilitiesKHR surface_capabilities;
GetCapabilitiesOfPresentationSurface(physical_device, presentation_surface, surface_capabilities);
//获取交换链图片数量
uint32_t number_of_images;
SelectNumberOfSwapchainImages(surface_capabilities, number_of_images);
//获取交换链图片尺寸
VkExtent2D size_of_images;
ChooseSizeOfSwapchainImages(surface_capabilities, size_of_images);
//选择交换链图像的使用场景:渲染目标、深度模板
VkImageUsageFlags image_usage;
SelectDesiredUsageScenariosOfSwapchainImages(surface_capabilities, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, image_usage);
//选择交换链在屏幕上的空间变换
VkSurfaceTransformFlagBitsKHR surface_transform;
SelectTransformationOfSwapchainImages(surface_capabilities, VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, surface_transform);
//选择交换链图像的格式与颜色空间
VkFormat image_format;
VkColorSpaceKHR image_color_space;
SelectFormatOfSwapchainImages(physical_device, presentation_surface, { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR },
image_format, image_color_space);
//调用设备接口,创建交换链
VkSwapchainKHR old_swapchain = VK_NULL_HANDLE, swapchain;
CreateSwapchain(logical_device, presentation_surface, number_of_images, { image_format, image_color_space }, size_of_images
,image_usage, surface_transform, present_mode, old_swapchain, swapchain);
//调用设备接口,获取交换链图像句柄
std::vector<VkImage> swapchain_images;
GetHandlesOfSwapchainImages(logical_device, swapchain, swapchain_images);
//创建指定格式的交换链
old_swapchain = swapchain;
CreateSwapchainWithR8G8B8A8FormatAndMailboxPresentMode(physical_device, presentation_surface, logical_device
, image_usage, size_of_images, image_format, old_swapchain , swapchain, swapchain_images);
//调用设备接口,创建围栏,用于同步命令
VkFence fence;
CreateFence(logical_device, false, fence);
//调用设备接口,获取当前交换链图像编号
uint32_t image_index;
AcquireSwapchainImage(logical_device, swapchain, nullptr , fence, image_index);
//调用设备接口,获取命令队列
VkQueue graphics_queue, compute_queue;
GetDeviceQueue(logical_device, graphics_queue_family_index, 0, graphics_queue);
GetDeviceQueue(logical_device, compute_queue_family_index, 0, compute_queue);
//显示图像
std::vector<VkSemaphore> rendering_semaphores;
std::vector<PresentInfo> images_to_present;
PresentImage(graphics_queue, rendering_semaphores, images_to_present);
//调用设备接口,销毁交换链
DestroySwapchain(logical_device, swapchain);
//调用实例接口,销毁显示曲面(屏幕)
DestroyPresentationSurface(instance, presentation_surface);
//调用设备接口,销毁逻辑设备
DestroyLogicalDevice(logical_device);
//调用实例接口销毁vulkan实例1
DestroyVulkanInstance(instance);
//调用系统接口销毁dll
ReleaseVulkanLoaderLibrary(vulkan_library);
return 1;
}

View File

@ -1,36 +1,15 @@
/******************************************************************************************
* Chili Direct3D Engine *
* Copyright 2018 PlanetChili <http://www.planetchili.net> *
* *
* This file is part of Chili Direct3D Engine. *
* *
* Chili Direct3D Engine is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* The Chili Direct3D Engine is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with The Chili Direct3D Engine. If not, see <http://www.gnu.org/licenses/>. *
******************************************************************************************/
#include "Window.h"
#include <sstream>
#pragma comment (lib,"user32.lib")
// Window Class Stuff
WindowClass WindowClass::wndClass;
Window::WindowClass Window::WindowClass::wndClass;
WindowClass::WindowClass() noexcept
Window::WindowClass::WindowClass() noexcept
:
hInst( GetModuleHandle( nullptr ) )
{
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof( wc );
wc.style = CS_OWNDC;
wc.lpfnWndProc = HandleMsgSetup;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetInstance();
@ -39,20 +18,97 @@ WindowClass::WindowClass() noexcept
wc.lpszMenuName = nullptr;
wc.lpszClassName = GetName();
RegisterClassEx( &wc );
}
WindowClass::~WindowClass()
Window::WindowClass::~WindowClass()
{
UnregisterClass( wndClassName,GetInstance() );
}
const char* WindowClass::GetName() noexcept
const char* Window::WindowClass::GetName() noexcept
{
return wndClassName;
}
HINSTANCE WindowClass::GetInstance() noexcept
HINSTANCE Window::WindowClass::GetInstance() noexcept
{
return wndClass.hInst;
}
Window::Window(int width, int height, const char* name)
:width(width),height(height)
{
RECT wr{};
wr.left = 100;
wr.right = width + wr.left;
wr.top = 100;
wr.bottom = height + wr.top;
hWnd = CreateWindow(
WindowClass::GetName(), name,
WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top,
nullptr, nullptr, WindowClass::GetInstance(), this
);
ShowWindow(hWnd, SW_SHOWDEFAULT);
}
bool Window::ProcessMessages(int& code)
{
MSG msg;
// while queue has messages, remove and dispatch them (but do not block on empty queue)
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
// check for quit because peekmessage does not signal this via return val
if (msg.message == WM_QUIT)
{
// return optional wrapping int (arg to PostQuitMessage is in wparam) signals quit
code = (int)msg.wParam;
return true;
}
// TranslateMessage will post auxilliary WM_CHAR messages from key msgs
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return false;
}
LRESULT CALLBACK Window::HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept
{
// use create parameter passed in from CreateWindow() to store window class pointer at WinAPI side
if (msg == WM_NCCREATE)
{
// extract ptr to window class from creation data
const CREATESTRUCTW* const pCreate = reinterpret_cast<CREATESTRUCTW*>(lParam);
Window* const pWnd = static_cast<Window*>(pCreate->lpCreateParams);
// set WinAPI-managed user data to store ptr to window instance
SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pWnd));
// set message proc to normal (non-setup) handler now that setup is finished
SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&Window::HandleMsgThunk));
// forward message to window instance handler
return pWnd->HandleMsg(hWnd, msg, wParam, lParam);
}
// if we get a message before the WM_NCCREATE message, handle with default handler
return DefWindowProc(hWnd, msg, wParam, lParam);
}
LRESULT CALLBACK Window::HandleMsgThunk(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept
{
// retrieve ptr to window instance
Window* const pWnd = reinterpret_cast<Window*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
// forward message to window instance handler
return pWnd->HandleMsg(hWnd, msg, wParam, lParam);
}
LRESULT Window::HandleMsg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept
{
switch (msg)
{
// we don't want the DefProc to handle this message because
// we want our destructor to destroy the window, so return 0 instead of break
case WM_CLOSE:
PostQuitMessage(0);
return 0;
// clear keystate when window loses focus to prevent input getting "stuck"
/************** END MOUSE MESSAGES **************/
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

View File

@ -1,36 +1,33 @@
/******************************************************************************************
* Chili Direct3D Engine *
* Copyright 2018 PlanetChili <http://www.planetchili.net> *
* *
* This file is part of Chili Direct3D Engine. *
* *
* Chili Direct3D Engine is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* The Chili Direct3D Engine is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with The Chili Direct3D Engine. If not, see <http://www.gnu.org/licenses/>. *
******************************************************************************************/
#pragma once
#include <wtypes.h>
// singleton manages registration/cleanup of window class
class WindowClass
class Window
{
public:
static const char* GetName() noexcept;
static HINSTANCE GetInstance() noexcept;
Window(int width, int height, const char* name);
HWND GetHWnd() {
return hWnd;
}
static bool ProcessMessages(int& code);
class WindowClass
{
public:
static const char* GetName() noexcept;
static HINSTANCE GetInstance() noexcept;
private:
WindowClass() noexcept;
~WindowClass();
WindowClass(const WindowClass&) = delete;
WindowClass& operator=(const WindowClass&) = delete;
static constexpr const char* wndClassName = "MainWnd";
static WindowClass wndClass;
HINSTANCE hInst;
};
private:
WindowClass() noexcept;
~WindowClass();
WindowClass(const WindowClass&) = delete;
WindowClass& operator=(const WindowClass&) = delete;
static constexpr const char* wndClassName = "Chili Direct3D Engine Window";
static WindowClass wndClass;
HINSTANCE hInst;
static LRESULT CALLBACK HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept;
static LRESULT CALLBACK HandleMsgThunk(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept;
LRESULT HandleMsg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept;
int width;
int height;
HWND hWnd;
};

View File

@ -6,6 +6,7 @@ set_project("vulkan")
set_toolchains("clang")
target("vulkanLearn")
set_kind("binary")
add_links("User32")
add_defines("VK_USE_PLATFORM_WIN32_KHR")
add_packages("vulkansdk","glfw","glm","tinyobjloader")
add_includedirs("src/demo", "src/com", "src/external", os.getenv("VULKAN_SDK") .. "/Include/vulkan")