Merge branch 'master' into project_setup_refactor

# Conflicts:
#	3rdParty/CMakeLists.txt
#	3rdParty/libarchive/CMakeLists.txt
#	CMakeLists.txt
This commit is contained in:
Georg Hagen
2024-08-04 18:05:50 +02:00
70 changed files with 1096 additions and 274 deletions

View File

@@ -12,23 +12,11 @@ env:
jobs: jobs:
build: build:
name: Build desktop name: Build desktop
runs-on: ${{matrix.config.os}} runs-on: ${{matrix.os}}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
config: os: [ windows_x64, ubuntu-latest, mac_arm ]
- {
name: "Windows",
os: windows_x64
}
- {
name: "Linux",
os: ubuntu-latest
}
# - {
# name: "macOS",
# os: macos-latest
# }
steps: steps:
- name: Checkout - name: Checkout
@@ -36,13 +24,13 @@ jobs:
with: with:
submodules: true submodules: true
- name: Install Vulkan SDK - name: Install Vulkan SDK
if: matrix.config.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
uses: humbletim/install-vulkan-sdk@v1.1.1 uses: humbletim/install-vulkan-sdk@v1.1.1
with: with:
version: 1.3.250.1 version: 1.3.250.1
cache: true cache: true
- name: Install Dev Packages - name: Install Dev Packages
if: matrix.config.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
run: > run: >
sudo apt update && sudo apt install -y extra-cmake-modules libwayland-dev libxkbcommon-dev xorg-dev libarchive-dev libassimp-dev ninja-build glslang-tools glslang-dev unzip sudo apt update && sudo apt install -y extra-cmake-modules libwayland-dev libxkbcommon-dev xorg-dev libarchive-dev libassimp-dev ninja-build glslang-tools glslang-dev unzip
&& sudo wget https://sourceforge.net/projects/bin2c/files/1.1/bin2c-1.1.zip && sudo unzip bin2c-1.1.zip && cd bin2c && sudo gcc -o bin2c bin2c.c && sudo mv bin2c /usr/bin && sudo wget https://sourceforge.net/projects/bin2c/files/1.1/bin2c-1.1.zip && sudo unzip bin2c-1.1.zip && cd bin2c && sudo gcc -o bin2c bin2c.c && sudo mv bin2c /usr/bin
@@ -55,3 +43,18 @@ jobs:
run: ctest -C ${{env.BUILD_TYPE}} run: ctest -C ${{env.BUILD_TYPE}}
#TODO archive executables #TODO archive executables
build_iOS:
name: Build iOS
runs-on: mac_arm
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Configure CMake
run: mkdir cmake-build && mkdir cmake-build/iOS && cd cmake-build/iOS && cmake ../.. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchain/ios.toolchain.cmake -DPLATFORM=OS64 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build & Archive
run: xcodebuild -project ${{github.workspace}}/cmake-build/iOS/openVulkanoCpp.xcodeproj -scheme OpenVulkano_Examples -configuration ${{env.BUILD_TYPE}} -archivePath ${{github.workspace}}/cmake-build/iOS/app.xcarchive -sdk iphoneos archive

View File

@@ -22,12 +22,12 @@ add_subdirectory(rapidyaml)
add_subdirectory(libarchive) add_subdirectory(libarchive)
add_subdirectory(boost) add_subdirectory(boost)
add_subdirectory(units) add_subdirectory(units)
add_subdirectory(libjpeg-turbo)
if (NOT IOS)
add_subdirectory(curl)
endif()
if(ENABLE_TEST) if(ENABLE_TEST)
add_subdirectory(catch2) add_subdirectory(catch2)
endif() endif()
if (NOT IOS)
add_subdirectory(libjpeg-turbo)
add_subdirectory(curl)
endif()

View File

@@ -13,5 +13,8 @@ FetchContent_Declare(
) )
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
if(APPLE)
set(GLFW_VULKAN_STATIC ON CACHE BOOL "" FORCE)
endif()
FetchContent_MakeAvailable(glfw) FetchContent_MakeAvailable(glfw)
set(glfw_FOUND ON PARENT_SCOPE) set(glfw_FOUND ON PARENT_SCOPE)

View File

@@ -28,12 +28,21 @@ function(LinkLibArchive TARGET)
find_package(zstd QUIET) find_package(zstd QUIET)
find_package(BZip2 QUIET) find_package(BZip2 QUIET)
find_package(LibLZMA QUIET) find_package(LibLZMA QUIET)
find_package(LibXml2 QUIET)
find_package(EXPAT QUIET)
target_include_directories(${TARGET} PUBLIC ${LibArchive_INCLUDE_DIR}) target_include_directories(${TARGET} PUBLIC ${LibArchive_INCLUDE_DIR})
target_link_libraries(${TARGET} PUBLIC ${LibArchive_LIBRARIES} ${ZLIB_LIBRARIES} ${zstd_LIBRARIES} ${LZ4_LIBRARIES}) target_link_libraries(${TARGET} PUBLIC ${LibArchive_LIBRARIES} ${ZLIB_LIBRARIES} ${zstd_LIBRARIES} ${LZ4_LIBRARIES})
if (BZIP2_LIBRARIES) if (BZIP2_LIBRARIES)
target_link_libraries(${TARGET} PUBLIC ${BZIP2_LIBRARIES}) target_link_libraries(${TARGET} PUBLIC ${BZIP2_LIBRARIES})
endif() endif()
if (LIBLZMA_LIBRARIES) if (LIBLZMA_LIBRARIES)
target_link_libraries(${TARGET} PUBLIC ${LIBLZMA_LIBRARIES}) target_link_libraries(${TARGET} PUBLIC ${LIBLZMA_LIBRARIES})
endif() endif()
if (LibXml2_FOUND)
target_link_libraries(${TARGET} PUBLIC ${LIBXML2_LIBRARIES})
endif()
if (EXPAT_FOUND)
target_link_libraries(${TARGET} PUBLIC ${EXPAT_LIBRARIES})
endif()
endfunction() endfunction()

View File

@@ -31,6 +31,11 @@ endif ()
function(LinkLibJpegTurbo TARGET) function(LinkLibJpegTurbo TARGET)
if (IOS)
target_link_libraries(${TARGET} PRIVATE "/opt/libjpeg-turbo-ios/lib/libturbojpeg.a")
target_include_directories(${TARGET} PRIVATE "/opt/libjpeg-turbo-ios/include")
return()
endif ()
if (libjpeg-turbo_BUILT) if (libjpeg-turbo_BUILT)
FindCmakeConfigDirs("${CMAKE_BINARY_DIR}/deps_ljt/INSTALL/" CMAKE_PREFIX_PATH) FindCmakeConfigDirs("${CMAKE_BINARY_DIR}/deps_ljt/INSTALL/" CMAKE_PREFIX_PATH)
endif() endif()

View File

@@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.28 FATAL_ERROR)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
if(LINUX) if(LINUX)
find_package(ECM REQUIRED NO_MODULE) find_package(ECM REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
@@ -45,3 +47,5 @@ endif()
if(ENABLE_EXAMPLE) if(ENABLE_EXAMPLE)
add_subdirectory(examples) add_subdirectory(examples)
endif() endif()
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT openVulkanoCpp)

View File

