编写完顶点渲染程序,先保存一下

This commit is contained in:
xsl
2025-10-19 19:49:27 +08:00
parent 572c53c0f4
commit 3c63027bf5
32 changed files with 2714 additions and 6225 deletions
+2 -5
View File
@@ -100,15 +100,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR WIN32)
third_party/vma/src/VmaUsage.h
third_party/vma/src/VmaUsage.cpp
third_party/fmt/src/format.cc
vulkan/framework/common/error.cpp
vulkan/framework/common/strings.cpp
vulkan/framework/core/allocated.cpp
)
endif()
target_compile_definitions(sample PRIVATE VK_NO_PROTOTYPES)
# target_compile_definitions(sample PRIVATE VK_NO_PROTOTYPES) 使用volk 动态加载的时候需要定义,不自动生成vulkan接口
target_compile_definitions(sample PRIVATE GLM_ENABLE_EXPERIMENTAL)
target_compile_definitions(sample PRIVATE VULKAN_HPP_NO_STRUCT_CONSTRUCTORS)
# target_compile_definitions(sample PRIVATE VULKAN_HPP_NO_STRUCT_CONSTRUCTORS) 解决vs 编译c++ 20 不支持新构造函数的特性
Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

-66
View File
@@ -1,66 +0,0 @@
name: build
on: [push, pull_request]
jobs:
build:
strategy:
matrix:
os: [ubuntu, macos, windows]
name: ${{matrix.os}}
runs-on: ${{matrix.os}}-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
repository: KhronosGroup/Vulkan-Headers
ref: main
path: Vulkan-Headers
fetch-depth: 0
fetch-tags: true
- name: move sdk
shell: bash
run: |
mv Vulkan-Headers ~/Vulkan-Headers
- name: build main
shell: bash
run: |
export VULKAN_SDK=~/Vulkan-Headers
git -C ~/Vulkan-Headers checkout main
test/run_tests.sh
- name: build 1.1.101
shell: bash
run: |
export VULKAN_SDK=~/Vulkan-Headers
git -C ~/Vulkan-Headers checkout sdk-1.1.101
test/run_tests.sh
- name: build 1.2.131
shell: bash
run: |
export VULKAN_SDK=~/Vulkan-Headers
git -C ~/Vulkan-Headers checkout sdk-1.2.131
test/run_tests.sh
- name: build 1.2.182
shell: bash
run: |
export VULKAN_SDK=~/Vulkan-Headers
git -C ~/Vulkan-Headers checkout sdk-1.2.182
test/run_tests.sh
- name: build 1.3.204
shell: bash
run: |
export VULKAN_SDK=~/Vulkan-Headers
git -C ~/Vulkan-Headers checkout sdk-1.3.204
test/run_tests.sh
- name: build 1.3.239
shell: bash
run: |
export VULKAN_SDK=~/Vulkan-Headers
git -C ~/Vulkan-Headers checkout sdk-1.3.239
test/run_tests.sh
- name: build 1.3.268
shell: bash
run: |
export VULKAN_SDK=~/Vulkan-Headers
git -C ~/Vulkan-Headers checkout vulkan-sdk-1.3.268
test/run_tests.sh
-33
View File
@@ -1,33 +0,0 @@
name: update
on:
schedule:
- cron: '0 16 * * *'
workflow_dispatch:
jobs:
update:
if: github.repository == 'zeux/volk'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: update
run: |
python3 generate.py >version.txt
echo "VOLK_VERSION=`cat version.txt`" >> $GITHUB_ENV
rm version.txt
- name: create pr
uses: peter-evans/create-pull-request@v6
with:
branch: update/${{env.VOLK_VERSION}}
delete-branch: true
commit-message: Update to 1.3.${{env.VOLK_VERSION}}
title: Update to 1.3.${{env.VOLK_VERSION}}
author: GitHub <noreply@github.com>
- name: enable pr automerge
run: gh pr merge --merge --auto ${{env.PULL_REQUEST_NUMBER}}
env:
GH_TOKEN: ${{ github.token }}
continue-on-error: true
-2
View File
@@ -1,2 +0,0 @@
build/
CMakeLists.txt.user
-137
View File
@@ -1,137 +0,0 @@
cmake_minimum_required(VERSION 3.5)
cmake_policy(PUSH)
cmake_policy(SET CMP0048 NEW) # project(... VERSION ...) support
project(volk VERSION
# VOLK_GENERATE_VERSION
280
# VOLK_GENERATE_VERSION
LANGUAGES C
)
# CMake 3.12 changes the default behaviour of option() to leave local variables
# unchanged if they exist (which we want), but we must work with older CMake versions.
if(NOT DEFINED VOLK_STATIC_DEFINES)
option(VOLK_STATIC_DEFINES "Additional defines for building the volk static library, e.g. Vulkan platform defines" "")
endif()
if(NOT DEFINED VOLK_PULL_IN_VULKAN)
option(VOLK_PULL_IN_VULKAN "Vulkan as a transitive dependency" ON)
endif()
if(NOT DEFINED VOLK_INSTALL)
option(VOLK_INSTALL "Create installation targets" OFF)
endif()
if(NOT DEFINED VOLK_HEADERS_ONLY)
option(VOLK_HEADERS_ONLY "Add interface library only" OFF)
endif()
if(NOT DEFINED VULKAN_HEADERS_INSTALL_DIR)
option(VULKAN_HEADERS_INSTALL_DIR "Where to get the Vulkan headers" "")
endif()
# -----------------------------------------------------
# Static library
if(NOT VOLK_HEADERS_ONLY OR VOLK_INSTALL)
add_library(volk STATIC volk.h volk.c)
add_library(volk::volk ALIAS volk)
target_include_directories(volk PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>
$<INSTALL_INTERFACE:include>
)
if(VOLK_STATIC_DEFINES)
target_compile_definitions(volk PUBLIC ${VOLK_STATIC_DEFINES})
endif()
if (NOT WIN32)
target_link_libraries(volk PUBLIC ${CMAKE_DL_LIBS})
endif()
endif()
# -----------------------------------------------------
# Interface library
add_library(volk_headers INTERFACE)
add_library(volk::volk_headers ALIAS volk_headers)
target_include_directories(volk_headers INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>
$<INSTALL_INTERFACE:include>
)
if (NOT WIN32)
target_link_libraries(volk_headers INTERFACE ${CMAKE_DL_LIBS})
endif()
# -----------------------------------------------------
# Vulkan transitive dependency
if(VOLK_PULL_IN_VULKAN)
# If CMake has the FindVulkan module and it works, use it.
find_package(Vulkan QUIET)
# Try an explicit CMake variable first, then any Vulkan paths
# discovered by FindVulkan.cmake, then the $VULKAN_SDK environment
# variable if nothing else works.
if(VULKAN_HEADERS_INSTALL_DIR)
message("volk: using VULKAN_HEADERS_INSTALL_DIR option")
set(VOLK_INCLUDES "${VULKAN_HEADERS_INSTALL_DIR}/include")
elseif(Vulkan_INCLUDE_DIRS)
message("volk: using Vulkan_INCLUDE_DIRS from FindVulkan module")
set(VOLK_INCLUDES "${Vulkan_INCLUDE_DIRS}")
elseif(DEFINED ENV{VULKAN_SDK})
message("volk: using VULKAN_SDK environment variable")
set(VOLK_INCLUDES "$ENV{VULKAN_SDK}/include")
endif()
if(VOLK_INCLUDES)
if(TARGET volk)
target_include_directories(volk PUBLIC "${VOLK_INCLUDES}")
endif()
target_include_directories(volk_headers INTERFACE "${VOLK_INCLUDES}")
endif()
endif()
# -----------------------------------------------------
# Installation
if(VOLK_INSTALL)
include(GNUInstallDirs)
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/volk)
# Install files
install(FILES volk.h volk.c DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# Install library target and add it and any dependencies to export set.
install(TARGETS volk volk_headers
EXPORT volk-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
# Actually write exported config w/ imported targets
install(EXPORT volk-targets
FILE volkTargets.cmake
NAMESPACE volk::
DESTINATION ${INSTALL_CONFIGDIR}
)
# Create a ConfigVersion.cmake file:
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/volkConfigVersion.cmake
COMPATIBILITY AnyNewerVersion
)
# Configure config file
configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/cmake/volkConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/volkConfig.cmake
INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
)
# Install the fully generated config and configVersion files
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/volkConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/volkConfigVersion.cmake
DESTINATION ${INSTALL_CONFIGDIR}
)
endif()
cmake_policy(POP)
-19
View File
@@ -1,19 +0,0 @@
Copyright (c) 2018-2024 Arseny Kapoulkine
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-99
View File
@@ -1,99 +0,0 @@
# 🐺 volk [![Build Status](https://github.com/zeux/volk/workflows/build/badge.svg)](https://github.com/zeux/volk/actions)
## Purpose
volk is a meta-loader for Vulkan. It allows you to dynamically load entrypoints required to use Vulkan
without linking to vulkan-1.dll or statically linking Vulkan loader. Additionally, volk simplifies the use of Vulkan extensions by automatically loading all associated entrypoints. Finally, volk enables loading
Vulkan entrypoints directly from the driver which can increase performance by skipping loader dispatch overhead.
volk is written in C89 and supports Windows, Linux, Android and macOS (via MoltenVK).
## Building
There are multiple ways to use volk in your project:
1. You can just add `volk.c` to your build system. Note that the usual preprocessor defines that enable Vulkan's platform-specific functions (VK_USE_PLATFORM_WIN32_KHR, VK_USE_PLATFORM_XLIB_KHR, VK_USE_PLATFORM_MACOS_MVK, etc) must be passed as desired to the compiler when building `volk.c`.
2. You can use provided CMake files, with the usage detailed below.
3. You can use volk in header-only fashion. Include `volk.h` wherever you want to use Vulkan functions. In exactly one source file, define `VOLK_IMPLEMENTATION` before including `volk.h`. Do not build `volk.c` at all in this case - however, `volk.c` must still be in the same directory as `volk.h`. This method of integrating volk makes it possible to set the platform defines mentioned above with arbitrary (preprocessor) logic in your code.
## Basic usage
To use volk, you have to include `volk.h` instead of `vulkan/vulkan.h`; this is necessary to use function definitions from volk.
If some files in your application include `vulkan/vulkan.h` and don't include `volk.h`, this can result in symbol conflicts; consider defining `VK_NO_PROTOTYPES` when compiling code that uses Vulkan to make sure this doesn't happen. It's also important to make sure that `vulkan-1` is not linked into the application, as this results in symbol name conflicts as well.
To initialize volk, call this function first:
```c++
VkResult volkInitialize();
```
This will attempt to load Vulkan loader from the system; if this function returns `VK_SUCCESS` you can proceed to create Vulkan instance.
If this function fails, this means Vulkan loader isn't installed on your system.
After creating the Vulkan instance using Vulkan API, call this function:
```c++
void volkLoadInstance(VkInstance instance);
```
This function will load all required Vulkan entrypoints, including all extensions; you can use Vulkan from here on as usual.
## Optimizing device calls
If you use volk as described in the previous section, all device-related function calls, such as `vkCmdDraw`, will go through Vulkan loader dispatch code.
This allows you to transparently support multiple VkDevice objects in the same application, but comes at a price of dispatch overhead which can be as high as 7% depending on the driver and application.
To avoid this, you have two options:
1. For applications that use just one VkDevice object, load device-related Vulkan entrypoints directly from the driver with this function:
```c++
void volkLoadDevice(VkDevice device);
```
2. For applications that use multiple VkDevice objects, load device-related Vulkan entrypoints into a table:
```c++
void volkLoadDeviceTable(struct VolkDeviceTable* table, VkDevice device);
```
The second option requires you to change the application code to store one `VolkDeviceTable` per `VkDevice` and call functions from this table instead.
Device entrypoints are loaded using `vkGetDeviceProcAddr`; when no layers are present, this commonly results in most function pointers pointing directly at the driver functions, minimizing the call overhead. When layers are loaded, the entrypoints will point at the implementations in the first applicable layer, so this is compatible with any layers including validation layers.
Since `volkLoadDevice` overwrites some function pointers with device-specific versions, you can choose to use `volkLoadInstanceOnly` instead of `volkLoadInstance`; when using table-based interface this can also help enforce the usage of the function tables as `volkLoadInstanceOnly` will leave device-specific functions as `NULL`.
## CMake support
If your project uses CMake, volk provides you with targets corresponding to the different use cases:
1. Target `volk` is a static library. Any platform defines can be passed to the compiler by setting `VOLK_STATIC_DEFINES`. Example:
```cmake
if (WIN32)
set(VOLK_STATIC_DEFINES VK_USE_PLATFORM_WIN32_KHR)
elseif()
...
endif()
add_subdirectory(volk)
target_link_library(my_application PRIVATE volk)
```
2. Target `volk_headers` is an interface target for the header-only style. Example:
```cmake
add_subdirectory(volk)
target_link_library(my_application PRIVATE volk_headers)
```
and in the code:
```c
/* ...any logic setting VK_USE_PLATFORM_WIN32_KHR and friends... */
#define VOLK_IMPLEMENTATION
#include "volk.h"
```
The above example use `add_subdirectory` to include volk into CMake's build tree. This is a good choice if you copy the volk files into your project tree or as a git submodule.
Volk also supports installation and config-file packages. Installation is disabled by default (so as to not pollute user projects with install rules), and can be enabled by passing `-DVOLK_INSTALL=ON` to CMake. Once installed, do something like `find_package(volk CONFIG REQUIRED)` in your project's CMakeLists.txt. The imported volk targets are called `volk::volk` and `volk::volk_headers`.
## License
This library is available to anybody free of charge, under the terms of MIT License (see LICENSE.md).
-21
View File
@@ -1,21 +0,0 @@
get_filename_component(volk_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
if(NOT TARGET volk::volk)
include("${volk_CMAKE_DIR}/volkTargets.cmake")
endif()
# Mirror the default behaviour of the respective option.
if(NOT DEFINED VOLK_PULL_IN_VULKAN)
set(VOLK_PULL_IN_VULKAN ON)
endif()
if(VOLK_PULL_IN_VULKAN)
find_package(Vulkan QUIET)
if(TARGET Vulkan::Vulkan)
add_dependencies(volk::volk Vulkan::Vulkan)
add_dependencies(volk::volk_headers Vulkan::Vulkan)
elseif(DEFINED ENV{VULKAN_SDK})
target_include_directories(volk::volk INTERFACE "$ENV{VULKAN_SDK}/include")
target_include_directories(volk::volk_headers INTERFACE "$ENV{VULKAN_SDK}/include")
endif()
endif()
-194
View File
@@ -1,194 +0,0 @@
#!/usr/bin/python3
# This file is part of volk library; see volk.h for version/license details
from collections import OrderedDict
import re
import sys
import urllib
import xml.etree.ElementTree as etree
import urllib.request
cmdversions = {
"vkCmdSetDiscardRectangleEnableEXT": 2,
"vkCmdSetDiscardRectangleModeEXT": 2,
"vkCmdSetExclusiveScissorEnableNV": 2
}
def parse_xml(path):
file = urllib.request.urlopen(path) if path.startswith("http") else open(path, 'r')
with file:
tree = etree.parse(file)
return tree
def patch_file(path, blocks):
result = []
block = None
with open(path, 'r') as file:
for line in file.readlines():
if block:
if line == block:
result.append(line)
block = None
else:
result.append(line)
# C comment marker
if line.strip().startswith('/* VOLK_GENERATE_'):
block = line
result.append(blocks[line.strip()[17:-3]])
# Shell/CMake comment marker
elif line.strip().startswith('# VOLK_GENERATE_'):
block = line
result.append(blocks[line.strip()[16:]])
with open(path, 'w', newline='\n') as file:
for line in result:
file.write(line)
def is_descendant_type(types, name, base):
if name == base:
return True
type = types.get(name)
if not type:
return False
parents = type.get('parent')
if not parents:
return False
return any([is_descendant_type(types, parent, base) for parent in parents.split(',')])
def defined(key):
return 'defined(' + key + ')'
def cdepends(key):
return re.sub(r'[a-zA-Z0-9_]+', lambda m: defined(m.group(0)), key).replace(',', ' || ').replace('+', ' && ')
if __name__ == "__main__":
specpath = "https://raw.githubusercontent.com/KhronosGroup/Vulkan-Docs/main/xml/vk.xml"
if len(sys.argv) > 1:
specpath = sys.argv[1]
spec = parse_xml(specpath)
block_keys = ('DEVICE_TABLE', 'PROTOTYPES_H', 'PROTOTYPES_C', 'LOAD_LOADER', 'LOAD_INSTANCE', 'LOAD_DEVICE', 'LOAD_DEVICE_TABLE')
blocks = {}
version = spec.find('types/type[name="VK_HEADER_VERSION"]')
blocks['VERSION'] = version.find('name').tail.strip() + '\n'
blocks['VERSION_DEFINE'] = '#define VOLK_HEADER_VERSION ' + version.find('name').tail.strip() + '\n'
command_groups = OrderedDict()
instance_commands = set()
for feature in spec.findall('feature'):
api = feature.get('api')
if 'vulkan' not in api.split(','):
continue
key = defined(feature.get('name'))
cmdrefs = feature.findall('require/command')
command_groups[key] = [cmdref.get('name') for cmdref in cmdrefs]
for ext in sorted(spec.findall('extensions/extension'), key=lambda ext: ext.get('name')):
supported = ext.get('supported')
if 'vulkan' not in supported.split(','):
continue
name = ext.get('name')
type = ext.get('type')
for req in ext.findall('require'):
key = defined(name)
if req.get('feature'): # old-style XML depends specification
for i in req.get('feature').split(','):
key += ' && ' + defined(i)
if req.get('extension'): # old-style XML depends specification
for i in req.get('extension').split(','):
key += ' && ' + defined(i)
if req.get('depends'): # new-style XML depends specification
dep = cdepends(req.get('depends'))
key += ' && ' + ('(' + dep + ')' if '||' in dep else dep)
cmdrefs = req.findall('command')
for cmdref in cmdrefs:
ver = cmdversions.get(cmdref.get('name'))
if ver:
command_groups.setdefault(key + ' && ' + name.upper() + '_SPEC_VERSION >= ' + str(ver), []).append(cmdref.get('name'))
else:
command_groups.setdefault(key, []).append(cmdref.get('name'))
if type == 'instance':
for cmdref in cmdrefs:
instance_commands.add(cmdref.get('name'))
commands_to_groups = OrderedDict()
for (group, cmdnames) in command_groups.items():
for name in cmdnames:
commands_to_groups.setdefault(name, []).append(group)
for (group, cmdnames) in command_groups.items():
command_groups[group] = [name for name in cmdnames if len(commands_to_groups[name]) == 1]
for (name, groups) in commands_to_groups.items():
if len(groups) == 1:
continue
key = ' || '.join(['(' + g + ')' for g in groups])
command_groups.setdefault(key, []).append(name)
commands = {}
for cmd in spec.findall('commands/command'):
if not cmd.get('alias'):
name = cmd.findtext('proto/name')
commands[name] = cmd
for cmd in spec.findall('commands/command'):
if cmd.get('alias'):
name = cmd.get('name')
commands[name] = commands[cmd.get('alias')]
types = {}
for type in spec.findall('types/type'):
name = type.findtext('name')
if name:
types[name] = type
for key in block_keys:
blocks[key] = ''
for (group, cmdnames) in command_groups.items():
ifdef = '#if ' + group + '\n'
for key in block_keys:
blocks[key] += ifdef
for name in sorted(cmdnames):
cmd = commands[name]
type = cmd.findtext('param[1]/type')
if name == 'vkGetInstanceProcAddr':
type = ''
if name == 'vkGetDeviceProcAddr':
type = 'VkInstance'
if is_descendant_type(types, type, 'VkDevice') and name not in instance_commands:
blocks['LOAD_DEVICE'] += '\t' + name + ' = (PFN_' + name + ')load(context, "' + name + '");\n'
blocks['DEVICE_TABLE'] += '\tPFN_' + name + ' ' + name + ';\n'
blocks['LOAD_DEVICE_TABLE'] += '\ttable->' + name + ' = (PFN_' + name + ')load(context, "' + name + '");\n'
elif is_descendant_type(types, type, 'VkInstance'):
blocks['LOAD_INSTANCE'] += '\t' + name + ' = (PFN_' + name + ')load(context, "' + name + '");\n'
elif type != '':
blocks['LOAD_LOADER'] += '\t' + name + ' = (PFN_' + name + ')load(context, "' + name + '");\n'
blocks['PROTOTYPES_H'] += 'extern PFN_' + name + ' ' + name + ';\n'
blocks['PROTOTYPES_C'] += 'PFN_' + name + ' ' + name + ';\n'
for key in block_keys:
if blocks[key].endswith(ifdef):
blocks[key] = blocks[key][:-len(ifdef)]
else:
blocks[key] += '#endif /* ' + group + ' */\n'
patch_file('volk.h', blocks)
patch_file('volk.c', blocks)
patch_file('CMakeLists.txt', blocks)
print(version.find('name').tail.strip())
@@ -1,9 +0,0 @@
cmake_minimum_required(VERSION 3.5)
project(volk_test LANGUAGES C)
# Include volk from a CMake package config.
# CMAKE_PREFIX_PATH or volk_DIR must be set properly.
find_package(volk CONFIG REQUIRED)
add_executable(volk_test main.c)
target_link_libraries(volk_test PRIVATE volk::volk_headers)
@@ -1,54 +0,0 @@
/* Set platform defines at build time for volk to pick up. */
#if defined(_WIN32)
# define VK_USE_PLATFORM_WIN32_KHR
#elif defined(__linux__) || defined(__unix__)
# define VK_USE_PLATFORM_XLIB_KHR
#elif defined(__APPLE__)
# define VK_USE_PLATFORM_MACOS_MVK
#else
# error "Platform not supported by this example."
#endif
#define VOLK_IMPLEMENTATION
#include "volk.h"
#include "stdio.h"
#include "stdlib.h"
int main()
{
VkResult r;
uint32_t version;
void* ptr;
/* This won't compile if the appropriate Vulkan platform define isn't set. */
ptr =
#if defined(_WIN32)
&vkCreateWin32SurfaceKHR;
#elif defined(__linux__) || defined(__unix__)
&vkCreateXlibSurfaceKHR;
#elif defined(__APPLE__)
&vkCreateMacOSSurfaceMVK;
#else
/* Platform not recogized for testing. */
NULL;
#endif
/* Try to initialize volk. This might not work on CI builds, but the
* above should have compiled at least. */
r = volkInitialize();
if (r != VK_SUCCESS) {
printf("volkInitialize failed!\n");
return -1;
}
version = volkGetInstanceVersion();
printf("Vulkan version %d.%d.%d initialized.\n",
VK_VERSION_MAJOR(version),
VK_VERSION_MINOR(version),
VK_VERSION_PATCH(version));
return 0;
}
@@ -1,40 +0,0 @@
# Compiles the volk sources as part of a user project.
# Volk comes with a volk.c for this purpose.
# Note that for volk to properly handle platform defines,
# those have to be set at build time.
# Also note that this way the Vulkan headers must
# handled by the user project as well as linking to dl on
# non-Windows platforms.
# For these reasons it's recommended to use one of
# the other ways to include volk (see the other examples).
cmake_minimum_required(VERSION 3.5)
project(volk_test LANGUAGES C)
add_executable(volk_test main.c ../../volk.c)
# Set include path for volk.h
target_include_directories(volk_test PRIVATE ../..)
# Set suitable platform defines
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
target_compile_definitions(volk_test PRIVATE VK_USE_PLATFORM_WIN32_KHR)
elseif(CMAKE_SYSTEM_NAME STREQUAL Linux)
target_compile_definitions(volk_test PRIVATE VK_USE_PLATFORM_XLIB_KHR)
elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
target_compile_definitions(volk_test PRIVATE VK_USE_PLATFORM_MACOS_MVK)
endif()
# Link requires libraries
if(NOT WIN32)
target_link_libraries(volk_test PRIVATE dl)
endif()
# Get Vulkan dependency
find_package(Vulkan QUIET)
if(TARGET Vulkan::Vulkan)
# Note: We don't use target_link_libraries for Vulkan::Vulkan to avoid a static dependency on libvulkan1
target_include_directories(volk_test PRIVATE ${Vulkan_INCLUDE_DIRS})
elseif(DEFINED ENV{VULKAN_SDK})
target_include_directories(volk_test PRIVATE "$ENV{VULKAN_SDK}/include")
endif()
@@ -1,41 +0,0 @@
#include "volk.h"
#include "stdio.h"
#include "stdlib.h"
int main()
{
VkResult r;
uint32_t version;
void* ptr;
/* This won't compile if the appropriate Vulkan platform define isn't set. */
ptr =
#if defined(_WIN32)
&vkCreateWin32SurfaceKHR;
#elif defined(__linux__) || defined(__unix__)
&vkCreateXlibSurfaceKHR;
#elif defined(__APPLE__)
&vkCreateMacOSSurfaceMVK;
#else
/* Platform not recogized for testing. */
NULL;
#endif
/* Try to initialize volk. This might not work on CI builds, but the
* above should have compiled at least. */
r = volkInitialize();
if (r != VK_SUCCESS) {
printf("volkInitialize failed!\n");
return -1;
}
version = volkGetInstanceVersion();
printf("Vulkan version %d.%d.%d initialized.\n",
VK_VERSION_MAJOR(version),
VK_VERSION_MINOR(version),
VK_VERSION_PATCH(version));
return 0;
}
@@ -1,11 +0,0 @@
# Include the volk target through add_subdirectory.
cmake_minimum_required(VERSION 3.5)
project(volk_test LANGUAGES C)
# Include volk as part of the build tree to make the target known.
# The two-argument version of add_subdirectory allows adding non-subdirs.
add_subdirectory(../.. volk)
add_executable(volk_test main.c)
target_link_libraries(volk_test PRIVATE volk_headers)
-53
View File
@@ -1,53 +0,0 @@
/* Set platform defines at build time for volk to pick up. */
#if defined(_WIN32)
# define VK_USE_PLATFORM_WIN32_KHR
#elif defined(__linux__) || defined(__unix__)
# define VK_USE_PLATFORM_XLIB_KHR
#elif defined(__APPLE__)
# define VK_USE_PLATFORM_MACOS_MVK
#else
# error "Platform not supported by this example."
#endif
#define VOLK_IMPLEMENTATION
#include "volk.h"
#include "stdio.h"
#include "stdlib.h"
int main()
{
VkResult r;
uint32_t version;
void* ptr;
/* This won't compile if the appropriate Vulkan platform define isn't set. */
ptr =
#if defined(_WIN32)
&vkCreateWin32SurfaceKHR;
#elif defined(__linux__) || defined(__unix__)
&vkCreateXlibSurfaceKHR;
#elif defined(__APPLE__)
&vkCreateMacOSSurfaceMVK;
#else
/* Platform not recogized for testing. */
NULL;
#endif
/* Try to initialize volk. This might not work on CI builds, but the
* above should have compiled at least. */
r = volkInitialize();
if (r != VK_SUCCESS) {
printf("volkInitialize failed!\n");
return -1;
}
version = volkGetInstanceVersion();
printf("Vulkan version %d.%d.%d initialized.\n",
VK_VERSION_MAJOR(version),
VK_VERSION_MINOR(version),
VK_VERSION_PATCH(version));
return 0;
}
@@ -1,22 +0,0 @@
# Include the volk target through add_subdirectory, use the static lib target.
# We must set platform defines.
# By default, Vulkan is pulled in as transitive dependency if found.
cmake_minimum_required(VERSION 3.5)
project(volk_test LANGUAGES C)
# Set a suitable platform define to compile volk with.
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
set(VOLK_STATIC_DEFINES VK_USE_PLATFORM_WIN32_KHR)
elseif(CMAKE_SYSTEM_NAME STREQUAL Linux)
set(VOLK_STATIC_DEFINES VK_USE_PLATFORM_XLIB_KHR)
elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(VOLK_STATIC_DEFINES VK_USE_PLATFORM_MACOS_MVK)
endif()
# Include volk as part of the build tree to make the target known.
# The two-argument version of add_subdirectory allows adding non-subdirs.
add_subdirectory(../.. volk)
add_executable(volk_test main.c)
target_link_libraries(volk_test PRIVATE volk)
-41
View File
@@ -1,41 +0,0 @@
#include "volk.h"
#include "stdio.h"
#include "stdlib.h"
int main()
{
VkResult r;
uint32_t version;
void* ptr;
/* This won't compile if the appropriate Vulkan platform define isn't set. */
ptr =
#if defined(_WIN32)
&vkCreateWin32SurfaceKHR;
#elif defined(__linux__) || defined(__unix__)
&vkCreateXlibSurfaceKHR;
#elif defined(__APPLE__)
&vkCreateMacOSSurfaceMVK;
#else
/* Platform not recogized for testing. */
NULL;
#endif
/* Try to initialize volk. This might not work on CI builds, but the
* above should have compiled at least. */
r = volkInitialize();
if (r != VK_SUCCESS) {
printf("volkInitialize failed!\n");
return -1;
}
version = volkGetInstanceVersion();
printf("Vulkan version %d.%d.%d initialized.\n",
VK_VERSION_MAJOR(version),
VK_VERSION_MINOR(version),
VK_VERSION_PATCH(version));
return 0;
}
-87
View File
@@ -1,87 +0,0 @@
#!/usr/bin/env bash
function reset_build {
for DIR in "_build" "_installed"
do
if [ -d $DIR ]; then
rm -rf $DIR
fi
mkdir -p $DIR
done
}
function run_volk_test {
for FILE in "./volk_test" "./volk_test.exe" "Debug/volk_test.exe" "Release/volk_test.exe"
do
if [ -f $FILE ]; then
echo "Running test:"
$FILE
RC=$?
break
fi
done
echo "volk_test return code: $RC"
}
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
pushd $SCRIPT_DIR/..
reset_build
pushd _build
cmake -DCMAKE_INSTALL_PREFIX=../_installed -DVOLK_INSTALL=ON .. || exit 1
cmake --build . --target install || exit 1
popd
echo
echo "cmake_using_source_directly =======================================>"
echo
pushd test/cmake_using_source_directly
reset_build
pushd _build
cmake .. || exit 1
cmake --build . || exit 1
run_volk_test
popd
popd
echo
echo "cmake_using_subdir_static =======================================>"
echo
pushd test/cmake_using_subdir_static
reset_build
pushd _build
cmake .. || exit 1
cmake --build . || exit 1
run_volk_test
popd
popd
echo
echo "cmake_using_subdir_headers =======================================>"
echo
pushd test/cmake_using_subdir_headers
reset_build
pushd _build
cmake .. || exit 1
cmake --build . || exit 1
run_volk_test
popd
popd
echo
echo "cmake_using_installed_headers =======================================>"
echo
pushd test/cmake_using_installed_headers
reset_build
pushd _build
cmake -DCMAKE_INSTALL_PREFIX=../../../_installed/lib/cmake .. || exit 1
cmake --build . || exit 1
run_volk_test
popd
popd
popd
-3179
View File
File diff suppressed because it is too large Load Diff
-2069
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -13,14 +13,14 @@ void VK_CHECK(VkResult ret)
assert(ret == VK_SUCCESS);
}
std::string AppBase::getPath(const std::string path)
{
#ifdef _WIN32
std::string android_path = "app/src/main/assets/" + path;
return android_path;
#endif
return path;
}
//std::string AppBase::getPath(const std::string path)
//{
//#ifdef _WIN32
// std::string android_path = "app/src/main/assets/" + path;
// return android_path;
//#endif
// return path;
//}
std::vector<char> AppBase::readFile(const std::string& path)
{
+12 -3
View File
@@ -11,7 +11,7 @@
// } \
// } while (0)
#include <volk.h>
//#include <volk.h>
#ifdef _WIN32
#define logOut std::cout
@@ -29,12 +29,15 @@
#include <fstream>
#include <iostream>
#include <iostream>
#include <stdexcept>
#include <cstdlib>
#include <vector>
#include <optional>
#include <set>
#include <thread>
#include <mutex>
#include <chrono>
#include <ctime>
void VK_CHECK(VkResult ret);
@@ -52,10 +55,16 @@ class AppBase
{
public:
std::vector<char> readFile(const std::string& enginePath);
std::string getPath(const std::string path);
//std::string getPath(const std::string path);
VkShaderModule createShaderModule(VkDevice& device, const std::vector<char>& code);
const std::vector<const char*> validationLayers = {"VK_LAYER_KHRONOS_validation"};
protected:
long long getCurrentTimeMillis() {
auto now = std::chrono::system_clock::now();
auto duration = now.time_since_epoch();
return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
}
VkInstance instance;
void createInstance();
bool checkValidationLayerSupport();
+12 -9
View File
@@ -178,8 +178,6 @@ void Application::createLogicalDevice() {
throw std::runtime_error("failed to create logical device!");
}
v_device = std::make_unique<vkb::core::DeviceC>(v_gpu, device, surface);
vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
}
@@ -480,11 +478,7 @@ void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t im
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
// 绑定图形管线
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
// 绘制三角形
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
render(commandBuffer);
// 结束渲染流程
vkCmdEndRenderPass(commandBuffer);
@@ -494,6 +488,15 @@ void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t im
}
}
void Application::render(VkCommandBuffer commandBuffer)
{
// 绑定图形管线
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
// 绘制三角形
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
}
void Application::drawFrame()
{
// 1. 等待前一帧完成
@@ -651,10 +654,10 @@ uint32_t Application::findMemoryType(VkPhysicalDevice physicalDevice, uint32_t t
Texture Application::loadTexture(std::string path)
{
const char* filename = getPath(path).c_str();
std::vector<char> data = readFile(path);
std::vector<unsigned char> image;
unsigned w, h;
unsigned error = lodepng::decode(image, w, h, filename, LCT_RGBA, 8);
unsigned error = lodepng::decode(image, w, h, data.data(), LCT_RGBA, 8);
Texture tex;
processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, true);
return tex;
+2 -5
View File
@@ -6,8 +6,6 @@
#include <thread>
#include <mutex>
#include <vulkan/vulkan.hpp>
#include "framework/core/buffer.h"
#include "framework/core/device.h"
struct Texture
{
@@ -44,12 +42,11 @@ public:
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex);
void createSyncObjects();
void drawFrame();
virtual void render(VkCommandBuffer commandBuffer);
bool isInited() { return inited; }
protected:
std::unique_ptr< vkb::core::InstanceC> v_instance;
std::unique_ptr<vkb::PhysicalDevice> v_gpu;
std::unique_ptr<vkb::core::DeviceC> v_device;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; // 物理设备
VkDevice device; // 逻辑设备
VkQueue graphicsQueue; // 图形队列
+274 -13
View File
@@ -1,37 +1,298 @@
#include "FaceApp.h"
#include "common/helpers.h"
#include "hardcode_data.h"
#include <sstream>
FaceApp* FaceApp::faceIns = nullptr;
FaceApp::FaceApp(/* args */)
{
faceIns = this;
}
FaceApp::~FaceApp()
{
}
bool FaceApp::LoadOBJ(const std::string& filename,
std::vector<TextureLoadingVertexStructure>& vertices,
std::vector<uint32_t>& indices) {
// 临时存储从OBJ文件读取的原始数据
std::vector<float> temp_positions;
std::vector<float> temp_texcoords;
std::vector<float> temp_normals;
// 用于处理顶点索引
std::vector<int> vertexIndices, uvIndices, normalIndices;
std::vector<char> data = readFile(filename);
// 将 vector<char> 转换为以 null 结尾的字符串(安全做法)
std::string content(data.begin(), data.end());
std::istringstream iss(content); // 用字符串创建字符串流
std::string line;
while (std::getline(iss, line)) {
// 跳过空行和注释行
if (line.empty() || line[0] == '#') {
continue;
}
std::istringstream iss(line);
std::string type;
iss >> type;
if (type == "v") { // 顶点位置
float x, y, z;
iss >> x >> y >> z;
temp_positions.push_back(x);
temp_positions.push_back(y);
temp_positions.push_back(z);
}
else if (type == "vt") { // 纹理坐标
float u, v;
iss >> u >> v;
temp_texcoords.push_back(u);
temp_texcoords.push_back(1 - v);
}
else if (type == "vn") { // 法线
float nx, ny, nz;
iss >> nx >> ny >> nz;
temp_normals.push_back(nx);
temp_normals.push_back(ny);
temp_normals.push_back(nz);
}
else if (type == "f") { // 面(三角形)
std::string vertex1, vertex2, vertex3;
iss >> vertex1 >> vertex2 >> vertex3;
// 处理每个顶点的索引
for (const std::string& vertex : { vertex1, vertex2, vertex3 }) {
std::istringstream viss(vertex);
std::string v, vt, vn;
// 解析顶点索引格式:v/vt/vn 或 v//vn 或 v
std::getline(viss, v, '/');
std::getline(viss, vt, '/');
std::getline(viss, vn, '/');
int posIndex = std::stoi(v) - 1; // OBJ索引从1开始
int texIndex = -1, normIndex = -1;
if (!vt.empty()) texIndex = std::stoi(vt) - 1;
if (!vn.empty()) normIndex = std::stoi(vn) - 1;
vertexIndices.push_back(posIndex);
uvIndices.push_back(texIndex);
normalIndices.push_back(normIndex);
}
}
}
// 创建顶点数据
vertices.clear();
indices.clear();
// 用于去重的哈希映射
std::map<std::string, uint32_t> vertexMap;
for (size_t i = 0; i < vertexIndices.size(); i++) {
int posIndex = vertexIndices[i];
int texIndex = uvIndices[i];
int normIndex = normalIndices[i];
// 创建唯一标识符
std::string vertexKey = std::to_string(posIndex) + "/" +
std::to_string(texIndex) + "/" +
std::to_string(normIndex);
// 检查是否已经存在相同的顶点
if (vertexMap.find(vertexKey) != vertexMap.end()) {
// 使用现有顶点的索引
indices.push_back(vertexMap[vertexKey]);
}
else {
// 创建新顶点
TextureLoadingVertexStructure vertex;
// 设置位置
if (posIndex >= 0 && posIndex * 3 + 2 < temp_positions.size()) {
vertex.pos[0] = temp_positions[posIndex * 3];
vertex.pos[1] = temp_positions[posIndex * 3 + 1];
vertex.pos[2] = temp_positions[posIndex * 3 + 2];
}
else {
vertex.pos[0] = vertex.pos[1] = vertex.pos[2] = 0.0f;
}
// 设置纹理坐标
if (texIndex >= 0 && texIndex * 2 + 1 < temp_texcoords.size()) {
vertex.uv[0] = temp_texcoords[texIndex * 2];
vertex.uv[1] = temp_texcoords[texIndex * 2 + 1];
}
else {
vertex.uv[0] = vertex.uv[1] = 0.0f;
}
// 设置法线
if (normIndex >= 0 && normIndex * 3 + 2 < temp_normals.size()) {
vertex.normal[0] = temp_normals[normIndex * 3];
vertex.normal[1] = temp_normals[normIndex * 3 + 1];
vertex.normal[2] = temp_normals[normIndex * 3 + 2];
}
else {
vertex.normal[0] = vertex.normal[1] = 0.0f;
vertex.normal[2] = 1.0f; // 默认法线
}
// 添加新顶点并记录索引
uint32_t newIndex = static_cast<uint32_t>(vertices.size());
vertices.push_back(vertex);
indices.push_back(newIndex);
obj_vertices_map[newIndex] = posIndex;
vertexMap[vertexKey] = newIndex;
}
}
return true;
}
void FaceApp::render(VkCommandBuffer commandBuffer)
{
Application::render(commandBuffer);
}
void FaceApp::initVulkan()
{
Application::initVulkan();
VmaAllocatorCreateInfo allocatorInfo = {};
allocatorInfo.physicalDevice = physicalDevice;
allocatorInfo.device = device;
allocatorInfo.instance = instance;
vmaCreateAllocator(&allocatorInfo, &allocator);
createVertexBuffer();
LoadOBJ("face_picture_3dmax.obj", obj_vertices, obj_indices);
uploadVertexData();
}
void FaceApp::generate_quad()
void FaceApp::createVertexBuffer()
{
//std::vector<TextureLoadingVertexStructure>& vertices = obj_vertices;
//std::vector<uint32_t> indices = obj_indices;
VkDeviceSize vertexBufferSize = sizeof(TextureLoadingVertexStructure) * obj_vertices.capacity();
VkDeviceSize indexBufferSize = sizeof(uint32_t) * obj_indices.capacity();
//index_count = static_cast<uint32_t>(indices.size());
// 创建顶点缓冲区(设备本地,用于渲染)
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufferInfo.size = vertexBufferSize;
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
//auto vertex_buffer_size = vkb::to_u32(vertices.size() * sizeof(TextureLoadingVertexStructure));
//auto index_buffer_size = vkb::to_u32(indices.size() * sizeof(uint32_t));
VmaAllocationCreateInfo allocInfo = {};
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
//vkb::core::DeviceC& cDevice = reinterpret_cast<vkb::core::DeviceC&>(*v_device);
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &m_vertexBuffer, &m_vertexBufferAllocation, nullptr);
//auto vertex_buffer = std::make_unique<vkb::core::BufferC>(cDevice, vertex_buffer_size,VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,VMA_MEMORY_USAGE_CPU_TO_GPU);
//vertex_buffer->update(vertices.data(), vertex_buffer_size);
// 创建暂存缓冲区(CPU可见,用于上传数据)
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
//index_buffer = std::make_unique<vkb::core::BufferC>(cDevice,index_buffer_size,VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,VMA_MEMORY_USAGE_CPU_TO_GPU);
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &m_stagingBuffer, &m_stagingBufferAllocation, nullptr);
//index_buffer->update(indices.data(), index_buffer_size);
// 创建索引缓冲区
bufferInfo.size = indexBufferSize;
bufferInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &m_indexBuffer, &m_indexBufferAllocation, nullptr);
}
void ReceiveFacePoint(float* pos, int pointCount, int width, int height)
{
FaceApp* self = FaceApp::Get();
if (self != nullptr)
{
FaceApp::Get()->update_face_vertex_buffer(pos, pointCount);
}
}
void FaceApp::update_face_vertex_buffer(float* pos, int pointCount)
{
std::lock_guard<std::mutex> lock(mtx_point);
last_update_time = getCurrentTimeMillis();
for (int i = 0; i < obj_vertices.size(); ++i)
{
int face_index = obj_vertices_map[HardCodeData::Get().indexMap[i]];
float x = pos[face_index * 3 + 0];
float y = pos[face_index * 3 + 1];
float z = pos[face_index * 3 + 2];
obj_vertices[i].pos[0] = x;
obj_vertices[i].pos[1] = y;
obj_vertices[i].pos[2] = z;
}
uploadVertexData();
}
void FaceApp::uploadVertexData() {
// 上传顶点数据
void* data;
vmaMapMemory(allocator, m_stagingBufferAllocation, &data);
memcpy(data, obj_vertices.data(), sizeof(TextureLoadingVertexStructure) * obj_vertices.size());
vmaUnmapMemory(allocator, m_stagingBufferAllocation);
// 复制到设备内存
copyBuffer(m_stagingBuffer, m_vertexBuffer, sizeof(TextureLoadingVertexStructure) * obj_vertices.size());
// 上传索引数据(如果需要暂存缓冲区,可以创建另一个)
vmaMapMemory(allocator, m_stagingBufferAllocation, &data);
memcpy(data, obj_indices.data(), sizeof(uint32_t) * obj_indices.size());
vmaUnmapMemory(allocator, m_stagingBufferAllocation);
copyBuffer(m_stagingBuffer, m_indexBuffer, sizeof(uint32_t) * obj_indices.size());
}
void FaceApp::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size)
{
VkCommandBuffer commandBuffer = beginSingleTimeCommands();
VkBufferCopy copyRegion = {};
copyRegion.size = size;
vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &copyRegion);
endSingleTimeCommands(commandBuffer);
}
VkCommandBuffer FaceApp::beginSingleTimeCommands() {
VkCommandBufferAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandPool = commandPool;
allocInfo.commandBufferCount = 1;
VkCommandBuffer commandBuffer;
vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer);
VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
vkBeginCommandBuffer(commandBuffer, &beginInfo);
return commandBuffer;
}
void FaceApp::endSingleTimeCommands(VkCommandBuffer commandBuffer) {
vkEndCommandBuffer(commandBuffer);
VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;
vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
vkQueueWaitIdle(graphicsQueue);
vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
}
+38 -5
View File
@@ -2,7 +2,8 @@
#define __FaceApp_H__
#include "Application.h"
#include "vma/include/vk_mem_alloc.h"
#include <map>
struct TextureLoadingVertexStructure
@@ -24,16 +25,48 @@ public:
void initVulkan() override;
void render(VkCommandBuffer commandBuffer) override;
static FaceApp* Get() { return faceIns; }
void update_face_vertex_buffer(float* pos, int pointCount);
private:
void generate_quad();
static FaceApp* faceIns;
VmaAllocator allocator = nullptr;
bool LoadOBJ(const std::string& filename,
std::vector<TextureLoadingVertexStructure>& vertices,
std::vector<uint32_t>& indices);
void createVertexBuffer();
void uploadVertexData();
void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size);
VkCommandBuffer beginSingleTimeCommands();
void endSingleTimeCommands(VkCommandBuffer commandBuffer);
// 顶点缓冲区相关
VkBuffer m_vertexBuffer = VK_NULL_HANDLE;
VmaAllocation m_vertexBufferAllocation = VK_NULL_HANDLE;
VkBuffer m_stagingBuffer = VK_NULL_HANDLE;
VmaAllocation m_stagingBufferAllocation = VK_NULL_HANDLE;
// 索引缓冲区相关
VkBuffer m_indexBuffer = VK_NULL_HANDLE;
VmaAllocation m_indexBufferAllocation = VK_NULL_HANDLE;
// 渲染管线和描述符
VkPipeline m_graphicsPipeline = VK_NULL_HANDLE;
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
std::unique_ptr<vkb::core::BufferC> vertex_buffer;
std::unique_ptr<vkb::core::BufferC> index_buffer;
uint32_t index_count;
std::vector<TextureLoadingVertexStructure> obj_vertices;
std::vector<uint32_t> obj_indices;
std::map<int, int> obj_vertices_map;
std::map<int, int> vertices_map_3dmax;
std::mutex mtx_point;
long long last_update_time;
};
#endif
File diff suppressed because one or more lines are too long