@@ -27,8 +27,8 @@ check_return_code() {
fi fi
} }
rm -f *.spv
mkdir -p "$GENERATED_DATA_PATH" mkdir -p "$GENERATED_DATA_PATH"
rm -f "$GENERATED_DATA_PATH/*.spv"
touch "$GENERATED_DATA_PATH"/GeneratedShaderData.h touch "$GENERATED_DATA_PATH"/GeneratedShaderData.h
touch "$GENERATED_DATA_PATH"/GeneratedShaderData.c touch "$GENERATED_DATA_PATH"/GeneratedShaderData.c
@@ -48,13 +48,13 @@ for unique_name in ${unique_file_names[@]} ; do
same_files=$(find $SHADER_PATH/ -type f -name "${unique_name}.*") same_files=$(find $SHADER_PATH/ -type f -name "${unique_name}.*")
for same_file in ${same_files[@]} ; do for same_file in ${same_files[@]} ; do
filename_with_ext_no_path=$(basename -- "$same_file") filename_with_ext_no_path=$(basename -- "$same_file")
glslangValidator -V $same_file -o $filename_with_ext_no_path.spv glslangValidator -V $same_file -o "$GENERATED_DATA_PATH/$filename_with_ext_no_path.spv"
check_return_code check_return_code
done done
bin2c -t -d "$GENERATED_DATA_PATH"/$unique_name.h -o "$GENERATED_DATA_PATH"/$unique_name.c *.spv (cd "$GENERATED_DATA_PATH" && bin2c -t -d $unique_name.h -o $unique_name.c *.spv)
check_return_code check_return_code
rm *.spv rm "$GENERATED_DATA_PATH"/*.spv
echo -e "#include \"${unique_name}.h\"" >> "$GENERATED_DATA_PATH"/GeneratedShaderData.c echo -e "#include \"${unique_name}.h\"" >> "$GENERATED_DATA_PATH"/GeneratedShaderData.c
filename_no_ext_first_upper=$(echo $unique_name | awk '{print toupper(substr($0,1,1))substr($0,2)}') filename_no_ext_first_upper=$(echo $unique_name | awk '{print toupper(substr($0,1,1))substr($0,2)}')

View File

@@ -4,14 +4,20 @@ function(LinkAppleFrameworks TARGET)
PUBLIC "-framework Foundation" PUBLIC "-framework Foundation"
PUBLIC "-framework CoreImage" PUBLIC "-framework CoreImage"
PUBLIC "-framework CoreVideo" PUBLIC "-framework CoreVideo"
PUBLIC "-framework CoreGraphics"
PUBLIC "-framework Metal" PUBLIC "-framework Metal"
PUBLIC "-framework MetalPerformanceShaders" PUBLIC "-framework MetalPerformanceShaders"
PUBLIC "-framework ARKit" PUBLIC "-framework MetalKit"
PUBLIC "-framework IOSurface"
PUBLIC "-framework QuartzCore"
PUBLIC "-lstdc++" PUBLIC "-lstdc++"
PUBLIC c++ PUBLIC c++
PUBLIC c PUBLIC c
) )
if(IOS)
target_link_libraries(${TARGET} PUBLIC "-framework ARKit")
endif()
# Locate system libraries on iOS # Locate system libraries on iOS
find_library(UIKIT UIKit) find_library(UIKIT UIKit)
@@ -19,11 +25,20 @@ function(LinkAppleFrameworks TARGET)
find_library(MOBILECORESERVICES MobileCoreServices) find_library(MOBILECORESERVICES MobileCoreServices)
find_library(CFNETWORK CFNetwork) find_library(CFNETWORK CFNetwork)
find_library(SYSTEMCONFIGURATION SystemConfiguration) find_library(SYSTEMCONFIGURATION SystemConfiguration)
find_library(APPKIT AppKit)
find_library(IOSURFACE IOSurface)
find_library(QUARTZ Quartz)
# link the frameworks located above # link the frameworks located above
if(IOS)
target_link_libraries(${TARGET} PUBLIC ${UIKIT}) target_link_libraries(${TARGET} PUBLIC ${UIKIT})
target_link_libraries(${TARGET} PUBLIC ${FOUNDATION})
target_link_libraries(${TARGET} PUBLIC ${MOBILECORESERVICES}) target_link_libraries(${TARGET} PUBLIC ${MOBILECORESERVICES})
else()
target_link_libraries(${TARGET} PUBLIC ${APPKIT})
target_link_libraries(${TARGET} PUBLIC ${QUARTZ})
endif()
target_link_libraries(${TARGET} PUBLIC ${IOSURFACE})
target_link_libraries(${TARGET} PUBLIC ${FOUNDATION})
target_link_libraries(${TARGET} PUBLIC ${CFNETWORK}) target_link_libraries(${TARGET} PUBLIC ${CFNETWORK})
target_link_libraries(${TARGET} PUBLIC ${SYSTEMCONFIGURATION}) target_link_libraries(${TARGET} PUBLIC ${SYSTEMCONFIGURATION})
endfunction() endfunction()

View File

@@ -1,9 +1,13 @@
function(FilterPlatformPaths sourcesVar) function(FilterPlatformPaths sourcesVar)
if (IOS) if (IOS)
list(FILTER ${sourcesVar} EXCLUDE REGEX ".*GLFW.*") list(FILTER ${sourcesVar} EXCLUDE REGEX ".*GLFW.*")
list(FILTER ${sourcesVar} EXCLUDE REGEX ".*[\\/]Host[\\/]MacOS[\\/].*")
else () else ()
list(FILTER ${sourcesVar} EXCLUDE REGEX ".*[\\/]Host[\\/]iOS[\\/].*") list(FILTER ${sourcesVar} EXCLUDE REGEX ".*[\\/]Host[\\/]iOS[\\/].*")
list(FILTER ${sourcesVar} EXCLUDE REGEX ".*[\\/]AR[\\/]Provider[\\/]ArKit[\\/].*")
endif ()
if (NOT APPLE)
list(FILTER ${sourcesVar} EXCLUDE REGEX ".*[\\/]Host[\\/]Apple[\\/].*")
endif () endif ()
if (NOT LINUX) if (NOT LINUX)
list(FILTER ${sourcesVar} EXCLUDE REGEX ".*[\\/]Host[\\/]Linux[\\/].*") list(FILTER ${sourcesVar} EXCLUDE REGEX ".*[\\/]Host[\\/]Linux[\\/].*")

View File

@@ -3,15 +3,42 @@ cmake_minimum_required(VERSION 3.28 FATAL_ERROR)
include(SetupVulkan) include(SetupVulkan)
include(Utils) include(Utils)
file(GLOB_RECURSE SUBDIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp") file(GLOB_RECURSE SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp")
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SUBDIRECTORIES}) if (IOS)
add_executable(examples main.cpp ${SUBDIRECTORIES}) file(GLOB_RECURSE SRC_IOS "${CMAKE_CURRENT_SOURCE_DIR}/Host/iOS/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/Host/iOS/*.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/Host/iOS/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Host/iOS/*.m" "${CMAKE_CURRENT_SOURCE_DIR}/Host/iOS/*.mm")
list(APPEND SOURCES ${SRC_IOS})
endif ()
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES})
target_include_directories(examples PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) set(MAIN_FILE main.cpp)
if (IOS)
set(MAIN_FILE Host/iOS/main.mm)
endif ()
add_executable(OpenVulkano_Examples ${MAIN_FILE} ${SOURCES})
set_property(TARGET OpenVulkano_Examples PROPERTY CXX_STANDARD 20)
target_include_directories(examples PRIVATE openVulkanoCpp) # Setup IOS
target_link_libraries(examples PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,openVulkanoCpp>") if(IOS)
SetupVulkan(examples) set(APP_BUNDLE_IDENTIFIER "eu.georgh93.openVulkano")
SetGlmDefines(examples) set(MACOSX_BUNDLE_INFO_STRING ${APP_BUNDLE_IDENTIFIER})
SetWarningSettings(examples) set(MACOSX_BUNDLE_GUI_IDENTIFIER ${APP_BUNDLE_IDENTIFIER})
LinkCurl(openVulkanoCpp) set(MACOSX_BUNDLE_BUNDLE_NAME ${APP_BUNDLE_IDENTIFIER})
set(CMAKE_OSX_DEPLOYMENT_TARGET ${DEPLOYMENT_TARGET})
set(CMAKE_XCODE_EMBED_FRAMEWORKS ON)
set_target_properties(OpenVulkano_Examples PROPERTIES XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "466MGSD624")
endif()
if(APPLE)
LinkAppleFrameworks(OpenVulkano_Examples)
endif ()
target_include_directories(OpenVulkano_Examples PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(OpenVulkano_Examples PRIVATE openVulkanoCpp)
target_link_libraries(OpenVulkano_Examples PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,openVulkanoCpp>")
SetupVulkan(OpenVulkano_Examples)
SetGlmDefines(OpenVulkano_Examples)
SetWarningSettings(OpenVulkano_Examples)

View File

@@ -0,0 +1,23 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "ExampleApps/CubesExampleApp.hpp"
#include "ExampleApps/MovingCubeApp.hpp"
#include "ExampleApps/TexturedCubeExampleApp.hpp"
#include "ExampleApps/BillboardExampleApp.hpp"
#include <vector>
namespace OpenVulkano
{
const std::vector<std::pair<const char*, IGraphicsApp*(*)()>> EXAMPLE_APPS = {
{ "Cubes Example App", &CubesExampleApp::Create },
{ "Moving Cube Example App", &MovingCubeApp::Create },
{ "Textured Cube Example App", &TexturedCubeExampleApp::Create },
{ "Billboard Example App", &BillboardExampleApp::Create }
};
}

View File

@@ -52,7 +52,7 @@ namespace OpenVulkano
m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/billboardFromSinglePoint"); m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/billboardFromSinglePoint");
m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::GEOMETRY, "Shader/billboardFromSinglePoint"); m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::GEOMETRY, "Shader/billboardFromSinglePoint");
m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/basicTexture"); m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/basic");
m_quadBillboardShader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); m_quadBillboardShader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription());
m_quadBillboardShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); m_quadBillboardShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING);
m_quadBillboardShader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING); m_quadBillboardShader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING);

View File

@@ -0,0 +1,19 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "Host/iOS/OpenVulkanoViewController.h"
@interface MainMenuViewController : UIViewController
@end
@interface ExampleViewController : OpenVulkanoViewController
@property(nonatomic, strong)OpenVulkanoView* renderView;
@property size_t exampleId;
@end

View File

@@ -0,0 +1,75 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#import "ExampleViewController.h"
#include "../../ExampleAppList.hpp"
@implementation MainMenuViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
CGFloat buttonHeight = 50;
CGFloat buttonSpacing = 10;
CGFloat topMargin = 50;
int i = 0;
for (const auto& app : OpenVulkano::EXAMPLE_APPS)
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(20,
topMargin + i * (buttonHeight + buttonSpacing),
self.view.bounds.size.width - 40,
buttonHeight);
[button setTitle:[NSString stringWithUTF8String:app.first] forState:UIControlStateNormal];
button.tag = i;
[button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
i++;
}
self.view.frame = [UIScreen mainScreen].bounds;
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
- (void)buttonPressed:(UIButton *)sender {
ExampleViewController* example = [[ExampleViewController alloc] init];
example.exampleId = sender.tag;
example.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:example animated:true completion:nil];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.view.frame = self.view.superview.bounds;
}
@end
@implementation ExampleViewController
- (void)viewDidLoad {
self.renderView = [[OpenVulkanoView alloc] initWithFrame:self.view.frame];
self.openVulkanoView = self.renderView;
[self.view addSubview:self.renderView];
[super viewDidLoad];
self.view.frame = [UIScreen mainScreen].bounds;
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.view.frame = self.view.superview.bounds;
self.renderView.frame = self.view.frame;
}
- (BOOL)prefersStatusBarHidden { return true; }
- (void *)makeGraphicsApp {
return OpenVulkano::EXAMPLE_APPS[self.exampleId].second();
}
@end

57
examples/Host/iOS/main.mm Normal file
View File

@@ -0,0 +1,57 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "ExampleViewController.h"
#import "Host/iOS/OpenVulkanoAppDelegate.h"
#include "Base/Logger.hpp"
@interface SceneDelegate : UIResponder<UIWindowSceneDelegate>
@end
@implementation SceneDelegate
@synthesize window = _window;
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
if ([scene isKindOfClass:[UIWindowScene class]]) {
UIWindowScene* wScene = (UIWindowScene*)scene;
self.window = [[UIWindow alloc] initWithWindowScene:wScene];
MainMenuViewController* rootViewController = [[MainMenuViewController alloc] init];
UINavigationController* navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
}
}
@end
@interface AppDelegate : OpenVulkanoAppDelegate
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
UISceneConfiguration *configuration = [[UISceneConfiguration alloc] initWithName:nil sessionRole:UIWindowSceneSessionRoleApplication];
configuration.delegateClass = SceneDelegate.class;
return configuration;
}
@end
int main(int argCount, char** args)
{
using namespace OpenVulkano;
Logger::SetupLogger();
@autoreleasepool
{
return UIApplicationMain(argCount, args, nil, NSStringFromClass([AppDelegate class]));
}
}

View File

@@ -5,10 +5,7 @@
*/ */
#include "Host/GraphicsAppManager.hpp" #include "Host/GraphicsAppManager.hpp"
#include "ExampleApps/CubesExampleApp.hpp" #include "ExampleAppList.hpp"
#include "ExampleApps/MovingCubeApp.hpp"
#include "ExampleApps/TexturedCubeExampleApp.hpp"
#include "ExampleApps/BillboardExampleApp.hpp"
#include <ftxui/component/captured_mouse.hpp> #include <ftxui/component/captured_mouse.hpp>
#include <ftxui/component/component.hpp> #include <ftxui/component/component.hpp>
@@ -22,12 +19,11 @@ using namespace OpenVulkano;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
std::vector<std::string> examples = { std::vector<std::string> examples;
"Cubes Example App", for (const auto& e : EXAMPLE_APPS)
"Moving Cube Example App", {
"Textured Cube Example App", examples.emplace_back(e.first);
"Billboard Example App" }
};
int selectedExample = 0; int selectedExample = 0;
ftxui::MenuOption option; ftxui::MenuOption option;
@@ -37,15 +33,9 @@ int main(int argc, char** argv)
screen.Loop(menu); screen.Loop(menu);
std::unique_ptr<IGraphicsApp> app; if (selectedExample >= examples.size()) throw std::runtime_error("Invalid menu selection!");
switch (selectedExample)
{ std::unique_ptr<IGraphicsApp> app( EXAMPLE_APPS[selectedExample].second() );
case 0: app = CubesExampleApp::CreateUnique(); break;
case 1: app = MovingCubeApp::CreateUnique(); break;
case 2: app = TexturedCubeExampleApp::CreateUnique(); break;
case 3: app = BillboardExampleApp::CreateUnique(); break;
default: throw std::runtime_error("Invalid menu selection!"); break;
}
GraphicsAppManager manager(app.get()); GraphicsAppManager manager(app.get());
manager.Run(); manager.Run();

View File

@@ -7,6 +7,8 @@
#include "ArFrame.hpp" #include "ArFrame.hpp"
#include "ArSession.hpp" #include "ArSession.hpp"
#include "ArRecorder.hpp" #include "ArRecorder.hpp"
#include <iostream>
#include <fstream>
namespace OpenVulkano::AR namespace OpenVulkano::AR
{ {
@@ -26,6 +28,11 @@ namespace OpenVulkano::AR
void ArFrame::SaveToFile(const std::filesystem::path& path, bool downsample) void ArFrame::SaveToFile(const std::filesystem::path& path, bool downsample)
{ {
m_session->GetRecorder().SaveToFile(shared_from_this(), path, downsample); m_session->GetRecorder().SaveToFile(shared_from_this(), path, downsample);
std::string metaContent = GetFrameMetadata().ToXML();
std::string metaPath = path.string() + std::string(".meta");
std::ofstream file (metaPath, std::ios::out);
file << metaContent;
file.close();
} }
const Scene::Texture* ArFrame::GetImageTexture() const Scene::Texture* ArFrame::GetImageTexture()

View File

@@ -122,7 +122,20 @@ namespace OpenVulkano::AR
[[nodiscard]] ArTrackingState GetTrackingState() const { return frameMetadata.trackingState; }; [[nodiscard]] ArTrackingState GetTrackingState() const { return frameMetadata.trackingState; };
[[nodiscard]] virtual Math::PoseF GetPose() const { return Math::PoseF(); }; //TODO [[nodiscard]] virtual Math::PoseF GetPose() const { return Math::PoseF(frameMetadata.transformation); };
[[nodiscard]] virtual Math::Vector3f GetEulerAngle() const {
return {
asin(-frameMetadata.transformation[2][1]),
atan2(frameMetadata.transformation[2][0], frameMetadata.transformation[2][2]),
atan2(frameMetadata.transformation[0][1], frameMetadata.transformation[1][1])
};
}
[[nodiscard]] virtual const Math::Vector3f_SIMD& GetPosition() const
{
return reinterpret_cast<const Math::Vector3f_SIMD&>(frameMetadata.transformation[3]);
}
[[nodiscard]] Math::Timestamp GetTimestamp() const { return frameMetadata.timestamp; }; [[nodiscard]] Math::Timestamp GetTimestamp() const { return frameMetadata.timestamp; };

View File

@@ -8,8 +8,13 @@
#include "Provider/Playback/ArSessionPlayback.hpp" #include "Provider/Playback/ArSessionPlayback.hpp"
#include "Provider/Network/ArSessionStream.h" #include "Provider/Network/ArSessionStream.h"
#ifdef __APPLE__ #ifdef __APPLE__
#include <TargetConditionals.h>
#if TARGET_OS_IOS == 1
#include "Provider/ArKit/ArSessionArKit.h" #include "Provider/ArKit/ArSessionArKit.h"
#else #else
#include "Provider/ArSessionNull.hpp"
#endif
#else
#ifdef ANDROID #ifdef ANDROID
#include "Provider/ArCore/ArSessionArCore.h" #include "Provider/ArCore/ArSessionArCore.h"
#else #else

View File

@@ -45,16 +45,22 @@ namespace OpenVulkano::AR
ArSessionType sessionType = ArSessionType::NATIVE; ArSessionType sessionType = ArSessionType::NATIVE;
bool uncompressed = true; bool uncompressed = true;
bool depthSupported = false; bool depthSupported = false;
bool supportsExposureLocking = false;
bool supportsWhitebalanceLocking = false;
bool hasFlashlight = false;
public: public:
ArSessionCapabilities() = default; ArSessionCapabilities() = default;
ArSessionCapabilities(const ArType type, const ArSessionType sessionType, const bool uncompressed, const bool depthSupported) ArSessionCapabilities(const ArType type, const ArSessionType sessionType, const bool uncompressed, const bool depthSupported, const bool supportsExposureLocking, const bool supportsWhitebalanceLocking, const bool hasFlash)
: type(type), sessionType(sessionType), uncompressed(uncompressed), depthSupported(depthSupported) : type(type), sessionType(sessionType), uncompressed(uncompressed), depthSupported(depthSupported), supportsExposureLocking(supportsExposureLocking), supportsWhitebalanceLocking(supportsWhitebalanceLocking), hasFlashlight(hasFlash)
{} {}
[[nodiscard]] bool IsUncompressed() const { return uncompressed; } [[nodiscard]] bool IsUncompressed() const { return uncompressed; }
[[nodiscard]] bool IsDepthSupported() const { return depthSupported; } [[nodiscard]] bool IsDepthSupported() const { return depthSupported; }
[[nodiscard]] bool IsExposureLockSupported() const { return supportsExposureLocking; }
[[nodiscard]] bool IsWhitebalanceLockSupported() const { return supportsWhitebalanceLocking; }
[[nodiscard]] bool HasFlashlight() const { return hasFlashlight; }
[[nodiscard]] bool IsNative() const { return sessionType == ArSessionType::NATIVE; } [[nodiscard]] bool IsNative() const { return sessionType == ArSessionType::NATIVE; }
[[nodiscard]] bool IsPlayback() const { return sessionType == ArSessionType::PLAYBACK; } [[nodiscard]] bool IsPlayback() const { return sessionType == ArSessionType::PLAYBACK; }
[[nodiscard]] bool IsStream() const { return sessionType == ArSessionType::NETWORK_STREAM; } [[nodiscard]] bool IsStream() const { return sessionType == ArSessionType::NETWORK_STREAM; }
@@ -214,6 +220,12 @@ namespace OpenVulkano::AR
*/ */
virtual void SetRenderer(IRenderer* renderer) = 0; virtual void SetRenderer(IRenderer* renderer) = 0;
virtual void LockExposureTime(bool locked) {};
virtual void LockWhitebalance(bool locked) {};
virtual void SetFlashlightOn(bool on) {};
/** /**
* Gets the capabilities for this ArSession. * Gets the capabilities for this ArSession.
* @return The capabilities for the current AR session. * @return The capabilities for the current AR session.

View File

@@ -14,7 +14,7 @@ namespace OpenVulkano::AR::ArKit
ArSessionCapabilities QueryNativeCapabilities() ArSessionCapabilities QueryNativeCapabilities()
{ {
bool supportsDepth = [ARWorldTrackingConfiguration supportsFrameSemantics:ARFrameSemanticSceneDepth]; bool supportsDepth = [ARWorldTrackingConfiguration supportsFrameSemantics:ARFrameSemanticSceneDepth];
ArSessionCapabilities capabilities(ArType::AR_KIT, ArSessionType::NATIVE, true, supportsDepth); ArSessionCapabilities capabilities(ArType::AR_KIT, ArSessionType::NATIVE, true, supportsDepth, true, true, true);
return capabilities; return capabilities;
} }
} }

View File

@@ -51,6 +51,10 @@ namespace OpenVulkano::AR::ArKit
void SetRenderer(IRenderer* renderer) override; void SetRenderer(IRenderer* renderer) override;
void LockExposureTime(bool locked) override;
void LockWhitebalance(bool locked) override;
void SetFlashlightOn(bool on) override;
protected: protected:
Scene::Texture * MakeTexture(ArFrame *frame) override; Scene::Texture * MakeTexture(ArFrame *frame) override;
@@ -66,6 +70,9 @@ namespace OpenVulkano::AR::ArKit
#else*/ #else*/
SpintexProtectedObject<std::shared_ptr<ArFrame>> m_frame; SpintexProtectedObject<std::shared_ptr<ArFrame>> m_frame;
//#endif //#endif
std::atomic_size_t m_frameId; std::atomic_size_t m_frameId = 0;
bool m_lockedConfiguration = false;
bool m_lockedExposure = false;
bool m_lockedWhitebalance = false;
}; };
} }

View File

@@ -22,6 +22,7 @@
#import <ARKit/ARConfiguration.h> #import <ARKit/ARConfiguration.h>
#import <ARKit/ARCamera.h> #import <ARKit/ARCamera.h>
#import <ARKit/ARKit.h> #import <ARKit/ARKit.h>
#import <AVFoundation/AVCaptureDevice.h>
#import <CoreVideo/CoreVideo.h> #import <CoreVideo/CoreVideo.h>
#import "ArKitDelegate.h" #import "ArKitDelegate.h"
@@ -138,6 +139,11 @@ namespace OpenVulkano::AR::ArKit
void ArSessionArKitInternal::Stop() void ArSessionArKitInternal::Stop()
{ {
if (m_lockedConfiguration)
{
m_lockedConfiguration = false;
[[ARWorldTrackingConfiguration configurableCaptureDeviceForPrimaryCamera] unlockForConfiguration];
}
OnStopped(); OnStopped();
[m_arSession pause]; [m_arSession pause];
/*#if (__cplusplus >= 202002L) /*#if (__cplusplus >= 202002L)
@@ -184,6 +190,27 @@ namespace OpenVulkano::AR::ArKit
} }
} }
void ArSessionArKitInternal::LockExposureTime(bool locked)
{
AVCaptureDevice* dev = [ARWorldTrackingConfiguration configurableCaptureDeviceForPrimaryCamera];
if (!m_lockedConfiguration) m_lockedConfiguration |=[dev lockForConfiguration:nil];
[dev setExposureMode: locked ? AVCaptureExposureModeLocked : AVCaptureExposureModeContinuousAutoExposure];
}
void ArSessionArKitInternal::LockWhitebalance(bool locked)
{
AVCaptureDevice* dev = [ARWorldTrackingConfiguration configurableCaptureDeviceForPrimaryCamera];
if (!m_lockedConfiguration) m_lockedConfiguration |=[dev lockForConfiguration:nil];
[dev setWhiteBalanceMode: locked ? AVCaptureWhiteBalanceModeLocked : AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance];
}
void ArSessionArKitInternal::SetFlashlightOn(bool on)
{
AVCaptureDevice* dev = [ARWorldTrackingConfiguration configurableCaptureDeviceForPrimaryCamera];
if (!m_lockedConfiguration) m_lockedConfiguration |=[dev lockForConfiguration:nil];
[dev setTorchMode: on ? AVCaptureTorchModeOn : AVCaptureTorchModeOff];
}
// AR Kit delegate events // AR Kit delegate events
void ArSessionArKitInternal::OnArNewFrame(ARSession* session, ARFrame* frame) void ArSessionArKitInternal::OnArNewFrame(ARSession* session, ARFrame* frame)

View File

@@ -17,7 +17,7 @@ namespace OpenVulkano::AR::Playback
ArSessionPlayback::ArSessionPlayback(const std::string& recordingPath, bool autoAdvance) ArSessionPlayback::ArSessionPlayback(const std::string& recordingPath, bool autoAdvance)
: ArSession(ArSessionMetadata(recordingPath)), recordingPath(recordingPath), autoAdvance(autoAdvance), playbackReader(recordingPath) : ArSession(ArSessionMetadata(recordingPath)), recordingPath(recordingPath), autoAdvance(autoAdvance), playbackReader(recordingPath)
{ {
capabilities = ArSessionCapabilities(metadata.type, ArSessionType::PLAYBACK, false, metadata.depthFormat != ArDepthFormat::UNAVAILABLE); capabilities = ArSessionCapabilities(metadata.type, ArSessionType::PLAYBACK, false, metadata.depthFormat != ArDepthFormat::UNAVAILABLE, false, false, false);
constants = { Math::Matrix4f(1), metadata.confidenceRange }; constants = { Math::Matrix4f(1), metadata.confidenceRange };
m_playbackReaderThread = std::thread([this](){ReadWorker();}); m_playbackReaderThread = std::thread([this](){ReadWorker();});

View File

@@ -227,12 +227,30 @@ namespace OpenVulkano
{} {}
void Notify(Arguments... args) const override void Notify(Arguments... args) const override
{
NotifyImpl(std::forward<Arguments>(args)...);
}
void NotifyImpl(Arguments... args) const
{ {
if (INamedEventProcessor::HasProcessor()) if (INamedEventProcessor::HasProcessor())
{ {
std::vector<INamedEventProcessor::Parameters> attributes; std::vector<INamedEventProcessor::Parameters> attributes;
attributes.reserve(sizeof...(Arguments)); attributes.reserve(sizeof...(Arguments));
if constexpr (!std::conjunction_v<std::is_enum<std::remove_reference_t<Arguments>>...>)
{
(attributes.emplace_back(args), ...); (attributes.emplace_back(args), ...);
}
else
{
auto fill = [&](auto&& arg) {
if constexpr (std::is_enum_v<std::remove_reference_t<decltype(arg)>>)
attributes.emplace_back(static_cast<int>(arg));
else
attributes.emplace_back(std::forward<decltype(arg)>(arg));
};
(fill(std::forward<Arguments>(args)), ...);
}
INamedEventProcessor::NotifyAll(m_name, attributes); INamedEventProcessor::NotifyAll(m_name, attributes);
} }
} }

View File

@@ -32,14 +32,14 @@ namespace OpenVulkano
{} {}
Observable(T&& initValue, const std::string& observableName) Observable(T&& initValue, const std::string& observableName)
: object(std::forward(initValue)), OnChange(observableName) : object(initValue), OnChange(observableName)
{} {}
template<typename = std::enable_if_t<std::is_copy_assignable_v<T>>> template<typename = std::enable_if_t<std::is_copy_assignable_v<T>>>
auto& operator = (const T& val) { object = val; Notify(); return *this; } auto& operator = (const T& val) { object = val; Notify(); return *this; }
template<typename = std::enable_if_t<std::is_move_assignable_v<T>>> template<typename = std::enable_if_t<std::is_move_assignable_v<T>>>
auto& operator = (T&& val) { object = std::forward(val); Notify(); return *this; } auto& operator = (T&& val) { object = val; Notify(); return *this; }
template<typename = std::enable_if_t<std::is_copy_assignable_v<T>>> template<typename = std::enable_if_t<std::is_copy_assignable_v<T>>>
operator T() const { return object; } operator T() const { return object; }
@@ -54,7 +54,9 @@ namespace OpenVulkano
bool operator >=(const T& other) const { return object >= other; } bool operator >=(const T& other) const { return object >= other; }
bool operator !() const { return !object; } bool operator !() const { return !object; }
operator bool() const { return object.operator bool(); } template<std::enable_if<std::is_convertible_v<T, bool>>>
operator bool() const { return static_cast<bool>(object); }
auto& operator ++() { ++object; Notify(); return *this; } auto& operator ++() { ++object; Notify(); return *this; }
auto& operator --() { --object; Notify(); return *this; } auto& operator --() { --object; Notify(); return *this; }
auto& operator ++(int) { object++; Notify(); return *this; } auto& operator ++(int) { object++; Notify(); return *this; }

View File

@@ -35,5 +35,8 @@ namespace OpenVulkano
virtual Scene::UI::Ui* GetActiveUi() = 0; virtual Scene::UI::Ui* GetActiveUi() = 0;
virtual IResourceManager* GetIResourceManager() = 0; virtual IResourceManager* GetIResourceManager() = 0;
virtual float GetLastQueriedDepthValue() = 0;
virtual void SetQueryDepthValue(const Math::Vector2f& depthCoordinates) = 0;
}; };
} }

View File

@@ -84,6 +84,9 @@ namespace OpenVulkano
[[nodiscard]] virtual uint32_t GetWindowId() const = 0; [[nodiscard]] virtual uint32_t GetWindowId() const = 0;
virtual void* GetNativeWindowHandle() = 0; virtual void* GetNativeWindowHandle() = 0;
virtual float GetContentScale() const { return 1; }
virtual float GetInterfaceOrientation() const { return 0; }
protected: protected:
static uint32_t CreateWindowId() static uint32_t CreateWindowId()
{ {

View File

@@ -46,6 +46,12 @@ namespace OpenVulkano
return result; return result;
} }
template<typename T, typename... N>
static auto MakeStdArray(N&&... args) -> std::array<T, sizeof...(args)>
{
return { std::forward<N>(args)... };
}
template<typename T, typename U> template<typename T, typename U>
static bool GetFlag(T var, U flag) static bool GetFlag(T var, U flag)
{ {

View File

@@ -15,22 +15,19 @@ configure_file(${CMAKE_SOURCE_DIR}/cmake/TryCompileShaders.cmake.in ${CMAKE_BINA
execute_process(COMMAND ${BASH_EXECUTABLE} CompileShaders.sh "${SHADER_OUTPUT_DEST}" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Scripts) execute_process(COMMAND ${BASH_EXECUTABLE} CompileShaders.sh "${SHADER_OUTPUT_DEST}" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Scripts)
file(GLOB GENERATED_SHADER_SOURCES "${SHADER_OUTPUT_DEST}/*") file(GLOB GENERATED_SHADER_SOURCES "${SHADER_OUTPUT_DEST}/*")
if(IOS)
set(CMAKE_Swift_LANGUAGE_VERSION 5.0)
enable_language(Swift)
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.mm" "${CMAKE_CURRENT_SOURCE_DIR}/*.m" "${CMAKE_CURRENT_SOURCE_DIR}/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.swift")
add_library(openVulkanoCpp STATIC main.m ${resources} ${GENERATED_SHADER_SOURCES})
else()
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
if (APPLE)
file(GLOB_RECURSE sources_obj CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.mm" "${CMAKE_CURRENT_SOURCE_DIR}/*.m")
list(APPEND sources ${sources_obj})
endif ()
file(GLOB SHADER_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/Shader/*) file(GLOB SHADER_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/Shader/*)
list(FILTER SHADER_SRC_FILES EXCLUDE REGEX ".*\\.(hpp|cpp)$") list(FILTER SHADER_SRC_FILES EXCLUDE REGEX ".*\\.(hpp|cpp)$")
add_library(openVulkanoCpp STATIC main.cpp ${SHADER_SRC_FILES} ${GENERATED_SHADER_SOURCES})
if (MSVC) add_library(openVulkanoCpp ${MAIN_FILE} ${SHADER_SRC_FILES} ${GENERATED_SHADER_SOURCES})
set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(TARGET openVulkanoCpp PROPERTY CXX_STANDARD 20)
source_group("Shaders" FILES ${SHADER_SRC_FILES}) source_group("Shaders" FILES ${SHADER_SRC_FILES})
endif()
endif()
FilterPlatformPaths(sources) FilterPlatformPaths(sources)
SetWarningSettings(openVulkanoCpp) SetWarningSettings(openVulkanoCpp)
@@ -39,25 +36,12 @@ SetGlmDefines(openVulkanoCpp)
target_sources(openVulkanoCpp PRIVATE ${sources}) target_sources(openVulkanoCpp PRIVATE ${sources})
target_include_directories(openVulkanoCpp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${SHADER_OUTPUT_DEST}) target_include_directories(openVulkanoCpp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${SHADER_OUTPUT_DEST})
# Setup IOS if(APPLE)
if(IOS)
set(APP_BUNDLE_IDENTIFIER "eu.georgh93.openVulkano")
set(MACOSX_BUNDLE_INFO_STRING ${APP_BUNDLE_IDENTIFIER})
set(MACOSX_BUNDLE_GUI_IDENTIFIER ${APP_BUNDLE_IDENTIFIER})
set(MACOSX_BUNDLE_BUNDLE_NAME ${APP_BUNDLE_IDENTIFIER})
set(CMAKE_OSX_DEPLOYMENT_TARGET "14.1") # The used ARKit features are only available starting with iOS 14
LinkAppleFrameworks(openVulkanoCpp) LinkAppleFrameworks(openVulkanoCpp)
endif () endif ()
if (WIN32) if (WIN32)
# Ws2
target_link_libraries(openVulkanoCpp PRIVATE Ws2_32) target_link_libraries(openVulkanoCpp PRIVATE Ws2_32)
set(CURL_STATIC_LIBS ${CMAKE_BINARY_DIR}/deps_curl/deps_curl)
file(GLOB_RECURSE LIBS "${CURL_STATIC_LIBS}/*.lib")
target_link_libraries(openVulkanoCpp PRIVATE ${LIBS})
endif () endif ()
SetupVulkan(openVulkanoCpp) SetupVulkan(openVulkanoCpp)
@@ -68,22 +52,15 @@ SetShaderDependency(openVulkanoCpp
if (NOT ANDROID AND NOT IOS) if (NOT ANDROID AND NOT IOS)
target_link_libraries(openVulkanoCpp PUBLIC glfw pugixml) target_link_libraries(openVulkanoCpp PUBLIC glfw pugixml)
target_link_libraries(openVulkanoCpp PUBLIC ftxui::screen ftxui::dom ftxui::component) target_link_libraries(openVulkanoCpp PUBLIC ftxui::screen ftxui::dom ftxui::component)
LinkCurl(openVulkanoCpp)
endif() endif()
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}/deps/INSTALL) target_link_libraries(openVulkanoCpp PUBLIC magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense units)
target_link_libraries(openVulkanoCpp PUBLIC magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense Boost::regex)
LinkCurl(openVulkanoCpp)
add_compile_definitions(LIBARCHIVE_STATIC)
add_compile_definitions(NOMINMAX)
add_compile_definitions("DEBUG=$<CONFIG:Debug>")
SetGlmDefines(openVulkanoCpp)
LinkAssimp(openVulkanoCpp) LinkAssimp(openVulkanoCpp)
LinkLibArchive(openVulkanoCpp) LinkLibArchive(openVulkanoCpp)
LinkLibJpegTurbo(openVulkanoCpp) LinkLibJpegTurbo(openVulkanoCpp)
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT openVulkanoCpp) SetGlmDefines(openVulkanoCpp)
add_compile_definitions(LIBARCHIVE_STATIC)
add_compile_definitions(NOMINMAX)
add_compile_definitions("DEBUG=$<CONFIG:Debug>")

View File

@@ -62,8 +62,8 @@ namespace OpenVulkano
if (vec != Math::Vector3f_SIMD (0)) if (vec != Math::Vector3f_SIMD (0))
{ {
if (Math::Utils::length2(vec) > 1.0f) if (Math::Utils::length2(vec) > 1.0f)
{ { //TODO only do this for keyboards
vec = Math::Utils::normalize(vec); //vec = Math::Utils::normalize(vec);
} }
const float timeScale = CURRENT_FRAME.frameTime; //TODO const float timeScale = CURRENT_FRAME.frameTime; //TODO
vec = vec * timeScale * 3.0f; // scale vector vec = vec * timeScale * 3.0f; // scale vector
@@ -149,12 +149,12 @@ namespace OpenVulkano
{ {
m_actionForward->BindKey(Input::InputKey::Controller::AXIS_LEFT_Y); m_actionForward->BindKey(Input::InputKey::Controller::AXIS_LEFT_Y);
m_actionForward->BindAxisButtons(Input::InputKey::Keyboard::KEY_W, Input::InputKey::Keyboard::KEY_S); m_actionForward->BindAxisButtons(Input::InputKey::Keyboard::KEY_W, Input::InputKey::Keyboard::KEY_S);
m_actionForward->BindKey(Input::InputKey::Touch::AXIS_PINCH, 0.2f); m_actionForward->BindKey(Input::InputKey::Touch::AXIS_PINCH, 0.3f);
m_actionSide->BindKey(Input::InputKey::Controller::AXIS_LEFT_X); m_actionSide->BindKey(Input::InputKey::Controller::AXIS_LEFT_X);
m_actionSide->BindAxisButtons(Input::InputKey::Keyboard::KEY_D, Input::InputKey::Keyboard::KEY_A); m_actionSide->BindAxisButtons(Input::InputKey::Keyboard::KEY_D, Input::InputKey::Keyboard::KEY_A);
m_actionSide->BindKey(Input::InputKey::Touch::AXIS_PAN_TWO_FINGERS_X, -0.03f); m_actionSide->BindKey(Input::InputKey::Touch::AXIS_PAN_TWO_FINGERS_X, -0.05f);
m_actionUp->BindAxisButtons(Input::InputKey::Keyboard::KEY_SPACE, Input::InputKey::Keyboard::KEY_LEFT_CONTROL); m_actionUp->BindAxisButtons(Input::InputKey::Keyboard::KEY_SPACE, Input::InputKey::Keyboard::KEY_LEFT_CONTROL);
m_actionUp->BindKey(Input::InputKey::Touch::AXIS_PAN_TWO_FINGERS_Y, 0.03f); m_actionUp->BindKey(Input::InputKey::Touch::AXIS_PAN_TWO_FINGERS_Y, 0.05f);
m_actionLookUp->BindKey(Input::InputKey::Controller::AXIS_RIGHT_Y); m_actionLookUp->BindKey(Input::InputKey::Controller::AXIS_RIGHT_Y);
m_actionLookUp->BindAxisButtons(Input::InputKey::Keyboard::KEY_DOWN, Input::InputKey::Keyboard::KEY_UP); m_actionLookUp->BindAxisButtons(Input::InputKey::Keyboard::KEY_DOWN, Input::InputKey::Keyboard::KEY_UP);
m_actionLookUp->BindKey(Input::InputKey::Touch::AXIS_PAN_Y, -0.001f); m_actionLookUp->BindKey(Input::InputKey::Touch::AXIS_PAN_Y, -0.001f);

View File

@@ -48,6 +48,7 @@ namespace OpenVulkano
Math::Matrix4f camTransformation = Math::Utils::toMat4(rot); Math::Matrix4f camTransformation = Math::Utils::toMat4(rot);
camTransformation[3] = Math::Vector4f(m_position, 1); camTransformation[3] = Math::Vector4f(m_position, 1);
GetCamera()->SetMatrix(camTransformation); GetCamera()->SetMatrix(camTransformation);
CURRENT_FRAME.needsRedraw = true;
} }
void FreeCamCameraController::SetDefaultKeybindings() void FreeCamCameraController::SetDefaultKeybindings()

View File

@@ -22,9 +22,10 @@ namespace OpenVulkano
{ {
auto [fileName, fileType] = Utils::SplitAtLastOccurrence(resourceName, '.'); auto [fileName, fileType] = Utils::SplitAtLastOccurrence(resourceName, '.');
NSString* filePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:fileName.c_str()] ofType:[NSString stringWithUTF8String:fileType.c_str()]]; NSString* filePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:fileName.c_str()] ofType:[NSString stringWithUTF8String:fileType.c_str()]];
if (filePath)
return Utils::ReadFile(std::string([filePath UTF8String])); return Utils::ReadFile(std::string([filePath UTF8String]));
} }
Logger::FILESYS->warn("Failed to find resource: '{}' in bundle", resourceName); Logger::FILESYS->warn("Failed to find resource: '{}' in bundle", resourceName);
return {0}; return {};
} }
} }

View File

@@ -16,6 +16,8 @@ namespace OpenVulkano
IWindowHandler* handler = nullptr; IWindowHandler* handler = nullptr;
void* caMetalLayer = nullptr; void* caMetalLayer = nullptr;
bool tickHandler = true; bool tickHandler = true;
float contentScale = 1;
float orientation = 0;
public: public:
void Init(RenderAPI::RenderApi renderApi) override {} void Init(RenderAPI::RenderApi renderApi) override {}
@@ -83,6 +85,14 @@ namespace OpenVulkano
void OnResize(uint32_t width, uint32_t height); void OnResize(uint32_t width, uint32_t height);
virtual float GetContentScale() const override { return contentScale; }
virtual float GetInterfaceOrientation() const override { return orientation; }
void SetContentScale(float scale) { contentScale = scale; }
void SetOrientation(float orientation) { this->orientation = orientation; }
void TickHandler(); void TickHandler();
}; };
} }

View File

@@ -159,12 +159,12 @@ namespace OpenVulkano
} }
else else
{ {
Logger::MANAGER->error("Cannot find constructor for named event %s", eventName); Logger::MANAGER->error("Cannot find constructor for named event {}", eventName);
} }
} }
else else
{ {
Logger::MANAGER->debug("Cannot find implementation for named event %s", eventName); Logger::MANAGER->debug("Cannot find implementation for named event {}", eventName);
} }
} }
} }

View File

@@ -45,7 +45,7 @@ namespace OpenVulkano
if (w > 0 && h > 0) if (w > 0 && h > 0)
io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);*/ io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);*/
io.DisplaySize = { static_cast<float>(m_window->GetWidth()), static_cast<float>(m_window->GetHeight()) }; io.DisplaySize = { static_cast<float>(m_window->GetWidth()), static_cast<float>(m_window->GetHeight()) };
io.DisplayFramebufferScale = { 1, 1 }; io.DisplayFramebufferScale = { m_window->GetContentScale(), m_window->GetContentScale() };
//if (bd->WantUpdateMonitors) //if (bd->WantUpdateMonitors)
//ImGui_ImplGlfw_UpdateMonitors(); //ImGui_ImplGlfw_UpdateMonitors();

View File

@@ -0,0 +1,183 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "Host/SystemInfo.hpp"
#include "Base/Logger.hpp"
#include <sstream>
#include <mach/mach.h>
#include <os/proc.h>
#import <Foundation/NSString.h>
#import <Foundation/NSProcessInfo.h>
namespace OpenVulkano
{
Event<> SystemInfo::OnLowPowerModeChanged;
Event<> SystemInfo::OnBatteryStateChanged;
Event<> SystemInfo::OnBatteryLevelChanged;
Event<> SystemInfo::OnDeviceOrientationChanged;
size_t SystemInfo::GetSystemRam()
{
return [NSProcessInfo processInfo].physicalMemory;
}
size_t SystemInfo::GetSystemRamAvailable()
{
return 0; //TODO
}
size_t SystemInfo::GetAppRamMax()
{
return GetAppRamAvailable() + GetAppRamUsed();
}
size_t SystemInfo::GetAppVirtualMemoryMax()
{
return INT64_MAX;
}
size_t SystemInfo::GetAppRamAvailable()
{
return 0; //TODO
}
size_t SystemInfo::GetAppRamUsed()
{
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
if( kerr == KERN_SUCCESS )
{
return info.resident_size;
}
Logger::PERF->error("Failed to read memory consumption: {}", mach_error_string(kerr));
return 0;
}
std::string SystemInfo::GetUserName()
{
return "";
}
std::string SystemInfo::GetHostName()
{
return [[NSProcessInfo processInfo].hostName UTF8String];
}
std::string SystemInfo::GetDeviceName()
{
return "Mac"; //TODO
}
std::string SystemInfo::GetDeviceVendorName()
{
return "Apple";
}
std::string SystemInfo::GetDeviceModelName()
{
return ""; //TODO
}
std::string SystemInfo::GetOsName()
{
return ""; //TODO
}
OsVersion SystemInfo::GetOsVersion()
{
NSOperatingSystemVersion osVersion = [NSProcessInfo processInfo].operatingSystemVersion;
return { static_cast<int>(osVersion.majorVersion), static_cast<int>(osVersion.minorVersion), static_cast<int>(osVersion.patchVersion), 0 };
}
std::string SystemInfo::GetOsNameHumanReadable()
{
std::stringstream name;
name << GetOsName() << ' ' << GetOsVersion().major;
return name.str();
}
DeviceType SystemInfo::GetDeviceType()
{
return DeviceType::PC;
}
size_t SystemInfo::GetCpuCoreCount()
{
return [NSProcessInfo processInfo].processorCount;
}
size_t SystemInfo::GetCpuThreadCount()
{
return [NSProcessInfo processInfo].activeProcessorCount;
}
int32_t SystemInfo::GetCpuTemperature()
{
switch([NSProcessInfo processInfo].thermalState)
{
case NSProcessInfoThermalStateNominal: return 20;
case NSProcessInfoThermalStateFair: return 50;
case NSProcessInfoThermalStateSerious: return 80;
case NSProcessInfoThermalStateCritical: return 100;
}
return -1;
}
CpuThermalState SystemInfo::GetCpuThermalState()
{
switch([NSProcessInfo processInfo].thermalState)
{
case NSProcessInfoThermalStateNominal: return CpuThermalState::Normal;
case NSProcessInfoThermalStateFair: return CpuThermalState::Fair;
case NSProcessInfoThermalStateSerious: return CpuThermalState::Serious;
case NSProcessInfoThermalStateCritical: return CpuThermalState::Critical;
}
return CpuThermalState::Normal;
}
bool SystemInfo::IsDeviceInLowPowerMode()
{
return [NSProcessInfo processInfo].lowPowerModeEnabled;
}
void SystemInfo::EnableEnergyEvents()
{
//TODO
}
BatteryState SystemInfo::GetDeviceBatteryState()
{
return BatteryState::Unavailable; //TODO
}
float SystemInfo::GetDeviceBatteryLevel()
{
return 0; //TODO
}
bool SystemInfo::IsMultitaskingSupported()
{
return true;
}
DeviceOrientation SystemInfo::GetDeviceOrientation()
{
return DeviceOrientation::LandscapeRight;
}
void SystemInfo::EnableDeviceOrientationEvents()
{
//TODO?
}
InterfaceOrientation SystemInfo::GetInterfaceOrientation()
{
return InterfaceOrientation::Landscape; //TODO?
}
}

View File

@@ -11,7 +11,7 @@
@implementation OpenVulkanoOrientationLockableViewController @implementation OpenVulkanoOrientationLockableViewController
-(id)init { -(id)init {
[super init]; self = [super init];
_rotationLockedView = nil; _rotationLockedView = nil;
return self; return self;
} }

View File

@@ -21,4 +21,6 @@
-(void)WillDisappear; -(void)WillDisappear;
-(void)DidDisappear; -(void)DidDisappear;
-(void)DidUnload; -(void)DidUnload;
-(void)SetInterfaceOrientation:(float)orientation;
@end @end

View File

@@ -9,7 +9,7 @@
#include "Base/Logger.hpp" #include "Base/Logger.hpp"
#include "Input/Touch/InputDeviceTouch.hpp" #include "Input/Touch/InputDeviceTouch.hpp"
#include "Input/InputManager.hpp" #include "Input/InputManager.hpp"
#include "MetalViewWindow.h" #include "Host/Apple/MetalViewWindow.h"
#include <map> #include <map>
#import <MetalKit/MTKView.h> #import <MetalKit/MTKView.h>
@@ -35,6 +35,7 @@ using namespace OpenVulkano;
- (void) mtkView:(MTKView *) view drawableSizeWillChange:(CGSize) size - (void) mtkView:(MTKView *) view drawableSizeWillChange:(CGSize) size
{ {
window->SetContentScale(UIScreen.mainScreen.nativeScale);
window->OnResize(size.width, size.height); window->OnResize(size.width, size.height);
} }
@@ -83,8 +84,7 @@ using namespace OpenVulkano;
- (void)commonInit { - (void)commonInit {
[self setMultipleTouchEnabled:YES]; [self setMultipleTouchEnabled:YES];
self.contentScaleFactor = UIScreen.mainScreen.nativeScale / 1.5f; self.contentScaleFactor = UIScreen.mainScreen.nativeScale;
auto size = self.bounds.size; auto size = self.bounds.size;
auto sizeX = size.width * self.contentScaleFactor; auto sizeX = size.width * self.contentScaleFactor;
auto sizeY = size.height * self.contentScaleFactor; auto sizeY = size.height * self.contentScaleFactor;
@@ -126,10 +126,17 @@ using namespace OpenVulkano;
auto size = self.bounds.size; auto size = self.bounds.size;
auto sizeX = size.width * self.contentScaleFactor; auto sizeX = size.width * self.contentScaleFactor;
auto sizeY = size.height * self.contentScaleFactor; auto sizeY = size.height * self.contentScaleFactor;
m_window.SetContentScale(self.contentScaleFactor);
m_window.OnResize(sizeX, sizeY); m_window.OnResize(sizeX, sizeY);
} }
} }
- (void)SetInterfaceOrientation:(float)orientation
{
m_window.SetOrientation(orientation);
}
- (Math::Vector2f)getTouchPosition:(UITouch*)touch - (Math::Vector2f)getTouchPosition:(UITouch*)touch
{ {
CGPoint uitouchLocation = [touch locationInView:touch.view]; CGPoint uitouchLocation = [touch locationInView:touch.view];

View File

@@ -17,7 +17,7 @@ namespace OpenVulkano::Scene
{ {
public: public:
ICloseable* renderCamera = nullptr; ICloseable* renderCamera = nullptr;
static constexpr inline size_t SIZE = sizeof(Math::Matrix4f) * 3 + sizeof(Math::Vector4f) + sizeof(float) * 8 + 16; static constexpr inline size_t SIZE = sizeof(Math::Matrix4f) * 3 + sizeof(Math::Vector4f) + sizeof(float) * 12;
static constexpr inline DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_UNIFORM_BUFFER_DYNAMIC, 1, ShaderProgramType::ALL_GRAPHICS }; static constexpr inline DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_UNIFORM_BUFFER_DYNAMIC, 1, ShaderProgramType::ALL_GRAPHICS };
protected: protected:
@@ -26,7 +26,8 @@ namespace OpenVulkano::Scene
float m_nearPlane, m_farPlane, m_width, m_height; float m_nearPlane, m_farPlane, m_width, m_height;
float m_fov = 0, m_aspect = 0, m_scaleFactor = 0, m_perPixelScaleFactor = 0; float m_fov = 0, m_aspect = 0, m_scaleFactor = 0, m_perPixelScaleFactor = 0;
float m_contentScaleFactor = 1, m_zoom = 1; // For use with ortho camera float m_contentScaleFactor = 1, m_zoom = 1; // For use with ortho camera
std::array<uint8_t, 8> m_userData{}; float m_interfaceOrientation = 0;
float m_padding = 0; //Unused
Camera() : m_nearPlane(0), m_farPlane(0), m_width(0), m_height(0) {} Camera() : m_nearPlane(0), m_farPlane(0), m_width(0), m_height(0) {}
@@ -55,32 +56,19 @@ namespace OpenVulkano::Scene
virtual void SetSize(const float width, const float height) virtual void SetSize(const float width, const float height)
{ {
if (m_width == width && m_height == height) return; if (m_width == width && m_height == height) [[likely]] return;
m_width = width; m_width = width;
m_height = height; m_height = height;
UpdateProjectionMatrix(); UpdateProjectionMatrix();
} }
void SetNearPlane(float nearPlane) void SetNearPlane(float nearPlane) { m_nearPlane = nearPlane; }
{
m_nearPlane = nearPlane;
}
void SetFarPlane(float farPlane) void SetFarPlane(float farPlane) { m_farPlane = farPlane; }
{
m_farPlane = farPlane;
}
[[nodiscard]] float NearPlane() const { return m_nearPlane; }
[[nodiscard]] float NearPlane() const [[nodiscard]] float FarPlane() const { return m_farPlane; }
{
return m_nearPlane;
}
[[nodiscard]] float FarPlane() const
{
return m_farPlane;
}
void SetContentScaleFactor(float contentScale = 1) void SetContentScaleFactor(float contentScale = 1)
{ {
@@ -89,6 +77,10 @@ namespace OpenVulkano::Scene
[[nodiscard]] float GetContentScaleFactor() const { return 1.0f / m_contentScaleFactor; } [[nodiscard]] float GetContentScaleFactor() const { return 1.0f / m_contentScaleFactor; }
void SetInterfaceOrientation(float orientation) { m_interfaceOrientation = orientation; }
float GetInterfaceOrientation() const { return m_interfaceOrientation; }
void SetZoom(float zoom) { m_zoom = 1.0f / zoom; } void SetZoom(float zoom) { m_zoom = 1.0f / zoom; }
[[nodiscard]] float GetZoom() const { return 1.0f / m_zoom; } [[nodiscard]] float GetZoom() const { return 1.0f / m_zoom; }
@@ -126,10 +118,7 @@ namespace OpenVulkano::Scene
return m_viewProjection; return m_viewProjection;
} }
[[nodiscard]] const Math::Vector4f& GetPosition() const [[nodiscard]] const Math::Vector4f& GetPosition() const { return m_camPosition; }
{
return m_camPosition;
}
[[nodiscard]] Math::Vector3f GetRightVector() const [[nodiscard]] Math::Vector3f GetRightVector() const
{ {
@@ -150,22 +139,19 @@ namespace OpenVulkano::Scene
[[nodiscard]] const Math::Matrix4f& GetViewMatrix() const { return m_view; } [[nodiscard]] const Math::Matrix4f& GetViewMatrix() const { return m_view; }
[[nodiscard]] Math::Frustum GetFrustum() const [[nodiscard]] const Math::Matrix4f& GetProjectionMatrix() const { return m_projection; }
{
return {m_viewProjection};
}
/** [[nodiscard]] Math::Frustum GetFrustum() const { return {m_viewProjection}; }
* The 16 byte of user data can be used to transmit additional data about the camera to the shader.
* @return reference to the custom data array
*/
[[nodiscard]] std::array<uint8_t, 8>& GetUserData() { return m_userData; }
[[nodiscard]] float GetScaleFactor() const { return m_scaleFactor; } [[nodiscard]] float GetScaleFactor() const { return m_scaleFactor; }
[[nodiscard]] float GetPixelScaleFactor() const { return m_perPixelScaleFactor; } [[nodiscard]] float GetPixelScaleFactor() const { return m_perPixelScaleFactor; }
[[nodiscard]] virtual bool IsPerspective() const { return false; } [[nodiscard]] virtual bool IsPerspective() const { return false; }
[[nodiscard]] virtual bool IsOrtho() const { return false; } [[nodiscard]] virtual bool IsOrtho() const { return false; }
float GetWidth() const { return m_width; }
float GetHeight() const { return m_height; }
Math::Vector2f GetSize() const { return { m_width, m_height }; }
}; };
class PerspectiveCamera : public Camera class PerspectiveCamera : public Camera
@@ -202,6 +188,7 @@ namespace OpenVulkano::Scene
void SetSize(const float width, const float height) override void SetSize(const float width, const float height) override
{ {
if (m_width == width && m_height == height) [[likely]] return;
m_aspect = width / height; m_aspect = width / height;
Camera::SetSize(width, height); Camera::SetSize(width, height);
m_perPixelScaleFactor = m_height / m_scaleFactor; m_perPixelScaleFactor = m_height / m_scaleFactor;
@@ -235,20 +222,14 @@ namespace OpenVulkano::Scene
m_perPixelScaleFactor = m_height / m_scaleFactor; m_perPixelScaleFactor = m_height / m_scaleFactor;
} }
[[nodiscard]] float GetFov() const [[nodiscard]] float GetFov() const { return Math::Utils::degrees(m_fov); }
{
return Math::Utils::degrees(m_fov);
}
[[nodiscard]] float GetFovX() const [[nodiscard]] float GetFovX() const
{ {
return 2.0f * atanf(tanf(GetFov() * 0.5f) * m_aspect); return 2.0f * atanf(tanf(GetFov() * 0.5f) * m_aspect);
} }
[[nodiscard]] float GetFovRad() const [[nodiscard]] float GetFovRad() const { return m_fov; }
{
return m_fov;
}
[[nodiscard]] float GetFovXRad() const [[nodiscard]] float GetFovXRad() const
{ {

View File

@@ -307,4 +307,48 @@ namespace OpenVulkano::Scene
return result; return result;
} }
Geometry GeometryFactory::MakeArchStrip(float radius, float width, float endRadius, int segments, const Math::Vector4f& color, float endVCoord, bool indexBuffer)
{
Geometry result;
segments = std::max(2, segments);
result.Init(2 * segments, indexBuffer ? 6 * segments : 0);
const float segmentAngle = endRadius / static_cast<float>(segments - 1);
width /= 2;
const float segmentV = endVCoord / (segments - 1);
float segV = 0;
for(int i = 0, seg = 0; seg < segments; seg++)
{
float angle = seg * segmentAngle;
float z = std::cos(angle) * radius;
float y = std::sin(angle) * radius;
//TODO normals
result.vertices[i].color = color;
result.vertices[i++].Set(width, y, z, +0, +0, +1, +1, +segV);
result.vertices[i].color = color;
result.vertices[i++].Set(-width, y, z, +0, +0, +1, +0, +segV);
segV += segmentV;
}
if (indexBuffer)
{
uint32_t* indices = new uint32_t[result.GetIndexCount()];
for (uint32_t i = 0, segment = 0; segment < segments; ++segment)
{
uint32_t first = segment * 2;
uint32_t second = first + 1;
indices[i++] = first;
indices[i++] = second;
indices[i++] = first + 2;
indices[i++] = first + 2;
indices[i++] = second;
indices[i++] = second + 2;
}
result.SetIndices(indices, result.GetIndexCount());
}
return result;
}
} }

View File

@@ -20,5 +20,6 @@ namespace OpenVulkano::Scene
static Geometry MakeTriangle(const Math::Vector3f& p1, const Math::Vector3f& p2, const Math::Vector3f& p3, const Math::Vector4f& color = Math::Vector4f(1)); static Geometry MakeTriangle(const Math::Vector3f& p1, const Math::Vector3f& p2, const Math::Vector3f& p3, const Math::Vector4f& color = Math::Vector4f(1));
static Geometry MakeCylinder(float radius, float height, uint32_t segments, const Math::Vector4f& color = Math::Vector4f(1)); static Geometry MakeCylinder(float radius, float height, uint32_t segments, const Math::Vector4f& color = Math::Vector4f(1));
static Geometry MakePyramid(float baseLength = 1, float height = 1, const Math::Vector4f& color = Math::Vector4f(1)); static Geometry MakePyramid(float baseLength = 1, float height = 1, const Math::Vector4f& color = Math::Vector4f(1));
static Geometry MakeArchStrip(float radius = 1, float width = 0.2, float endRadius = std::numbers::pi, int segments = 16, const Math::Vector4f& color = Math::Vector4f(1), float endVCoord = 1, bool indexBuffer = true);
}; };
} }

View File

@@ -25,6 +25,7 @@ namespace OpenVulkano::Scene
m_shader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/background"); m_shader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/background");
m_shader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING); m_shader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING);
m_shader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); m_shader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING);
m_shader.depthCompareOp = CompareOp::LESS_OR_EQUAL;
SetShader(&m_shader); SetShader(&m_shader);
m_intrinsicsBuffer.Init(sizeof(Math::CameraIntrinsicWithResolution), &FALLBACK_INTRINSICS); m_intrinsicsBuffer.Init(sizeof(Math::CameraIntrinsicWithResolution), &FALLBACK_INTRINSICS);
m_intrinsicsBuffer.updateFrequency = UpdateFrequency::Always; m_intrinsicsBuffer.updateFrequency = UpdateFrequency::Always;

View File

@@ -16,6 +16,8 @@ namespace OpenVulkano::Scene
m_shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/grid"); m_shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/grid");
m_shader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/grid"); m_shader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/grid");
m_shader.alphaBlend = true; m_shader.alphaBlend = true;
m_shader.depthTest = true;
m_shader.depthWrite = false;
SetShader(&m_shader); SetShader(&m_shader);
} }

View File

@@ -0,0 +1,19 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "SamplerConfig.hpp"
namespace OpenVulkano::Scene
{
const SamplerConfig SamplerConfig::DEFAULT;
const SamplerConfig SamplerConfig::NEAREST(TextureSamplerFilter::NEAREST, TextureSamplerFilter::NEAREST);
const SamplerConfig SamplerConfig::LINEAR(TextureSamplerFilter::LINEAR, TextureSamplerFilter::NEAREST);
const SamplerConfig SamplerConfig::BILINEAR(TextureSamplerFilter::LINEAR, TextureSamplerFilter::LINEAR);
const SamplerConfig SamplerConfig::TIRILINEAR(TextureSamplerFilter::LINEAR, TextureSamplerFilter::LINEAR, TextureSamplerMipmapMode::LINEAR);
const SamplerConfig SamplerConfig::ANISOTROPIC_LOW(TextureSamplerFilter::LINEAR, TextureSamplerFilter::LINEAR, TextureSamplerMipmapMode::LINEAR, true, 4);
const SamplerConfig SamplerConfig::ANISOTROPIC_HIGH(TextureSamplerFilter::LINEAR, TextureSamplerFilter::LINEAR, TextureSamplerMipmapMode::LINEAR, true, 16);
const SamplerConfig SamplerConfig::ANISOTROPIC_PRO(TextureSamplerFilter::LINEAR, TextureSamplerFilter::LINEAR, TextureSamplerMipmapMode::LINEAR, true, 32);
}

View File

@@ -0,0 +1,104 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <cinttypes>
#include <compare>
namespace OpenVulkano::Scene
{
enum class TextureSamplerFilter : int
{
NEAREST = 0,
LINEAR = 1,
CUBIC = 1000015000
};
enum class TextureSamplerEdgeMode : int
{
REPEAT = 0,
MIRRORED_REPEAT = 1,
CLAMP_TO_EDGE = 2,
CLAMP_TO_BORDER = 3,
MIRROR_CLAMP_TO_EDGE = 4
};
enum class TextureSamplerMipmapMode : int
{
NEAREST = 0,
LINEAR = 1
};
class SamplerConfig final
{
public:
using bool32_t = uint32_t;
private:
uint32_t type = 31; // To allow casting to vulkan struct
const void* next = nullptr; // To allow casting to vulkan struct
public:
uint32_t flags = 0;
TextureSamplerFilter magFilter = TextureSamplerFilter::NEAREST;
TextureSamplerFilter minFilter = TextureSamplerFilter::NEAREST;
TextureSamplerMipmapMode mipmapMode = TextureSamplerMipmapMode::NEAREST;
TextureSamplerEdgeMode edgeModeU = TextureSamplerEdgeMode::REPEAT;
TextureSamplerEdgeMode edgeModeV = TextureSamplerEdgeMode::REPEAT;
TextureSamplerEdgeMode edgeModeW = TextureSamplerEdgeMode::REPEAT;
float mipLoadBias = 0;
bool32_t anisotropyEnabled = false;
float maxAnisotropy = 0;
bool32_t compareEnabled = false;
uint32_t compareOp = 0; //TODO
float minLod = 0, maxLod = 0;
uint32_t borderColor = 0;
bool32_t unnormalizedCoordinates = false;
SamplerConfig(TextureSamplerEdgeMode edgeMode, TextureSamplerMipmapMode mipmapMode = TextureSamplerMipmapMode::NEAREST,
TextureSamplerFilter magFilter = TextureSamplerFilter::NEAREST, TextureSamplerFilter minFilter = TextureSamplerFilter::NEAREST)
: magFilter(magFilter), minFilter(minFilter), mipmapMode(mipmapMode), edgeModeU(edgeMode), edgeModeV(edgeMode), edgeModeW(edgeMode)
{}
SamplerConfig(uint32_t flags = 0, TextureSamplerFilter magFilter = TextureSamplerFilter::LINEAR,
TextureSamplerFilter minFilter = TextureSamplerFilter::LINEAR,
TextureSamplerMipmapMode mipmapMode = TextureSamplerMipmapMode::NEAREST,
TextureSamplerEdgeMode edgeModeU = TextureSamplerEdgeMode::REPEAT,
TextureSamplerEdgeMode edgeModeV = TextureSamplerEdgeMode::REPEAT,
TextureSamplerEdgeMode edgeModeW = TextureSamplerEdgeMode::REPEAT,
float mipLoadBias = 0, bool32_t anisotropyEnabled = false, float maxAnisotropy = 0,
bool32_t compareEnabled = false, uint32_t compareOp = 0, //TODO
float minLod = 0, float maxLod = 0, uint32_t borderColor = 0, bool32_t unnormalizedCoordinates = false)
: flags(flags), magFilter(magFilter), minFilter(minFilter), mipmapMode(mipmapMode)
, edgeModeU(edgeModeU), edgeModeV(edgeModeV), edgeModeW(edgeModeW)
, mipLoadBias(mipLoadBias), anisotropyEnabled(anisotropyEnabled), maxAnisotropy(maxAnisotropy)
, compareEnabled(compareEnabled), compareOp(compareOp)
, minLod(minLod), maxLod(maxLod), borderColor(borderColor), unnormalizedCoordinates(unnormalizedCoordinates)
{}
SamplerConfig(TextureSamplerFilter magFilter, TextureSamplerFilter minFilter = TextureSamplerFilter::LINEAR,
TextureSamplerMipmapMode mipmapMode = TextureSamplerMipmapMode::NEAREST,
bool32_t anisotropyEnabled = false, float maxAnisotropy = 0)
: magFilter(magFilter), minFilter(minFilter), mipmapMode(mipmapMode), anisotropyEnabled(anisotropyEnabled), maxAnisotropy(maxAnisotropy)
{}
auto operator <=>(const SamplerConfig& other) const = default;
public:
// Default configs
static const SamplerConfig DEFAULT;
static const SamplerConfig NEAREST;
static const SamplerConfig LINEAR;
static const SamplerConfig BILINEAR;
static const SamplerConfig TIRILINEAR;
static const SamplerConfig ANISOTROPIC_LOW;
static const SamplerConfig ANISOTROPIC_HIGH;
// Not supported on most consumer grphics cards!
static const SamplerConfig ANISOTROPIC_PRO;
};
}

View File

@@ -40,6 +40,18 @@ namespace OpenVulkano::Scene
PATCH_LIST PATCH_LIST
}; };
enum class CompareOp : uint32_t
{
NEVER = 0,
LESS = 1,
EQUAL = 2,
LESS_OR_EQUAL = 3,
GREATER = 4,
NOT_EQUAL = 5,
GREATER_OR_EQUAL = 6,
ALWAYS = 7
};
struct ShaderProgram struct ShaderProgram
{ {
ShaderProgramType type; ShaderProgramType type;
@@ -77,12 +89,14 @@ namespace OpenVulkano::Scene
Topology topology = Topology::TRIANGLE_LIST; Topology topology = Topology::TRIANGLE_LIST;
CullMode cullMode = CullMode::BACK; CullMode cullMode = CullMode::BACK;
ICloseable* renderShader = nullptr; ICloseable* renderShader = nullptr;
CompareOp depthCompareOp = CompareOp::LESS;
bool alphaBlend = false; // TODO allow fine control over blending bool alphaBlend = false; // TODO allow fine control over blending
bool depthTest = true; bool depthTest = true;
bool depthWrite = true; bool depthWrite = true;
bool dynamicViewport = true; // If disabled the swapchains fullscreen viewport will always be used, regardless of framebuffer or viewport
Shader() = default; Shader() = default;
~Shader() override { /*if (renderShader) Shader::Close();*/ } ~Shader() override { if (renderShader) Shader::Close(); }
Shader& AddShaderProgram(const ShaderProgram& shaderProgram) Shader& AddShaderProgram(const ShaderProgram& shaderProgram)
{ {

View File

@@ -8,7 +8,7 @@
namespace OpenVulkano::Scene namespace OpenVulkano::Scene
{ {
Texture Texture::PLACEHOLDER = Texture(true); Texture Texture::PLACEHOLDER = Texture(&SamplerConfig::NEAREST, true);
void Texture::MakePlaceholder(uint32_t width, uint32_t height, Math::Vector4uc color1, Math::Vector4uc color2) void Texture::MakePlaceholder(uint32_t width, uint32_t height, Math::Vector4uc color1, Math::Vector4uc color2)
{ {
@@ -25,5 +25,6 @@ namespace OpenVulkano::Scene
resolution = {width, height, 1}; resolution = {width, height, 1};
size = sizeof(Math::Vector4uc) * width * height; size = sizeof(Math::Vector4uc) * width * height;
format = DataFormat::B8G8R8A8_UNORM; format = DataFormat::B8G8R8A8_UNORM;
m_samplerConfig = &SamplerConfig::NEAREST;
} }
} }

View File

@@ -7,6 +7,7 @@
#pragma once #pragma once
#include "UpdateFrequency.hpp" #include "UpdateFrequency.hpp"
#include "SamplerConfig.hpp"
#include "Base/ICloseable.hpp" #include "Base/ICloseable.hpp"
#include "Math/Math.hpp" #include "Math/Math.hpp"
#include "DataFormat.hpp" #include "DataFormat.hpp"
@@ -32,10 +33,13 @@ namespace OpenVulkano::Scene
size_t size = 0; size_t size = 0;
Math::Vector3ui resolution = {0,0,0}; Math::Vector3ui resolution = {0,0,0};
DataFormat format = DataFormat::B8G8R8A8_UNORM; DataFormat format = DataFormat::B8G8R8A8_UNORM;
bool updated = true;
UpdateFrequency updateFrequency = UpdateFrequency::Never; UpdateFrequency updateFrequency = UpdateFrequency::Never;
const SamplerConfig* m_samplerConfig;
bool updated = true;
Texture(bool placeholder = false) { if (placeholder) MakePlaceholder(); } Texture(const SamplerConfig* samplerConfig = &SamplerConfig::DEFAULT, bool placeholder = false)
: m_samplerConfig(samplerConfig)
{ if (placeholder) MakePlaceholder(); }
~Texture() ~Texture()
{ {

View File

@@ -27,10 +27,9 @@ layout(set = 2, binding = 0) uniform RealCameraData
layout(location = 0) out vec2 textureCoordinates; layout(location = 0) out vec2 textureCoordinates;
layout(location = 1) out float scaleOut; layout(location = 1) out float scaleOut;
const float FLOAT_MAX_LESS_THAN_1 = 0.999999940395355224609;
// Background plane positions are in clipped space // Background plane positions are in clipped space
const vec4 PLANE[4] = vec4[]( const vec4 PLANE[4] = vec4[](
vec4(1, -1, FLOAT_MAX_LESS_THAN_1, 1), vec4(-1, -1, FLOAT_MAX_LESS_THAN_1, 1), vec4(1, 1, FLOAT_MAX_LESS_THAN_1, 1), vec4(-1, 1, FLOAT_MAX_LESS_THAN_1, 1) vec4(1, -1, 1, 1), vec4(-1, -1, 1, 1), vec4(1, 1, 1, 1), vec4(-1, 1, 1, 1)
); );
const vec2 TEX_COORDS[4] = vec2[]( const vec2 TEX_COORDS[4] = vec2[](
vec2(1, 0), vec2(0, 0), vec2(1, 1), vec2(0, 1) vec2(1, 0), vec2(0, 0), vec2(1, 1), vec2(0, 1)

View File

@@ -0,0 +1,96 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "DepthBufferQuery.hpp"
#include "Renderer.hpp"
#include <vulkan/vulkan.hpp>
//TODO resize
namespace OpenVulkano::Vulkan
{
void DepthBufferQuery::Init()
{
auto device = renderer.GetContext().device->device;
vk::BufferCreateInfo bufferInfo = { {}, 25 * sizeof(float), vk::BufferUsageFlagBits::eTransferDst };
bufferDepth = device.createBuffer(bufferInfo);
const vk::MemoryRequirements memRequirements = device.getBufferMemoryRequirements(bufferDepth);
size_t size = memRequirements.size;
const vk::MemoryAllocateInfo memAllocInfo = { size, renderer.GetContext().device->GetMemoryType(memRequirements.memoryTypeBits, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible) };
memory = device.allocateMemory(memAllocInfo);
cpuDepthBuffer = static_cast<float*>(device.mapMemory(memory, 0, VK_WHOLE_SIZE, {}));
device.bindBufferMemory(bufferDepth, memory, 0);
}
void DepthBufferQuery::Close()
{
auto device = renderer.GetContext().device->device;
device.destroy(bufferDepth);
device.unmapMemory(memory);
device.free(memory);
cpuDepthBuffer = nullptr;
}
void DepthBufferQuery::Resize(uint32_t width, uint32_t height)
{
//TODO
}
float DepthBufferQuery::GetQueriedValue() const
{
if (cpuDepthBuffer[0] == -2) return -2;
if (cpuDepthBuffer[12] > 0 && cpuDepthBuffer[12] < 1) return cpuDepthBuffer[12];
double val = 0;
int validCount = 0;
for (int i = 0; i < 25; i++)
{
float f = cpuDepthBuffer[i];
if (f > 0 && f < 1)
{
val += f;
validCount++;
}
}
if (validCount == 0) return 1; // Prevent divide by 0
return val / validCount;
}
vk::Offset3D DepthBufferQuery::GetCopyOffset() const
{
vk::Extent3D depthExtent = renderer.GetContext().swapChain.GetCurrentDepthBuffer().extent;
int32_t x = static_cast<int32_t>(depthQueryCoordinates.x * depthExtent.width);
x = std::min<int32_t>(depthExtent.width - 5, std::max(0, x));
int32_t y = static_cast<int32_t>(depthQueryCoordinates.y * depthExtent.height);
y = std::min<int32_t>(depthExtent.height - 5, std::max(0, y));
return { x, y, 0 };
}
void DepthBufferQuery::Encode(vk::CommandBuffer& commandBuffer)
{
if (!copyDepthBuffer) return;
copyDepthBuffer = false;
std::fill(cpuDepthBuffer, cpuDepthBuffer + 25, -2.0f); // Invalidate data in buffer to allow detecting if copy is done
const vk::ImageAspectFlags aspectMask = vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil;
const Image& depthBufferImage = renderer.GetContext().swapChain.GetCurrentDepthBuffer();
constexpr vk::Extent3D copySize = { 5, 5, 1 };
const vk::ImageSubresourceLayers layout = { vk::ImageAspectFlagBits::eDepth, 0, 0, 1 };
vk::BufferImageCopy imgCopy = { 0, 5, 5, layout, GetCopyOffset(), copySize };
const vk::ImageMemoryBarrier imgMemBarrier({}, vk::AccessFlagBits::eTransferRead, vk::ImageLayout::eDepthStencilAttachmentOptimal, vk::ImageLayout::eTransferSrcOptimal, 0, 0, depthBufferImage.image, vk::ImageSubresourceRange(aspectMask, 0, 1, 0, 1));
commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, nullptr, nullptr, imgMemBarrier);
commandBuffer.copyImageToBuffer(depthBufferImage.image, vk::ImageLayout::eTransferSrcOptimal, bufferDepth, 1, &imgCopy);
depthBufferImage.SetLayout(commandBuffer, aspectMask, vk::ImageLayout::eDepthStencilAttachmentOptimal, vk::ImageLayout::eTransferSrcOptimal);
}
}

View File

@@ -0,0 +1,48 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "Math/Math.hpp"
#include "Vulkan/Image.hpp"
namespace OpenVulkano::Vulkan
{
class Renderer;
class DepthBufferQuery final
{
Renderer& renderer;
vk::DeviceMemory memory;
vk::Buffer bufferDepth;
float* cpuDepthBuffer = nullptr;
Math::Vector2f depthQueryCoordinates = { 0.5f, 0.5f };
bool copyDepthBuffer = true;
vk::Offset3D GetCopyOffset() const;
public:
DepthBufferQuery(Renderer& renderer): renderer(renderer) {}
~DepthBufferQuery() { if (cpuDepthBuffer != nullptr) Close(); }
void Init();
void Close();
void Encode(vk::CommandBuffer& commandBuffer);
void Resize(uint32_t width, uint32_t height);
float GetQueriedValue() const;
void SetQueryCoordinates(const Math::Vector2f& coords)
{
copyDepthBuffer = true;
depthQueryCoordinates = coords;
}
};
}

View File

@@ -18,6 +18,8 @@ void OpenVulkano::Vulkan::FrameBuffer::Init(Device* device, vk::Extent3D size, b
depthBufferFormat = FindDepthFormat(); depthBufferFormat = FindDepthFormat();
CreateDepthStencil(); CreateDepthStencil();
} }
fullscreenViewport = vk::Viewport{ 0, 0, (float)size.width, (float)size.height, 0, 1 };
fullscreenScissor = vk::Rect2D{ { 0, 0 }, { size.width, size.height } };
} }
void OpenVulkano::Vulkan::FrameBuffer::RegisterRenderPass(RenderPass* renderPass) void OpenVulkano::Vulkan::FrameBuffer::RegisterRenderPass(RenderPass* renderPass)
@@ -44,6 +46,8 @@ void OpenVulkano::Vulkan::FrameBuffer::Resize(vk::Extent3D size)
{ {
renderPass->Resize(size); renderPass->Resize(size);
} }
fullscreenViewport = vk::Viewport{ 0, 0, (float)size.width, (float)size.height, 0, 1 };
fullscreenScissor = vk::Rect2D{ { 0, 0 }, { size.width, size.height } };
} }
void OpenVulkano::Vulkan::FrameBuffer::CreateDepthStencil() void OpenVulkano::Vulkan::FrameBuffer::CreateDepthStencil()

View File

@@ -24,8 +24,10 @@ namespace OpenVulkano::Vulkan
vk::Format depthBufferFormat = vk::Format::eUndefined, colorFormat = vk::Format::eUndefined; vk::Format depthBufferFormat = vk::Format::eUndefined, colorFormat = vk::Format::eUndefined;
vk::Extent3D size; vk::Extent3D size;
std::vector<RenderPass*> renderPasses; std::vector<RenderPass*> renderPasses;
bool useDepthBuffer; vk::Viewport fullscreenViewport;
vk::Rect2D fullscreenScissor;
Device* device = nullptr; Device* device = nullptr;
bool useDepthBuffer;
protected: protected:
uint32_t currentFrameBufferId = 0; uint32_t currentFrameBufferId = 0;
@@ -38,15 +40,9 @@ namespace OpenVulkano::Vulkan
void Init(Device* device, vk::Extent3D size, bool useDepthBuffer = true); void Init(Device* device, vk::Extent3D size, bool useDepthBuffer = true);
void SetCurrentFrameId(uint32_t id) void SetCurrentFrameId(uint32_t id) { currentFrameBufferId = id; }
{
currentFrameBufferId = id;
}
uint32_t GetCurrentFrameId() const [[nodiscard]] uint32_t GetCurrentFrameId() const { return currentFrameBufferId; }
{
return currentFrameBufferId;
}
public: public:
void RegisterRenderPass(RenderPass* renderPass); void RegisterRenderPass(RenderPass* renderPass);
@@ -69,44 +65,32 @@ namespace OpenVulkano::Vulkan
void DestroyFrameBuffer(); void DestroyFrameBuffer();
virtual vk::Format FindColorFormat() = 0; [[nodiscard]] virtual vk::Format FindColorFormat() = 0;
virtual vk::Format FindDepthFormat() [[nodiscard]] virtual vk::Format FindDepthFormat()
{ {
return device->GetSupportedDepthFormat(); return device->GetSupportedDepthFormat();
} }
public: public:
virtual vk::Format GetColorFormat() [[nodiscard]] vk::Format GetColorFormat() const { return colorFormat; }
{
return colorFormat;
}
virtual vk::Format GetDepthFormat() [[nodiscard]] vk::Format GetDepthFormat() const { return depthBufferFormat; }
{
return depthBufferFormat;
}
virtual std::vector<IImage*> GetImages() = 0; [[nodiscard]] virtual std::vector<IImage*> GetImages() = 0;
bool UseDepthBuffer() const [[nodiscard]] bool UseDepthBuffer() const { return useDepthBuffer; }
{
return useDepthBuffer;
}
vk::Extent3D GetSize3D() const [[nodiscard]] const vk::Extent3D& GetSize3D() const { return size; }
{
return size;
}
vk::Extent2D GetSize2D() const [[nodiscard]] vk::Extent2D GetSize2D() const { return { size.width, size.height }; }
{
return { size.width, size.height };
}
vk::Framebuffer& GetCurrentFrameBuffer() [[nodiscard]] vk::Framebuffer& GetCurrentFrameBuffer() { return frameBuffers[currentFrameBufferId]; }
{
return frameBuffers[currentFrameBufferId]; [[nodiscard]] const vk::Viewport& GetFullscreenViewport() const { return fullscreenViewport; }
}
[[nodiscard]] const vk::Rect2D& GetFullscreenScissor() const { return fullscreenScissor; }
[[nodiscard]] const Image& GetCurrentDepthBuffer() { return depthBuffer; }
}; };
} }

View File

@@ -54,7 +54,7 @@ namespace OpenVulkano::Vulkan
} }
m_vulkanTexture.view = m_vulkanTexture.device.createImageView(imgViewCreateInfo); m_vulkanTexture.view = m_vulkanTexture.device.createImageView(imgViewCreateInfo);
m_vulkanTexture.m_sampler = resManager->CreateSampler(VulkanTexture::DEFAULT_SAMPLER_CONFIG); m_vulkanTexture.m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(Scene::SamplerConfig::DEFAULT));
m_vulkanTexture.SetDescriptorSet(resManager, resManager->GetDescriptorLayoutSet(binding), binding); m_vulkanTexture.SetDescriptorSet(resManager, resManager->GetDescriptorLayoutSet(binding), binding);
renderTexture = &m_vulkanTexture; renderTexture = &m_vulkanTexture;

View File

@@ -57,7 +57,7 @@ namespace OpenVulkano::Vulkan
if (m_frameBuffer->UseDepthBuffer()) if (m_frameBuffer->UseDepthBuffer())
{ // Depth attachment { // Depth attachment
attachments.emplace_back(vk::AttachmentDescriptionFlags(), m_frameBuffer->GetDepthFormat(), vk::SampleCountFlagBits::e1, attachments.emplace_back(vk::AttachmentDescriptionFlags(), m_frameBuffer->GetDepthFormat(), vk::SampleCountFlagBits::e1,
m_useClearDepth ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eDontCare, m_useClearDepth ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, m_useClearDepth ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eStore, m_useClearDepth ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad,
vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eDepthStencilAttachmentOptimal, vk::ImageLayout::eDepthStencilAttachmentOptimal); vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eDepthStencilAttachmentOptimal, vk::ImageLayout::eDepthStencilAttachmentOptimal);
depthReference = new vk::AttachmentReference(1, vk::ImageLayout::eDepthStencilAttachmentOptimal); depthReference = new vk::AttachmentReference(1, vk::ImageLayout::eDepthStencilAttachmentOptimal);
} }

View File

@@ -18,6 +18,11 @@
namespace OpenVulkano::Vulkan namespace OpenVulkano::Vulkan
{ {
Renderer::Renderer()
: depthBufferQuery(*this)
{
}
void Renderer::Init(IGraphicsAppManager* graphicsAppManager, IWindow* window) void Renderer::Init(IGraphicsAppManager* graphicsAppManager, IWindow* window)
{ {
logger = Logger::RENDER; logger = Logger::RENDER;
@@ -62,6 +67,8 @@ namespace OpenVulkano::Vulkan
} }
} }
depthBufferQuery.Init();
logger->info("Vulkan renderer initialized"); logger->info("Vulkan renderer initialized");
} }
@@ -69,6 +76,8 @@ namespace OpenVulkano::Vulkan
{ {
currentImageId = context.swapChain.AcquireNextImage(); currentImageId = context.swapChain.AcquireNextImage();
scene->GetCamera()->SetSize(context.window->GetWidth(), context.window->GetHeight()); scene->GetCamera()->SetSize(context.window->GetWidth(), context.window->GetHeight());
scene->GetCamera()->SetContentScaleFactor(context.window->GetContentScale());
scene->GetCamera()->SetInterfaceOrientation(context.window->GetInterfaceOrientation());
Render(); Render();
} }
@@ -85,6 +94,7 @@ namespace OpenVulkano::Vulkan
closeables.pop_back(); closeables.pop_back();
closeable->Close(); closeable->Close();
} }
depthBufferQuery.Close();
uiRenderer.Close(); uiRenderer.Close();
resourceManager.Close(); resourceManager.Close();
commands.clear(); commands.clear();
@@ -104,7 +114,7 @@ namespace OpenVulkano::Vulkan
resourceManager.Resize(); resourceManager.Resize();
} }
CommandHelper* Renderer::GetCommandData(uint32_t poolId) CommandHelper* Renderer::GetCommandData(size_t poolId)
{ {
return &commands[poolId][currentImageId]; return &commands[poolId][currentImageId];
} }
@@ -136,6 +146,7 @@ namespace OpenVulkano::Vulkan
CommandHelper* cmdHelper = GetCommandData(commands.size() - 1); CommandHelper* cmdHelper = GetCommandData(commands.size() - 1);
cmdHelper->cmdBuffer.executeCommands(submitBuffers[currentImageId].size(), submitBuffers[currentImageId].data()); cmdHelper->cmdBuffer.executeCommands(submitBuffers[currentImageId].size(), submitBuffers[currentImageId].data());
context.swapChainRenderPass.End(cmdHelper->cmdBuffer); context.swapChainRenderPass.End(cmdHelper->cmdBuffer);
depthBufferQuery.Encode(cmdHelper->cmdBuffer);
uiRenderer.DrawUiFrame(cmdHelper->cmdBuffer); uiRenderer.DrawUiFrame(cmdHelper->cmdBuffer);
cmdHelper->cmdBuffer.end(); cmdHelper->cmdBuffer.end();
std::array<vk::PipelineStageFlags, 2> stateFlags = { vk::PipelineStageFlags(vk::PipelineStageFlagBits::eColorAttachmentOutput), vk::PipelineStageFlags(vk::PipelineStageFlagBits::eColorAttachmentOutput) }; std::array<vk::PipelineStageFlags, 2> stateFlags = { vk::PipelineStageFlags(vk::PipelineStageFlagBits::eColorAttachmentOutput), vk::PipelineStageFlags(vk::PipelineStageFlagBits::eColorAttachmentOutput) };
@@ -162,12 +173,14 @@ namespace OpenVulkano::Vulkan
Submit(); Submit();
} }
void Renderer::RecordSecondaryBuffer(Data::ReadOnlyAtomicArrayQueue<Scene::Drawable*>* jobQueue, uint32_t poolId) void Renderer::RecordSecondaryBuffer(Data::ReadOnlyAtomicArrayQueue<Scene::Drawable*>* jobQueue, size_t poolId)
{ {
CommandHelper* cmdHelper = GetCommandData(poolId); CommandHelper* cmdHelper = GetCommandData(poolId);
cmdHelper->Reset(); cmdHelper->Reset();
vk::CommandBufferInheritanceInfo inheritance = { context.swapChainRenderPass.renderPass, 0, context.swapChainRenderPass.GetFrameBuffer()->GetCurrentFrameBuffer() }; vk::CommandBufferInheritanceInfo inheritance = { context.swapChainRenderPass.renderPass, 0, context.swapChainRenderPass.GetFrameBuffer()->GetCurrentFrameBuffer() };
cmdHelper->cmdBuffer.begin(vk::CommandBufferBeginInfo{ vk::CommandBufferUsageFlagBits::eOneTimeSubmit | vk::CommandBufferUsageFlagBits::eRenderPassContinue, &inheritance }); cmdHelper->cmdBuffer.begin(vk::CommandBufferBeginInfo{ vk::CommandBufferUsageFlagBits::eOneTimeSubmit | vk::CommandBufferUsageFlagBits::eRenderPassContinue, &inheritance });
cmdHelper->cmdBuffer.setViewport(0, 1, &context.swapChainRenderPass.GetFrameBuffer()->GetFullscreenViewport());
cmdHelper->cmdBuffer.setScissor(0, 1, &context.swapChainRenderPass.GetFrameBuffer()->GetFullscreenScissor());
Scene::Drawable** drawablePointer; Scene::Drawable** drawablePointer;
VulkanDrawContext drawContext { poolId, currentImageId, cmdHelper->cmdBuffer, this }; VulkanDrawContext drawContext { poolId, currentImageId, cmdHelper->cmdBuffer, this };

View File

@@ -16,6 +16,7 @@
#include "CommandHelper.hpp" #include "CommandHelper.hpp"
#include "Base/EngineConfiguration.hpp" #include "Base/EngineConfiguration.hpp"
#include "Resources/ResourceManager.hpp" #include "Resources/ResourceManager.hpp"
#include "DepthBufferQuery.hpp"
#include <vector> #include <vector>
#include <thread> #include <thread>
@@ -40,9 +41,10 @@ namespace OpenVulkano::Vulkan
std::vector<std::vector<vk::CommandBuffer>> submitBuffers; std::vector<std::vector<vk::CommandBuffer>> submitBuffers;
UiRenderer uiRenderer; UiRenderer uiRenderer;
std::vector<ICloseable*> closeables; std::vector<ICloseable*> closeables;
DepthBufferQuery depthBufferQuery;
public: public:
Renderer() = default; Renderer();
~Renderer() override = default; ~Renderer() override = default;
void Init(IGraphicsAppManager* graphicsAppManager, IWindow* window) override; void Init(IGraphicsAppManager* graphicsAppManager, IWindow* window) override;
@@ -63,7 +65,7 @@ namespace OpenVulkano::Vulkan
Scene::UI::Ui* GetActiveUi() override { return uiRenderer.GetActiveUi(); } Scene::UI::Ui* GetActiveUi() override { return uiRenderer.GetActiveUi(); }
CommandHelper* GetCommandData(uint32_t poolId); CommandHelper* GetCommandData(size_t poolId);
static void RunThread(Renderer* renderer, Data::ReadOnlyAtomicArrayQueue<Scene::Drawable*>* jobQueue, uint32_t id); static void RunThread(Renderer* renderer, Data::ReadOnlyAtomicArrayQueue<Scene::Drawable*>* jobQueue, uint32_t id);
@@ -75,7 +77,7 @@ namespace OpenVulkano::Vulkan
void Render(); void Render();
void RecordSecondaryBuffer(Data::ReadOnlyAtomicArrayQueue<Scene::Drawable*>* jobQueue, uint32_t poolId); void RecordSecondaryBuffer(Data::ReadOnlyAtomicArrayQueue<Scene::Drawable*>* jobQueue, size_t poolId);
ResourceManager& GetResourceManager() { return resourceManager; } ResourceManager& GetResourceManager() { return resourceManager; }
@@ -86,5 +88,9 @@ namespace OpenVulkano::Vulkan
void UnregisterCloseable(ICloseable* closeable) { Utils::Remove(closeables, closeable); } void UnregisterCloseable(ICloseable* closeable) { Utils::Remove(closeables, closeable); }
IResourceManager* GetIResourceManager() override { return &resourceManager; } IResourceManager* GetIResourceManager() override { return &resourceManager; }
float GetLastQueriedDepthValue() override { return depthBufferQuery.GetQueriedValue(); }
void SetQueryDepthValue(const Math::Vector2f& depthCoordinates) override { depthBufferQuery.SetQueryCoordinates(depthCoordinates); }
}; };
} }

View File

@@ -55,7 +55,7 @@ namespace OpenVulkano::Vulkan
* \return The pointer to the mapped buffer. * \return The pointer to the mapped buffer.
*/ */
template <typename T = void> template <typename T = void>
T* Map(size_t offset = 0, vk::DeviceSize size = VK_WHOLE_SIZE, bool longTermMapping = true) T* Map(vk::DeviceSize offset = 0, vk::DeviceSize size = VK_WHOLE_SIZE, bool longTermMapping = true)
{ {
if (!mapped) if (!mapped)
{ {
@@ -106,7 +106,7 @@ namespace OpenVulkano::Vulkan
} }
} }
void Copy(const void* data, uint32_t size, uint32_t offset) void Copy(const void* data, vk::DeviceSize size, vk::DeviceSize offset)
{ {
if(mapped) memcpy(static_cast<char*>(mapped) + offset, data, size); if(mapped) memcpy(static_cast<char*>(mapped) + offset, data, size);
else else

View File

@@ -53,6 +53,7 @@ namespace OpenVulkano::Vulkan
ResourceManager::ResourceManager() ResourceManager::ResourceManager()
{ {
static_assert(sizeof(DescriptorSetLayoutBinding) == sizeof(vk::DescriptorSetLayoutBinding)); static_assert(sizeof(DescriptorSetLayoutBinding) == sizeof(vk::DescriptorSetLayoutBinding));
static_assert(sizeof(Scene::SamplerConfig) == sizeof(vk::SamplerCreateInfo));
} }
ResourceManager::~ResourceManager() noexcept ResourceManager::~ResourceManager() noexcept

View File

@@ -17,8 +17,15 @@ namespace OpenVulkano::Vulkan
VulkanShader::~VulkanShader() VulkanShader::~VulkanShader()
{ {
if (!shader) return; if (shader) Close();
Close(); device.destroyPipeline(pipeline);
for(auto& shaderModule : shaderModules)
{
device.destroyShaderModule(shaderModule);
}
device.destroyPipelineLayout(pipelineLayout);
for(auto& descriptorSetLayout : descriptorSetLayouts)
device.destroyDescriptorSetLayout(descriptorSetLayout);
} }
void VulkanShader::Init(Context* context, Scene::Shader* shader, IShaderOwner* owner) void VulkanShader::Init(Context* context, Scene::Shader* shader, IShaderOwner* owner)
@@ -63,12 +70,12 @@ namespace OpenVulkano::Vulkan
if (shader->vertexInputDescriptions.size() == 1) if (shader->vertexInputDescriptions.size() == 1)
{ // Reuse already existing vertex attribute description { // Reuse already existing vertex attribute description
static_assert(sizeof(VertexInputParameter) == sizeof(vk::VertexInputAttributeDescription)); static_assert(sizeof(VertexInputParameter) == sizeof(vk::VertexInputAttributeDescription));
attributeDescriptionsSize = shader->vertexInputDescriptions[0].inputParameters.size(); attributeDescriptionsSize = static_cast<uint32_t>(shader->vertexInputDescriptions[0].inputParameters.size());
attributeDescriptionsData = reinterpret_cast<vk::VertexInputAttributeDescription*>(shader->vertexInputDescriptions[0].inputParameters.data()); attributeDescriptionsData = reinterpret_cast<vk::VertexInputAttributeDescription*>(shader->vertexInputDescriptions[0].inputParameters.data());
} }
else else
{ {
attributeDescriptionsSize = attributeDescriptions.size(); attributeDescriptionsSize = static_cast<uint32_t>(attributeDescriptions.size());
attributeDescriptionsData = attributeDescriptions.data(); attributeDescriptionsData = attributeDescriptions.data();
} }
@@ -80,7 +87,7 @@ namespace OpenVulkano::Vulkan
vk::PipelineRasterizationStateCreateInfo rasterizer = {}; vk::PipelineRasterizationStateCreateInfo rasterizer = {};
rasterizer.cullMode = static_cast<vk::CullModeFlagBits>(shader->cullMode); rasterizer.cullMode = static_cast<vk::CullModeFlagBits>(shader->cullMode);
vk::PipelineMultisampleStateCreateInfo msaa = {}; vk::PipelineMultisampleStateCreateInfo msaa = {};
vk::PipelineDepthStencilStateCreateInfo depth = { {}, shader->depthTest, shader->depthWrite, vk::CompareOp::eLess }; vk::PipelineDepthStencilStateCreateInfo depth = { {}, shader->depthTest, shader->depthWrite, static_cast<vk::CompareOp>(shader->depthCompareOp) };
depth.maxDepthBounds = 1; depth.maxDepthBounds = 1;
vk::PipelineColorBlendAttachmentState colorBlendAttachment = {}; vk::PipelineColorBlendAttachmentState colorBlendAttachment = {};
colorBlendAttachment.colorWriteMask = vk::ColorComponentFlagBits::eA | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eR; colorBlendAttachment.colorWriteMask = vk::ColorComponentFlagBits::eA | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eR;
@@ -100,8 +107,14 @@ namespace OpenVulkano::Vulkan
CreatePipelineLayout(); CreatePipelineLayout();
vk::GraphicsPipelineCreateInfo pipelineCreateInfo = { {}, static_cast<uint32_t>(shaderStageCreateInfo.size()), shaderStageCreateInfo.data(), &pipelineVertexInputStateCreateInfo, &inputAssembly, const auto dynSates = Utils::MakeStdArray<vk::DynamicState>( vk::DynamicState::eViewport, vk::DynamicState::eScissor );
nullptr, &viewportStateCreateInfo, &rasterizer, &msaa, &depth, &colorInfo, nullptr, pipelineLayout, context->swapChainRenderPass.renderPass }; vk::PipelineDynamicStateCreateInfo dynStateInfo { {}, dynSates.size(), dynSates.data() };
vk::GraphicsPipelineCreateInfo pipelineCreateInfo = { {}, static_cast<uint32_t>(shaderStageCreateInfo.size()),
shaderStageCreateInfo.data(), &pipelineVertexInputStateCreateInfo,
&inputAssembly, nullptr, &viewportStateCreateInfo, &rasterizer,
&msaa, &depth, &colorInfo, shader->dynamicViewport ? &dynStateInfo : nullptr, pipelineLayout,
context->swapChainRenderPass.renderPass };
pipeline = this->device.createGraphicsPipeline({}, pipelineCreateInfo).value; pipeline = this->device.createGraphicsPipeline({}, pipelineCreateInfo).value;
} }
@@ -119,16 +132,9 @@ namespace OpenVulkano::Vulkan
void VulkanShader::Close() void VulkanShader::Close()
{ {
shader->renderShader = nullptr; shader->renderShader = nullptr;
device.destroyPipeline(pipeline);
for(auto& shaderModule : shaderModules)
{
device.destroyShaderModule(shaderModule);
}
device.destroyPipelineLayout(pipelineLayout);
for(auto& descriptorSetLayout : descriptorSetLayouts)
device.destroyDescriptorSetLayout(descriptorSetLayout);
shader = nullptr; shader = nullptr;
if (owner) owner->RemoveShader(this); if (owner) owner->RemoveShader(this);
owner = nullptr;
} }
void VulkanShader::CreatePipelineLayout() void VulkanShader::CreatePipelineLayout()

View File

@@ -19,7 +19,6 @@ namespace OpenVulkano::Vulkan
class VulkanTexture : public Scene::RenderTexture, public IRecordable, public Image class VulkanTexture : public Scene::RenderTexture, public IRecordable, public Image
{ {
public: public:
static inline vk::SamplerCreateInfo DEFAULT_SAMPLER_CONFIG {};
vk::Sampler m_sampler; vk::Sampler m_sampler;
vk::DescriptorSet m_descriptorSet; vk::DescriptorSet m_descriptorSet;
@@ -30,7 +29,7 @@ namespace OpenVulkano::Vulkan
resManager->CopyDataToImage(m_texture->size, m_texture->textureBuffer, this); resManager->CopyDataToImage(m_texture->size, m_texture->textureBuffer, this);
texture->updated = false; texture->updated = false;
m_sampler = resManager->CreateSampler(DEFAULT_SAMPLER_CONFIG); m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(texture->m_samplerConfig));
SetDescriptorSet(resManager, descriptorSetLayout, binding); SetDescriptorSet(resManager, descriptorSetLayout, binding);
texture->renderTexture = this; texture->renderTexture = this;
@@ -43,7 +42,7 @@ namespace OpenVulkano::Vulkan
texture->updated = false; texture->updated = false;
texture->textureBuffer = Map(); texture->textureBuffer = Map();
m_sampler = resManager->CreateSampler(DEFAULT_SAMPLER_CONFIG); m_sampler = resManager->CreateSampler(reinterpret_cast<const vk::SamplerCreateInfo&>(texture->m_samplerConfig));
SetDescriptorSet(resManager, descriptorSetLayout, binding); SetDescriptorSet(resManager, descriptorSetLayout, binding);
texture->renderTexture = this; texture->renderTexture = this;

View File

@@ -59,7 +59,7 @@ namespace OpenVulkano::Vulkan
{ {
if(uBuffer->updated) //TODO fix if(uBuffer->updated) //TODO fix
{ {
//uBuffer->updated = false; uBuffer->updated = false;
buffer->Update(uBuffer->data, uBuffer->size, context->currentImageId); buffer->Update(uBuffer->data, uBuffer->size, context->currentImageId);
} }
buffer->Record(context); buffer->Record(context);

View File

@@ -118,8 +118,6 @@ namespace OpenVulkano::Vulkan
for (size_t i = 0; i < images.size() + 1; i++) for (size_t i = 0; i < images.size() + 1; i++)
imageAvailableSemaphores.emplace_back(device->device.createSemaphore({})); imageAvailableSemaphores.emplace_back(device->device.createSemaphore({}));
fullscreenViewport = vk::Viewport{ 0, 0, (float)size.width, (float)size.height, 0, 1 };
fullscreenScissor = vk::Rect2D{ {0,0}, size };
Logger::RENDER->debug("Swap chain for window {0} created", window->GetWindowId()); Logger::RENDER->debug("Swap chain for window {0} created", window->GetWindowId());
} }

View File

@@ -43,8 +43,6 @@ namespace OpenVulkano
IVulkanWindow* window = nullptr; IVulkanWindow* window = nullptr;
vk::SurfaceFormatKHR surfaceFormat; vk::SurfaceFormatKHR surfaceFormat;
vk::PresentModeKHR presentMode; vk::PresentModeKHR presentMode;
vk::Viewport fullscreenViewport;
vk::Rect2D fullscreenScissor;
std::vector<vk::Semaphore> imageAvailableSemaphores; std::vector<vk::Semaphore> imageAvailableSemaphores;
uint32_t currentSemaphoreId = 0; uint32_t currentSemaphoreId = 0;
vk::Extent2D size{ 0, 0 }; vk::Extent2D size{ 0, 0 };
@@ -61,20 +59,7 @@ namespace OpenVulkano
void Resize(uint32_t newWidth, uint32_t newHeight); void Resize(uint32_t newWidth, uint32_t newHeight);
[[nodiscard]] vk::Extent2D GetSize() const [[nodiscard]] vk::Extent2D GetSize() const { return size; }
{
return size;
}
[[nodiscard]] const vk::Viewport& GetFullscreenViewport() const
{
return fullscreenViewport;
}
[[nodiscard]] const vk::Rect2D& GetFullscreenScissor() const
{
return fullscreenScissor;
}
uint32_t AcquireNextImage(const vk::Fence& fence = vk::Fence()); uint32_t AcquireNextImage(const vk::Fence& fence = vk::Fence());
@@ -93,10 +78,7 @@ namespace OpenVulkano
} }
} }
[[nodiscard]] uint32_t GetImageCount() const [[nodiscard]] uint32_t GetImageCount() const { return images.size(); }
{
return images.size();
}
vk::Semaphore& GetCurrentSemaphore() { return imageAvailableSemaphores[currentSemaphoreId]; } vk::Semaphore& GetCurrentSemaphore() { return imageAvailableSemaphores[currentSemaphoreId]; }
@@ -108,10 +90,7 @@ namespace OpenVulkano
void DestroySwapChain(); void DestroySwapChain();
protected: protected:
vk::Format FindColorFormat() override [[nodiscard]] vk::Format FindColorFormat() override { return surfaceFormat.format; }
{
return surfaceFormat.format;
}
virtual vk::PresentModeKHR ChosePresentMode(); virtual vk::PresentModeKHR ChosePresentMode();

0
tests/placeholder.cpp Normal file
View File