diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml new file mode 100644 index 0000000..fe9d813 --- /dev/null +++ b/.github/workflows/build-android.yml @@ -0,0 +1,25 @@ +name: build android + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build: + runs-on: windows-latest + strategy: + matrix: + use_debug_libraries: [true, false] + target_arch_abi: [armeabi-v7a, arm64-v8a, x86, x86_64] + steps: + - uses: actions/checkout@main + with: + submodules: 'recursive' + - shell: cmd + run: | + call "%ANDROID_NDK_ROOT%\ndk-build" -C "./thirdparty/Brioche/build-android" "NDK_PROJECT_PATH:=null" "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_${{matrix.use_debug_libraries}}\obj" "NDK_LIBS_OUT:=.\debug_${{matrix.use_debug_libraries}}\lib" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" + call "%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make" -C "./build-GLSL" -f ".\GLSL.mk" "APP_DEBUG:=${{matrix.use_debug_libraries}}" + call "%ANDROID_NDK_ROOT%\ndk-build" -C "./build-android" "NDK_PROJECT_PATH:=null" "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_${{matrix.use_debug_libraries}}\obj" "NDK_LIBS_OUT:=.\debug_${{matrix.use_debug_libraries}}\lib" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" + call "%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make" -C "./build-android" -f ".\APK.mk" "ANDROID_SDK_DIR:=%ANDROID_SDK_ROOT%\." "JDK_DIR:=%JAVA_HOME%\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml new file mode 100644 index 0000000..9df71b9 --- /dev/null +++ b/.github/workflows/build-linux.yml @@ -0,0 +1,23 @@ +name: build linux + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + use_debug_libraries: [true, false] + steps: + - uses: actions/checkout@main + with: + submodules: 'recursive' + - shell: bash + run: | + make -C "./thirdparty/Brioche/build-linux" -f "Linux.mk" "APP_DEBUG:=${{matrix.use_debug_libraries}}" + make -C "./build-GLSL" -f "GLSL.mk" "APP_DEBUG:=${{matrix.use_debug_libraries}}" + make -C "./build-linux" -f "Linux.mk" "APP_DEBUG:=${{matrix.use_debug_libraries}}" diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml new file mode 100644 index 0000000..02cc20c --- /dev/null +++ b/.github/workflows/build-windows.yml @@ -0,0 +1,23 @@ +name: build windows + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build: + runs-on: windows-latest + strategy: + matrix: + configuration: [Debug, Release] + platform: [x86, x64] + steps: + - uses: actions/checkout@main + with: + submodules: 'recursive' + - uses: microsoft/setup-msbuild@main + - shell: cmd + run: | + msbuild ./build-windows/Demo-Windows.sln /p:Configuration=${{matrix.configuration}} /p:Platform=${{matrix.platform}} diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f84fb0c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,24 @@ +[submodule "thirdparty/Brioche"] + path = thirdparty/Brioche + url = git@github.com:HanetakaChou/Brioche.git + branch = master +[submodule "thirdparty/ConvertUTF"] + path = thirdparty/ConvertUTF + url = git@github.com:HanetakaChou/Import-Asset.git + branch = ConvertUTF +[submodule "thirdparty/CoreRT"] + path = thirdparty/CoreRT + url = git@github.com:HanetakaChou/Import-Asset.git + branch = CoreRT +[submodule "thirdparty/DirectXMath"] + path = thirdparty/DirectXMath + url = git@github.com:HanetakaChou/Import-Asset.git + branch = DirectXMath +[submodule "thirdparty/cgltf"] + path = thirdparty/cgltf + url = git@github.com:HanetakaChou/Import-Asset.git + branch = cgltf +[submodule "thirdparty/ImportAsset"] + path = thirdparty/ImportAsset + url = git@github.com:HanetakaChou/Import-Asset.git + branch = master diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5cc63c2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. [http://fsf.org/] + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b56ec6f --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +## glTF Viewer diff --git a/build-GLSL/GLSL.mk b/build-GLSL/GLSL.mk new file mode 100644 index 0000000..d5f5145 --- /dev/null +++ b/build-GLSL/GLSL.mk @@ -0,0 +1,171 @@ +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# ==================================================================== +# +# Host system auto-detection. +# +# ==================================================================== +ifeq ($(OS),Windows_NT) + # On all modern variants of Windows (including Cygwin and Wine) + # the OS environment variable is defined to 'Windows_NT' + # + # The value of PROCESSOR_ARCHITECTURE will be x86 or AMD64 + # + HOST_OS := windows + + # Trying to detect that we're running from Cygwin is tricky + # because we can't use $(OSTYPE): It's a Bash shell variable + # that is not exported to sub-processes, and isn't defined by + # other shells (for those with really weird setups). + # + # Instead, we assume that a program named /bin/uname.exe + # that can be invoked and returns a valid value corresponds + # to a Cygwin installation. + # + UNAME := $(shell /bin/uname.exe -s 2>NUL) + ifneq (,$(filter CYGWIN% MINGW32% MINGW64%,$(UNAME))) + HOST_OS := unix + _ := $(shell rm -f NUL) # Cleaning up + endif +else + HOST_OS := unix +endif + +# ----------------------------------------------------------------------------- +# Function : host-mkdir +# Arguments: 1: directory path +# Usage : $(call host-mkdir, +# Rationale: This function expands to the host-specific shell command used +# to create a path if it doesn't exist. +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-mkdir = md $(subst /,\,"$1") >NUL 2>NUL || rem +else +host-mkdir = mkdir -p $1 +endif + +# ----------------------------------------------------------------------------- +# Function : host-rm +# Arguments: 1: list of files +# Usage : $(call host-rm,) +# Rationale: This function expands to the host-specific shell command used +# to remove some files. +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-rm = \ + $(eval __host_rm_files := $(foreach __host_rm_file,$1,$(subst /,\,$(wildcard $(__host_rm_file)))))\ + $(if $(__host_rm_files),del /f/q $(__host_rm_files) >NUL 2>NUL || rem) +else +host-rm = rm -f $1 +endif + +# +# Copyright (C) YuqiaoZhang(HanetakaChou) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +HIDE := @ + +LOCAL_PATH := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) +SHADERS_DIR := $(LOCAL_PATH)/../shaders +ifeq (true, $(APP_DEBUG)) + SPIRV_DIR := $(LOCAL_PATH)/../spirv/debug +else + SPIRV_DIR := $(LOCAL_PATH)/../spirv/release +endif +THIRD_PARTY_DIR := $(LOCAL_PATH)/../thirdparty +ifeq ($(OS),Windows_NT) + GLSL_COMPILER_PATH := $(THIRD_PARTY_DIR)/Brioche/thirdparty/shaderc/bin/win32/x64/glslc.exe +else + GLSL_COMPILER_PATH := $(THIRD_PARTY_DIR)/Brioche/thirdparty/shaderc/bin/linux/x64/glslc +endif + +GLSL_COMPILER_FLAGS := +ifeq (true, $(APP_DEBUG)) + GLSL_COMPILER_FLAGS += -g -O0 +else + GLSL_COMPILER_FLAGS += -O +endif + +all : \ + $(SPIRV_DIR)/_internal_full_screen_transfer_vertex.inl \ + $(SPIRV_DIR)/_internal_full_screen_transfer_fragment.inl \ + $(SPIRV_DIR)/_internal_gbuffer_vertex.inl \ + $(SPIRV_DIR)/_internal_gbuffer_fragment.inl \ + $(SPIRV_DIR)/_internal_deferred_shading_vertex.inl \ + $(SPIRV_DIR)/_internal_deferred_shading_fragment.inl + +$(SPIRV_DIR)/_internal_full_screen_transfer_vertex.inl : $(SHADERS_DIR)/support/full_screen_transfer_vertex.sl + $(HIDE) $(call host-mkdir,$(SPIRV_DIR)) + $(HIDE) "$(GLSL_COMPILER_PATH)" -std=310es -mfmt=num -fshader-stage=vert $(GLSL_COMPILER_FLAGS) -MD -MF "$(SPIRV_DIR)/_internal_full_screen_transfer_vertex.d" -o "$(SPIRV_DIR)/_internal_full_screen_transfer_vertex.inl" "$(SHADERS_DIR)/support/full_screen_transfer_vertex.sl" + +$(SPIRV_DIR)/_internal_full_screen_transfer_fragment.inl : $(SHADERS_DIR)/support/full_screen_transfer_fragment.sl + $(HIDE) $(call host-mkdir,$(SPIRV_DIR)) + $(HIDE) "$(GLSL_COMPILER_PATH)" -std=310es -mfmt=num -fshader-stage=frag $(GLSL_COMPILER_FLAGS) -MD -MF "$(SPIRV_DIR)/_internal_full_screen_transfer_fragment.d" -o "$(SPIRV_DIR)/_internal_full_screen_transfer_fragment.inl" "$(SHADERS_DIR)/support/full_screen_transfer_fragment.sl" + +$(SPIRV_DIR)/_internal_gbuffer_vertex.inl : $(SHADERS_DIR)/gbuffer_vertex.sl + $(HIDE) $(call host-mkdir,$(SPIRV_DIR)) + $(HIDE) "$(GLSL_COMPILER_PATH)" -std=310es -mfmt=num -fshader-stage=vert $(GLSL_COMPILER_FLAGS) -MD -MF "$(SPIRV_DIR)/_internal_gbuffer_vertex.d" -o "$(SPIRV_DIR)/_internal_gbuffer_vertex.inl" "$(SHADERS_DIR)/gbuffer_vertex.sl" + +$(SPIRV_DIR)/_internal_gbuffer_fragment.inl : $(SHADERS_DIR)/gbuffer_fragment.sl + $(HIDE) $(call host-mkdir,$(SPIRV_DIR)) + $(HIDE) "$(GLSL_COMPILER_PATH)" -std=310es -mfmt=num -fshader-stage=frag $(GLSL_COMPILER_FLAGS) -MD -MF "$(SPIRV_DIR)/_internal_gbuffer_fragment.d" -o "$(SPIRV_DIR)/_internal_gbuffer_fragment.inl" "$(SHADERS_DIR)/gbuffer_fragment.sl" + +$(SPIRV_DIR)/_internal_deferred_shading_vertex.inl : $(SHADERS_DIR)/deferred_shading_vertex.sl + $(HIDE) $(call host-mkdir,$(SPIRV_DIR)) + $(HIDE) "$(GLSL_COMPILER_PATH)" -std=310es -mfmt=num -fshader-stage=vert $(GLSL_COMPILER_FLAGS) -MD -MF "$(SPIRV_DIR)/_internal_deferred_shading_vertex.d" -o "$(SPIRV_DIR)/_internal_deferred_shading_vertex.inl" "$(SHADERS_DIR)/deferred_shading_vertex.sl" + +$(SPIRV_DIR)/_internal_deferred_shading_fragment.inl : $(SHADERS_DIR)/deferred_shading_fragment.sl + $(HIDE) $(call host-mkdir,$(SPIRV_DIR)) + $(HIDE) "$(GLSL_COMPILER_PATH)" -std=310es -mfmt=num -fshader-stage=frag $(GLSL_COMPILER_FLAGS) -MD -MF "$(SPIRV_DIR)/_internal_deferred_shading_fragment.d" -o "$(SPIRV_DIR)/_internal_deferred_shading_fragment.inl" "$(SHADERS_DIR)/deferred_shading_fragment.sl" + +-include \ + $(SPIRV_DIR)/_internal_full_screen_transfer_vertex.d \ + $(SPIRV_DIR)/_internal_full_screen_transfer_fragment.d \ + $(SPIRV_DIR)/_internal_gbuffer_vertex.d \ + $(SPIRV_DIR)/_internal_gbuffer_fragment.d \ + $(SPIRV_DIR)/_internal_deferred_shading_vertex.d \ + $(SPIRV_DIR)/_internal_deferred_shading_fragment.d + +clean: + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_full_screen_transfer_vertex.inl) + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_full_screen_transfer_fragment.inl) + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_gbuffer_vertex.inl) + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_gbuffer_fragment.inl) + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_deferred_shading_vertex.inl) + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_deferred_shading_fragment.inl) + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_full_screen_transfer_vertex.d) + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_full_screen_transfer_fragment.d) + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_gbuffer_vertex.d) + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_gbuffer_fragment.d) + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_deferred_shading_vertex.d) + $(HIDE) $(call host-rm,$(SPIRV_DIR)/_internal_deferred_shading_fragment.d) + +.PHONY : \ + all \ + clean diff --git a/build-android/.gitignore b/build-android/.gitignore new file mode 100644 index 0000000..f922774 --- /dev/null +++ b/build-android/.gitignore @@ -0,0 +1,11 @@ +/debug_true +/debug_false +/keystore +/flat +/apk + +/.vs +/.agde +/bin-agde +/obj-agde +/*.vcxproj.user diff --git a/build-android/APK.mk b/build-android/APK.mk new file mode 100644 index 0000000..e9f8671 --- /dev/null +++ b/build-android/APK.mk @@ -0,0 +1,164 @@ +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# ==================================================================== +# +# Host system auto-detection. +# +# ==================================================================== +ifeq ($(OS),Windows_NT) + # On all modern variants of Windows (including Cygwin and Wine) + # the OS environment variable is defined to 'Windows_NT' + # + # The value of PROCESSOR_ARCHITECTURE will be x86 or AMD64 + # + HOST_OS := windows + + # Trying to detect that we're running from Cygwin is tricky + # because we can't use $(OSTYPE): It's a Bash shell variable + # that is not exported to sub-processes, and isn't defined by + # other shells (for those with really weird setups). + # + # Instead, we assume that a program named /bin/uname.exe + # that can be invoked and returns a valid value corresponds + # to a Cygwin installation. + # + UNAME := $(shell /bin/uname.exe -s 2>NUL) + ifneq (,$(filter CYGWIN% MINGW32% MINGW64%,$(UNAME))) + HOST_OS := unix + _ := $(shell rm -f NUL) # Cleaning up + endif +else + HOST_OS := unix +endif + +# ----------------------------------------------------------------------------- +# Function : host-mkdir +# Arguments: 1: directory path +# Usage : $(call host-mkdir, +# Rationale: This function expands to the host-specific shell command used +# to create a path if it doesn't exist. +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-mkdir = md $(subst /,\,"$1") >NUL 2>NUL || rem +else +host-mkdir = mkdir -p $1 +endif + +# ----------------------------------------------------------------------------- +# Function : host-cp +# Arguments: 1: source file +# 2: target file +# Usage : $(call host-cp,,) +# Rationale: This function expands to the host-specific shell command used +# to copy a single file +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-cp = copy /b/y $(subst /,\,"$1" "$2") > NUL 2>NUL || rem +else +host-cp = cp -f $1 $2 +endif + +# ----------------------------------------------------------------------------- +# Function : host-rm +# Arguments: 1: list of files +# Usage : $(call host-rm,) +# Rationale: This function expands to the host-specific shell command used +# to remove some files. +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-rm = \ + $(eval __host_rm_files := $(foreach __host_rm_file,$1,$(subst /,\,$(wildcard $(__host_rm_file)))))\ + $(if $(__host_rm_files),del /f/q $(__host_rm_files) >NUL 2>NUL || rem) +else +host-rm = rm -f $1 +endif + +# +# Copyright (C) YuqiaoZhang(HanetakaChou) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +# ANDROID_SDK_BUILD_TOOLS_VERSION := 33.0.2 +# APP_PLATFORM:=android-28 + +HIDE := @ + +LOCAL_PATH := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) +KEYSTORE_DIR := $(LOCAL_PATH)/keystore +RES_DIR := $(LOCAL_PATH)/res +FLAT_DIR := $(LOCAL_PATH)/flat +APK_DIR := $(LOCAL_PATH)/apk +ANDROID_JAR_PATH := $(ANDROID_SDK_DIR)/platforms/$(APP_PLATFORM)/android.jar +ifeq ($(OS),Windows_NT) +AAPT2_PATH := $(ANDROID_SDK_DIR)/build-tools/$(ANDROID_SDK_BUILD_TOOLS_VERSION)/aapt2.exe +ZIPALIGN_PATH := $(ANDROID_SDK_DIR)/build-tools/$(ANDROID_SDK_BUILD_TOOLS_VERSION)/zipalign.exe +APKSIGNER_PATH := $(ANDROID_SDK_DIR)/build-tools/$(ANDROID_SDK_BUILD_TOOLS_VERSION)/apksigner.bat +JAR_PATH := $(JDK_DIR)/bin/jar.exe +KEYTOOL_PATH := $(JDK_DIR)/bin/keytool.exe +else +AAPT2_PATH := $(ANDROID_SDK_DIR)/build-tools/$(ANDROID_SDK_BUILD_TOOLS_VERSION)/aapt2 +ZIPALIGN_PATH := $(ANDROID_SDK_DIR)/build-tools/$(ANDROID_SDK_BUILD_TOOLS_VERSION)/zipalign +APKSIGNER_PATH := $(ANDROID_SDK_DIR)/build-tools/$(ANDROID_SDK_BUILD_TOOLS_VERSION)/apksigner +JAR_PATH := $(JDK_DIR)/bin/jar +KEYTOOL_PATH := $(JDK_DIR)/bin/keytool +endif + +all : $(APK_DIR)/demo-android.apk + +$(KEYSTORE_DIR)/demo-android-debug.keystore : + $(HIDE) $(call host-mkdir,$(KEYSTORE_DIR)) + $(HIDE) "$(KEYTOOL_PATH)" -genkey -v -keystore "$(KEYSTORE_DIR)/demo-android-debug.keystore" -storepass demo-android -storetype PKCS12 -keypass demo-android -alias demo-android-debug -keyalg RSA -keysize 3072 -validity 1024 -dname "CN=Demo-Android" + +$(FLAT_DIR)/values_styles.arsc.flat : $(RES_DIR)/values/styles.xml + $(HIDE) $(call host-mkdir,$(FLAT_DIR)) + $(HIDE) "$(AAPT2_PATH)" compile -o "$(FLAT_DIR)" "$(RES_DIR)\values\styles.xml" + +$(APK_DIR)/demo-android-unaligned.apk : $(addprefix $(LOCAL_PATH)/debug_$(APP_DEBUG)/lib/, $(addsuffix /libNativeActivity.so, $(APP_ABI))) $(FLAT_DIR)/values_styles.arsc.flat $(LOCAL_PATH)/AndroidManifest.xml + $(HIDE) $(call host-mkdir,$(APK_DIR)) + $(HIDE) "$(AAPT2_PATH)" link --debug-mode -I "$(ANDROID_JAR_PATH)" "$(FLAT_DIR)/values_styles.arsc.flat" -o "$(APK_DIR)/demo-android-unaligned.apk" --manifest "$(LOCAL_PATH)/AndroidManifest.xml" + $(HIDE) "$(JAR_PATH)" uf "$(APK_DIR)/demo-android-unaligned.apk" -C "$(LOCAL_PATH)/debug_$(APP_DEBUG)" lib + +$(APK_DIR)/demo-android-unsigned.apk : $(APK_DIR)/demo-android-unaligned.apk + $(HIDE) $(call host-mkdir,$(APK_DIR)) + $(HIDE) "$(ZIPALIGN_PATH)" -f 4 "$(APK_DIR)/demo-android-unaligned.apk" "$(APK_DIR)/demo-android-unsigned.apk" + +$(APK_DIR)/demo-android.apk : $(KEYSTORE_DIR)/demo-android-debug.keystore $(APK_DIR)/demo-android-unsigned.apk + $(HIDE) $(call host-mkdir,$(APK_DIR)) + $(HIDE) $(call host-cp,$(APK_DIR)/demo-android-unsigned.apk,$(APK_DIR)/demo-android.apk) + $(HIDE) "$(APKSIGNER_PATH)" sign -v --ks "$(KEYSTORE_DIR)/demo-android-debug.keystore" --ks-pass pass:demo-android -ks-key-alias demo-android-debug "$(APK_DIR)/demo-android.apk" + +clean: + $(HIDE) $(call host-rm,$(KEYSTORE_DIR)/demo-android-debug.keystore) + $(HIDE) $(call host-rm,$(FLAT_DIR)/values_styles.arsc.flat) + $(HIDE) $(call host-rm,$(APK_DIR)/demo-android-unaligned.apk) + $(HIDE) $(call host-rm,$(APK_DIR)/demo-android-unsigned.apk) + $(HIDE) $(call host-rm,$(APK_DIR)/demo-android.apk) + +.PHONY : \ + all \ + clean \ No newline at end of file diff --git a/build-android/Android.mk b/build-android/Android.mk new file mode 100644 index 0000000..1fac85b --- /dev/null +++ b/build-android/Android.mk @@ -0,0 +1,106 @@ +# +# Copyright (C) YuqiaoZhang(HanetakaChou) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +# https://developer.android.com/ndk/guides/android_mk + +LOCAL_PATH := $(call my-dir) + +# Android Application Library + +include $(CLEAR_VARS) + +LOCAL_MODULE := NativeActivity + +LOCAL_SRC_FILES := \ + $(LOCAL_PATH)/../source/support/camera_controller.cpp \ + $(LOCAL_PATH)/../source/support/main.cpp \ + $(LOCAL_PATH)/../source/support/renderer.cpp \ + $(LOCAL_PATH)/../source/support/tick_count.cpp \ + $(LOCAL_PATH)/../source/demo.cpp \ + $(LOCAL_PATH)/../thirdparty/ImportAsset/import_asset_input_stream_file.cpp \ + $(LOCAL_PATH)/../thirdparty/ImportAsset/import_asset_input_stream_memory.cpp \ + $(LOCAL_PATH)/../thirdparty/ImportAsset/import_image_asset_dds.cpp \ + $(LOCAL_PATH)/../thirdparty/ImportAsset/import_image_asset_pvr.cpp \ + $(LOCAL_PATH)/../thirdparty/ImportAsset/import_scene_asset_gltf_cgltf.cpp \ + $(LOCAL_PATH)/../thirdparty/ImportAsset/import_scene_asset_gltf.cpp \ + $(LOCAL_PATH)/../thirdparty/ImportAsset/import_scene_asset.cpp + +ifeq (arm, $(TARGET_ARCH)) +LOCAL_ARM_MODE := arm +LOCAL_ARM_NEON := true +endif + +LOCAL_CFLAGS := +# LOCAL_CFLAGS += -finput-charset=UTF-8 -fexec-charset=UTF-8 +# LOCAL_CFLAGS += -fvisibility=hidden +LOCAL_CFLAGS += -Wall -Werror=return-type +LOCAL_CFLAGS += -Dbrx_init_unknown_device=brx_init_vk_device +LOCAL_CFLAGS += -Dbrx_destroy_unknown_device=brx_destroy_vk_device +LOCAL_CFLAGS += -DPAL_STDCPP_COMPAT=1 + +# LOCAL_CPPFLAGS := +# LOCAL_CPPFLAGS += -std=c++11 + +LOCAL_C_INCLUDES := +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../spirv +ifeq (true, $(APP_DEBUG)) + LOCAL_C_INCLUDES += $(LOCAL_PATH)/../spirv/debug +else + LOCAL_C_INCLUDES +=$(LOCAL_PATH)/../spirv/release +endif +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../thirdparty/CoreRT/src/Native/inc/unix +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../thirdparty/DirectXMath/Inc + +LOCAL_LDFLAGS := +# LOCAL_LDFLAGS += -finput-charset=UTF-8 -fexec-charset=UTF-8 +# the "dynamic linker" can't recognize the old dtags +LOCAL_LDFLAGS += -Wl,--enable-new-dtags +# the "chrpath" can only make path shorter +# LOCAL_LDFLAGS += -Wl,-rpath,XORIGIN +LOCAL_LDFLAGS += -Wl,--version-script,$(LOCAL_PATH)/libNativeActivity.map + +LOCAL_LDLIBS := +LOCAL_LDLIBS += -landroid + +LOCAL_SHARED_LIBRARIES := +LOCAL_SHARED_LIBRARIES := BRX + +include $(BUILD_SHARED_LIBRARY) + +# BRX + +include $(CLEAR_VARS) + +LOCAL_MODULE := BRX + +LOCAL_SRC_FILES := $(LOCAL_PATH)/../thirdparty/Brioche/build-android/debug_$(APP_DEBUG)/lib/$(TARGET_ARCH_ABI)/libBRX$(TARGET_SONAME_EXTENSION) + +include $(PREBUILT_SHARED_LIBRARY) + +# VkLayer_khronos_validation + +ifeq (true, $(APP_DEBUG)) + +include $(CLEAR_VARS) + +LOCAL_MODULE := VkLayer_khronos_validation + +LOCAL_SRC_FILES := $(LOCAL_PATH)/../thirdparty/Brioche/thirdparty/Vulkan-ValidationLayers/bin/android/$(TARGET_ARCH_ABI)/libVkLayer_khronos_validation$(TARGET_SONAME_EXTENSION) + +include $(PREBUILT_SHARED_LIBRARY) + +endif diff --git a/build-android/AndroidManifest.xml b/build-android/AndroidManifest.xml new file mode 100644 index 0000000..48c8d6a --- /dev/null +++ b/build-android/AndroidManifest.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-android/Application.mk b/build-android/Application.mk new file mode 100644 index 0000000..3e4399e --- /dev/null +++ b/build-android/Application.mk @@ -0,0 +1,24 @@ +# +# Copyright (C) YuqiaoZhang(HanetakaChou) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +# https://developer.android.com/ndk/guides/application_mk + +NDK_TOOLCHAIN_VERSION := clang +# APP_ABI := x86_64 x86 arm64-v8a armeabi-v7a +# APP_DEBUG:= true +# APP_PLATFORM := android-28 +# APP_STL := c++_static \ No newline at end of file diff --git a/build-android/Demo-Android.sln b/build-android/Demo-Android.sln new file mode 100644 index 0000000..57f9c57 --- /dev/null +++ b/build-android/Demo-Android.sln @@ -0,0 +1,64 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31314.256 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Demo-Android", "Demo-Android.vcxproj", "{2610E7F8-A7DA-4314-A677-A88E5E91432F}" + ProjectSection(ProjectDependencies) = postProject + {719A58B7-8373-4C08-988E-A21F43E7EE23} = {719A58B7-8373-4C08-988E-A21F43E7EE23} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BRX-Android", "..\thirdparty\Brioche\build-android\BRX-Android.vcxproj", "{719A58B7-8373-4C08-988E-A21F43E7EE23}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Android-arm64-v8a = Debug|Android-arm64-v8a + Debug|Android-armeabi-v7a = Debug|Android-armeabi-v7a + Debug|Android-x86 = Debug|Android-x86 + Debug|Android-x86_64 = Debug|Android-x86_64 + Release|Android-arm64-v8a = Release|Android-arm64-v8a + Release|Android-armeabi-v7a = Release|Android-armeabi-v7a + Release|Android-x86 = Release|Android-x86 + Release|Android-x86_64 = Release|Android-x86_64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Debug|Android-arm64-v8a.ActiveCfg = Debug|Android-arm64-v8a + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Debug|Android-arm64-v8a.Build.0 = Debug|Android-arm64-v8a + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Debug|Android-armeabi-v7a.ActiveCfg = Debug|Android-armeabi-v7a + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Debug|Android-armeabi-v7a.Build.0 = Debug|Android-armeabi-v7a + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Debug|Android-x86.ActiveCfg = Debug|Android-x86 + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Debug|Android-x86.Build.0 = Debug|Android-x86 + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Debug|Android-x86_64.ActiveCfg = Debug|Android-x86_64 + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Debug|Android-x86_64.Build.0 = Debug|Android-x86_64 + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Release|Android-arm64-v8a.ActiveCfg = Release|Android-arm64-v8a + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Release|Android-arm64-v8a.Build.0 = Release|Android-arm64-v8a + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Release|Android-armeabi-v7a.ActiveCfg = Release|Android-armeabi-v7a + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Release|Android-armeabi-v7a.Build.0 = Release|Android-armeabi-v7a + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Release|Android-x86.ActiveCfg = Release|Android-x86 + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Release|Android-x86.Build.0 = Release|Android-x86 + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Release|Android-x86_64.ActiveCfg = Release|Android-x86_64 + {2610E7F8-A7DA-4314-A677-A88E5E91432F}.Release|Android-x86_64.Build.0 = Release|Android-x86_64 + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Debug|Android-arm64-v8a.ActiveCfg = Debug|Android-arm64-v8a + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Debug|Android-arm64-v8a.Build.0 = Debug|Android-arm64-v8a + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Debug|Android-armeabi-v7a.ActiveCfg = Debug|Android-armeabi-v7a + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Debug|Android-armeabi-v7a.Build.0 = Debug|Android-armeabi-v7a + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Debug|Android-x86.ActiveCfg = Debug|Android-x86 + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Debug|Android-x86.Build.0 = Debug|Android-x86 + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Debug|Android-x86_64.ActiveCfg = Debug|Android-x86_64 + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Debug|Android-x86_64.Build.0 = Debug|Android-x86_64 + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Release|Android-arm64-v8a.ActiveCfg = Release|Android-arm64-v8a + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Release|Android-arm64-v8a.Build.0 = Release|Android-arm64-v8a + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Release|Android-armeabi-v7a.ActiveCfg = Release|Android-armeabi-v7a + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Release|Android-armeabi-v7a.Build.0 = Release|Android-armeabi-v7a + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Release|Android-x86.ActiveCfg = Release|Android-x86 + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Release|Android-x86.Build.0 = Release|Android-x86 + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Release|Android-x86_64.ActiveCfg = Release|Android-x86_64 + {719A58B7-8373-4C08-988E-A21F43E7EE23}.Release|Android-x86_64.Build.0 = Release|Android-x86_64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3142C50D-495E-471E-A6B1-1E555B3ADA9B} + EndGlobalSection +EndGlobal diff --git a/build-android/Demo-Android.vcxproj b/build-android/Demo-Android.vcxproj new file mode 100644 index 0000000..5a07ff7 --- /dev/null +++ b/build-android/Demo-Android.vcxproj @@ -0,0 +1,308 @@ + + + + + Debug + Android-arm64-v8a + + + Debug + Android-armeabi-v7a + + + Debug + Android-x86 + + + Debug + Android-x86_64 + + + Release + Android-arm64-v8a + + + Release + Android-armeabi-v7a + + + Release + Android-x86 + + + Release + Android-x86_64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 15.0 + {2610E7F8-A7DA-4314-A677-A88E5E91432F} + MakeFileProj + Demo-Android + 10.0.18362.0 + + + + true + 25.2.9519653 + Makefile + + + false + 25.2.9519653 + Makefile + + + true + 25.2.9519653 + Makefile + + + false + 25.2.9519653 + Makefile + + + 25.2.9519653 + Makefile + + + 25.2.9519653 + Makefile + + + 25.2.9519653 + Makefile + + + 25.2.9519653 + Makefile + + + + + + + + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" -B +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM :=android-28" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean + $(ProjectDir)\apk\demo-android.apk + $(ProjectDir)\..\thirdparty\Brioche\build-android\obj\local\$(PlatformTarget);$(ProjectDir)\obj\local\$(PlatformTarget) + $(SolutionDir)\bin-agde\$(Platform)\$(Configuration)\ + $(SolutionDir)\obj-agde\$(Platform)\$(Configuration)\ + + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" -B +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM :=android-28" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean + $(ProjectDir)\apk\demo-android.apk + $(ProjectDir)\..\thirdparty\Brioche\build-android\obj\local\$(PlatformTarget);$(ProjectDir)\obj\local\$(PlatformTarget) + $(SolutionDir)\bin-agde\$(Platform)\$(Configuration)\ + $(SolutionDir)\obj-agde\$(Platform)\$(Configuration)\ + + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" -B +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM :=android-28" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean + $(ProjectDir)\apk\demo-android.apk + $(ProjectDir)\..\thirdparty\Brioche\build-android\obj\local\$(PlatformTarget);$(ProjectDir)\obj\local\$(PlatformTarget) + $(SolutionDir)\bin-agde\$(Platform)\$(Configuration)\ + $(SolutionDir)\obj-agde\$(Platform)\$(Configuration)\ + + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" -B +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM :=android-28" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean + $(ProjectDir)\apk\demo-android.apk + $(ProjectDir)\..\thirdparty\Brioche\build-android\obj\local\$(PlatformTarget);$(ProjectDir)\obj\local\$(PlatformTarget) + $(SolutionDir)\bin-agde\$(Platform)\$(Configuration)\ + $(SolutionDir)\obj-agde\$(Platform)\$(Configuration)\ + + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" -B +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM :=android-28" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean + $(ProjectDir)\apk\demo-android.apk + $(ProjectDir)\..\thirdparty\Brioche\build-android\obj\local\$(PlatformTarget);$(ProjectDir)\obj\local\$(PlatformTarget) + $(SolutionDir)\bin-agde\$(Platform)\$(Configuration)\ + $(SolutionDir)\obj-agde\$(Platform)\$(Configuration)\ + + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" -B +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM :=android-28" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean + $(ProjectDir)\apk\demo-android.apk + $(ProjectDir)\..\thirdparty\Brioche\build-android\obj\local\$(PlatformTarget);$(ProjectDir)\obj\local\$(PlatformTarget) + $(SolutionDir)\bin-agde\$(Platform)\$(Configuration)\ + $(SolutionDir)\obj-agde\$(Platform)\$(Configuration)\ + + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" -B +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM :=android-28" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean + $(ProjectDir)\apk\demo-android.apk + $(ProjectDir)\..\thirdparty\Brioche\build-android\obj\local\$(PlatformTarget);$(ProjectDir)\obj\local\$(PlatformTarget) + $(SolutionDir)\bin-agde\$(Platform)\$(Configuration)\ + $(SolutionDir)\obj-agde\$(Platform)\$(Configuration)\ + + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_DEBUG:=$(UseDebugLibraries)" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" -B +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" "ANDROID_SDK_DIR:=$(AndroidSdk)\." "JDK_DIR=$(AGDE_JAVA_HOME)\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" + + call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\APK.mk" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\ndk-build" -C "$(ProjectDir)\." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_$(UseDebugLibraries)\obj" "NDK_LIBS_OUT:=.\debug_$(UseDebugLibraries)\lib" "APP_ABI:=$(PlatformTarget)" "APP_PLATFORM :=android-28" clean +call "$(AndroidSdk)\ndk\$(AndroidNdkVersion)\prebuilt\windows-x86_64\bin\make" -C "$(ProjectDir)\." -f ".\GLSL.mk" clean + $(ProjectDir)\apk\demo-android.apk + $(ProjectDir)\..\thirdparty\Brioche\build-android\obj\local\$(PlatformTarget);$(ProjectDir)\obj\local\$(PlatformTarget) + $(SolutionDir)\bin-agde\$(Platform)\$(Configuration)\ + $(SolutionDir)\obj-agde\$(Platform)\$(Configuration)\ + + + + + + + + + + + + + + + + + + + + $(CleanDependson) + + + + + + \ No newline at end of file diff --git a/build-android/Demo-Android.vcxproj.filters b/build-android/Demo-Android.vcxproj.filters new file mode 100644 index 0000000..5d18170 --- /dev/null +++ b/build-android/Demo-Android.vcxproj.filters @@ -0,0 +1,160 @@ + + + + + + {d3d44437-e70c-46bd-8c20-c2cd514ac0e9} + + + {34b12179-03f8-4980-bf41-3d511b13a773} + + + {736508dc-56c9-4d65-be52-be367b671481} + + + {fdeb210d-c2e5-4c62-97d5-6dffea2f65d1} + + + {b61d08d5-1eee-4c9e-ac04-30cdb0a92f1a} + + + {e04f4479-55dc-4c69-9e6c-a2db6e3fe81b} + + + {8254002f-9645-46a6-89ca-55f6c0754a01} + + + + + source\support + + + source\support + + + source\support + + + code + + + assets + + + assets + + + source\support + + + + + source\support + + + source\support + + + source\support + + + code + + + assets + + + assets + + + source\support + + + + + build-android + + + build-android + + + build-android + + + spirv + + + spirv + + + spirv + + + spirv + + + shaders + + + shaders + + + shaders + + + shaders + + + shaders + + + shaders + + + shaders + + + shaders + + + shaders + + + shaders + + + shaders + + + shaders\support + + + shaders\support + + + shaders\support + + + build-android + + + + + build-android + + + \ No newline at end of file diff --git a/build-android/build-android.cmd b/build-android/build-android.cmd new file mode 100644 index 0000000..945b8f4 --- /dev/null +++ b/build-android/build-android.cmd @@ -0,0 +1,29 @@ +:: +:: Copyright (C) YuqiaoZhang(HanetakaChou) +:: +:: This program is free software: you can redistribute it and\or modify +:: it under the terms of the GNU Lesser General Public License as published +:: by the Free Software Foundation, either version 3 of the License, or +:: (at your option) any later version. +:: +:: This program is distributed in the hope that it will be useful, +:: but WITHOUT ANY WARRANTY; without even the implied warranty of +:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +:: GNU Lesser General Public License for more details. +:: +:: You should have received a copy of the GNU Lesser General Public License +:: along with this program. If not, see . +:: + +@echo off + +:: SET ANDROID_NDK_ROOT=C:\Users\Public\Documents\android-sdk\ndk\25.2.9519653 +:: SET ANDROID_SDK_ROOT=C:\Users\Public\Documents\android-sdk +:: SET JAVA_HOME=C:\Users\Public\Documents\jdk-17 + +pushd %~dp0 +call "%~dp0..\thirdparty\Brioche\build-android\build-android.cmd" +call "%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make" -C "%~dp0..\build-GLSL" -f ".\GLSL.mk" "APP_DEBUG:=false" +call "%ANDROID_NDK_ROOT%\ndk-build" -C "%~dp0." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_false\obj" "NDK_LIBS_OUT:=.\debug_false\lib" "APP_DEBUG:=false" "APP_ABI:=arm64-v8a armeabi-v7a x86 x86_64" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" +call "%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make" -C "%~dp0." -f ".\APK.mk" "ANDROID_SDK_DIR:=%ANDROID_SDK_ROOT%\." "JDK_DIR:=%JAVA_HOME%\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=arm64-v8a armeabi-v7a x86 x86_64" "APP_PLATFORM:=android-33" +popd \ No newline at end of file diff --git a/build-android/clean-android.cmd b/build-android/clean-android.cmd new file mode 100644 index 0000000..1ee37c1 --- /dev/null +++ b/build-android/clean-android.cmd @@ -0,0 +1,29 @@ +:: +:: Copyright (C) YuqiaoZhang(HanetakaChou) +:: +:: This program is free software: you can redistribute it and\or modify +:: it under the terms of the GNU Lesser General Public License as published +:: by the Free Software Foundation, either version 3 of the License, or +:: (at your option) any later version. +:: +:: This program is distributed in the hope that it will be useful, +:: but WITHOUT ANY WARRANTY; without even the implied warranty of +:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +:: GNU Lesser General Public License for more details. +:: +:: You should have received a copy of the GNU Lesser General Public License +:: along with this program. If not, see . +:: + +@echo off + +:: SET ANDROID_NDK_ROOT=C:\Users\Public\Documents\android-sdk\ndk\25.2.9519653 +:: SET ANDROID_SDK_ROOT=C:\Users\Public\Documents\android-sdk +:: SET JAVA_HOME=C:\Users\Public\Documents\jdk-17 + +pushd %~dp0 +call "%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make" -C "%~dp0." -f ".\APK.mk" clean +call "%ANDROID_NDK_ROOT%\ndk-build" -C "%~dp0." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_false\obj" "NDK_LIBS_OUT:=.\debug_false\lib" "APP_ABI:=armeabi-v7a arm64-v8a x86 x86_64" "APP_PLATFORM:=android-28" clean +call "%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make" -C "%~dp0..\build-GLSL" -f ".\GLSL.mk" clean +call "%~dp0..\thirdparty\Brioche\build-android\clean-android.cmd" +popd \ No newline at end of file diff --git a/build-android/libNativeActivity.map b/build-android/libNativeActivity.map new file mode 100644 index 0000000..de226bf --- /dev/null +++ b/build-android/libNativeActivity.map @@ -0,0 +1,23 @@ +/* + * Copyright (C) YuqiaoZhang(HanetakaChou) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +{ + global: + ANativeActivity_onCreate; + local: + *; +}; \ No newline at end of file diff --git a/build-android/rebuild-android.cmd b/build-android/rebuild-android.cmd new file mode 100644 index 0000000..123a77e --- /dev/null +++ b/build-android/rebuild-android.cmd @@ -0,0 +1,31 @@ +:: +:: Copyright (C) YuqiaoZhang(HanetakaChou) +:: +:: This program is free software: you can redistribute it and\or modify +:: it under the terms of the GNU Lesser General Public License as published +:: by the Free Software Foundation, either version 3 of the License, or +:: (at your option) any later version. +:: +:: This program is distributed in the hope that it will be useful, +:: but WITHOUT ANY WARRANTY; without even the implied warranty of +:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +:: GNU Lesser General Public License for more details. +:: +:: You should have received a copy of the GNU Lesser General Public License +:: along with this program. If not, see . +:: + +@echo off + +:: SET ANDROID_NDK_ROOT=C:\Users\Public\Documents\android-sdk\ndk\25.2.9519653 +:: SET ANDROID_SDK_ROOT=C:\Users\Public\Documents\android-sdk +:: SET JAVA_HOME=C:\Users\Public\Documents\jdk-17 + +pushd %~dp0 +call "%~dp0..\thirdparty\Brioche\build-android\rebuild-android.cmd" +call "%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make" -C "%~dp0." -f ".\APK.mk" clean +call "%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make" -C "%~dp0." -f ".\GLSL.mk" clean +call "%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make" -C "%~dp0." -f ".\GLSL.mk" "APP_DEBUG:=false" +call "%ANDROID_NDK_ROOT%\ndk-build" -C "%~dp0." NDK_PROJECT_PATH:=null "NDK_APPLICATION_MK:=.\Application.mk" "APP_BUILD_SCRIPT:=.\Android.mk" "NDK_OUT:=.\debug_false\obj" "NDK_LIBS_OUT:=.\debug_false\lib" "APP_DEBUG:=false" "APP_ABI:=arm64-v8a armeabi-v7a x86 x86_64" "APP_PLATFORM:=android-28" "APP_STL:=c++_static" -B +call "%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make" -C "%~dp0." -f ".\APK.mk" "ANDROID_SDK_DIR:=%ANDROID_SDK_ROOT%\." "JDK_DIR:=%JAVA_HOME%\." "ANDROID_SDK_BUILD_TOOLS_VERSION:=33.0.2" "APP_ABI:=${{matrix.target_arch_abi}}" "APP_DEBUG:=${{matrix.use_debug_libraries}}" "APP_PLATFORM:=android-33" +popd \ No newline at end of file diff --git a/build-android/res/values/styles.xml b/build-android/res/values/styles.xml new file mode 100644 index 0000000..afd4e15 --- /dev/null +++ b/build-android/res/values/styles.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/build-linux/.gitignore b/build-linux/.gitignore new file mode 100644 index 0000000..4c7473d --- /dev/null +++ b/build-linux/.gitignore @@ -0,0 +1,2 @@ +/bin +/obj diff --git a/build-linux/Demo-Linux.map b/build-linux/Demo-Linux.map new file mode 100644 index 0000000..2df9b7d --- /dev/null +++ b/build-linux/Demo-Linux.map @@ -0,0 +1,21 @@ +/* + * Copyright (C) YuqiaoZhang(HanetakaChou) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +{ + local: + *; +}; \ No newline at end of file diff --git a/build-linux/Linux.mk b/build-linux/Linux.mk new file mode 100644 index 0000000..d8616dd --- /dev/null +++ b/build-linux/Linux.mk @@ -0,0 +1,238 @@ +# +# Copyright (C) YuqiaoZhang(HanetakaChou) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +HIDE := @ + +LOCAL_PATH := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) +ifeq (true, $(APP_DEBUG)) + BIN_DIR := $(LOCAL_PATH)/bin/debug + OBJ_DIR := $(LOCAL_PATH)/obj/debug +else + BIN_DIR := $(LOCAL_PATH)/bin/release + OBJ_DIR := $(LOCAL_PATH)/obj/release +endif +SOURCE_DIR := $(LOCAL_PATH)/../source +THIRD_PARTY_DIR := $(LOCAL_PATH)/../thirdparty + +CC := clang++ + +C_FLAGS := +C_FLAGS += -Wall -Werror=return-type +# C_FLAGS += -fvisibility=hidden +C_FLAGS += -fPIE -fPIC +C_FLAGS += -pthread +ifeq (true, $(APP_DEBUG)) + C_FLAGS += -g -O0 -UNDEBUG +else + C_FLAGS += -O2 -DNDEBUG +endif +C_FLAGS += -Dbrx_init_unknown_device=brx_init_vk_device +C_FLAGS += -Dbrx_destroy_unknown_device=brx_destroy_vk_device +C_FLAGS += -I$(LOCAL_PATH)/../spirv +ifeq (true, $(APP_DEBUG)) + C_FLAGS += -I$(LOCAL_PATH)/../spirv/debug +else + C_FLAGS += -I$(LOCAL_PATH)/../spirv/release +endif +C_FLAGS += -DPAL_STDCPP_COMPAT=1 +C_FLAGS += -I$(THIRD_PARTY_DIR)/CoreRT/src/Native/inc/unix +C_FLAGS += -I$(THIRD_PARTY_DIR)/DirectXMath/Inc + +LD_FLAGS := +LD_FLAGS += -pthread +LD_FLAGS += -Wl,--no-undefined +LD_FLAGS += -Wl,--enable-new-dtags +LD_FLAGS += -Wl,-rpath,'$$ORIGIN' +ifneq (true, $(APP_DEBUG)) + LD_FLAGS += -s +endif + +all : \ + $(BIN_DIR)/glTF-Viewer + +# Link +ifeq (true, $(APP_DEBUG)) +$(BIN_DIR)/glTF-Viewer: \ + $(OBJ_DIR)/Demo-support-camera_controller.o \ + $(OBJ_DIR)/Demo-support-main.o \ + $(OBJ_DIR)/Demo-support-renderer.o \ + $(OBJ_DIR)/Demo-support-tick_count.o \ + $(OBJ_DIR)/Demo-demo.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_file.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_memory.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_dds.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_pvr.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf_cgltf.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset.o \ + $(BIN_DIR)/libBRX.so \ + $(BIN_DIR)/libVkLayer_khronos_validation.so \ + $(BIN_DIR)/VkLayer_khronos_validation.json \ + $(LOCAL_PATH)/Demo-Linux.map +else +$(BIN_DIR)/glTF-Viewer: \ + $(OBJ_DIR)/Demo-support-camera_controller.o \ + $(OBJ_DIR)/Demo-support-main.o \ + $(OBJ_DIR)/Demo-support-renderer.o \ + $(OBJ_DIR)/Demo-support-tick_count.o \ + $(OBJ_DIR)/Demo-demo.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_file.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_memory.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_dds.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_pvr.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf_cgltf.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset.o \ + $(BIN_DIR)/libBRX.so \ + $(LOCAL_PATH)/Demo-Linux.map +endif + $(HIDE) mkdir -p $(BIN_DIR) + $(HIDE) $(CC) -pie $(LD_FLAGS) \ + -Wl,--version-script=$(LOCAL_PATH)/Demo-Linux.map \ + $(OBJ_DIR)/Demo-support-camera_controller.o \ + $(OBJ_DIR)/Demo-support-main.o \ + $(OBJ_DIR)/Demo-support-renderer.o \ + $(OBJ_DIR)/Demo-support-tick_count.o \ + $(OBJ_DIR)/Demo-demo.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_file.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_memory.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_dds.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_pvr.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf_cgltf.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf.o \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset.o \ + -L$(BIN_DIR) -lBRX \ + -lxcb \ + -o $(BIN_DIR)/glTF-Viewer + +# Compile +$(OBJ_DIR)/Demo-support-camera_controller.o: $(SOURCE_DIR)/support/camera_controller.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/support/camera_controller.cpp -MD -MF $(OBJ_DIR)/Demo-support-camera_controller.d -o $(OBJ_DIR)/Demo-support-camera_controller.o + +$(OBJ_DIR)/Demo-support-main.o: $(SOURCE_DIR)/support/main.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/support/main.cpp -MD -MF $(OBJ_DIR)/Demo-support-main.d -o $(OBJ_DIR)/Demo-support-main.o + +$(OBJ_DIR)/Demo-support-renderer.o: $(SOURCE_DIR)/support/renderer.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/support/renderer.cpp -MD -MF $(OBJ_DIR)/Demo-support-renderer.d -o $(OBJ_DIR)/Demo-support-renderer.o + +$(OBJ_DIR)/Demo-support-tick_count.o: $(SOURCE_DIR)/support/tick_count.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/support/tick_count.cpp -MD -MF $(OBJ_DIR)/Demo-support-tick_count.d -o $(OBJ_DIR)/Demo-support-tick_count.o + +$(OBJ_DIR)/Demo-demo.o: $(SOURCE_DIR)/demo.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/demo.cpp -MD -MF $(OBJ_DIR)/Demo-demo.d -o $(OBJ_DIR)/Demo-demo.o + +$(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_file.o: $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_asset_input_stream_file.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_asset_input_stream_file.cpp -MD -MF $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_file.d -o $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_file.o + +$(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_memory.o: $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_asset_input_stream_memory.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_asset_input_stream_memory.cpp -MD -MF $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_memory.d -o $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_memory.o + +$(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_dds.o: $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_image_asset_dds.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_image_asset_dds.cpp -MD -MF $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_dds.d -o $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_dds.o + +$(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_pvr.o: $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_image_asset_pvr.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_image_asset_pvr.cpp -MD -MF $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_pvr.d -o $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_pvr.o + +$(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf_cgltf.o: $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_scene_asset_gltf_cgltf.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_scene_asset_gltf_cgltf.cpp -MD -MF $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf_cgltf.d -o $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf_cgltf.o + +$(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf.o: $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_scene_asset_gltf.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_scene_asset_gltf.cpp -MD -MF $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf.d -o $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf.o + +$(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset.o: $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_scene_asset.cpp + $(HIDE) mkdir -p $(OBJ_DIR) + $(HIDE) $(CC) -c $(C_FLAGS) $(SOURCE_DIR)/../thirdparty/ImportAsset/source/import_scene_asset.cpp -MD -MF $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset.d -o $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset.o + +# Copy +ifeq (true, $(APP_DEBUG)) +CONFIG_NAME := debug +else +CONFIG_NAME := release +endif +$(BIN_DIR)/libBRX.so: $(THIRD_PARTY_DIR)/Brioche/build-linux/bin/$(CONFIG_NAME)/libBRX.so + $(HIDE) mkdir -p $(BIN_DIR) + $(HIDE) cp -f $(THIRD_PARTY_DIR)/Brioche/build-linux/bin/$(CONFIG_NAME)/libBRX.so $(BIN_DIR)/libBRX.so + + +$(BIN_DIR)/libVkLayer_khronos_validation.so: $(THIRD_PARTY_DIR)/Brioche/thirdparty/Vulkan-ValidationLayers/bin/linux/x64/libVkLayer_khronos_validation.so + $(HIDE) mkdir -p $(BIN_DIR) + $(HIDE) cp -f $(THIRD_PARTY_DIR)/Brioche/thirdparty/Vulkan-ValidationLayers/bin/linux/x64/libVkLayer_khronos_validation.so $(BIN_DIR)/libVkLayer_khronos_validation.so + +$(BIN_DIR)/VkLayer_khronos_validation.json: $(THIRD_PARTY_DIR)/Brioche/thirdparty/Vulkan-ValidationLayers/bin/linux/x64/VkLayer_khronos_validation.json + $(HIDE) mkdir -p $(BIN_DIR) + $(HIDE) cp -f $(THIRD_PARTY_DIR)/Brioche/thirdparty/Vulkan-ValidationLayers/bin/linux/x64/VkLayer_khronos_validation.json $(BIN_DIR)/VkLayer_khronos_validation.json + +-include \ + $(OBJ_DIR)/Demo-support-camera_controller.d \ + $(OBJ_DIR)/Demo-support-main.d \ + $(OBJ_DIR)/Demo-support-renderer.d \ + $(OBJ_DIR)/Demo-support-tick_count.d \ + $(OBJ_DIR)/Demo-demo.d \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_file.d \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_memory.d \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_dds.d \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_pvr.d \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf_cgltf.d \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf.d \ + $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset.d + +clean: + $(HIDE) rm -f $(BIN_DIR)/glTF-Viewer + $(HIDE) rm -f $(OBJ_DIR)/Demo-support-camera_controller.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-support-main.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-support-renderer.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-support-tick_count.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-demo.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_file.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_memory.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_dds.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_pvr.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf_cgltf.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset.o + $(HIDE) rm -f $(OBJ_DIR)/Demo-support-camera_controller.d + $(HIDE) rm -f $(OBJ_DIR)/Demo-support-main.d + $(HIDE) rm -f $(OBJ_DIR)/Demo-support-renderer.d + $(HIDE) rm -f $(OBJ_DIR)/Demo-support-tick_count.d + $(HIDE) rm -f $(OBJ_DIR)/Demo-demo.d + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_file.d + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_asset_input_stream_memory.d + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_dds.d + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_image_asset_pvr.d + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf_cgltf.d + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset_gltf.d + $(HIDE) rm -f $(OBJ_DIR)/Demo-thirdparty-ImportAsset-import_scene_asset.d + $(HIDE) rm -f $(BIN_DIR)/libBRX.so +ifeq (true, $(APP_DEBUG)) + $(HIDE) rm -f $(BIN_DIR)/libVkLayer_khronos_validation.so + $(HIDE) rm -f $(BIN_DIR)/VkLayer_khronos_validation.json +endif + +.PHONY : \ + all \ + clean \ No newline at end of file diff --git a/build-windows/.gitignore b/build-windows/.gitignore new file mode 100644 index 0000000..b9884c6 --- /dev/null +++ b/build-windows/.gitignore @@ -0,0 +1,4 @@ +/.vs +/bin +/obj +/*.vcxproj.user diff --git a/build-windows/Demo-Windows-D3D12.vcxproj b/build-windows/Demo-Windows-D3D12.vcxproj new file mode 100644 index 0000000..8776344 --- /dev/null +++ b/build-windows/Demo-Windows-D3D12.vcxproj @@ -0,0 +1,292 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Document + Pixel + Pixel + Pixel + Pixel + + + Document + Vertex + Vertex + Vertex + Vertex + + + Document + Pixel + Pixel + Pixel + Pixel + + + + Document + Vertex + Vertex + Vertex + Vertex + + + + + + + Document + Pixel + Pixel + Pixel + Pixel + + + + + Document + Vertex + Vertex + Vertex + Vertex + + + + + {78fae1fa-0a6a-4408-9285-030a876b0649} + + + + 15.0 + {8515DB3F-23BB-424F-A356-2967FF78E83E} + Win32Proj + Demo-Windows-D3D12 + 10.0 + Demo-Windows-D3D12 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + glTF-Viewer-D3D12 + + + true + $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + glTF-Viewer-D3D12 + + + true + $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + glTF-Viewer-D3D12 + + + false + $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + glTF-Viewer-D3D12 + + + + Level3 + MaxSpeed + true + true + true + brx_init_unknown_device=brx_init_d3d12_device;brx_destroy_unknown_device=brx_destroy_d3d12_device;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) + ..\dxbc;..\dxbc\$(Configuration);%(AdditionalIncludeDirectories) + + + true + true + true + Windows + wmainCRTStartup + + + 5.1 + $(SolutionDir)\..\dxbc\$(Configuration)\_internal_%(Filename).inl + + %(Filename)_shader_module_code + + + + + Level3 + Disabled + true + brx_init_unknown_device=brx_init_d3d12_device;brx_destroy_unknown_device=brx_destroy_d3d12_device;_WINDOWS;_DEBUG;WIN32;%(PreprocessorDefinitions) + ProgramDatabase + ..\dxbc;..\dxbc\$(Configuration);%(AdditionalIncludeDirectories) + + + true + Windows + + + + + 209715200 + 104857600 + wmainCRTStartup + + + 5.1 + $(SolutionDir)\..\dxbc\$(Configuration)\_internal_%(Filename).inl + + %(Filename)_shader_module_code + + + + + Level3 + Disabled + true + brx_init_unknown_device=brx_init_d3d12_device;brx_destroy_unknown_device=brx_destroy_d3d12_device;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) + ProgramDatabase + ..\dxbc;..\dxbc\$(Configuration);%(AdditionalIncludeDirectories) + + + true + Windows + + + + + wmainCRTStartup + + + 5.1 + $(SolutionDir)\..\dxbc\$(Configuration)\_internal_%(Filename).inl + + %(Filename)_shader_module_code + + + + + Level3 + MaxSpeed + true + true + true + brx_init_unknown_device=brx_init_d3d12_device;brx_destroy_unknown_device=brx_destroy_d3d12_device;_WINDOWS;NDEBUG;WIN32;%(PreprocessorDefinitions) + ..\dxbc;..\dxbc\$(Configuration);%(AdditionalIncludeDirectories) + + + true + true + true + Windows + wmainCRTStartup + + + 5.1 + $(SolutionDir)\..\dxbc\$(Configuration)\_internal_%(Filename).inl + + %(Filename)_shader_module_code + + + + + + \ No newline at end of file diff --git a/build-windows/Demo-Windows-D3D12.vcxproj.filters b/build-windows/Demo-Windows-D3D12.vcxproj.filters new file mode 100644 index 0000000..7a60cae --- /dev/null +++ b/build-windows/Demo-Windows-D3D12.vcxproj.filters @@ -0,0 +1,181 @@ + + + + + {6564cc1a-1902-4833-bf99-8a3fd8b5f6fb} + + + {0fdd0fa4-cdf6-47e5-9605-a438eac8a7bf} + + + {4ea7a279-3984-44fb-905e-7243713ff6d4} + + + {6b62e300-cff7-473b-81b7-b9828e035938} + + + {1395e396-5ae8-4bc3-87ac-db1a12e3c0db} + + + {baf2d192-809f-42f3-87ef-cc9338cc67e4} + + + {878cdbd0-309f-49fe-bec5-bf64a8ea8c95} + + + {588679ab-dc7d-4f65-8caf-0737dc99ecf4} + + + {898b0181-2305-475e-b862-b329b30e9416} + + + {f2a3a172-54d9-4c6d-8db2-64846e2fdbcb} + + + {bd6f1366-4849-4592-be66-d8fcc6590719} + + + {c3721dee-ffe8-4532-acfd-9cb41ad2f05a} + + + + + source + + + source\support + + + source\support + + + source\support + + + source\support + + + thirdparty\ConvertUTF\source + + + thirdparty\ConvertUTF\source + + + thirdparty\ImportAsset\source + + + thirdparty\ImportAsset\source + + + thirdparty\ImportAsset\source + + + thirdparty\ImportAsset\source + + + thirdparty\ImportAsset\source + + + thirdparty\ImportAsset\source + + + thirdparty\ImportAsset\source + + + + + source + + + source\support + + + source\support + + + source\support + + + source\support + + + thirdparty\ConvertUTF\include + + + thirdparty\ImportAsset\include + + + thirdparty\ImportAsset\include + + + thirdparty\ImportAsset\include + + + thirdparty\ImportAsset\include + + + thirdparty\ImportAsset\include + + + + + shaders + + + dxbc + + + dxbc + + + dxbc + + + shaders + + + shaders + + + dxbc + + + shaders + + + dxbc + + + shaders\support + + + shaders + + + shaders + + + dxbc + + + + + shaders + + + shaders + + + shaders\support + + + shaders\support + + + shaders + + + shaders + + + \ No newline at end of file diff --git a/build-windows/Demo-Windows-VK.vcxproj b/build-windows/Demo-Windows-VK.vcxproj new file mode 100644 index 0000000..f56d107 --- /dev/null +++ b/build-windows/Demo-Windows-VK.vcxproj @@ -0,0 +1,362 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Document + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + Compile GLSL %(Filename) + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -O -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + Compile GLSL %(Filename) + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + Compile GLSL %(Filename) + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -O -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + Compile GLSL %(Filename) + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\support\full_screen_transfer_pipeline_layout.sli + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\support\full_screen_transfer_pipeline_layout.sli + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\support\full_screen_transfer_pipeline_layout.sli + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\support\full_screen_transfer_pipeline_layout.sli + + + Document + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + Compile GLSL %(Filename) + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -O -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + Compile GLSL %(Filename) + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + Compile GLSL %(Filename) + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -O -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + Compile GLSL %(Filename) + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\support\full_screen_transfer_pipeline_layout.sli + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\support\full_screen_transfer_pipeline_layout.sli + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\support\full_screen_transfer_pipeline_layout.sli + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\support\full_screen_transfer_pipeline_layout.sli + + + + + + Document + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + Compile GLSL %(Filename) + Compile GLSL %(Filename) + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\deferred_shading_pipeline_resource_binding.sli + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\deferred_shading_pipeline_resource_binding.sli + Compile GLSL %(Filename) + Compile GLSL %(Filename) + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\deferred_shading_pipeline_resource_binding.sli + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\deferred_shading_pipeline_resource_binding.sli + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + + + + Document + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + Compile GLSL %(Filename) + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + Compile GLSL %(Filename) + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\deferred_shading_pipeline_resource_binding.sli + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\deferred_shading_pipeline_resource_binding.sli + Compile GLSL %(Filename) + Compile GLSL %(Filename) + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\deferred_shading_pipeline_resource_binding.sli + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\deferred_shading_pipeline_resource_binding.sli + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + + + Document + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + Compile GLSL %(Filename) + Compile GLSL %(Filename) + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\gbuffer_pipeline_resource_binding.sli + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\gbuffer_pipeline_resource_binding.sli + Compile GLSL %(Filename) + Compile GLSL %(Filename) + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\gbuffer_pipeline_resource_binding.sli + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\gbuffer_pipeline_resource_binding.sli + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=frag -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + + + + Document + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -g -O0 -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + Compile GLSL %(Filename) + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + Compile GLSL %(Filename) + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\gbuffer_pipeline_resource_binding.sli + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\gbuffer_pipeline_resource_binding.sli + Compile GLSL %(Filename) + Compile GLSL %(Filename) + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\gbuffer_pipeline_resource_binding.sli + $(SolutionDir)..\thirdparty\Brioche\shaders\brx_define.sli;$(SolutionDir)..\shaders\gbuffer_pipeline_resource_binding.sli + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + "$(SolutionDir)..\thirdparty\Brioche\thirdparty\shaderc\bin\win32\x64\glslc.exe" -std=310es -mfmt=num -fshader-stage=vert -o "$(SolutionDir)\..\spirv\$(Configuration)\_internal_%(Filename).inl" "%(FullPath)" + + + + + + + Document + true + true + + + Document + true + true + + + Document + true + true + + + Document + true + true + + + + + + + + + + + {78fae1fa-0a6a-4408-9285-030a876b0649} + + + + 15.0 + {00ACFB22-3872-4380-BA9D-E1DD24888EF4} + Win32Proj + Demo-Windows-VK + 10.0 + Demo-Windows-VK + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + glTF-Viewer-VK + + + true + $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + glTF-Viewer-VK + + + true + $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + glTF-Viewer-VK + + + false + $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + glTF-Viewer-VK + + + + Level3 + MaxSpeed + true + true + true + brx_init_unknown_device=brx_init_vk_device;brx_destroy_unknown_device=brx_destroy_vk_device;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) + ..\spirv;..\spirv\$(Configuration); + + + true + true + true + Windows + wmainCRTStartup + + + + + Level3 + Disabled + true + brx_init_unknown_device=brx_init_vk_device;brx_destroy_unknown_device=brx_destroy_vk_device;_WINDOWS;_DEBUG;WIN32;%(PreprocessorDefinitions) + ProgramDatabase + ..\spirv;..\spirv\$(Configuration); + + + true + Windows + + + + + 209715200 + 104857600 + wmainCRTStartup + + + + + Level3 + Disabled + true + brx_init_unknown_device=brx_init_vk_device;brx_destroy_unknown_device=brx_destroy_vk_device;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) + ProgramDatabase + ..\spirv;..\spirv\$(Configuration); + + + true + Windows + + + + + wmainCRTStartup + + + + + Level3 + MaxSpeed + true + true + true + brx_init_unknown_device=brx_init_vk_device;brx_destroy_unknown_device=brx_destroy_vk_device;_WINDOWS;NDEBUG;WIN32;%(PreprocessorDefinitions) + ..\spirv;..\spirv\$(Configuration); + + + true + true + true + Windows + wmainCRTStartup + + + + + + \ No newline at end of file diff --git a/build-windows/Demo-Windows-VK.vcxproj.filters b/build-windows/Demo-Windows-VK.vcxproj.filters new file mode 100644 index 0000000..3c06cb8 --- /dev/null +++ b/build-windows/Demo-Windows-VK.vcxproj.filters @@ -0,0 +1,204 @@ + + + + + source + + + source\support + + + source\support + + + source\support + + + source\support + + + thirdparty\ImportAsset\source + + + thirdparty\ImportAsset\source + + + thirdparty\ImportAsset\source + + + thirdparty\ImportAsset\source + + + thirdparty\ConvertUTF\source + + + thirdparty\ConvertUTF\source + + + thirdparty\ImportAsset\source + + + thirdparty\ImportAsset\source + + + thirdparty\ImportAsset\source + + + + + source + + + source\support + + + source\support + + + source\support + + + source\support + + + thirdparty\ImportAsset\include + + + thirdparty\ImportAsset\include + + + thirdparty\ConvertUTF\include + + + thirdparty\ImportAsset\include + + + thirdparty\ImportAsset\include + + + thirdparty\ImportAsset\include + + + + + shaders\support + + + shaders\support + + + shaders + + + shaders + + + shaders + + + shaders + + + + + thirdparty\Vulkan-ValidationLayers\x86 + + + thirdparty\Vulkan-ValidationLayers\x86 + + + thirdparty\Vulkan-ValidationLayers\x64 + + + thirdparty\Vulkan-ValidationLayers\x64 + + + + + spirv + + + spirv + + + shaders\support + + + spirv + + + spirv + + + shaders + + + shaders + + + shaders + + + shaders + + + shaders + + + shaders + + + spirv + + + spirv + + + + + {5ef8ee9f-5a80-48bd-82a4-0cec12b21719} + + + {f6b3b0f4-57bb-4f0f-b3c1-af7cb367457c} + + + {3fd46330-fb50-48b9-9af8-f2bd1292021a} + + + {0a393837-6c85-4124-89a5-28e5ae120ec4} + + + {8392cec9-8a4b-4f55-939a-fda75c196bb8} + + + {20e5e431-be5d-49a8-9c62-4973be7abee1} + + + {9a26aaf8-9e1c-45da-a6dc-54788eb50266} + + + {59f24b2c-072f-4fca-91b0-b70b46bd4124} + + + {acd6da07-575e-4359-9d68-a0998b90dd02} + + + {c65442bb-15e9-4bfc-bc0c-4c74edddd1f5} + + + {f090f88f-683a-427f-9207-32271dc25c91} + + + {4d5eedcd-4e13-4bfb-826d-97363f91be3e} + + + {7538861b-f7f1-439f-9192-ca28dbf261ad} + + + {b5d88abe-d344-44b6-9031-e70cc4549238} + + + {a65309de-7b7b-4e93-9b1d-5a4c03e6a9b9} + + + \ No newline at end of file diff --git a/build-windows/Demo-Windows.sln b/build-windows/Demo-Windows.sln new file mode 100644 index 0000000..47573a9 --- /dev/null +++ b/build-windows/Demo-Windows.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31314.256 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Demo-Windows-VK", "Demo-Windows-VK.vcxproj", "{00ACFB22-3872-4380-BA9D-E1DD24888EF4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BRX-Windows", "..\thirdparty\Brioche\build-windows\BRX-Windows.vcxproj", "{78FAE1FA-0A6A-4408-9285-030A876B0649}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Demo-Windows-D3D12", "Demo-Windows-D3D12.vcxproj", "{8515DB3F-23BB-424F-A356-2967FF78E83E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {00ACFB22-3872-4380-BA9D-E1DD24888EF4}.Debug|x64.ActiveCfg = Debug|x64 + {00ACFB22-3872-4380-BA9D-E1DD24888EF4}.Debug|x64.Build.0 = Debug|x64 + {00ACFB22-3872-4380-BA9D-E1DD24888EF4}.Debug|x86.ActiveCfg = Debug|Win32 + {00ACFB22-3872-4380-BA9D-E1DD24888EF4}.Debug|x86.Build.0 = Debug|Win32 + {00ACFB22-3872-4380-BA9D-E1DD24888EF4}.Release|x64.ActiveCfg = Release|x64 + {00ACFB22-3872-4380-BA9D-E1DD24888EF4}.Release|x64.Build.0 = Release|x64 + {00ACFB22-3872-4380-BA9D-E1DD24888EF4}.Release|x86.ActiveCfg = Release|Win32 + {00ACFB22-3872-4380-BA9D-E1DD24888EF4}.Release|x86.Build.0 = Release|Win32 + {78FAE1FA-0A6A-4408-9285-030A876B0649}.Debug|x64.ActiveCfg = Debug|x64 + {78FAE1FA-0A6A-4408-9285-030A876B0649}.Debug|x64.Build.0 = Debug|x64 + {78FAE1FA-0A6A-4408-9285-030A876B0649}.Debug|x86.ActiveCfg = Debug|Win32 + {78FAE1FA-0A6A-4408-9285-030A876B0649}.Debug|x86.Build.0 = Debug|Win32 + {78FAE1FA-0A6A-4408-9285-030A876B0649}.Release|x64.ActiveCfg = Release|x64 + {78FAE1FA-0A6A-4408-9285-030A876B0649}.Release|x64.Build.0 = Release|x64 + {78FAE1FA-0A6A-4408-9285-030A876B0649}.Release|x86.ActiveCfg = Release|Win32 + {78FAE1FA-0A6A-4408-9285-030A876B0649}.Release|x86.Build.0 = Release|Win32 + {8515DB3F-23BB-424F-A356-2967FF78E83E}.Debug|x64.ActiveCfg = Debug|x64 + {8515DB3F-23BB-424F-A356-2967FF78E83E}.Debug|x64.Build.0 = Debug|x64 + {8515DB3F-23BB-424F-A356-2967FF78E83E}.Debug|x86.ActiveCfg = Debug|Win32 + {8515DB3F-23BB-424F-A356-2967FF78E83E}.Debug|x86.Build.0 = Debug|Win32 + {8515DB3F-23BB-424F-A356-2967FF78E83E}.Release|x64.ActiveCfg = Release|x64 + {8515DB3F-23BB-424F-A356-2967FF78E83E}.Release|x64.Build.0 = Release|x64 + {8515DB3F-23BB-424F-A356-2967FF78E83E}.Release|x86.ActiveCfg = Release|Win32 + {8515DB3F-23BB-424F-A356-2967FF78E83E}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C128871C-DA37-4E4F-A583-4089B7086626} + EndGlobalSection +EndGlobal diff --git a/dxbc/.gitignore b/dxbc/.gitignore new file mode 100644 index 0000000..70a618f --- /dev/null +++ b/dxbc/.gitignore @@ -0,0 +1,2 @@ +/debug +/release diff --git a/dxbc/deferred_shading_fragment.inl b/dxbc/deferred_shading_fragment.inl new file mode 100644 index 0000000..443de6e --- /dev/null +++ b/dxbc/deferred_shading_fragment.inl @@ -0,0 +1,3 @@ +#define BYTE uint8_t +#include <_internal_deferred_shading_fragment.inl> +#undef BYTE \ No newline at end of file diff --git a/dxbc/deferred_shading_vertex.inl b/dxbc/deferred_shading_vertex.inl new file mode 100644 index 0000000..fca9f26 --- /dev/null +++ b/dxbc/deferred_shading_vertex.inl @@ -0,0 +1,3 @@ +#define BYTE uint8_t +#include <_internal_deferred_shading_vertex.inl> +#undef BYTE \ No newline at end of file diff --git a/dxbc/full_screen_transfer_fragment.inl b/dxbc/full_screen_transfer_fragment.inl new file mode 100644 index 0000000..80efb2d --- /dev/null +++ b/dxbc/full_screen_transfer_fragment.inl @@ -0,0 +1,3 @@ +#define BYTE uint8_t +#include <_internal_full_screen_transfer_fragment.inl> +#undef BYTE \ No newline at end of file diff --git a/dxbc/full_screen_transfer_vertex.inl b/dxbc/full_screen_transfer_vertex.inl new file mode 100644 index 0000000..ec96e19 --- /dev/null +++ b/dxbc/full_screen_transfer_vertex.inl @@ -0,0 +1,3 @@ +#define BYTE uint8_t +#include <_internal_full_screen_transfer_vertex.inl> +#undef BYTE \ No newline at end of file diff --git a/dxbc/gbuffer_fragment.inl b/dxbc/gbuffer_fragment.inl new file mode 100644 index 0000000..9b51e9a --- /dev/null +++ b/dxbc/gbuffer_fragment.inl @@ -0,0 +1,3 @@ +#define BYTE uint8_t +#include <_internal_gbuffer_fragment.inl> +#undef BYTE \ No newline at end of file diff --git a/dxbc/gbuffer_vertex.inl b/dxbc/gbuffer_vertex.inl new file mode 100644 index 0000000..a31bad0 --- /dev/null +++ b/dxbc/gbuffer_vertex.inl @@ -0,0 +1,3 @@ +#define BYTE uint8_t +#include <_internal_gbuffer_vertex.inl> +#undef BYTE \ No newline at end of file diff --git a/shaders/common_resource_binding.sli b/shaders/common_resource_binding.sli new file mode 100644 index 0000000..114c4b1 --- /dev/null +++ b/shaders/common_resource_binding.sli @@ -0,0 +1,36 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _COMMON_RESOURCE_BINDING_SLI_ +#define _COMMON_RESOURCE_BINDING_SLI_ 1 + +#include "../thirdparty/Brioche/shaders/brx_define.sli" + +brx_cbuffer(common_none_update_set_uniform_buffer_binding, 0, 0) +{ + brx_column_major brx_float4x4 g_view_transform; + brx_column_major brx_float4x4 g_projection_transform; + brx_column_major brx_float4x4 g_inverse_view_transform; + brx_column_major brx_float4x4 g_inverse_projection_transform; + + brx_float g_screen_width; + brx_float g_screen_height; + brx_float _unused_padding_1; + brx_float _unused_padding_2; +}; + +#endif \ No newline at end of file diff --git a/shaders/deferred_shading_fragment.sl b/shaders/deferred_shading_fragment.sl new file mode 100644 index 0000000..3bc7dfb --- /dev/null +++ b/shaders/deferred_shading_fragment.sl @@ -0,0 +1,158 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#include "deferred_shading_pipeline_resource_binding.sli" +#include "octahedron_mapping.sli" +#include "packed_vector.sli" +#include "math_constant.sli" + +#define INVALID_GBUFFER_DEPTH 0.0 + +brx_root_signature(deferred_shading_root_signature_macro, deferred_shading_root_signature_name) +brx_early_depth_stencil +brx_pixel_shader_parameter_begin(main) +brx_pixel_shader_parameter_in_frag_coord brx_pixel_shader_parameter_split +brx_pixel_shader_parameter_out(brx_float4, out_color, 0) +brx_pixel_shader_parameter_end(main) +{ + brx_float depth = brx_load_2d(g_depth_texture[0], brx_int3(brx_frag_coord.xy, 0)).x; + + brx_branch + if (INVALID_GBUFFER_DEPTH == depth) + { + out_color = brx_float4(0.0, 0.0, 0.0, 1.0); + return; + } + + brx_uint4 gbuffer = brx_load_2d(g_gbuffer_texture[0], brx_int3(brx_frag_coord.xy, 0)); + + brx_float3 shading_normal_world_space = octahedron_unmap(R16G16_SNORM_to_FLOAT2(gbuffer.x)); + brx_float3 base_color = R10G10B10A2_UNORM_to_FLOAT4(gbuffer.y).xyz; + brx_float2 metallic_roughness = R16G16_UNORM_to_FLOAT2(gbuffer.z); + brx_float metallic = metallic_roughness.x; + brx_float roughness = metallic_roughness.y; + brx_float3 emissive = R10G10B10A2_UNORM_to_FLOAT4(gbuffer.w).xyz; + + const brx_float dielectric_specular = 0.04; + brx_float3 f0 = brx_clamp(brx_lerp(brx_float3(dielectric_specular, dielectric_specular, dielectric_specular), base_color, metallic), brx_float3(0.0, 0.0, 0.0), brx_float3(1.0, 1.0, 1.0)); + brx_float3 albedo = brx_clamp(base_color - f0, brx_float3(0.0, 0.0, 0.0), brx_float3(1.0, 1.0, 1.0)); + + brx_float3 surface_position_world_space; + { + brx_float2 uv = brx_frag_coord.xy / brx_float2(g_screen_width, g_screen_height); + + brx_float surface_position_depth = depth; + + brx_float3 surface_position_ndc_space = brx_float3(uv * brx_float2(2.0, -2.0) + brx_float2(-1.0, 1.0), surface_position_depth); + + brx_float4 surface_position_view_space_with_w = brx_mul(g_inverse_projection_transform, brx_float4(surface_position_ndc_space, 1.0)); + + brx_float3 surface_position_view_space = surface_position_view_space_with_w.xyz / surface_position_view_space_with_w.w; + + surface_position_world_space = brx_mul(g_inverse_view_transform, brx_float4(surface_position_view_space, 1.0)).xyz; + } + + brx_float3 camera_ray_origin = brx_mul(g_inverse_view_transform, brx_float4(0.0, 0.0, 0.0, 1.0)).xyz; + + // TODO: shadow + // TODO: environment lighting + brx_float3 outgoing_radiance = brx_float3(0.0, 0.0, 0.0); + + const brx_float3 incident_illuminances[2] = brx_array_constructor_begin(brx_float3, 2) + brx_float3(1.0, 1.0, 1.0) brx_array_constructor_split + brx_float3(1.0, 1.0, 1.0) + brx_array_constructor_end; + + const brx_float3 Ls[2] = brx_array_constructor_begin(brx_float3, 2) + brx_float3(0.73994, 0.64279, 0.19827) brx_array_constructor_split + brx_float3(-0.73994, 0.64279, 0.19827) + brx_array_constructor_end; + + brx_unroll + for(brx_int incident_light_index = 0; incident_light_index < 2; ++incident_light_index) + { + brx_float3 incident_illuminance = incident_illuminances[incident_light_index]; + brx_float3 L = brx_normalize(Ls[incident_light_index]); + + brx_float3 V = brx_normalize(camera_ray_origin - surface_position_world_space); + brx_float3 N = shading_normal_world_space; + brx_float3 H = normalize(L + V); + brx_float NdotL = brx_clamp(dot(N, L), 0.0, 1.0); + brx_float NdotH = brx_clamp(dot(N, H), 0.0, 1.0); + brx_float NdotV = brx_clamp(dot(N, V), 0.0, 1.0); + brx_float VdotH = brx_clamp(dot(V, H), 0.0, 1.0); + + brx_float3 brdf_diffuse; + { + // Lambert + + brdf_diffuse = (1.0 / M_PI) * albedo; + } + + brx_float3 brdf_specular; + { + // Trowbridge Reitz + + // Real-Time Rendering Fourth Edition / 9.8.1 Normal Distribution Functions: "In the Disney principled shading model, Burley[214] exposes the roughness control to users as ��g = r2, where r is the user-interface roughness parameter value between 0 and 1." + brx_float alpha = roughness * roughness; + + // Equation 9.41 of Real-Time Rendering Fourth Edition: "Although **Trowbridge-Reitz distribution** is technically the correct name" + // Equation 8.11 of PBR Book: https://pbr-book.org/3ed-2018/Reflection_Models/Microfacet_Models#MicrofacetDistributionFunctions + brx_float alpha2 = alpha * alpha; + brx_float denominator = 1.0 + NdotH * (NdotH * alpha2 - NdotH); + brx_float D = (1.0 / M_PI) * (alpha2 / (denominator * denominator)); + + // Lambda: + // Equation 8.13 of PBR Book: https://pbr-book.org/3ed-2018/Reflection_Models/Microfacet_Models#MaskingandShadowing + // Equation 9.42 of Real-Time Rendering Fourth Edition + // Figure 8.18 of PBR Book: https://pbr-book.org/3ed-2018/Reflection_Models/Microfacet_Models#MaskingandShadowing + // Lambda(V) = 0.5*(-1.0 + (1.0/NoV)*sqrt(alpha^2 + (1.0 - alpha^2)*NoV^2)) + // Lambda(L) = 0.5*(-1.0 + (1.0/NoL)*sqrt(alpha^2 + (1.0 - alpha^2)*NoL^2)) + + // G2 + // Equation 9.31 of Real-Time Rendering Fourth Edition + // PBR Book / 8.4.3 Masking and Shadowing: "A more accurate model can be derived assuming that microfacet visibility is more likely the higher up a given point on a microface" + // G2 = 1.0/(1.0 + Lambda(V) + Lambda(L)) = (2.0*NoV*NoL)/(NoL*sqrt(alpha^2 + (1.0 - alpha^2)*NoV^2) + NoV*sqrt(alpha^2 + (1.0 - alpha^2)*NoL^2)) + + // V = G2/(4.0*NoV*NoL) = 0.5/(NoL*sqrt(alpha^2 + (1.0 - alpha^2)*NoV^2) + NoV*sqrt(alpha^2 + (1.0 - alpha^2)*NoL^2)) + + // float alpha2 = alpha * alpha; + // float term_v = NdotL * sqrt(alpha2 + (1.0 - alpha2) * NdotV * NdotV); + // float term_l = NdotV * sqrt(alpha2 + (1.0 - alpha2) * NdotL * NdotL); + // UE: [Vis_SmithJointApprox](https://github.com/EpicGames/UnrealEngine/blob/4.27/Engine/Shaders/Private/BRDF.ush#L380) + brx_float term_v = NdotL * (alpha + (1.0 - alpha) * NdotV); + brx_float term_l = NdotV * (alpha + (1.0 - alpha) * NdotL); + brx_float V = (0.5 / (term_v + term_l)); + + // glTF Sample Renderer: [F_Schlick](https://github.com/KhronosGroup/glTF-Sample-Renderer/blob/e5646a2bf87b0871ba3f826fc2335fe117a11411/source/Renderer/shaders/brdf.glsl#L24) + const brx_float3 f90 = brx_float3(1.0, 1.0, 1.0); + + brx_float x = brx_clamp(1.0 - VdotH, 0.0, 1.0); + brx_float x2 = x * x; + brx_float x5 = x * x2 * x2; + brx_float3 F = f0 + (f90 - f0) * x5; + + brdf_specular = D * V * F; + } + + outgoing_radiance += (brdf_diffuse + brdf_specular) * (NdotL * incident_illuminance); + } + + outgoing_radiance += emissive; + + out_color = brx_float4(outgoing_radiance, 1.0); +} \ No newline at end of file diff --git a/shaders/deferred_shading_pipeline_resource_binding.sli b/shaders/deferred_shading_pipeline_resource_binding.sli new file mode 100644 index 0000000..60e23c5 --- /dev/null +++ b/shaders/deferred_shading_pipeline_resource_binding.sli @@ -0,0 +1,35 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _DEFERRED_SHADING_TRANSFER_PIPELINE_LAYOUT_SLI_ +#define _DEFERRED_SHADING_TRANSFER_PIPELINE_LAYOUT_SLI_ 1 + +#include "../thirdparty/Brioche/shaders/brx_define.sli" +#include "common_resource_binding.sli" + +brx_texture_2d_uint(g_gbuffer_texture, 0, 1, 1); + +brx_texture_2d(g_depth_texture, 0, 2, 1); + +#define deferred_shading_root_signature_macro \ + brx_root_signature_root_parameter_begin(deferred_shading_root_signature_name) \ + brx_root_signature_root_cbv(0, 0) brx_root_signature_root_parameter_split \ + brx_root_signature_root_descriptor_table_srv(0, 1, 1) brx_root_signature_root_parameter_split \ + brx_root_signature_root_descriptor_table_srv(0, 2, 1) \ + brx_root_signature_root_parameter_end + +#endif \ No newline at end of file diff --git a/shaders/deferred_shading_vertex.sl b/shaders/deferred_shading_vertex.sl new file mode 100644 index 0000000..c3499ff --- /dev/null +++ b/shaders/deferred_shading_vertex.sl @@ -0,0 +1,33 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#include "deferred_shading_pipeline_resource_binding.sli" + +brx_root_signature(deferred_shading_root_signature_macro, deferred_shading_root_signature_name) +brx_vertex_shader_parameter_begin(main) +brx_vertex_shader_parameter_in_vertex_id brx_vertex_shader_parameter_split +brx_vertex_shader_parameter_out_position +brx_vertex_shader_parameter_end(main) +{ + const brx_float2 full_screen_triangle_positions[3] = brx_array_constructor_begin(brx_float2, 3) + brx_float2(-1.0, -1.0) brx_array_constructor_split + brx_float2(3.0, -1.0) brx_array_constructor_split + brx_float2(-1.0, 3.0) + brx_array_constructor_end; + + brx_position = brx_float4(full_screen_triangle_positions[brx_vertex_id], 0.5, 1.0); +} \ No newline at end of file diff --git a/shaders/gbuffer_fragment.sl b/shaders/gbuffer_fragment.sl new file mode 100644 index 0000000..a419ec2 --- /dev/null +++ b/shaders/gbuffer_fragment.sl @@ -0,0 +1,94 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#include "gbuffer_pipeline_resource_binding.sli" +#include "octahedron_mapping.sli" +#include "packed_vector.sli" + +brx_root_signature(gbuffer_root_signature_macro, gbuffer_root_signature_name) +brx_early_depth_stencil +brx_pixel_shader_parameter_begin(main) +brx_pixel_shader_parameter_in_frag_coord brx_pixel_shader_parameter_split +brx_pixel_shader_parameter_in(brx_float3, in_interpolated_normal, 0) brx_pixel_shader_parameter_split +brx_pixel_shader_parameter_in(brx_float4, in_interpolated_tangent, 1) brx_pixel_shader_parameter_split +brx_pixel_shader_parameter_in(brx_float2, in_interpolated_texcoord, 2) brx_pixel_shader_parameter_split +brx_pixel_shader_parameter_out(brx_uint4, out_gbuffer, 0) +brx_pixel_shader_parameter_end(main) +{ + brx_float3 geometry_normal_world_sapce = brx_normalize(in_interpolated_normal); + brx_float4 tangent_world_sapce = brx_float4(brx_normalize(in_interpolated_tangent.xyz), in_interpolated_tangent.w); + brx_float2 texcoord = in_interpolated_texcoord; + + brx_uint4 packed_material_buffer_vectors[3]; + packed_material_buffer_vectors[0] = brx_byte_address_buffer_load4(g_geometry_material_buffers[3], 0); + packed_material_buffer_vectors[1] = brx_byte_address_buffer_load4(g_geometry_material_buffers[3], 4 * 4); + packed_material_buffer_vectors[2].xy = brx_byte_address_buffer_load2(g_geometry_material_buffers[3], 4 * 4 + 4 * 4); + brx_uint material_texture_enable_flags = packed_material_buffer_vectors[0].x; + brx_float normal_texture_scale = brx_uint_as_float(packed_material_buffer_vectors[0].y); + brx_float3 emissive_factor = brx_uint_as_float(brx_uint3(packed_material_buffer_vectors[0].zw, packed_material_buffer_vectors[1].x)); + brx_float3 base_color_factor = brx_uint_as_float(packed_material_buffer_vectors[1].yzw); + brx_float metallic_factor = brx_uint_as_float(packed_material_buffer_vectors[2].x); + brx_float roughness_factor = brx_uint_as_float(packed_material_buffer_vectors[2].y); + + brx_float3 shading_normal_world_space; + brx_branch + if(0u != (material_texture_enable_flags & Material_Texture_Enable_Normal)) + { + // ["5.20.3. material.normalTextureInfo.scale" of "glTF 2.0 Specification"](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_material_normaltextureinfo_scale) + brx_float3 shading_normal_tangent_space = brx_normalize((brx_sample_2d(g_material_textures[0], g_sampler[0], texcoord).xyz * 2.0 - brx_float3(1.0, 1.0, 1.0)) * brx_float3(normal_texture_scale, normal_texture_scale, 1.0)); + brx_float3 bitangent_world_sapce = brx_cross(geometry_normal_world_sapce, tangent_world_sapce.xyz) * tangent_world_sapce.w; + shading_normal_world_space = brx_normalize(tangent_world_sapce.xyz * shading_normal_tangent_space.x + bitangent_world_sapce * shading_normal_tangent_space.y + geometry_normal_world_sapce * shading_normal_tangent_space.z); + } + else + { + shading_normal_world_space = geometry_normal_world_sapce; + } + + brx_float3 emissive = emissive_factor; + brx_branch + if(0u != (material_texture_enable_flags & Material_Texture_Enable_Emissive)) + { + emissive *= brx_sample_2d(g_material_textures[1], g_sampler[0], texcoord).xyz; + } + + brx_float3 base_color = base_color_factor; + brx_branch + if(0u != (material_texture_enable_flags & Material_Texture_Enable_Base_Color)) + { + base_color *= brx_sample_2d(g_material_textures[2], g_sampler[0], texcoord).xyz; + } + + brx_float metallic = metallic_factor; + brx_float roughness = roughness_factor; + brx_branch + if(0u != (material_texture_enable_flags & Material_Texture_Enable_Metallic_Roughness)) + { + brx_float2 metallic_roughness = brx_sample_2d(g_material_textures[3], g_sampler[0], texcoord).bg; + metallic *= metallic_roughness.x; + roughness *= metallic_roughness.y; + } + + // TODO: Specular Antialiasing + // Toksvig + + brx_uint packed_shading_normal_world_space = FLOAT2_to_R16G16_SNORM(octahedron_map(shading_normal_world_space)); + brx_uint packed_base_color = FLOAT4_to_R10G10B10A2_UNORM(brx_float4(base_color.x, base_color.y, base_color.z, 1.0)); + brx_uint packed_metallic_roughness = FLOAT2_to_R16G16_UNORM(brx_float2(metallic, roughness)); + brx_uint packed_emissive = FLOAT4_to_R10G10B10A2_UNORM(brx_float4(emissive.x, emissive.y, emissive.z, 1.0)); + + out_gbuffer = brx_uint4(packed_shading_normal_world_space, packed_base_color, packed_metallic_roughness, packed_emissive); +} \ No newline at end of file diff --git a/shaders/gbuffer_pipeline_resource_binding.sli b/shaders/gbuffer_pipeline_resource_binding.sli new file mode 100644 index 0000000..0b934e7 --- /dev/null +++ b/shaders/gbuffer_pipeline_resource_binding.sli @@ -0,0 +1,79 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _GBUFFER_PIPELINE_RESOURCE_BINDING_SLI_ +#define _GBUFFER_PIPELINE_RESOURCE_BINDING_SLI_ 1 + +#include "../thirdparty/Brioche/shaders/brx_define.sli" +#include "common_resource_binding.sli" + +#define g_vertex_position_buffer_stride 12u +#define g_vertex_varying_buffer_stride 12u +#define g_index_buffer_stride 2u + +#if defined(__cplusplus) +static_assert((sizeof(scene_mesh_vertex_position_binding)) == g_vertex_position_buffer_stride, ""); +static_assert((sizeof(scene_mesh_vertex_varying_binding)) == g_vertex_varying_buffer_stride, ""); +static_assert((sizeof(uint16_t)) == g_index_buffer_stride, ""); +#endif + +#define Material_Texture_Enable_Normal 0x1u +#define Material_Texture_Enable_Emissive 0x2u +#define Material_Texture_Enable_Base_Color 0x4u +#define Material_Texture_Enable_Metallic_Roughness 0x8u + +#if defined(__cplusplus) +struct gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding +{ + uint32_t m_material_texture_enable_flags; + float m_normal_texture_scale; + float m_emissive_factor_x; + float m_emissive_factor_y; + + float m_emissive_factor_z; + float m_base_color_factor_x; + float m_base_color_factor_y; + float m_base_color_factor_z; + + float m_metallic_factor; + float m_roughness_factor; + uint32_t _unused_padding_1; + uint32_t _unused_padding_2; +}; +#endif + +brx_sampler_state(g_sampler, 0, 1, 1); + +brx_read_only_byte_address_buffer(g_geometry_material_buffers, 1, 0, 4); + +brx_texture_2d(g_material_textures, 1, 4, 4); + +brx_cbuffer(gbuffer_pipeline_per_mesh_instance_update_set_uniform_buffer_binding, 2, 0) +{ + brx_column_major brx_float4x4 g_model_transform; +}; + +#define gbuffer_root_signature_macro \ + brx_root_signature_root_parameter_begin(gbuffer_root_signature_name) \ + brx_root_signature_root_cbv(0, 0) brx_root_signature_root_parameter_split \ + brx_root_signature_root_descriptor_table_sampler(0, 1, 1) brx_root_signature_root_parameter_split \ + brx_root_signature_root_descriptor_table_srv(1, 0, 4) brx_root_signature_root_parameter_split \ + brx_root_signature_root_descriptor_table_srv(1, 4, 4) brx_root_signature_root_parameter_split \ + brx_root_signature_root_cbv(2, 0) \ + brx_root_signature_root_parameter_end + +#endif \ No newline at end of file diff --git a/shaders/gbuffer_vertex.sl b/shaders/gbuffer_vertex.sl new file mode 100644 index 0000000..48281c6 --- /dev/null +++ b/shaders/gbuffer_vertex.sl @@ -0,0 +1,58 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#include "gbuffer_pipeline_resource_binding.sli" +#include "packed_vector.sli" +#include "octahedron_mapping.sli" + +brx_root_signature(gbuffer_root_signature_macro, gbuffer_root_signature_name) +brx_vertex_shader_parameter_begin(main) +brx_vertex_shader_parameter_in_vertex_id brx_vertex_shader_parameter_split +brx_vertex_shader_parameter_out_position brx_vertex_shader_parameter_split +brx_vertex_shader_parameter_out(brx_float3, out_vertex_normal, 0) brx_vertex_shader_parameter_split +brx_vertex_shader_parameter_out(brx_float4, out_vertex_tagent, 1) brx_vertex_shader_parameter_split +brx_vertex_shader_parameter_out(brx_float2, out_vertex_texcoord, 2) +brx_vertex_shader_parameter_end(main) +{ + brx_uint index_buffer_offset = (0u == ((g_index_buffer_stride * brx_uint(brx_vertex_id)) % 4u)) ? (g_index_buffer_stride * brx_uint(brx_vertex_id)) : ((g_index_buffer_stride * brx_uint(brx_vertex_id)) - 2u); + brx_uint packed_vector_index_buffer = brx_byte_address_buffer_load(g_geometry_material_buffers[2], index_buffer_offset); + brx_uint2 unpacked_vector_index_buffer = R16G16_UINT_to_UINT2(packed_vector_index_buffer); + brx_uint vertex_index = (0u == ((g_index_buffer_stride * brx_uint(brx_vertex_id)) % 4u)) ? unpacked_vector_index_buffer.x : unpacked_vector_index_buffer.y; + + brx_uint vertex_position_buffer_offset = g_vertex_position_buffer_stride * vertex_index; + brx_float3 vertex_position_model_space = brx_uint_as_float(brx_byte_address_buffer_load3(g_geometry_material_buffers[0], vertex_position_buffer_offset)); + + brx_uint vertex_varying_buffer_offset = g_vertex_varying_buffer_stride * vertex_index; + brx_uint3 packed_vector_vertex_varying_buffer = brx_byte_address_buffer_load3(g_geometry_material_buffers[1], vertex_varying_buffer_offset); + brx_float3 vertex_normal_model_space = R10G10B10A2_SNORM_to_FLOAT4(packed_vector_vertex_varying_buffer.x).xyz; + brx_float4 vertex_tangent_model_space = R10G10B10A2_SNORM_to_FLOAT4(packed_vector_vertex_varying_buffer.y); + brx_float2 vertex_texcoord = R16G16_UNORM_to_FLOAT2(packed_vector_vertex_varying_buffer.z); + + brx_float3 vertex_position_world_space = brx_mul(g_model_transform, brx_float4(vertex_position_model_space, 1.0)).xyz; + brx_float3 vertex_position_view_space = brx_mul(g_view_transform, brx_float4(vertex_position_world_space, 1.0)).xyz; + brx_float4 vertex_position_clip_space = brx_mul(g_projection_transform, brx_float4(vertex_position_view_space, 1.0)); + + brx_float3 vertex_normal_world_space = brx_mul(g_model_transform, brx_float4(vertex_normal_model_space, 0.0)).xyz; + + brx_float4 vertex_tangent_world_space = brx_float4(brx_mul(g_model_transform, brx_float4(vertex_tangent_model_space.xyz, 0.0)).xyz, vertex_tangent_model_space.w); + + brx_position = vertex_position_clip_space; + out_vertex_normal = vertex_normal_world_space; + out_vertex_tagent = vertex_tangent_world_space; + out_vertex_texcoord = vertex_texcoord; +} + diff --git a/shaders/math_constant.sli b/shaders/math_constant.sli new file mode 100644 index 0000000..dbdbb79 --- /dev/null +++ b/shaders/math_constant.sli @@ -0,0 +1,23 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _MATH_CONSTANT_SLI_ +#define _MATH_CONSTANT_SLI_ 1 + +#define M_PI 3.141592653589793238462643 + +#endif \ No newline at end of file diff --git a/shaders/octahedron_mapping.sli b/shaders/octahedron_mapping.sli new file mode 100644 index 0000000..a39c97f --- /dev/null +++ b/shaders/octahedron_mapping.sli @@ -0,0 +1,86 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _OCTAHEDRON_MAPPING_SLI_ +#define _OCTAHEDRON_MAPPING_SLI_ 1 + +// [Engelhardt 2008] Thomas Engelhardt, Carsten Dachsbacher. "Octahedron Environment Maps." VMV 2008. +// [Cigolle 2014] Zina Cigolle, Sam Donow, Daniel Evangelakos, Michael Mara, Morgan McGuire, Quirin Meyer. "A Survey of Efficient Representations for Independent Unit Vectors." JCGT 2014. + +// Real-Time Rendering Fourth Edition: 16.6 Compression and Precision + +// PBR Book V4: [3.8.3 Spherical Parameterizations / Octahedral Encoding](https://pbr-book.org/4ed/Geometry_and_Transformations/Spherical_Geometry#x3-OctahedralEncoding) +// PBRT-V4 [OctahedralVector::OctahedralVector](https://github.com/mmp/pbrt-v4/blob/ci/src/pbrt/util/vecmath.h#L1738) +// PBRT-V4 [OctahedralVector::operator](https://github.com/mmp/pbrt-v4/blob/ci/src/pbrt/util/vecmath.h#L1751) + +#if defined(__STDC__) || defined(__cplusplus) + +DirectX::XMFLOAT2 octahedron_map(DirectX::XMFLOAT3 const &position_sphere_space) +{ + float const manhattan_norm = std::abs(position_sphere_space.x) + std::abs(position_sphere_space.y) + std::abs(position_sphere_space.z); + + DirectX::XMFLOAT3 position_octahedron_space; + DirectX::XMStoreFloat3(&position_octahedron_space, DirectX::XMVectorScale(DirectX::XMLoadFloat3(&position_sphere_space), 1.0F / manhattan_norm)); + + DirectX::XMFLOAT2 const position_rectangle_space = (position_octahedron_space.z > 0.0F) ? DirectX::XMFLOAT2(position_octahedron_space.x, position_octahedron_space.y) : DirectX::XMFLOAT2((1.0F - std::abs(position_octahedron_space.y)) * ((position_octahedron_space.x >= 0.0F) ? 1.0F : -1.0F), (1.0F - std::abs(position_octahedron_space.x)) * ((position_octahedron_space.y >= 0.0F) ? 1.0F : -1.0F)); + return position_rectangle_space; +} + +DirectX::XMFLOAT3 octahedron_unmap(DirectX::XMFLOAT2 const &position_rectangle_space) +{ + float const position_octahedron_space_z = 1.0F - std::abs(position_rectangle_space.x) - std::abs(position_rectangle_space.y); + + DirectX::XMFLOAT2 const position_octahedron_space_xy = (position_octahedron_space_z >= 0.0F) ? position_rectangle_space : DirectX::XMFLOAT2((1.0F - std::abs(position_rectangle_space.y)) * ((position_rectangle_space.x >= 0.0F) ? 1.0F : -1.0F), (1.0F - std::abs(position_rectangle_space.x)) * ((position_rectangle_space.y >= 0.0F) ? 1.0F : -1.0F)); + + DirectX::XMFLOAT3 const position_octahedron_space = DirectX::XMFLOAT3(position_octahedron_space_xy.x, position_octahedron_space_xy.y, position_octahedron_space_z); + + DirectX::XMFLOAT3 position_sphere_space; + DirectX::XMStoreFloat3(&position_sphere_space, DirectX::XMVector3Normalize(DirectX::XMLoadFloat3(&position_octahedron_space))); + return position_sphere_space; +} + +#elif defined(GL_SPIRV) || defined(VULKAN) || defined(HLSL_VERSION) || defined(__HLSL_VERSION) + +#include "../thirdparty/Brioche/shaders/brx_define.sli" + +brx_float2 octahedron_map(brx_float3 position_sphere_space) +{ + brx_float manhattan_norm = brx_abs(position_sphere_space.x) + brx_abs(position_sphere_space.y) + brx_abs(position_sphere_space.z); + + brx_float3 position_octahedron_space = position_sphere_space * (1.0 / manhattan_norm); + + brx_float2 position_rectangle_space = (position_octahedron_space.z > 0.0) ? position_octahedron_space.xy : brx_float2((1.0 - brx_abs(position_octahedron_space.y)) * ((position_octahedron_space.x >= 0.0) ? 1.0 : -1.0), (1.0 - brx_abs(position_octahedron_space.x)) * ((position_octahedron_space.y >= 0.0) ? 1.0 : -1.0)); + + return position_rectangle_space; +} + +brx_float3 octahedron_unmap(brx_float2 position_rectangle_space) +{ + brx_float position_octahedron_space_z = 1.0 - brx_abs(position_rectangle_space.x) - brx_abs(position_rectangle_space.y); + + brx_float2 position_octahedron_space_xy = (position_octahedron_space_z >= 0.0) ? position_rectangle_space : brx_float2((1.0 - brx_abs(position_rectangle_space.y)) * ((position_rectangle_space.x >= 0.0) ? 1.0 : -1.0), (1.0 - brx_abs(position_rectangle_space.x)) * ((position_rectangle_space.y >= 0.0) ? 1.0 : -1.0)); + + brx_float3 position_sphere_space = brx_normalize(brx_float3(position_octahedron_space_xy, position_octahedron_space_z)); + + return position_sphere_space; +} + +#else +#error Unknown Compiler +#endif + +#endif diff --git a/shaders/packed_vector.sli b/shaders/packed_vector.sli new file mode 100644 index 0000000..4dfd1da --- /dev/null +++ b/shaders/packed_vector.sli @@ -0,0 +1,151 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _PACKED_VECTOR_SLI_ +#define _PACKED_VECTOR_SLI_ 1 + +brx_float4 R10G10B10A2_UNORM_to_FLOAT4(brx_uint packed_input) +{ + // DirectX::PackedVector::XMLoadUDecN4 + + brx_uint element_x = (packed_input & 0x3FFu); + brx_uint element_y = ((packed_input >> 10) & 0x3FFu); + brx_uint element_z = ((packed_input >> 20) & 0x3FFu); + brx_uint element_w = (packed_input >> 30); + + return brx_float4(brx_float3(element_x, element_y, element_z) * (1.0f / 1023.0f), brx_float(brx_sign(brx_int(element_w) - 1)) * 0.5 + 0.5); +} + +brx_uint FLOAT4_to_R10G10B10A2_UNORM(brx_float4 unpacked_input) +{ + // DirectX::PackedVector::XMStoreUDec4 + + brx_float4 tmp = brx_float4(brx_clamp(unpacked_input.xyz, brx_float3(0.0, 0.0, 0.0), brx_float3(1.0, 1.0, 1.0)) * 1023.0f, brx_sign(unpacked_input.w - 0.5f) + 1.0); + + brx_uint element_x = (brx_uint(tmp.x) & 0x3FFu); + brx_uint element_y = ((brx_uint(tmp.y) & 0x3FFu) << 10); + brx_uint element_z = ((brx_uint(tmp.z) & 0x3FFu) << 20); + brx_uint element_w = (brx_uint(tmp.w) << 30); + + return brx_uint(element_x | element_y | element_z | element_w); +} + +brx_float4 R10G10B10A2_SNORM_to_FLOAT4(brx_uint packed_input) +{ + // DirectX::PackedVector::XMLoadDecN4 + + brx_int element_x = (brx_int((packed_input & 0x3FFu) << 22) >> 22); + brx_int element_y = (brx_int(((packed_input >> 10) & 0x3FFu) << 22) >> 22); + brx_int element_z = (brx_int(((packed_input >> 20) & 0x3FFu) << 22) >> 22); + brx_int element_w = (brx_int((packed_input >> 30) << 30) >> 30); + + return brx_float4(brx_clamp(brx_float3(element_x, element_y, element_z) * (1.0f / 511.0f), brx_float3(-1.0, -1.0, -1.0), brx_float3(1.0, 1.0, 1.0)), brx_sign(element_w)); +} + +brx_uint FLOAT4_to_R10G10B10A2_SNORM(brx_float4 unpacked_input) +{ + // DirectX::PackedVector::XMStoreDecN4 + + brx_float4 tmp = brx_float4(brx_clamp(unpacked_input.xyz, brx_float3(-1.0, -1.0, -1.0), brx_float3(1.0, 1.0, 1.0)) * 511.0f, brx_sign(unpacked_input.w)); + + brx_int element_x = (brx_int(tmp.x) & 0x3FF); + brx_int element_y = ((brx_int(tmp.y) & 0x3FF) << 10); + brx_int element_z = ((brx_int(tmp.z) & 0x3FF) << 20); + brx_int element_w = (brx_int(tmp.w) << 30); + + return brx_uint(element_x | element_y | element_z | element_w); +} + +brx_float2 R16G16_UNORM_to_FLOAT2(brx_uint packed_input) +{ + // DirectX::PackedVector::XMLoadUShortN2 + + brx_uint element_x = (packed_input & 0xffffu); + brx_uint element_y = (packed_input >> 16); + + return brx_float2(element_x, element_y) * (1.0f / 65535.0f); +} + +brx_uint FLOAT2_to_R16G16_UNORM(brx_float2 unpacked_input) +{ + // DirectX::PackedVector::XMStoreUShortN2 + + brx_float2 tmp = brx_clamp(unpacked_input, brx_float2(0.0, 0.0), brx_float2(1.0, 1.0)) * brx_float2(65535.0f, 65535.0f) + brx_float2(0.5f, 0.5f); + + brx_uint element_x = (brx_uint(tmp.x) & 0xffffu); + brx_uint element_y = (brx_uint(tmp.y) << 16); + + return brx_uint(element_x | element_y); +} + +brx_float2 R16G16_SNORM_to_FLOAT2(brx_uint packed_input) +{ + // DirectX::PackedVector::XMLoadShortN2 + + brx_int element_x = (brx_int((packed_input & 0xffffu) << 16) >> 16); + brx_int element_y = (brx_int(((packed_input >> 16) & 0xffffu) << 16) >> 16); + + return brx_clamp(brx_float2(element_x, element_y) * (1.0f / 32767.0f), brx_float2(-1.0, -1.0), brx_float2(1.0, 1.0)); +} + +brx_uint FLOAT2_to_R16G16_SNORM(brx_float2 unpacked_input) +{ + // DirectX::PackedVector::XMStoreShortN2 + + brx_float2 tmp = brx_clamp(unpacked_input, brx_float2(-1.0, -1.0), brx_float2(1.0, 1.0)) * 32767.0f; + + brx_int element_x = (brx_int(tmp.x) & 0xffff); + brx_int element_y = (brx_int(tmp.y) << 16); + + return brx_uint(element_x | element_y); +} + +brx_uint2 R16G16_UINT_to_UINT2(brx_uint packed_input) +{ + // DirectX::PackedVector::XMLoadUShort4 + + brx_uint element_x = (packed_input & 0xffffu); + brx_uint element_y = (packed_input >> 16); + + return brx_uint2(element_x, element_y); +} + +brx_uint4 R16G16B16A16_UINT_to_UINT4(brx_uint2 packed_input) +{ + // DirectX::PackedVector::XMLoadUShort4 + + brx_uint element_x = (packed_input.x & 0xffffu); + brx_uint element_y = (packed_input.x >> 16); + brx_uint element_z = (packed_input.y & 0xffffu); + brx_uint element_w = (packed_input.y >> 16); + + return brx_uint4(element_x, element_y, element_z, element_w); +} + +brx_float4 R16G16B16A16_UNORM_to_FLOAT4(brx_uint2 packed_input) +{ + // DirectX::PackedVector::XMLoadUShortN4 + + brx_uint element_x = (packed_input.x & 0xffffu); + brx_uint element_y = (packed_input.x >> 16); + brx_uint element_z = (packed_input.y & 0xffffu); + brx_uint element_w = (packed_input.y >> 16); + + return brx_float4(element_x, element_y, element_z, element_w) * (1.0f / 65535.0f); +} + +#endif \ No newline at end of file diff --git a/shaders/support/full_screen_transfer_fragment.sl b/shaders/support/full_screen_transfer_fragment.sl new file mode 100644 index 0000000..33a7181 --- /dev/null +++ b/shaders/support/full_screen_transfer_fragment.sl @@ -0,0 +1,31 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#include "full_screen_transfer_pipeline_layout.sli" + +brx_root_signature(full_screen_transfer_root_signature_macro, full_screen_transfer_root_signature_name) +brx_early_depth_stencil +brx_pixel_shader_parameter_begin(main) +brx_pixel_shader_parameter_in_frag_coord brx_pixel_shader_parameter_split +brx_pixel_shader_parameter_out(brx_float4, out_image, 0) +brx_pixel_shader_parameter_end(main) +{ + // TODO: HDR swapchain + brx_float3 color_linear = brx_load_2d(g_in_texture[0], brx_int3(brx_frag_coord.xy, 0)).xyz; + brx_float3 color_srgb = brx_float3(brx_pow(brx_clamp(color_linear.x, 0.0, 1.0), (1.0 / 2.2)), brx_pow(brx_clamp(color_linear.y, 0.0, 1.0), (1.0 / 2.2)), brx_pow(brx_clamp(color_linear.z, 0.0, 1.0), (1.0 / 2.2))); + out_image = brx_float4(color_srgb, 1.0); +} \ No newline at end of file diff --git a/shaders/support/full_screen_transfer_pipeline_layout.sli b/shaders/support/full_screen_transfer_pipeline_layout.sli new file mode 100644 index 0000000..b618702 --- /dev/null +++ b/shaders/support/full_screen_transfer_pipeline_layout.sli @@ -0,0 +1,32 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _FULL_SCREEN_TRANSFER_PIPELINE_LAYOUT_SLI_ +#define _FULL_SCREEN_TRANSFER_PIPELINE_LAYOUT_SLI_ 1 + +#include "../../thirdparty/Brioche/shaders/brx_define.sli" + +brx_texture_2d(g_in_texture, 0, 0, 1); + +brx_sampler_state(g_sampler, 0, 1, 1); + +#define full_screen_transfer_root_signature_macro \ + brx_root_signature_root_parameter_begin(full_screen_transfer_root_signature_name) \ + brx_root_signature_root_descriptor_table_srv(0, 0, 1) brx_root_signature_root_parameter_split \ + brx_root_signature_root_parameter_end + +#endif \ No newline at end of file diff --git a/shaders/support/full_screen_transfer_vertex.sl b/shaders/support/full_screen_transfer_vertex.sl new file mode 100644 index 0000000..1bfb9bc --- /dev/null +++ b/shaders/support/full_screen_transfer_vertex.sl @@ -0,0 +1,33 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#include "full_screen_transfer_pipeline_layout.sli" + +brx_root_signature(full_screen_transfer_root_signature_macro, full_screen_transfer_root_signature_name) +brx_vertex_shader_parameter_begin(main) +brx_vertex_shader_parameter_in_vertex_id brx_vertex_shader_parameter_split +brx_vertex_shader_parameter_out_position +brx_vertex_shader_parameter_end(main) +{ + const brx_float2 full_screen_triangle_positions[3] = brx_array_constructor_begin(brx_float2, 3) + brx_float2(-1.0, -1.0) brx_array_constructor_split + brx_float2(3.0, -1.0) brx_array_constructor_split + brx_float2(-1.0, 3.0) + brx_array_constructor_end; + + brx_position = brx_float4(full_screen_triangle_positions[brx_vertex_id], 0.5, 1.0); +} \ No newline at end of file diff --git a/source/demo.cpp b/source/demo.cpp new file mode 100644 index 0000000..c29de54 --- /dev/null +++ b/source/demo.cpp @@ -0,0 +1,1106 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#include "demo.h" +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#endif +#include +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif +#include +#include +#include +#include +#include +#include "support/camera_controller.h" +#include "../thirdparty/ImportAsset/include/import_image_asset.h" +#include "../thirdparty/ImportAsset/include/import_asset_input_stream_file.h" +#include "../shaders/octahedron_mapping.sli" +#include "../shaders/common_resource_binding.sli" +#include "../shaders/gbuffer_pipeline_resource_binding.sli" +#include "../shaders/deferred_shading_pipeline_resource_binding.sli" + +static inline uint32_t tbb_align_up(uint32_t value, uint32_t alignment); + +static inline DirectX::XMMATRIX XM_CALLCONV DirectX_Math_Matrix_PerspectiveFovRH_ReversedZ(float FovAngleY, float AspectRatio, float NearZ, float FarZ); + +static float g_camera_fov = -1.0F; + +Demo::Demo() +{ +} + +void Demo::init(brx_device *device, std::vector const &file_names) +{ + // Descriptor Layout + brx_descriptor_set_layout *gbuffer_pipeline_none_update_descriptor_set_layout; + brx_descriptor_set_layout *gbuffer_pipeline_per_mesh_subset_update_descriptor_set_layout; + brx_descriptor_set_layout *gbuffer_pipeline_per_mesh_instance_update_descriptor_set_layout; + { + BRX_DESCRIPTOR_SET_LAYOUT_BINDING const gbuffer_pipeline_none_update_descriptor_set_layout_bindings[] = { + {0U, BRX_DESCRIPTOR_TYPE_DYNAMIC_UNIFORM_BUFFER, 1U}, + {1U, BRX_DESCRIPTOR_TYPE_SAMPLER, 1U}}; + gbuffer_pipeline_none_update_descriptor_set_layout = device->create_descriptor_set_layout(sizeof(gbuffer_pipeline_none_update_descriptor_set_layout_bindings) / sizeof(gbuffer_pipeline_none_update_descriptor_set_layout_bindings[0]), gbuffer_pipeline_none_update_descriptor_set_layout_bindings); + + BRX_DESCRIPTOR_SET_LAYOUT_BINDING const gbuffer_pipeline_per_mesh_subset_update_descriptor_set_layout_bindings[] = { + {0U, BRX_DESCRIPTOR_TYPE_READ_ONLY_STORAGE_BUFFER, DEMO_MESH_SUBSET_GEOMETRY_METERIAL_BUFFER_COUNT}, + {4U, BRX_DESCRIPTOR_TYPE_SAMPLED_IMAGE, DEMO_MESH_SUBSET_METERIAL_TEXTURE_COUNT}}; + gbuffer_pipeline_per_mesh_subset_update_descriptor_set_layout = device->create_descriptor_set_layout(sizeof(gbuffer_pipeline_per_mesh_subset_update_descriptor_set_layout_bindings) / sizeof(gbuffer_pipeline_per_mesh_subset_update_descriptor_set_layout_bindings[0]), gbuffer_pipeline_per_mesh_subset_update_descriptor_set_layout_bindings); + + BRX_DESCRIPTOR_SET_LAYOUT_BINDING const gbuffer_pipeline_per_mesh_instance_update_descriptor_set_layout_bindings[] = { + {0U, BRX_DESCRIPTOR_TYPE_DYNAMIC_UNIFORM_BUFFER, 1U}}; + gbuffer_pipeline_per_mesh_instance_update_descriptor_set_layout = device->create_descriptor_set_layout(sizeof(gbuffer_pipeline_per_mesh_instance_update_descriptor_set_layout_bindings) / sizeof(gbuffer_pipeline_per_mesh_instance_update_descriptor_set_layout_bindings[0]), gbuffer_pipeline_per_mesh_instance_update_descriptor_set_layout_bindings); + + brx_descriptor_set_layout *const gbuffer_pipeline_descriptor_set_layouts[] = { + gbuffer_pipeline_none_update_descriptor_set_layout, gbuffer_pipeline_per_mesh_subset_update_descriptor_set_layout, gbuffer_pipeline_per_mesh_instance_update_descriptor_set_layout}; + this->m_gbuffer_pipeline_layout = device->create_pipeline_layout(sizeof(gbuffer_pipeline_descriptor_set_layouts) / sizeof(gbuffer_pipeline_descriptor_set_layouts[0]), gbuffer_pipeline_descriptor_set_layouts); + + BRX_DESCRIPTOR_SET_LAYOUT_BINDING const deferred_shading_pipeline_none_update_descriptor_set_layout_bindings[] = { + {0U, BRX_DESCRIPTOR_TYPE_DYNAMIC_UNIFORM_BUFFER, 1U}, + {1U, BRX_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1U}, + {2U, BRX_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1U}}; + this->m_deferred_shading_pipeline_none_update_descriptor_set_layout = device->create_descriptor_set_layout(sizeof(deferred_shading_pipeline_none_update_descriptor_set_layout_bindings) / sizeof(deferred_shading_pipeline_none_update_descriptor_set_layout_bindings[0]), deferred_shading_pipeline_none_update_descriptor_set_layout_bindings); + + brx_descriptor_set_layout *const deferred_shading_pipeline_descriptor_set_layouts[] = { + this->m_deferred_shading_pipeline_none_update_descriptor_set_layout}; + this->m_deferred_shading_pipeline_layout = device->create_pipeline_layout(sizeof(deferred_shading_pipeline_descriptor_set_layouts) / sizeof(deferred_shading_pipeline_descriptor_set_layouts[0]), deferred_shading_pipeline_descriptor_set_layouts); + } + + // Render Pass and Pipeline + { + this->m_gbuffer_color_attachement_format = BRX_COLOR_ATTACHMENT_FORMAT_R32G32B32A32_UINT; + this->m_gbuffer_depth_attachement_format = device->get_depth_attachment_image_format(); + + // GBuffer Render Pass + { + BRX_RENDER_PASS_COLOR_ATTACHMENT const color_attachment = { + this->m_gbuffer_color_attachement_format, + BRX_RENDER_PASS_COLOR_ATTACHMENT_LOAD_OPERATION_CLEAR, + BRX_RENDER_PASS_COLOR_ATTACHMENT_STORE_OPERATION_FLUSH_FOR_SAMPLED_IMAGE}; + + BRX_RENDER_PASS_DEPTH_STENCIL_ATTACHMENT const depth_stencil_attachment = { + this->m_gbuffer_depth_attachement_format, + BRX_RENDER_PASS_DEPTH_STENCIL_ATTACHMENT_LOAD_OPERATION_CLEAR, + BRX_RENDER_PASS_DEPTH_STENCIL_ATTACHMENT_STORE_OPERATION_FLUSH_FOR_SAMPLED_IMAGE}; + + this->m_gbuffer_render_pass = device->create_render_pass(1U, &color_attachment, &depth_stencil_attachment); + } + + // GBuffer Pipeline + { +#include +#include + this->m_gbuffer_pipeline = device->create_graphics_pipeline(this->m_gbuffer_render_pass, this->m_gbuffer_pipeline_layout, sizeof(gbuffer_vertex_shader_module_code), gbuffer_vertex_shader_module_code, sizeof(gbuffer_fragment_shader_module_code), gbuffer_fragment_shader_module_code, 0U, NULL, 0U, NULL, true, BRX_GRAPHICS_PIPELINE_COMPARE_OPERATION_GREATER); + } + + this->m_deferred_shading_color_attachement_format = BRX_COLOR_ATTACHMENT_FORMAT_A2R10G10B10_UNORM_PACK32; + + // Deferred Shading Pass + { + BRX_RENDER_PASS_COLOR_ATTACHMENT const color_attachment = { + this->m_deferred_shading_color_attachement_format, + BRX_RENDER_PASS_COLOR_ATTACHMENT_LOAD_OPERATION_CLEAR, + BRX_RENDER_PASS_COLOR_ATTACHMENT_STORE_OPERATION_FLUSH_FOR_SAMPLED_IMAGE}; + + this->m_deferred_shading_render_pass = device->create_render_pass(1U, &color_attachment, NULL); + } + + // Deferred Shading Pipeline + { +#include +#include + this->m_deferred_shading_pipeline = device->create_graphics_pipeline(this->m_deferred_shading_render_pass, this->m_deferred_shading_pipeline_layout, sizeof(deferred_shading_vertex_shader_module_code), deferred_shading_vertex_shader_module_code, sizeof(deferred_shading_fragment_shader_module_code), deferred_shading_fragment_shader_module_code, 0U, NULL, 0U, NULL, false, BRX_GRAPHICS_PIPELINE_COMPARE_OPERATION_ALWAYS); + } + } + + // Asset & Place Holder Texture + { + brx_upload_command_buffer *const upload_command_buffer = device->create_upload_command_buffer(); + + brx_graphics_command_buffer *const graphics_command_buffer = device->create_graphics_command_buffer(); + + brx_upload_queue *const upload_queue = device->create_upload_queue(); + + brx_graphics_queue *const graphics_queue = device->create_graphics_queue(); + + brx_fence *const fence = device->create_fence(true); + + { + std::vector staging_upload_buffers; + + device->reset_upload_command_buffer(upload_command_buffer); + + device->reset_graphics_command_buffer(graphics_command_buffer); + + upload_command_buffer->begin(); + + graphics_command_buffer->begin(); + + // 60 FPS + constexpr float const frame_rate = 60.0F; + + // Asset + for (size_t file_name_index = 0U; file_name_index < file_names.size(); ++file_name_index) + { + std::string const &file_name = file_names[file_name_index]; + + std::vector total_mesh_data; + if (import_scene_asset_gltf(total_mesh_data, frame_rate, file_name.c_str())) + { + for (size_t mesh_index = 0U; mesh_index < total_mesh_data.size(); ++mesh_index) + { + scene_mesh_data const &in_mesh_data = total_mesh_data[mesh_index]; + + this->m_scene_meshes.push_back({}); + Demo_Mesh &out_mesh = this->m_scene_meshes.back(); + + out_mesh.m_skinned = in_mesh_data.m_skinned; + + for (size_t subset_index = 0U; subset_index < in_mesh_data.m_subsets.size(); ++subset_index) + { + scene_mesh_subset_data const &in_subset_data = in_mesh_data.m_subsets[subset_index]; + + out_mesh.m_subsets.push_back({}); + Demo_Mesh_Subset &out_subset = out_mesh.m_subsets.back(); + + uint32_t const vertex_count = static_cast(in_subset_data.m_vertex_position_binding.size()); + + { + uint32_t const vertex_position_buffer_size = sizeof(scene_mesh_vertex_position_binding) * vertex_count; + + out_subset.m_vertex_position_buffer = device->create_storage_asset_buffer(vertex_position_buffer_size); + + brx_staging_upload_buffer *const vertex_position_staging_upload_buffer = device->create_staging_upload_buffer(vertex_position_buffer_size); + + staging_upload_buffers.push_back(vertex_position_staging_upload_buffer); + + std::memcpy(vertex_position_staging_upload_buffer->get_host_memory_range_base(), in_subset_data.m_vertex_position_binding.data(), vertex_position_buffer_size); + + upload_command_buffer->upload_from_staging_upload_buffer_to_storage_asset_buffer(out_subset.m_vertex_position_buffer, 0U, vertex_position_staging_upload_buffer, 0U, vertex_position_buffer_size); + } + + { + assert(vertex_count == in_subset_data.m_vertex_varying_binding.size()); + + uint32_t const vertex_varying_buffer_size = sizeof(scene_mesh_vertex_varying_binding) * vertex_count; + + out_subset.m_vertex_varying_buffer = device->create_storage_asset_buffer(vertex_varying_buffer_size); + + brx_staging_upload_buffer *const vertex_varying_staging_upload_buffer = device->create_staging_upload_buffer(vertex_varying_buffer_size); + + staging_upload_buffers.push_back(vertex_varying_staging_upload_buffer); + + std::memcpy(vertex_varying_staging_upload_buffer->get_host_memory_range_base(), in_subset_data.m_vertex_varying_binding.data(), vertex_varying_buffer_size); + + upload_command_buffer->upload_from_staging_upload_buffer_to_storage_asset_buffer(out_subset.m_vertex_varying_buffer, 0U, vertex_varying_staging_upload_buffer, 0U, vertex_varying_buffer_size); + } + + if (in_mesh_data.m_skinned) + { + assert(vertex_count == in_subset_data.m_vertex_skinned_binding.size()); + + uint32_t const vertex_skinned_buffer_size = sizeof(scene_mesh_vertex_skinned_binding) * vertex_count; + + out_subset.m_vertex_skinned_binding_buffer = device->create_storage_asset_buffer(vertex_skinned_buffer_size); + + brx_staging_upload_buffer *const vertex_skinned_staging_upload_buffer = device->create_staging_upload_buffer(vertex_skinned_buffer_size); + + staging_upload_buffers.push_back(vertex_skinned_staging_upload_buffer); + + std::memcpy(vertex_skinned_staging_upload_buffer->get_host_memory_range_base(), in_subset_data.m_vertex_skinned_binding.data(), vertex_skinned_buffer_size); + + upload_command_buffer->upload_from_staging_upload_buffer_to_storage_asset_buffer(out_subset.m_vertex_skinned_binding_buffer, 0U, vertex_skinned_staging_upload_buffer, 0U, vertex_skinned_buffer_size); + } + else + { + out_subset.m_vertex_skinned_binding_buffer = NULL; + } + + out_subset.m_index_count = static_cast(in_subset_data.m_indices.size()); + + { + // TODO: support 32-bit index + assert(in_subset_data.m_max_index < static_cast(UINT16_MAX)); + + std::vector converted_indices(static_cast(out_subset.m_index_count)); + for (uint32_t index_index = 0; index_index < out_subset.m_index_count; ++index_index) + { + converted_indices[index_index] = static_cast(in_subset_data.m_indices[index_index]); + } + + uint32_t const index_buffer_size = sizeof(uint16_t) * out_subset.m_index_count; + + out_subset.m_index_buffer = device->create_storage_asset_buffer(index_buffer_size); + + brx_staging_upload_buffer *const index_staging_upload_buffer = device->create_staging_upload_buffer(index_buffer_size); + + staging_upload_buffers.push_back(index_staging_upload_buffer); + + std::memcpy(index_staging_upload_buffer->get_host_memory_range_base(), converted_indices.data(), index_buffer_size); + + upload_command_buffer->upload_from_staging_upload_buffer_to_storage_asset_buffer(out_subset.m_index_buffer, 0U, index_staging_upload_buffer, 0U, index_buffer_size); + } + + { + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination; + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_material_texture_enable_flags = 0U; + if (!in_subset_data.m_normal_texture_image_uri.empty()) + { + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_material_texture_enable_flags |= Material_Texture_Enable_Normal; + } + if (!in_subset_data.m_emissive_texture_image_uri.empty()) + { + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_material_texture_enable_flags |= Material_Texture_Enable_Emissive; + } + if (!in_subset_data.m_base_color_texture_image_uri.empty()) + { + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_material_texture_enable_flags |= Material_Texture_Enable_Base_Color; + } + if (!in_subset_data.m_metallic_roughness_texture_image_uri.empty()) + { + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_material_texture_enable_flags |= Material_Texture_Enable_Metallic_Roughness; + } + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_normal_texture_scale = in_subset_data.m_normal_texture_scale; + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_emissive_factor_x = in_subset_data.m_emissive_factor.x; + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_emissive_factor_y = in_subset_data.m_emissive_factor.y; + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_emissive_factor_z = in_subset_data.m_emissive_factor.z; + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_base_color_factor_x = in_subset_data.m_base_color_factor.x; + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_base_color_factor_y = in_subset_data.m_base_color_factor.y; + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_base_color_factor_z = in_subset_data.m_base_color_factor.z; + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_metallic_factor = in_subset_data.m_metallic_factor; + gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination.m_roughness_factor = in_subset_data.m_roughness_factor; + + uint32_t const material_buffer_size = sizeof(gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding); + + out_subset.m_material_buffer = device->create_storage_asset_buffer(material_buffer_size); + + brx_staging_upload_buffer *const material_staging_upload_buffer = device->create_staging_upload_buffer(material_buffer_size); + + staging_upload_buffers.push_back(material_staging_upload_buffer); + + std::memcpy(material_staging_upload_buffer->get_host_memory_range_base(), &gbuffer_pipeline_per_mesh_subset_update_set_material_storage_buffer_binding_destination, material_buffer_size); + + upload_command_buffer->upload_from_staging_upload_buffer_to_storage_asset_buffer(out_subset.m_material_buffer, 0U, material_staging_upload_buffer, 0U, material_buffer_size); + } + + { + uint32_t const staging_upload_buffer_offset_alignment = device->get_staging_upload_buffer_offset_alignment(); + uint32_t const staging_upload_buffer_row_pitch_alignment = device->get_staging_upload_buffer_row_pitch_alignment(); + + std::string const *const meterial_texture_image_uris[] = { + &in_subset_data.m_normal_texture_image_uri, + &in_subset_data.m_emissive_texture_image_uri, + &in_subset_data.m_base_color_texture_image_uri, + &in_subset_data.m_metallic_roughness_texture_image_uri}; + + for (uint32_t mesh_subset_meterial_texture_index = 0U; mesh_subset_meterial_texture_index < DEMO_MESH_SUBSET_METERIAL_TEXTURE_COUNT; ++mesh_subset_meterial_texture_index) + { + std::string const &meterial_texture_image_uri = (*meterial_texture_image_uris[mesh_subset_meterial_texture_index]); + + if (!meterial_texture_image_uri.empty()) + { + std::string image_asset_file_name_dds; + std::string image_asset_file_name_pvr; + { + std::string image_asset_file_name; + + size_t dir_name_pos = file_name.find_last_of("/\\"); + if (std::string::npos != dir_name_pos) + { + image_asset_file_name = file_name.substr(0U, dir_name_pos + 1U); + } + else + { + image_asset_file_name += "./"; + } + + size_t ext_name_pos = meterial_texture_image_uri.find_last_of("."); + if (std::string::npos != ext_name_pos) + { + image_asset_file_name += meterial_texture_image_uri.substr(0U, ext_name_pos + 1U); + } + else + { + image_asset_file_name += meterial_texture_image_uri; + } + + image_asset_file_name_dds = (image_asset_file_name + "dds"); + image_asset_file_name_pvr = (image_asset_file_name + "pvr"); + } + + import_asset_input_stream_file import_image_asset_file_input_stream; + if (device->is_sampled_asset_image_compression_bc_supported() && import_image_asset_file_input_stream.init(image_asset_file_name_dds.c_str())) + { + BRX_SAMPLED_ASSET_IMAGE_IMPORT_HEADER image_asset_header; + std::vector subresource_memcpy_dests; + + size_t image_asset_data_offset; + bool const res_import_image_asset_header = import_image_asset_header_from_input_stream_dds(&import_image_asset_file_input_stream, &image_asset_header, &image_asset_data_offset); + assert(res_import_image_asset_header); + + uint32_t const subresource_count = image_asset_header.mip_levels; + subresource_memcpy_dests.resize(subresource_count); + + // TODO: support more image paramters + assert(!image_asset_header.is_cube_map); + assert(BRX_SAMPLED_ASSET_IMAGE_TYPE_2D == image_asset_header.type); + assert(1U == image_asset_header.depth); + assert(1U == image_asset_header.array_layers); + uint32_t const total_bytes = brx_sampled_asset_image_import_calculate_subresource_memcpy_dests(image_asset_header.format, image_asset_header.width, image_asset_header.height, 1U, image_asset_header.mip_levels, 1U, 0U, staging_upload_buffer_offset_alignment, staging_upload_buffer_row_pitch_alignment, subresource_count, &subresource_memcpy_dests[0]); + brx_staging_upload_buffer * const image_staging_upload_buffer = device->create_staging_upload_buffer(static_cast(total_bytes)); + staging_upload_buffers.push_back(image_staging_upload_buffer); + + bool const res_import_image_asset_data = import_image_asset_data_from_input_stream_dds(&import_image_asset_file_input_stream, &image_asset_header, image_asset_data_offset, image_staging_upload_buffer->get_host_memory_range_base(), subresource_count, &subresource_memcpy_dests[0]); + assert(res_import_image_asset_data); + + import_image_asset_file_input_stream.uninit(); + + out_subset.m_material_textures[mesh_subset_meterial_texture_index] = device->create_sampled_asset_image(image_asset_header.format, image_asset_header.width, image_asset_header.height, image_asset_header.mip_levels); + + for (uint32_t mip_level = 0U; mip_level < image_asset_header.mip_levels; ++mip_level) + { + upload_command_buffer->upload_from_staging_upload_buffer_to_sampled_asset_image(out_subset.m_material_textures[mesh_subset_meterial_texture_index], image_asset_header.format, image_asset_header.width, image_asset_header.height, mip_level, image_staging_upload_buffer, subresource_memcpy_dests[mip_level].staging_upload_buffer_offset, subresource_memcpy_dests[mip_level].output_row_pitch, subresource_memcpy_dests[mip_level].output_row_count); + } + + } + else if(device->is_sampled_asset_image_compression_astc_supported() && import_image_asset_file_input_stream.init(image_asset_file_name_pvr.c_str())) + { + BRX_SAMPLED_ASSET_IMAGE_IMPORT_HEADER image_asset_header; + std::vector subresource_memcpy_dests; + + size_t image_asset_data_offset; + bool const res_import_image_asset_header = import_image_asset_header_from_input_stream_pvr(&import_image_asset_file_input_stream, &image_asset_header, &image_asset_data_offset); + assert(res_import_image_asset_header); + + uint32_t const subresource_count = image_asset_header.mip_levels; + subresource_memcpy_dests.resize(subresource_count); + + // TODO: support more image paramters + assert(!image_asset_header.is_cube_map); + assert(BRX_SAMPLED_ASSET_IMAGE_TYPE_2D == image_asset_header.type); + assert(1U == image_asset_header.depth); + assert(1U == image_asset_header.array_layers); + uint32_t const total_bytes = brx_sampled_asset_image_import_calculate_subresource_memcpy_dests(image_asset_header.format, image_asset_header.width, image_asset_header.height, 1U, image_asset_header.mip_levels, 1U, 0U, staging_upload_buffer_offset_alignment, staging_upload_buffer_row_pitch_alignment, subresource_count, &subresource_memcpy_dests[0]); + brx_staging_upload_buffer* const image_staging_upload_buffer = device->create_staging_upload_buffer(static_cast(total_bytes)); + staging_upload_buffers.push_back(image_staging_upload_buffer); + + bool const res_import_image_asset_data = import_image_asset_data_from_input_stream_pvr(&import_image_asset_file_input_stream, &image_asset_header, image_asset_data_offset, image_staging_upload_buffer->get_host_memory_range_base(), subresource_count, &subresource_memcpy_dests[0]); + assert(res_import_image_asset_data); + + import_image_asset_file_input_stream.uninit(); + + out_subset.m_material_textures[mesh_subset_meterial_texture_index] = device->create_sampled_asset_image(image_asset_header.format, image_asset_header.width, image_asset_header.height, image_asset_header.mip_levels); + + for (uint32_t mip_level = 0U; mip_level < image_asset_header.mip_levels; ++mip_level) + { + upload_command_buffer->upload_from_staging_upload_buffer_to_sampled_asset_image(out_subset.m_material_textures[mesh_subset_meterial_texture_index], image_asset_header.format, image_asset_header.width, image_asset_header.height, mip_level, image_staging_upload_buffer, subresource_memcpy_dests[mip_level].staging_upload_buffer_offset, subresource_memcpy_dests[mip_level].output_row_pitch, subresource_memcpy_dests[mip_level].output_row_count); + } + } + else + { + // TODO: jpeg + // TODO: png + out_subset.m_material_textures[mesh_subset_meterial_texture_index] = NULL; + } + } + else + { + out_subset.m_material_textures[mesh_subset_meterial_texture_index] = NULL; + } + } + } + } + + for (size_t instance_index = 0U; instance_index < total_mesh_data[mesh_index].m_instances.size(); ++instance_index) + { + scene_mesh_instance_data &in_instance_data = total_mesh_data[mesh_index].m_instances[instance_index]; + + out_mesh.m_instances.push_back({}); + Demo_Mesh_Instance &out_mesh_instance = out_mesh.m_instances.back(); + + out_mesh_instance.m_model_transform = std::move(in_instance_data.m_model_transform); + out_mesh_instance.m_animation_skeleton = std::move(in_instance_data.m_animation_skeleton); + } + } + } + } + + // Place Holder Texture + { + uint32_t const staging_upload_buffer_offset_alignment = device->get_staging_upload_buffer_offset_alignment(); + uint32_t const staging_upload_buffer_row_pitch_alignment = device->get_staging_upload_buffer_row_pitch_alignment(); + + BRX_SAMPLED_ASSET_IMAGE_FORMAT const format = BRX_SAMPLED_ASSET_IMAGE_FORMAT_R8G8B8A8_UNORM; + uint32_t const width = 1U; + uint32_t const height = 1U; + uint32_t const mip_levels = 1U; + this->m_place_holder_texture = device->create_sampled_asset_image(format, width, height, mip_levels); + + std::vector subresource_memcpy_dests; + uint32_t const subresource_count = mip_levels; + subresource_memcpy_dests.resize(subresource_count); + + uint32_t total_bytes = brx_sampled_asset_image_import_calculate_subresource_memcpy_dests(format, width, height, 1U, mip_levels, 1U, 0U, staging_upload_buffer_offset_alignment, staging_upload_buffer_row_pitch_alignment, subresource_count, &subresource_memcpy_dests[0]); + brx_staging_upload_buffer *place_holder_image_staging_upload_buffer = device->create_staging_upload_buffer(total_bytes); + + staging_upload_buffers.push_back(place_holder_image_staging_upload_buffer); + + uint32_t const mip_level = 0U; + uint32_t const subresource_index = brx_sampled_asset_image_import_calculate_subresource_index(mip_level, 0U, 0U, mip_levels, 1U); + for (uint32_t output_slice_index = 0U; output_slice_index < subresource_memcpy_dests[mip_level].output_slice_count; ++output_slice_index) + { + for (uint32_t output_row_index = 0U; output_row_index < subresource_memcpy_dests[mip_level].output_row_count; ++output_row_index) + { + void *destination = reinterpret_cast(reinterpret_cast(place_holder_image_staging_upload_buffer->get_host_memory_range_base()) + (subresource_memcpy_dests[subresource_index].staging_upload_buffer_offset + subresource_memcpy_dests[subresource_index].output_slice_pitch * output_slice_index + subresource_memcpy_dests[subresource_index].output_row_pitch * output_row_index)); + + std::memset(destination, 0, subresource_memcpy_dests[mip_level].output_row_size); + } + } + + upload_command_buffer->upload_from_staging_upload_buffer_to_sampled_asset_image(this->m_place_holder_texture, format, width, height, mip_level, place_holder_image_staging_upload_buffer, subresource_memcpy_dests[mip_level].staging_upload_buffer_offset, subresource_memcpy_dests[mip_level].output_row_pitch, subresource_memcpy_dests[mip_level].output_row_count); + } + + // store + // release + // acquire + { + std::vector uploaded_storage_asset_buffers; + std::vector uploaded_sampled_asset_images; + std::vector uploaded_destination_mip_levels; + + // Asset + for (uint32_t mesh_index = 0; mesh_index < this->m_scene_meshes.size(); ++mesh_index) + { + Demo_Mesh const &scene_mesh = this->m_scene_meshes[mesh_index]; + + for (size_t subset_index = 0U; subset_index < scene_mesh.m_subsets.size(); ++subset_index) + { + Demo_Mesh_Subset const &scene_mesh_subset = scene_mesh.m_subsets[subset_index]; + + uploaded_storage_asset_buffers.push_back(scene_mesh_subset.m_vertex_position_buffer); + + uploaded_storage_asset_buffers.push_back(scene_mesh_subset.m_vertex_varying_buffer); + + uploaded_storage_asset_buffers.push_back(scene_mesh_subset.m_vertex_skinned_binding_buffer); + + uploaded_storage_asset_buffers.push_back(scene_mesh_subset.m_index_buffer); + + uploaded_storage_asset_buffers.push_back(scene_mesh_subset.m_material_buffer); + + for (uint32_t mesh_subset_meterial_texture_index = 0U; mesh_subset_meterial_texture_index < DEMO_MESH_SUBSET_METERIAL_TEXTURE_COUNT; ++mesh_subset_meterial_texture_index) + { + brx_sampled_asset_image *const material_texture = scene_mesh_subset.m_material_textures[mesh_subset_meterial_texture_index]; + + if (NULL != material_texture) + { + uint32_t const mip_level_count = material_texture->get_mip_levels(); + + for (uint32_t mip_level = 0U; mip_level < mip_level_count; ++mip_level) + { + uploaded_sampled_asset_images.push_back(material_texture); + + uploaded_destination_mip_levels.push_back(mip_level); + } + } + } + } + } + + // Place Holder Texture + { + uploaded_sampled_asset_images.push_back(this->m_place_holder_texture); + + uploaded_destination_mip_levels.push_back(0U); + } + + assert(uploaded_sampled_asset_images.size() == uploaded_destination_mip_levels.size()); + + upload_command_buffer->release(static_cast(uploaded_storage_asset_buffers.size()), uploaded_storage_asset_buffers.data(), static_cast(uploaded_sampled_asset_images.size()), &uploaded_sampled_asset_images[0], uploaded_destination_mip_levels.data(), 0U, NULL); + + graphics_command_buffer->acquire(static_cast(uploaded_storage_asset_buffers.size()), uploaded_storage_asset_buffers.data(), static_cast(uploaded_sampled_asset_images.size()), &uploaded_sampled_asset_images[0], uploaded_destination_mip_levels.data(), 0U, NULL); + } + + upload_command_buffer->end(); + + graphics_command_buffer->end(); + + upload_queue->submit_and_signal(upload_command_buffer); + + device->reset_fence(fence); + + graphics_queue->wait_and_submit(upload_command_buffer, graphics_command_buffer, fence); + + device->wait_for_fence(fence); + + for (brx_staging_upload_buffer *const staging_upload_buffer : staging_upload_buffers) + { + device->destroy_staging_upload_buffer(staging_upload_buffer); + } + + staging_upload_buffers.clear(); + } + + device->destroy_fence(fence); + + device->destroy_upload_command_buffer(upload_command_buffer); + + device->destroy_graphics_command_buffer(graphics_command_buffer); + + device->destroy_upload_queue(upload_queue); + + device->destroy_graphics_queue(graphics_queue); + } + + // Sampler + { + this->m_sampler = device->create_sampler(BRX_SAMPLER_FILTER_LINEAR); + } + + // Uniform Buffer + { + this->m_uniform_upload_buffer_offset_alignment = device->get_uniform_upload_buffer_offset_alignment(); + + this->m_common_none_update_uniform_buffer = device->create_uniform_upload_buffer(tbb_align_up(static_cast(sizeof(common_none_update_set_uniform_buffer_binding)), this->m_uniform_upload_buffer_offset_alignment) * FRAME_THROTTLING_COUNT); + + for (uint32_t mesh_index = 0; mesh_index < this->m_scene_meshes.size(); ++mesh_index) + { + Demo_Mesh &scene_mesh = this->m_scene_meshes[mesh_index]; + + for (size_t instance_index = 0U; instance_index < scene_mesh.m_instances.size(); ++instance_index) + { + Demo_Mesh_Instance &scene_mesh_instance = scene_mesh.m_instances[instance_index]; + + scene_mesh_instance.m_gbuffer_pipeline_per_mesh_instance_update_uniform_buffer = device->create_uniform_upload_buffer(tbb_align_up(static_cast(sizeof(gbuffer_pipeline_per_mesh_instance_update_set_uniform_buffer_binding)), this->m_uniform_upload_buffer_offset_alignment) * FRAME_THROTTLING_COUNT); + } + } + } + + // Descriptor + { + // GBuffer Pipeline + { + { + this->m_gbuffer_pipeline_none_update_descriptor_set = device->create_descriptor_set(gbuffer_pipeline_none_update_descriptor_set_layout); + + constexpr uint32_t const dynamic_uniform_buffers_range = sizeof(common_none_update_set_uniform_buffer_binding); + device->write_descriptor_set(this->m_gbuffer_pipeline_none_update_descriptor_set, 0U, BRX_DESCRIPTOR_TYPE_DYNAMIC_UNIFORM_BUFFER, 0U, 1U, &this->m_common_none_update_uniform_buffer, &dynamic_uniform_buffers_range, NULL, NULL, NULL, NULL, NULL, NULL); + + device->write_descriptor_set(this->m_gbuffer_pipeline_none_update_descriptor_set, 1U, BRX_DESCRIPTOR_TYPE_SAMPLER, 0U, 1U, NULL, NULL, NULL, NULL, NULL, NULL, &this->m_sampler, NULL); + } + + for (uint32_t mesh_index = 0; mesh_index < this->m_scene_meshes.size(); ++mesh_index) + { + Demo_Mesh &scene_mesh = this->m_scene_meshes[mesh_index]; + + for (size_t subset_index = 0U; subset_index < scene_mesh.m_subsets.size(); ++subset_index) + { + Demo_Mesh_Subset &scene_mesh_subset = scene_mesh.m_subsets[subset_index]; + + scene_mesh_subset.m_gbuffer_pipeline_per_mesh_subset_update_descriptor_set = device->create_descriptor_set(gbuffer_pipeline_per_mesh_subset_update_descriptor_set_layout); + + brx_read_only_storage_buffer const *const read_only_storage_buffers[] = { + scene_mesh_subset.m_vertex_position_buffer->get_read_only_storage_buffer(), + scene_mesh_subset.m_vertex_varying_buffer->get_read_only_storage_buffer(), + scene_mesh_subset.m_index_buffer->get_read_only_storage_buffer(), + scene_mesh_subset.m_material_buffer->get_read_only_storage_buffer()}; + device->write_descriptor_set(scene_mesh_subset.m_gbuffer_pipeline_per_mesh_subset_update_descriptor_set, 0U, BRX_DESCRIPTOR_TYPE_READ_ONLY_STORAGE_BUFFER, 0U, sizeof(read_only_storage_buffers) / sizeof(read_only_storage_buffers[0]), NULL, NULL, read_only_storage_buffers, NULL, NULL, NULL, NULL, NULL); + + brx_sampled_image const *sample_images[DEMO_MESH_SUBSET_METERIAL_TEXTURE_COUNT]; + for (uint32_t mesh_subset_meterial_texture_index = 0U; mesh_subset_meterial_texture_index < DEMO_MESH_SUBSET_METERIAL_TEXTURE_COUNT; ++mesh_subset_meterial_texture_index) + { + brx_sampled_asset_image *material_texture = scene_mesh_subset.m_material_textures[mesh_subset_meterial_texture_index]; + + sample_images[mesh_subset_meterial_texture_index] = (NULL != material_texture) ? material_texture->get_sampled_image() : this->m_place_holder_texture->get_sampled_image(); + } + device->write_descriptor_set(scene_mesh_subset.m_gbuffer_pipeline_per_mesh_subset_update_descriptor_set, 4U, BRX_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0U, sizeof(sample_images) / sizeof(sample_images[0]), NULL, NULL, NULL, NULL, sample_images, NULL, NULL, NULL); + } + + for (size_t instance_index = 0U; instance_index < scene_mesh.m_instances.size(); ++instance_index) + { + Demo_Mesh_Instance &scene_mesh_instance = scene_mesh.m_instances[instance_index]; + + scene_mesh_instance.m_gbuffer_pipeline_per_mesh_instance_update_descriptor_set = device->create_descriptor_set(gbuffer_pipeline_per_mesh_instance_update_descriptor_set_layout); + + constexpr uint32_t const dynamic_uniform_buffers_range = sizeof(gbuffer_pipeline_per_mesh_instance_update_set_uniform_buffer_binding); + device->write_descriptor_set(scene_mesh_instance.m_gbuffer_pipeline_per_mesh_instance_update_descriptor_set, 0U, BRX_DESCRIPTOR_TYPE_DYNAMIC_UNIFORM_BUFFER, 0U, 1U, &scene_mesh_instance.m_gbuffer_pipeline_per_mesh_instance_update_uniform_buffer, &dynamic_uniform_buffers_range, NULL, NULL, NULL, NULL, NULL, NULL); + } + } + } + + // Deferred Shading Pipeline + { + { + this->m_deferred_shading_pipeline_none_update_descriptor_set = device->create_descriptor_set(this->m_deferred_shading_pipeline_none_update_descriptor_set_layout); + + constexpr uint32_t const dynamic_uniform_buffers_range = sizeof(common_none_update_set_uniform_buffer_binding); + device->write_descriptor_set(this->m_deferred_shading_pipeline_none_update_descriptor_set, 0U, BRX_DESCRIPTOR_TYPE_DYNAMIC_UNIFORM_BUFFER, 0U, 1U, &this->m_common_none_update_uniform_buffer, &dynamic_uniform_buffers_range, NULL, NULL, NULL, NULL, NULL, NULL); + } + } + } + + device->destroy_descriptor_set_layout(gbuffer_pipeline_none_update_descriptor_set_layout); + gbuffer_pipeline_none_update_descriptor_set_layout = NULL; + device->destroy_descriptor_set_layout(gbuffer_pipeline_per_mesh_subset_update_descriptor_set_layout); + gbuffer_pipeline_per_mesh_subset_update_descriptor_set_layout = NULL; + device->destroy_descriptor_set_layout(gbuffer_pipeline_per_mesh_instance_update_descriptor_set_layout); + gbuffer_pipeline_per_mesh_instance_update_descriptor_set_layout = NULL; + + // Init Intermediate Images + this->m_intermediate_width = 0U; + this->m_intermediate_height = 0U; + this->m_gbuffer_color_attachment = NULL; + this->m_gbuffer_depth_attachment = NULL; + this->m_deferred_shading_color_attachment = NULL; + this->m_gbuffer_frame_buffer = NULL; + this->m_deferred_shading_frame_buffer = NULL; + + // Init Camera + g_camera_controller.m_eye_position = DirectX::XMFLOAT3(0.0F, 1.3F, 1.0F); + g_camera_controller.m_eye_direction = DirectX::XMFLOAT3(0.0F, -0.36F, -0.98F); + g_camera_controller.m_up_direction = DirectX::XMFLOAT3(0.0F, 1.0F, 0.0F); + g_camera_fov = DirectX::XM_PI * (1.0F / 3.0F); +} + +void Demo::destroy(brx_device *device) +{ + // Descriptor + { + // GBuffer Pipeline + { + device->destroy_descriptor_set(this->m_gbuffer_pipeline_none_update_descriptor_set); + + for (uint32_t mesh_index = 0; mesh_index < this->m_scene_meshes.size(); ++mesh_index) + { + Demo_Mesh &scene_mesh = this->m_scene_meshes[mesh_index]; + + for (size_t subset_index = 0U; subset_index < scene_mesh.m_subsets.size(); ++subset_index) + { + Demo_Mesh_Subset &scene_mesh_subset = scene_mesh.m_subsets[subset_index]; + + device->destroy_descriptor_set(scene_mesh_subset.m_gbuffer_pipeline_per_mesh_subset_update_descriptor_set); + } + + for (size_t instance_index = 0U; instance_index < scene_mesh.m_instances.size(); ++instance_index) + { + Demo_Mesh_Instance &scene_mesh_instance = scene_mesh.m_instances[instance_index]; + + device->destroy_descriptor_set(scene_mesh_instance.m_gbuffer_pipeline_per_mesh_instance_update_descriptor_set); + } + } + } + + // Deferred Shading Pipeline + { + device->destroy_descriptor_set_layout(this->m_deferred_shading_pipeline_none_update_descriptor_set_layout); + + device->destroy_descriptor_set(this->m_deferred_shading_pipeline_none_update_descriptor_set); + } + } + + // Uniform Buffer + { + device->destroy_uniform_upload_buffer(this->m_common_none_update_uniform_buffer); + + for (uint32_t mesh_index = 0; mesh_index < this->m_scene_meshes.size(); ++mesh_index) + { + Demo_Mesh &scene_mesh = this->m_scene_meshes[mesh_index]; + + for (size_t instance_index = 0U; instance_index < scene_mesh.m_instances.size(); ++instance_index) + { + Demo_Mesh_Instance &scene_mesh_instance = scene_mesh.m_instances[instance_index]; + + device->destroy_uniform_upload_buffer(scene_mesh_instance.m_gbuffer_pipeline_per_mesh_instance_update_uniform_buffer); + } + } + } + + // Sampler + { + device->destroy_sampler(this->m_sampler); + } + + // Place Holder Texture + { + device->destroy_sampled_asset_image(this->m_place_holder_texture); + } + + // Asset + { + for (uint32_t mesh_index = 0; mesh_index < this->m_scene_meshes.size(); ++mesh_index) + { + Demo_Mesh &scene_mesh = this->m_scene_meshes[mesh_index]; + + for (size_t subset_index = 0U; subset_index < scene_mesh.m_subsets.size(); ++subset_index) + { + Demo_Mesh_Subset &scene_mesh_subset = scene_mesh.m_subsets[subset_index]; + + device->destroy_storage_asset_buffer(scene_mesh_subset.m_vertex_position_buffer); + + device->destroy_storage_asset_buffer(scene_mesh_subset.m_vertex_varying_buffer); + + if (scene_mesh.m_skinned) + { + device->destroy_storage_asset_buffer(scene_mesh_subset.m_vertex_skinned_binding_buffer); + } + else + { + assert(NULL == scene_mesh_subset.m_vertex_skinned_binding_buffer); + } + + device->destroy_storage_asset_buffer(scene_mesh_subset.m_index_buffer); + + device->destroy_storage_asset_buffer(scene_mesh_subset.m_material_buffer); + + for (uint32_t mesh_subset_meterial_texture_index = 0U; mesh_subset_meterial_texture_index < DEMO_MESH_SUBSET_METERIAL_TEXTURE_COUNT; ++mesh_subset_meterial_texture_index) + { + brx_sampled_asset_image *const material_texture = scene_mesh_subset.m_material_textures[mesh_subset_meterial_texture_index]; + + if (NULL != material_texture) + { + device->destroy_sampled_asset_image(material_texture); + } + } + } + } + } + + // Render Pass and Pipeline + { + device->destroy_graphics_pipeline(this->m_gbuffer_pipeline); + + device->destroy_pipeline_layout(this->m_gbuffer_pipeline_layout); + + device->destroy_render_pass(this->m_gbuffer_render_pass); + + device->destroy_graphics_pipeline(this->m_deferred_shading_pipeline); + + device->destroy_pipeline_layout(this->m_deferred_shading_pipeline_layout); + + device->destroy_render_pass(this->m_deferred_shading_render_pass); + } +} + +void Demo::on_swap_chain_attach(brx_device *device, uint32_t swap_chain_image_width, uint32_t swap_chain_image_height) +{ + assert(0U == this->m_intermediate_width); + assert(0U == this->m_intermediate_height); + + this->m_intermediate_width = swap_chain_image_width; + this->m_intermediate_height = swap_chain_image_height; + + // Intermediate Images + { + assert(NULL == this->m_gbuffer_color_attachment); + assert(NULL == this->m_gbuffer_depth_attachment); + assert(NULL == this->m_deferred_shading_color_attachment); + + this->m_gbuffer_color_attachment = device->create_color_attachment_image(this->m_gbuffer_color_attachement_format, this->m_intermediate_width, this->m_intermediate_height, true); + this->m_gbuffer_depth_attachment = device->create_depth_stencil_attachment_image(this->m_gbuffer_depth_attachement_format, this->m_intermediate_width, this->m_intermediate_height, true); + this->m_deferred_shading_color_attachment = device->create_color_attachment_image(this->m_deferred_shading_color_attachement_format, this->m_intermediate_width, this->m_intermediate_height, true); + } + + // Frame Buffer + { + assert(NULL == this->m_gbuffer_frame_buffer); + assert(NULL == this->m_deferred_shading_frame_buffer); + + this->m_gbuffer_frame_buffer = device->create_frame_buffer(this->m_gbuffer_render_pass, this->m_intermediate_width, this->m_intermediate_height, 1U, &this->m_gbuffer_color_attachment, this->m_gbuffer_depth_attachment); + this->m_deferred_shading_frame_buffer = device->create_frame_buffer(this->m_deferred_shading_render_pass, this->m_intermediate_width, this->m_intermediate_height, 1U, &this->m_deferred_shading_color_attachment, NULL); + } + + // Descriptor + { + // Deferred Shading Pipeline + { + // The VkDescriptorSetLayout should still be valid when perform write update on VkDescriptorSet + assert(NULL != this->m_deferred_shading_pipeline_none_update_descriptor_set_layout); + { + { + brx_sampled_image const *const sampled_images[] = { + this->m_gbuffer_color_attachment->get_sampled_image()}; + device->write_descriptor_set(this->m_deferred_shading_pipeline_none_update_descriptor_set, 1U, BRX_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0U, sizeof(sampled_images) / sizeof(sampled_images[0]), NULL, NULL, NULL, NULL, sampled_images, NULL, NULL, NULL); + } + + { + brx_sampled_image const *const sampled_images[] = { + this->m_gbuffer_depth_attachment->get_sampled_image()}; + device->write_descriptor_set(this->m_deferred_shading_pipeline_none_update_descriptor_set, 2U, BRX_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0U, sizeof(sampled_images) / sizeof(sampled_images[0]), NULL, NULL, NULL, NULL, sampled_images, NULL, NULL, NULL); + } + } + } + } +} + +brx_sampled_image const *Demo::get_sampled_image_for_present() +{ + return this->m_deferred_shading_color_attachment->get_sampled_image(); +} + +void Demo::on_swap_chain_dettach(brx_device *device) +{ + device->destroy_frame_buffer(this->m_gbuffer_frame_buffer); + device->destroy_frame_buffer(this->m_deferred_shading_frame_buffer); + + this->m_gbuffer_frame_buffer = NULL; + this->m_deferred_shading_frame_buffer = NULL; + + device->destroy_color_attachment_image(this->m_deferred_shading_color_attachment); + device->destroy_depth_stencil_attachment_image(this->m_gbuffer_depth_attachment); + device->destroy_color_attachment_image(this->m_gbuffer_color_attachment); + + this->m_deferred_shading_color_attachment = NULL; + this->m_gbuffer_depth_attachment = NULL; + this->m_gbuffer_color_attachment = NULL; + + this->m_intermediate_width = 0U; + this->m_intermediate_height = 0U; +} + +void Demo::draw(brx_graphics_command_buffer *command_buffer, float interval_time, uint32_t frame_throttling_index) +{ + // Update Uniform Buffer + { + // Common - None Update (update frequency denotes the updating of the resource bindings instead of the data) + { + common_none_update_set_uniform_buffer_binding *const common_none_update_set_uniform_buffer_binding_destination = reinterpret_cast(reinterpret_cast(this->m_common_none_update_uniform_buffer->get_host_memory_range_base()) + tbb_align_up(static_cast(sizeof(common_none_update_set_uniform_buffer_binding)), this->m_uniform_upload_buffer_offset_alignment) * frame_throttling_index); + + DirectX::XMFLOAT3 eye_position = g_camera_controller.m_eye_position; + DirectX::XMFLOAT3 eye_direction = g_camera_controller.m_eye_direction; + DirectX::XMFLOAT3 up_direction = g_camera_controller.m_up_direction; + DirectX::XMMATRIX view_transform = DirectX::XMMatrixLookToRH(DirectX::XMLoadFloat3(&eye_position), DirectX::XMLoadFloat3(&eye_direction), DirectX::XMLoadFloat3(&up_direction)); + DirectX::XMMATRIX projection_transform = DirectX_Math_Matrix_PerspectiveFovRH_ReversedZ(g_camera_fov, static_cast(this->m_intermediate_width) / static_cast(this->m_intermediate_height), 0.1F, 1000.0F); + + DirectX::XMStoreFloat4x4(&common_none_update_set_uniform_buffer_binding_destination->g_view_transform, view_transform); + DirectX::XMStoreFloat4x4(&common_none_update_set_uniform_buffer_binding_destination->g_projection_transform, projection_transform); + DirectX::XMStoreFloat4x4(&common_none_update_set_uniform_buffer_binding_destination->g_inverse_view_transform, DirectX::XMMatrixInverse(NULL, view_transform)); + DirectX::XMStoreFloat4x4(&common_none_update_set_uniform_buffer_binding_destination->g_inverse_projection_transform, DirectX::XMMatrixInverse(NULL, projection_transform)); + + common_none_update_set_uniform_buffer_binding_destination->g_screen_width = static_cast(this->m_intermediate_width); + common_none_update_set_uniform_buffer_binding_destination->g_screen_height = static_cast(this->m_intermediate_height); + } + + // GBuffer Pipeline - Per Mesh Instance Update + { + for (uint32_t mesh_index = 0; mesh_index < this->m_scene_meshes.size(); ++mesh_index) + { + Demo_Mesh &scene_mesh = this->m_scene_meshes[mesh_index]; + + for (size_t instance_index = 0U; instance_index < scene_mesh.m_instances.size(); ++instance_index) + { + Demo_Mesh_Instance &scene_mesh_instance = scene_mesh.m_instances[instance_index]; + + gbuffer_pipeline_per_mesh_instance_update_set_uniform_buffer_binding *const gbuffer_pipeline_per_mesh_instance_update_set_uniform_buffer_binding_destination = reinterpret_cast(reinterpret_cast(scene_mesh_instance.m_gbuffer_pipeline_per_mesh_instance_update_uniform_buffer->get_host_memory_range_base()) + tbb_align_up(static_cast(sizeof(gbuffer_pipeline_per_mesh_instance_update_set_uniform_buffer_binding)), this->m_uniform_upload_buffer_offset_alignment) * frame_throttling_index); + + gbuffer_pipeline_per_mesh_instance_update_set_uniform_buffer_binding_destination->g_model_transform = scene_mesh_instance.m_model_transform; + } + } + } + } + + // GBuffer Pass + { + command_buffer->begin_debug_utils_label("GBuffer Pass"); + + float color_clear_values[4] = {0.0F, 0.0F, 0.0F, 0.0F}; + float depth_clear_value = 0.0F; + command_buffer->begin_render_pass(this->m_gbuffer_render_pass, this->m_gbuffer_frame_buffer, this->m_intermediate_width, this->m_intermediate_height, 1U, &color_clear_values, &depth_clear_value, NULL); + + command_buffer->bind_graphics_pipeline(this->m_gbuffer_pipeline); + + command_buffer->set_view_port(this->m_intermediate_width, this->m_intermediate_height); + + command_buffer->set_scissor(this->m_intermediate_width, this->m_intermediate_height); + + for (uint32_t mesh_index = 0; mesh_index < this->m_scene_meshes.size(); ++mesh_index) + { + Demo_Mesh &scene_mesh = this->m_scene_meshes[mesh_index]; + + for (size_t subset_index = 0U; subset_index < scene_mesh.m_subsets.size(); ++subset_index) + { + Demo_Mesh_Subset &scene_mesh_subset = scene_mesh.m_subsets[subset_index]; + + for (size_t instance_index = 0U; instance_index < scene_mesh.m_instances.size(); ++instance_index) + { + Demo_Mesh_Instance &scene_mesh_instance = scene_mesh.m_instances[instance_index]; + + brx_descriptor_set *const descritor_sets[] = { + this->m_gbuffer_pipeline_none_update_descriptor_set, + scene_mesh_subset.m_gbuffer_pipeline_per_mesh_subset_update_descriptor_set, + scene_mesh_instance.m_gbuffer_pipeline_per_mesh_instance_update_descriptor_set}; + + uint32_t const dynamic_offsets[] = { + tbb_align_up(static_cast(sizeof(common_none_update_set_uniform_buffer_binding)), this->m_uniform_upload_buffer_offset_alignment) * frame_throttling_index, + tbb_align_up(static_cast(sizeof(gbuffer_pipeline_per_mesh_instance_update_set_uniform_buffer_binding)), this->m_uniform_upload_buffer_offset_alignment) * frame_throttling_index}; + + command_buffer->bind_graphics_descriptor_sets(this->m_gbuffer_pipeline_layout, sizeof(descritor_sets) / sizeof(descritor_sets[0]), descritor_sets, sizeof(dynamic_offsets) / sizeof(dynamic_offsets[0]), dynamic_offsets); + + command_buffer->draw(scene_mesh_subset.m_index_count, 1U); + } + } + } + + command_buffer->end_render_pass(); + + command_buffer->end_debug_utils_label(); + } + + // Deferred Shading Pass + { + command_buffer->begin_debug_utils_label("Deferred Shading Pass"); + + float color_clear_values[4] = {0.0F, 0.0F, 0.0F, 0.0F}; + command_buffer->begin_render_pass(this->m_deferred_shading_render_pass, this->m_deferred_shading_frame_buffer, this->m_intermediate_width, this->m_intermediate_height, 1U, &color_clear_values, NULL, NULL); + + command_buffer->bind_graphics_pipeline(this->m_deferred_shading_pipeline); + + command_buffer->set_view_port(this->m_intermediate_width, this->m_intermediate_height); + + command_buffer->set_scissor(this->m_intermediate_width, this->m_intermediate_height); + + brx_descriptor_set *const descritor_sets[] = { + this->m_deferred_shading_pipeline_none_update_descriptor_set}; + + uint32_t const dynamic_offsets[] = { + tbb_align_up(static_cast(sizeof(common_none_update_set_uniform_buffer_binding)), this->m_uniform_upload_buffer_offset_alignment) * frame_throttling_index}; + + command_buffer->bind_graphics_descriptor_sets(this->m_deferred_shading_pipeline_layout, sizeof(descritor_sets) / sizeof(descritor_sets[0]), descritor_sets, sizeof(dynamic_offsets) / sizeof(dynamic_offsets[0]), dynamic_offsets); + + command_buffer->draw(3U, 1U); + + command_buffer->end_render_pass(); + + command_buffer->end_debug_utils_label(); + } +} + +static inline uint32_t tbb_align_up(uint32_t value, uint32_t alignment) +{ + // + // Copyright (c) 2005-2019 Intel Corporation + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + // + + // [alignUp](https://github.com/oneapi-src/oneTBB/blob/tbb_2019/src/tbbmalloc/shared_utils.h#L42) + + assert(alignment != static_cast(0)); + + // power-of-2 alignment + assert((alignment & (alignment - static_cast(1))) == static_cast(0)); + + return (((value - static_cast(1)) | (alignment - static_cast(1))) + static_cast(1)); +} + +static inline DirectX::XMMATRIX XM_CALLCONV DirectX_Math_Matrix_PerspectiveFovRH_ReversedZ(float FovAngleY, float AspectRatio, float NearZ, float FarZ) +{ + // [Reversed-Z](https://developer.nvidia.com/content/depth-precision-visualized) + // + // _ 0 0 0 + // 0 _ 0 0 + // 0 0 b -1 + // 0 0 a 0 + // + // _ 0 0 0 + // 0 _ 0 0 + // 0 0 zb -z + // 0 0 a + // + // z' = -b - a/z + // + // Standard + // 0 = -b + a/nearz // z=-nearz + // 1 = -b + a/farz // z=-farz + // a = farz*nearz/(nearz - farz) + // b = farz/(nearz - farz) + // + // Reversed-Z + // 1 = -b + a/nearz // z=-nearz + // 0 = -b + a/farz // z=-farz + // a = farz*nearz/(farz - nearz) + // b = nearz/(farz - nearz) + + // __m128 _mm_shuffle_ps(__m128 lo,__m128 hi, _MM_SHUFFLE(hi3,hi2,lo1,lo0)) + // Interleave inputs into low 2 floats and high 2 floats of output. Basically + // out[0]=lo[lo0]; + // out[1]=lo[lo1]; + // out[2]=hi[hi2]; + // out[3]=hi[hi3]; + + // DirectX::XMMatrixPerspectiveFovRH + + float SinFov; + float CosFov; + DirectX::XMScalarSinCos(&SinFov, &CosFov, 0.5F * FovAngleY); + + float Height = CosFov / SinFov; + float Width = Height / AspectRatio; + float b = NearZ / (FarZ - NearZ); + float a = (FarZ / (FarZ - NearZ)) * NearZ; +#if defined(_XM_SSE_INTRINSICS_) + // Note: This is recorded on the stack + DirectX::XMVECTOR rMem = { + Width, + Height, + b, + a}; + + // Copy from memory to SSE register + DirectX::XMVECTOR vValues = rMem; + DirectX::XMVECTOR vTemp = _mm_setzero_ps(); + // Copy x only + vTemp = _mm_move_ss(vTemp, vValues); + // CosFov / SinFov,0,0,0 + DirectX::XMMATRIX M; + M.r[0] = vTemp; + // 0,Height / AspectRatio,0,0 + vTemp = vValues; + vTemp = _mm_and_ps(vTemp, DirectX::g_XMMaskY); + M.r[1] = vTemp; + // x=b,y=a,0,-1.0f + vTemp = _mm_setzero_ps(); + vValues = _mm_shuffle_ps(vValues, DirectX::g_XMNegIdentityR3, _MM_SHUFFLE(3, 2, 3, 2)); + // 0,0,b,-1.0f + vTemp = _mm_shuffle_ps(vTemp, vValues, _MM_SHUFFLE(3, 0, 0, 0)); + M.r[2] = vTemp; + // 0,0,a,0.0f + vTemp = _mm_shuffle_ps(vTemp, vValues, _MM_SHUFFLE(2, 1, 0, 0)); + M.r[3] = vTemp; + return M; +#elif defined(_XM_ARM_NEON_INTRINSICS_) + const float32x4_t Zero = vdupq_n_f32(0); + + DirectX::XMMATRIX M; + M.r[0] = vsetq_lane_f32(Width, Zero, 0); + M.r[1] = vsetq_lane_f32(Height, Zero, 1); + M.r[2] = vsetq_lane_f32(b, DirectX::g_XMNegIdentityR3.v, 2); + M.r[3] = vsetq_lane_f32(a, Zero, 2); + return M; +#endif +} diff --git a/source/demo.h b/source/demo.h new file mode 100644 index 0000000..5a79106 --- /dev/null +++ b/source/demo.h @@ -0,0 +1,121 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _DEMO_H_ +#define _DEMO_H_ 1 + +#include "support/frame_throttling.h" +#include "../thirdparty/Brioche/include/brx_device.h" +#include "../thirdparty/ImportAsset/include/import_scene_asset.h" +#include +#include + +struct Demo_Mesh_Skinned_Subset +{ + brx_storage_intermediate_buffer *m_skinned_vertex_position_buffer; + brx_storage_intermediate_buffer *m_skinned_vertex_varying_buffer; + brx_descriptor_set *m_gbuffer_pipeline_per_mesh_skinned_subset_update_descriptor_set; +}; + +struct Demo_Mesh_Instance +{ + DirectX::XMFLOAT4X4 m_model_transform; + scene_animation_skeleton m_animation_skeleton; + brx_uniform_upload_buffer *m_gbuffer_pipeline_per_mesh_instance_update_uniform_buffer; + std::vector m_subsets; + brx_descriptor_set *m_gbuffer_pipeline_per_mesh_instance_update_descriptor_set; +}; + +static constexpr uint32_t const DEMO_MESH_SUBSET_GEOMETRY_METERIAL_BUFFER_COUNT = 4U; + +static constexpr uint32_t const DEMO_MESH_SUBSET_METERIAL_TEXTURE_COUNT = 4U; + +struct Demo_Mesh_Subset +{ + brx_storage_asset_buffer *m_vertex_position_buffer; + brx_storage_asset_buffer *m_vertex_varying_buffer; + brx_storage_asset_buffer *m_vertex_skinned_binding_buffer; + brx_storage_asset_buffer *m_index_buffer; + uint32_t m_index_count; + brx_storage_asset_buffer *m_material_buffer; + brx_sampled_asset_image *m_material_textures[DEMO_MESH_SUBSET_METERIAL_TEXTURE_COUNT]; + brx_descriptor_set *m_gbuffer_pipeline_per_mesh_subset_update_descriptor_set; +}; + +struct Demo_Mesh +{ + bool m_skinned; + std::vector m_subsets; + std::vector m_instances; +}; + +class Demo +{ + BRX_COLOR_ATTACHMENT_IMAGE_FORMAT m_gbuffer_color_attachement_format; + BRX_DEPTH_STENCIL_ATTACHMENT_IMAGE_FORMAT m_gbuffer_depth_attachement_format; + brx_render_pass *m_gbuffer_render_pass; + + brx_pipeline_layout *m_gbuffer_pipeline_layout; + brx_graphics_pipeline *m_gbuffer_pipeline; + + // TODO: self dependency + // TODO: VK_EXT_rasterization_order_attachment_access + BRX_COLOR_ATTACHMENT_IMAGE_FORMAT m_deferred_shading_color_attachement_format; + brx_render_pass *m_deferred_shading_render_pass; + + brx_pipeline_layout *m_deferred_shading_pipeline_layout; + brx_graphics_pipeline *m_deferred_shading_pipeline; + + brx_sampled_asset_image *m_place_holder_texture; + + brx_sampler *m_sampler; + + uint32_t m_uniform_upload_buffer_offset_alignment; + brx_uniform_upload_buffer *m_common_none_update_uniform_buffer; + + brx_descriptor_set *m_gbuffer_pipeline_none_update_descriptor_set; + + brx_descriptor_set_layout *m_deferred_shading_pipeline_none_update_descriptor_set_layout; + brx_descriptor_set *m_deferred_shading_pipeline_none_update_descriptor_set; + + std::vector m_scene_meshes; + + uint32_t m_intermediate_width; + uint32_t m_intermediate_height; + brx_color_attachment_image *m_gbuffer_color_attachment; + brx_depth_stencil_attachment_image *m_gbuffer_depth_attachment; + brx_frame_buffer *m_gbuffer_frame_buffer; + brx_color_attachment_image *m_deferred_shading_color_attachment; + brx_frame_buffer *m_deferred_shading_frame_buffer; + +public: + Demo(); + + void init(brx_device *device, std::vector const &file_names); + + void destroy(brx_device *device); + + void on_swap_chain_attach(brx_device *device, uint32_t swap_chain_image_width, uint32_t swap_chain_image_height); + + brx_sampled_image const *get_sampled_image_for_present(); + + void on_swap_chain_dettach(brx_device *device); + + void draw(brx_graphics_command_buffer *command_buffer, float interval_time, uint32_t frame_throttling_index); +}; + +#endif \ No newline at end of file diff --git a/source/support/camera_controller.cpp b/source/support/camera_controller.cpp new file mode 100644 index 0000000..12a8cfd --- /dev/null +++ b/source/support/camera_controller.cpp @@ -0,0 +1,201 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#include +#include +#include "camera_controller.h" + +class CameraController g_camera_controller; + +static float g_SpeedTranslate = 0.25F; +static float g_RotationTranslate = 2.0F; + +CameraController::CameraController() : m_previous_x(-1.0F), m_previous_y(-1.0F) +{ +} + +void CameraController::MoveForward() +{ + m_eye_position.x += m_eye_direction.x * g_SpeedTranslate; + m_eye_position.y += m_eye_direction.y * g_SpeedTranslate; + m_eye_position.z += m_eye_direction.z * g_SpeedTranslate; +} + +void CameraController::MoveBack() +{ + m_eye_position.x -= m_eye_direction.x * g_SpeedTranslate; + m_eye_position.y -= m_eye_direction.y * g_SpeedTranslate; + m_eye_position.z -= m_eye_direction.z * g_SpeedTranslate; +} + +void CameraController::MoveLeft() +{ + DirectX::XMFLOAT3 EyeDirection = {m_eye_direction.x, m_eye_direction.y, m_eye_direction.z}; + DirectX::XMFLOAT3 UpDirection = {m_up_direction.x, m_up_direction.y, m_up_direction.z}; + + DirectX::XMVECTOR NegEyeDirection = DirectX::XMVectorNegate(DirectX::XMLoadFloat3(&EyeDirection)); + DirectX::XMVECTOR AxisForwardDirection = DirectX::XMVector3Normalize(NegEyeDirection); + DirectX::XMVECTOR AxisRightDirection = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(DirectX::XMLoadFloat3(&UpDirection), AxisForwardDirection)); + // DirectX::XMVECTOR AxisViewUpDirection = DirectX::XMVector3Cross(AxisForwardDirection, AxisRightDirection); + + DirectX::XMFLOAT3 AxisRightDirectionF; + DirectX::XMStoreFloat3(&AxisRightDirectionF, AxisRightDirection); + + m_eye_position.x -= AxisRightDirectionF.x * g_SpeedTranslate; + m_eye_position.y -= AxisRightDirectionF.y * g_SpeedTranslate; + m_eye_position.z -= AxisRightDirectionF.z * g_SpeedTranslate; +} + +void CameraController::MoveRight() +{ + DirectX::XMFLOAT3 EyeDirection = {m_eye_direction.x, m_eye_direction.y, m_eye_direction.z}; + DirectX::XMFLOAT3 UpDirection = {m_up_direction.x, m_up_direction.y, m_up_direction.z}; + + DirectX::XMVECTOR NegEyeDirection = DirectX::XMVectorNegate(DirectX::XMLoadFloat3(&EyeDirection)); + DirectX::XMVECTOR AxisForwardDirection = DirectX::XMVector3Normalize(NegEyeDirection); + DirectX::XMVECTOR AxisRightDirection = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(DirectX::XMLoadFloat3(&UpDirection), AxisForwardDirection)); + // DirectX::XMVECTOR AxisViewUpDirection = DirectX::XMVector3Cross(AxisForwardDirection, AxisRightDirection); + + DirectX::XMFLOAT3 AxisRightDirectionF; + DirectX::XMStoreFloat3(&AxisRightDirectionF, AxisRightDirection); + + m_eye_position.x += AxisRightDirectionF.x * g_SpeedTranslate; + m_eye_position.y += AxisRightDirectionF.y * g_SpeedTranslate; + m_eye_position.z += AxisRightDirectionF.z * g_SpeedTranslate; +} + +void CameraController::MoveUp() +{ + DirectX::XMFLOAT3 EyeDirection = {m_eye_direction.x, m_eye_direction.y, m_eye_direction.z}; + DirectX::XMFLOAT3 UpDirection = {m_up_direction.x, m_up_direction.y, m_up_direction.z}; + + DirectX::XMVECTOR NegEyeDirection = DirectX::XMVectorNegate(DirectX::XMLoadFloat3(&EyeDirection)); + DirectX::XMVECTOR AxisForwardDirection = DirectX::XMVector3Normalize(NegEyeDirection); + DirectX::XMVECTOR AxisRightDirection = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(DirectX::XMLoadFloat3(&UpDirection), AxisForwardDirection)); + DirectX::XMVECTOR AxisViewUpDirection = DirectX::XMVector3Cross(AxisForwardDirection, AxisRightDirection); + + DirectX::XMFLOAT3 AxisViewUpDirectionF; + DirectX::XMStoreFloat3(&AxisViewUpDirectionF, AxisViewUpDirection); + + m_eye_position.x += AxisViewUpDirectionF.x * g_SpeedTranslate; + m_eye_position.y += AxisViewUpDirectionF.y * g_SpeedTranslate; + m_eye_position.z += AxisViewUpDirectionF.z * g_SpeedTranslate; +} + +void CameraController::MoveDown() +{ + DirectX::XMFLOAT3 EyeDirection = {m_eye_direction.x, m_eye_direction.y, m_eye_direction.z}; + DirectX::XMFLOAT3 UpDirection = {m_up_direction.x, m_up_direction.y, m_up_direction.z}; + + DirectX::XMVECTOR NegEyeDirection = DirectX::XMVectorNegate(DirectX::XMLoadFloat3(&EyeDirection)); + DirectX::XMVECTOR AxisForwardDirection = DirectX::XMVector3Normalize(NegEyeDirection); + DirectX::XMVECTOR AxisRightDirection = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(DirectX::XMLoadFloat3(&UpDirection), AxisForwardDirection)); + DirectX::XMVECTOR AxisViewUpDirection = DirectX::XMVector3Cross(AxisForwardDirection, AxisRightDirection); + + DirectX::XMFLOAT3 AxisViewUpDirectionF; + DirectX::XMStoreFloat3(&AxisViewUpDirectionF, AxisViewUpDirection); + + m_eye_position.x -= AxisViewUpDirectionF.x * g_SpeedTranslate; + m_eye_position.y -= AxisViewUpDirectionF.y * g_SpeedTranslate; + m_eye_position.z -= AxisViewUpDirectionF.z * g_SpeedTranslate; +} + +void CameraController::OnMouseMove(float x, float y, bool hold) +{ + float Current_X = std::min(std::max(0.0f, x), 1.0f); + float Current_Y = std::min(std::max(0.0f, y), 1.0f); + + float Offset_X = Current_X - this->m_previous_x; + float Offset_Y = Current_Y - this->m_previous_y; + + if (hold && this->m_previous_x > 0.0F && this->m_previous_x < 1.0F && this->m_previous_y > 0.0F && this->m_previous_y < 1.0F) + { + float LengthNormalized = ::sqrtf(Offset_X * Offset_X + Offset_Y * Offset_Y); + + if ((Offset_Y < Offset_X) && (Offset_Y > -Offset_X)) + { + // right + DirectX::XMFLOAT3 EyeDirection = {m_eye_direction.x, m_eye_direction.y, m_eye_direction.z}; + DirectX::XMFLOAT3 UpDirection = {m_up_direction.x, m_up_direction.y, m_up_direction.z}; + + DirectX::XMVECTOR NegEyeDirection = DirectX::XMVectorNegate(DirectX::XMLoadFloat3(&EyeDirection)); + DirectX::XMVECTOR AxisForwardDirection = DirectX::XMVector3Normalize(NegEyeDirection); + DirectX::XMVECTOR AxisRightDirection = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(DirectX::XMLoadFloat3(&UpDirection), AxisForwardDirection)); + DirectX::XMVECTOR AxisViewUpDirection = DirectX::XMVector3Cross(AxisForwardDirection, AxisRightDirection); + + DirectX::XMFLOAT3 EyeDirectionNew; + DirectX::XMStoreFloat3(&EyeDirectionNew, DirectX::XMVectorNegate(DirectX::XMVector3Transform(AxisForwardDirection, DirectX::XMMatrixRotationAxis(AxisViewUpDirection, -g_RotationTranslate * LengthNormalized)))); + m_eye_direction.x = EyeDirectionNew.x; + m_eye_direction.y = EyeDirectionNew.y; + m_eye_direction.z = EyeDirectionNew.z; + } + else if ((Offset_Y < -Offset_X) && (Offset_Y > Offset_X)) + { + // left + DirectX::XMFLOAT3 EyeDirection = {m_eye_direction.x, m_eye_direction.y, m_eye_direction.z}; + DirectX::XMFLOAT3 UpDirection = {m_up_direction.x, m_up_direction.y, m_up_direction.z}; + + DirectX::XMVECTOR NegEyeDirection = DirectX::XMVectorNegate(DirectX::XMLoadFloat3(&EyeDirection)); + DirectX::XMVECTOR AxisForwardDirection = DirectX::XMVector3Normalize(NegEyeDirection); + DirectX::XMVECTOR AxisRightDirection = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(DirectX::XMLoadFloat3(&UpDirection), AxisForwardDirection)); + DirectX::XMVECTOR AxisViewUpDirection = DirectX::XMVector3Cross(AxisForwardDirection, AxisRightDirection); + + DirectX::XMFLOAT3 EyeDirectionNew; + DirectX::XMStoreFloat3(&EyeDirectionNew, DirectX::XMVectorNegate(DirectX::XMVector3Transform(AxisForwardDirection, DirectX::XMMatrixRotationAxis(AxisViewUpDirection, g_RotationTranslate * LengthNormalized)))); + m_eye_direction.x = EyeDirectionNew.x; + m_eye_direction.y = EyeDirectionNew.y; + m_eye_direction.z = EyeDirectionNew.z; + } + else if ((Offset_Y < Offset_X) && (Offset_Y < -Offset_X)) + { + // up + DirectX::XMFLOAT3 EyeDirection = {m_eye_direction.x, m_eye_direction.y, m_eye_direction.z}; + DirectX::XMFLOAT3 UpDirection = {m_up_direction.x, m_up_direction.y, m_up_direction.z}; + + DirectX::XMVECTOR NegEyeDirection = DirectX::XMVectorNegate(DirectX::XMLoadFloat3(&EyeDirection)); + DirectX::XMVECTOR AxisForwardDirection = DirectX::XMVector3Normalize(NegEyeDirection); + DirectX::XMVECTOR AxisRightDirection = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(DirectX::XMLoadFloat3(&UpDirection), AxisForwardDirection)); + // DirectX::XMVECTOR AxisViewUpDirection = DirectX::XMVector3Cross(AxisForwardDirection, AxisRightDirection); + + DirectX::XMFLOAT3 EyeDirectionNew; + DirectX::XMStoreFloat3(&EyeDirectionNew, DirectX::XMVectorNegate(DirectX::XMVector3Transform(AxisForwardDirection, DirectX::XMMatrixRotationAxis(AxisRightDirection, g_RotationTranslate * LengthNormalized)))); + m_eye_direction.x = EyeDirectionNew.x; + m_eye_direction.y = EyeDirectionNew.y; + m_eye_direction.z = EyeDirectionNew.z; + } + else if ((Offset_Y > Offset_X) && (Offset_Y > -Offset_X)) + { + // down + DirectX::XMFLOAT3 EyeDirection = {m_eye_direction.x, m_eye_direction.y, m_eye_direction.z}; + DirectX::XMFLOAT3 UpDirection = {m_up_direction.x, m_up_direction.y, m_up_direction.z}; + + DirectX::XMVECTOR NegEyeDirection = DirectX::XMVectorNegate(DirectX::XMLoadFloat3(&EyeDirection)); + DirectX::XMVECTOR AxisForwardDirection = DirectX::XMVector3Normalize(NegEyeDirection); + DirectX::XMVECTOR AxisRightDirection = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(DirectX::XMLoadFloat3(&UpDirection), AxisForwardDirection)); + // DirectX::XMVECTOR AxisViewUpDirection = DirectX::XMVector3Cross(AxisForwardDirection, AxisRightDirection); + + DirectX::XMFLOAT3 EyeDirectionNew; + DirectX::XMStoreFloat3(&EyeDirectionNew, DirectX::XMVectorNegate(DirectX::XMVector3Transform(AxisForwardDirection, DirectX::XMMatrixRotationAxis(AxisRightDirection, -g_RotationTranslate * LengthNormalized)))); + m_eye_direction.x = EyeDirectionNew.x; + m_eye_direction.y = EyeDirectionNew.y; + m_eye_direction.z = EyeDirectionNew.z; + } + } + + this->m_previous_x = Current_X; + this->m_previous_y = Current_Y; +} diff --git a/source/support/camera_controller.h b/source/support/camera_controller.h new file mode 100644 index 0000000..c6f2263 --- /dev/null +++ b/source/support/camera_controller.h @@ -0,0 +1,54 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _CAMERA_CONTROLLER_H_ +#define _CAMERA_CONTROLLER_H_ 1 + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#endif +#include +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +class CameraController +{ + float m_previous_x; + float m_previous_y; + +public: + DirectX::XMFLOAT3 m_eye_position; + DirectX::XMFLOAT3 m_eye_direction; + DirectX::XMFLOAT3 m_up_direction; + + CameraController(); + + void MoveForward(); + void MoveBack(); + void MoveLeft(); + void MoveRight(); + void MoveUp(); + void MoveDown(); + + void OnMouseMove(float x, float y, bool hold); +}; + +extern class CameraController g_camera_controller; + +#endif \ No newline at end of file diff --git a/source/support/frame_throttling.h b/source/support/frame_throttling.h new file mode 100644 index 0000000..44256b0 --- /dev/null +++ b/source/support/frame_throttling.h @@ -0,0 +1,26 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _FRAME_THROTTLINE_H_ +#define _FRAME_THROTTLINE_H_ 1 + +#include + +// [Pipeline Throttling](https://community.arm.com/arm-community-blogs/b/graphics-gaming-and-vr-blog/posts/the-mali-gpu-an-abstract-machine-part-1---frame-pipelining) +static uint32_t constexpr const FRAME_THROTTLING_COUNT = 3U; + +#endif \ No newline at end of file diff --git a/source/support/main.cpp b/source/support/main.cpp new file mode 100644 index 0000000..5b28943 --- /dev/null +++ b/source/support/main.cpp @@ -0,0 +1,846 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#include +#include +#include "camera_controller.h" +#include "renderer.h" + +static class renderer *g_renderer = NULL; +static int32_t g_window_width = -1; +static int32_t g_window_height = -1; + +#if defined(__GNUC__) + +#if defined(__linux__) + +#if defined(__ANDROID__) +#include +#include +#include +#include +#include +#include +#include +#include + +static void ANativeActivity_Destroy(ANativeActivity *native_activity); +static void ANativeActivity_WindowFocusChanged(ANativeActivity *native_activity, int hasFocus); +static void ANativeActivity_NativeWindowCreated(ANativeActivity *native_activity, ANativeWindow *native_window); +static void ANativeActivity_NativeWindowResized(ANativeActivity *native_activity, ANativeWindow *native_window); +static void ANativeActivity_NativeWindowRedrawNeeded(ANativeActivity *native_activity, ANativeWindow *native_window); +static void ANativeActivity_NativeWindowDestroyed(ANativeActivity *native_activity, ANativeWindow *native_window); +static void ANativeActivity_InputQueueCreated(ANativeActivity *native_activity, AInputQueue *input_queue); +static void ANativeActivity_InputQueueDestroyed(ANativeActivity *native_activity, AInputQueue *input_queue); + +static bool g_this_process_has_inited = false; + +static int g_main_thread_looper_draw_callback_fd_read = -1; +static int g_main_thread_looper_draw_callback_fd_write = -1; + +static int main_thread_looper_draw_callback(int fd, int, void *); + +static pthread_t g_draw_request_thread; +bool volatile g_draw_request_thread_running = false; + +static void *draw_request_thread_main(void *); + +static int main_thread_looper_input_queue_callback(int fd, int, void *input_queue_void); + +extern "C" JNIEXPORT void ANativeActivity_onCreate(ANativeActivity *native_activity, void *saved_state, size_t saved_state_size) +{ + native_activity->callbacks->onStart = NULL; + native_activity->callbacks->onResume = NULL; + native_activity->callbacks->onSaveInstanceState = NULL; + native_activity->callbacks->onPause = NULL; + native_activity->callbacks->onStop = NULL; + native_activity->callbacks->onDestroy = ANativeActivity_Destroy; + native_activity->callbacks->onWindowFocusChanged = ANativeActivity_WindowFocusChanged; + native_activity->callbacks->onNativeWindowCreated = ANativeActivity_NativeWindowCreated; + native_activity->callbacks->onNativeWindowResized = ANativeActivity_NativeWindowResized; + native_activity->callbacks->onNativeWindowRedrawNeeded = ANativeActivity_NativeWindowRedrawNeeded; + native_activity->callbacks->onNativeWindowDestroyed = ANativeActivity_NativeWindowDestroyed; + native_activity->callbacks->onInputQueueCreated = ANativeActivity_InputQueueCreated; + native_activity->callbacks->onInputQueueDestroyed = ANativeActivity_InputQueueDestroyed; + native_activity->callbacks->onContentRectChanged = NULL; + native_activity->callbacks->onConfigurationChanged = NULL; + native_activity->callbacks->onLowMemory = NULL; + + if (!g_this_process_has_inited) + { + // TODO: get file name + std::vector file_names; + + g_renderer = renderer_init(NULL, file_names); + + // Simulate the following callback on Android: + // WM_PAINT + // CVDisplayLinkSetOutputCallback + // displayLinkWithTarget + { + // the looper of the main thread + ALooper *main_thread_looper = ALooper_forThread(); + assert(main_thread_looper != NULL); + + // Evidently, the real "draw" is slower than the "request" + // There are no message boundaries for "SOCK_STREAM", and We can read all the data once + int sv[2]; + int res_socketpair = socketpair(AF_UNIX, SOCK_STREAM, 0, sv); + assert(0 == res_socketpair); + g_main_thread_looper_draw_callback_fd_read = sv[0]; + g_main_thread_looper_draw_callback_fd_write = sv[1]; + + // the identifier is ignored when callback is not NULL (the ALooper_pollOnce always returns the ALOOPER_POLL_CALLBACK) + int res_looper_add_fd = ALooper_addFd(main_thread_looper, g_main_thread_looper_draw_callback_fd_read, -1, ALOOPER_EVENT_INPUT, main_thread_looper_draw_callback, NULL); + assert(1 == res_looper_add_fd); + + // the "draw request" thread + // TODO: use Load/Store + g_draw_request_thread_running = false; + int res_ptread_create = pthread_create(&g_draw_request_thread, NULL, draw_request_thread_main, NULL); + assert(0 == res_ptread_create); + while (!g_draw_request_thread_running) + { + // pthread_yield(); + sched_yield(); + } + } + + // Don't worry + // Single thread + g_this_process_has_inited = true; + } +} + +// TODO: +// destroy before this process terminates + +static void ANativeActivity_Destroy(ANativeActivity *native_activity) +{ +} + +static void ANativeActivity_WindowFocusChanged(ANativeActivity *native_activity, int hasFocus) +{ +} + +static void ANativeActivity_NativeWindowCreated(ANativeActivity *native_activity, ANativeWindow *native_window) +{ + g_window_width = ANativeWindow_getWidth(native_window); + g_window_height = ANativeWindow_getHeight(native_window); + + renderer_attach_window(g_renderer, native_window); +} + +static void ANativeActivity_NativeWindowResized(ANativeActivity *native_activity, ANativeWindow *native_window) +{ +} + +static void ANativeActivity_NativeWindowRedrawNeeded(ANativeActivity *native_activity, ANativeWindow *native_window) +{ +} + +static void ANativeActivity_NativeWindowDestroyed(ANativeActivity *native_activity, ANativeWindow *native_window) +{ + renderer_dettach_window(g_renderer); + + g_window_width = -1; + g_window_height = -1; +} + +static void ANativeActivity_InputQueueCreated(ANativeActivity *native_activity, AInputQueue *input_queue) +{ + // the looper of the main thread + ALooper *main_thread_looper = ALooper_forThread(); + assert(NULL != main_thread_looper); + + // the identifier is ignored when callback is not NULL (the ALooper_pollOnce always returns the ALOOPER_POLL_CALLBACK) + AInputQueue_attachLooper(input_queue, main_thread_looper, 0, main_thread_looper_input_queue_callback, input_queue); +} + +static void ANativeActivity_InputQueueDestroyed(ANativeActivity *native_activity, AInputQueue *input_queue) +{ + ALooper *looper = ALooper_forThread(); + assert(NULL != looper); + + AInputQueue_detachLooper(input_queue); +} + +static int main_thread_looper_draw_callback(int fd, int, void *) +{ + // Evidently, the real "draw" is slower than the "request" + // There are no message boundaries for "SOCK_STREAM", and We can read all the data once + { + uint8_t buf[4096]; + ssize_t res_recv; + while ((-1 == (res_recv = recv(fd, buf, 4096U, 0))) && (EINTR == errno)) + { + // pthread_yield(); + sched_yield(); + } + assert(-1 != res_recv); + } + + // draw + renderer_draw(g_renderer); + + return 1; +} + +static void *draw_request_thread_main(void *) +{ + g_draw_request_thread_running = true; + + while (g_draw_request_thread_running) + { + // 60 FPS + uint32_t milli_second = 1000U / 60U; + + // wait + { + struct timespec request = {((time_t)milli_second) / ((time_t)1000), ((long)1000000) * (((long)milli_second) % ((long)1000))}; + + struct timespec remain; + int res_nanosleep; + while ((-1 == (res_nanosleep = nanosleep(&request, &remain))) && (EINTR == errno)) + { + assert(remain.tv_nsec > 0 || remain.tv_sec > 0); + request = remain; + } + assert(0 == res_nanosleep); + } + + // draw request + { + uint8_t buf[1] = {7}; // seven is the luck number + ssize_t res_send; + while ((-1 == (res_send = send(g_main_thread_looper_draw_callback_fd_write, buf, 1U, 0))) && (EINTR == errno)) + { + // pthread_yield(); + sched_yield(); + } + assert(1 == res_send); + } + } + + return NULL; +} + +static int main_thread_looper_input_queue_callback(int fd, int, void *input_queue_void) +{ + AInputQueue *input_queue = static_cast(input_queue_void); + + AInputEvent *input_event; + while (AInputQueue_getEvent(input_queue, &input_event) >= 0) + { + // The app will be "No response" if we don't call AInputQueue_finishEvent and pass the non-zero value for all events which is not pre-dispatched + if (0 == AInputQueue_preDispatchEvent(input_queue, input_event)) + { + int handled = 0; + + switch (AInputEvent_getType(input_event)) + { + case AINPUT_EVENT_TYPE_MOTION: + { + + float Current_X = AMotionEvent_getX(input_event, 0U); + float Current_Y = AMotionEvent_getY(input_event, 0U); + + float CurrentNormalized_X = Current_X / static_cast(g_window_width); + float CurrentNormalized_Y = Current_Y / static_cast(g_window_height); + + switch (AMotionEvent_getAction(input_event) & AMOTION_EVENT_ACTION_MASK) + { + case AMOTION_EVENT_ACTION_DOWN: + { + g_camera_controller.OnMouseMove(CurrentNormalized_X, CurrentNormalized_Y, false); + } + break; + case AMOTION_EVENT_ACTION_UP: + { + g_camera_controller.OnMouseMove(CurrentNormalized_X, CurrentNormalized_Y, false); + } + break; + case AMOTION_EVENT_ACTION_MOVE: + { + g_camera_controller.OnMouseMove(CurrentNormalized_X, CurrentNormalized_Y, true); + } + break; + default: + { + // Do Nothing + } + } + } + break; + default: + { + // Do Nothing + } + } + + AInputQueue_finishEvent(input_queue, input_event, handled); + } + } + + return 1; +} +#else + +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + // Vulkan Validation Layer +#ifndef NDEBUG + { + // We assume that the "VkLayer_khronos_validation.json" is at the same directory of the executable file + char dir_name[4096]; + ssize_t res_read_link = readlink("/proc/self/exe", dir_name, sizeof(dir_name) / sizeof(dir_name[0])); + assert(-1 != res_read_link); + + for (int i = (res_read_link - 1); i > 0; --i) + { + if (L'/' == dir_name[i]) + { + dir_name[i] = L'\0'; + break; + } + } + + int res_set_env_vk_layer_path = setenv("VK_LAYER_PATH", dir_name, 1); + assert(0 == res_set_env_vk_layer_path); + + int res_set_env_ld_library_path = setenv("LD_LIBRARY_PATH", dir_name, 1); + assert(0 == res_set_env_ld_library_path); + } +#endif + + std::vector file_names; + { + if (argc < 2) + { + puts("Usage: glTF-Viewer \n"); + return 0; + } + else + { + for (int arg_index = 1; arg_index < argc; ++arg_index) + { + file_names.push_back({}); + file_names.back() = argv[arg_index]; + } + } + } + + g_window_width = 512; + g_window_height = 512; + + xcb_connection_t *connection = NULL; + xcb_screen_t *screen = NULL; + { + int screen_number; + connection = xcb_connect(NULL, &screen_number); + assert(0 == xcb_connection_has_error(connection)); + + xcb_setup_t const *setup = xcb_get_setup(connection); + + int i = 0; + for (xcb_screen_iterator_t screen_iterator = xcb_setup_roots_iterator(setup); screen_iterator.rem > 0; xcb_screen_next(&screen_iterator)) + { + if (i == screen_number) + { + screen = screen_iterator.data; + break; + } + ++i; + } + } + + constexpr uint8_t const depth = 32; + xcb_visualid_t visual_id = -1; + { + for (xcb_depth_iterator_t depth_iterator = xcb_screen_allowed_depths_iterator(screen); depth_iterator.rem > 0; xcb_depth_next(&depth_iterator)) + { + if (depth == depth_iterator.data->depth) + { + for (xcb_visualtype_iterator_t visual_iterator = xcb_depth_visuals_iterator(depth_iterator.data); visual_iterator.rem > 0; xcb_visualtype_next(&visual_iterator)) + { + if (XCB_VISUAL_CLASS_TRUE_COLOR == visual_iterator.data->_class) + { + visual_id = visual_iterator.data->visual_id; + break; + } + } + break; + } + } + } + + xcb_colormap_t colormap = 0; + { + colormap = xcb_generate_id(connection); + + xcb_void_cookie_t cookie_create_colormap = xcb_create_colormap_checked(connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visual_id); + + xcb_generic_error_t *error_create_colormap = xcb_request_check(connection, cookie_create_colormap); + assert(NULL == error_create_colormap); + } + + xcb_window_t window = 0; + { + window = xcb_generate_id(connection); + + // Both "border pixel" and "colormap" are required when the depth is NOT equal to the root window's. + uint32_t value_mask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_BACKING_STORE | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; + + uint32_t value_list[5] = {screen->black_pixel, 0, XCB_BACKING_STORE_NOT_USEFUL, XCB_EVENT_MASK_STRUCTURE_NOTIFY, colormap}; + + xcb_void_cookie_t cookie_create_window = xcb_create_window_checked(connection, depth, window, screen->root, 0, 0, g_window_width, g_window_height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual_id, value_mask, value_list); + + xcb_generic_error_t *error_create_window = xcb_request_check(connection, cookie_create_window); + assert(NULL == error_create_window); + } + + xcb_atom_t atom_wm_protocols = 0; + xcb_atom_t atom_wm_delete_window = 0; + { + xcb_intern_atom_cookie_t cookie_wm_protocols = xcb_intern_atom(connection, 0, 12U, "WM_PROTOCOLS"); + + xcb_intern_atom_cookie_t cookie_wm_delete_window = xcb_intern_atom(connection, 0, 16U, "WM_DELETE_WINDOW"); + + xcb_generic_error_t *error_intern_atom_reply_wm_protocols; + xcb_intern_atom_reply_t *reply_wm_protocols = xcb_intern_atom_reply(connection, cookie_wm_protocols, &error_intern_atom_reply_wm_protocols); + assert(NULL == error_intern_atom_reply_wm_protocols); + atom_wm_protocols = reply_wm_protocols->atom; + free(error_intern_atom_reply_wm_protocols); + + xcb_generic_error_t *error_intern_atom_reply_wm_delete_window; + xcb_intern_atom_reply_t *reply_wm_delete_window = xcb_intern_atom_reply(connection, cookie_wm_delete_window, &error_intern_atom_reply_wm_delete_window); + assert(NULL == error_intern_atom_reply_wm_delete_window); + atom_wm_delete_window = reply_wm_delete_window->atom; + free(error_intern_atom_reply_wm_delete_window); + } + + { + xcb_void_cookie_t cookie_change_property_wm_name = xcb_change_property(connection, XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8 * sizeof(uint8_t), 11, "glTF Viewer"); + + xcb_void_cookie_t cookie_change_property_wm_protocols_delete_window = xcb_change_property_checked(connection, XCB_PROP_MODE_REPLACE, window, atom_wm_protocols, XCB_ATOM_ATOM, 8 * sizeof(uint32_t), sizeof(xcb_atom_t) / sizeof(uint32_t), &atom_wm_delete_window); + + xcb_generic_error_t *error_change_property_net_wm_name = xcb_request_check(connection, cookie_change_property_wm_name); + assert(NULL == error_change_property_net_wm_name); + + xcb_generic_error_t *error_change_property_wm_protocols_delete_window = xcb_request_check(connection, cookie_change_property_wm_protocols_delete_window); + assert(NULL == error_change_property_wm_protocols_delete_window); + } + + { + struct brx_xcb_connection_T + { + xcb_connection_t *m_connection; + xcb_visualid_t m_visual_id; + }; + brx_xcb_connection_T brx_xcb_connection = { + connection, + visual_id}; + + g_renderer = renderer_init(&brx_xcb_connection, file_names); + + struct brx_xcb_window_T + { + xcb_connection_t *m_connection; + xcb_window_t m_window; + }; + + brx_xcb_window_T brx_xcb_window = { + connection, + window}; + + renderer_attach_window(g_renderer, &brx_xcb_window); + } + + { + xcb_void_cookie_t cookie_map_window = xcb_map_window_checked(connection, window); + + xcb_generic_error_t *error_map_window = xcb_request_check(connection, cookie_map_window); + assert(NULL == error_map_window); + } + + bool quit = false; + while (!quit) + { + // WSI Event + { + xcb_generic_event_t *event; + while ((event = xcb_poll_for_event(connection)) != NULL) + { + // The most significant bit(uint8_t(0X80)) in this code is set if the event was generated from a SendEvent request. + // https://www.x.org/releases/current/doc/xproto/x11protocol.html#event_format + switch (event->response_type & (~uint8_t(0X80))) + { + case XCB_CONFIGURE_NOTIFY: + { + assert(XCB_CONFIGURE_NOTIFY == (event->response_type & (~uint8_t(0X80)))); + + xcb_configure_notify_event_t *const configure_notify = reinterpret_cast(event); + + if (g_window_width != configure_notify->width || g_window_height != configure_notify->height) + { + renderer_on_window_resize(g_renderer); + g_window_width = configure_notify->width; + g_window_height = configure_notify->height; + } + } + break; + case XCB_CLIENT_MESSAGE: + { + assert(XCB_CLIENT_MESSAGE == (event->response_type & (~uint8_t(0X80)))); + + xcb_client_message_event_t *const client_message_event = reinterpret_cast(event); + assert(client_message_event->type == atom_wm_protocols && client_message_event->data.data32[0] == atom_wm_delete_window && client_message_event->window == window); + + quit = true; + } + break; + case 0: + { + assert(0 == (event->response_type & (~uint8_t(0X80)))); + + xcb_generic_error_t *error = reinterpret_cast(event); + + printf("Error Code: %d Major Code: %d", static_cast(error->error_code), static_cast(error->major_code)); + } + break; + } + + free(event); + } + } + + // Render + renderer_draw(g_renderer); + } + + { + xcb_void_cookie_t cookie_free_colormap = xcb_free_colormap_checked(connection, colormap); + + xcb_generic_error_t *error_free_colormap = xcb_request_check(connection, cookie_free_colormap); + assert(NULL == error_free_colormap); + } + + xcb_disconnect(connection); + + renderer_dettach_window(g_renderer); + + renderer_destroy(g_renderer); + + return 0; +} + +#endif +#else +#error Unknown Platform +#endif + +#elif defined(_MSC_VER) + +#define NOMINMAX 1 +#define WIN32_LEAN_AND_MEAN 1 +#include +#include +#include +#include +#include "../../thirdparty/ConvertUTF/include/ConvertUTF.h" + +static LRESULT CALLBACK wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +extern "C" IMAGE_DOS_HEADER __ImageBase; + +int wmain(int argc, wchar_t *argv[]) +{ + // Vulkan Validation Layer +#ifndef NDEBUG + { + // We assume that the "VkLayer_khronos_validation.json" is at the same directory of the executable file + WCHAR file_name[4096]; + DWORD res_get_file_name = GetModuleFileNameW(NULL, file_name, sizeof(file_name) / sizeof(file_name[0])); + assert(0U != res_get_file_name); + + for (int i = (res_get_file_name - 1); i > 0; --i) + { + if (L'\\' == file_name[i]) + { + file_name[i] = L'\0'; + break; + } + } + + BOOL res_set_environment_variable = SetEnvironmentVariableW(L"VK_LAYER_PATH", file_name); + assert(FALSE != res_set_environment_variable); + } +#endif + + // Initialize + { + std::vector file_names; + { + if (argc < 2) + { + HRESULT res_co_initialize_ex = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + assert(SUCCEEDED(res_co_initialize_ex)); + + IFileOpenDialog *file_open_dialog; + HRESULT res_co_create_instance = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&file_open_dialog)); + assert(SUCCEEDED(res_co_create_instance)); + + FILEOPENDIALOGOPTIONS file_open_dialog_options; + HRESULT res_file_open_dialog_get_options = file_open_dialog->GetOptions(&file_open_dialog_options); + assert(SUCCEEDED(res_file_open_dialog_get_options)); + + file_open_dialog_options |= FOS_FORCEFILESYSTEM; + file_open_dialog_options |= FOS_ALLOWMULTISELECT; + + HRESULT res_file_open_dialog_set_options = file_open_dialog->SetOptions(file_open_dialog_options); + assert(SUCCEEDED(res_file_open_dialog_set_options)); + + COMDLG_FILTERSPEC const filter_specs[] = { + {L"All Files", L"*.*"}, + {L"glTF Binary", L"*.glb"}, + {L"glTF Separate", L"*.gltf"}}; + HRESULT res_file_open_dialog_set_file_types = file_open_dialog->SetFileTypes(sizeof(filter_specs) / sizeof(filter_specs[0]), filter_specs); + assert(SUCCEEDED(res_file_open_dialog_set_file_types)); + + HRESULT res_file_open_dialog_set_file_type_index = file_open_dialog->SetFileTypeIndex(3U); + assert(SUCCEEDED(res_file_open_dialog_set_file_type_index)); + + HRESULT res_file_open_dialog_show = file_open_dialog->Show(NULL); + if (SUCCEEDED(res_file_open_dialog_show)) + { + IShellItemArray *item_array; + HRESULT res_file_open_dialog_get_result = file_open_dialog->GetResults(&item_array); + assert(SUCCEEDED(res_file_open_dialog_get_result)); + + DWORD item_count; + HRESULT res_shell_item_array_get_count = item_array->GetCount(&item_count); + assert(SUCCEEDED(res_shell_item_array_get_count)); + + for (DWORD item_index = 0U; item_index < item_count; ++item_index) + { + IShellItem *item; + HRESULT res_shell_item_array_get_item_at = item_array->GetItemAt(item_index, &item); + assert(SUCCEEDED(res_shell_item_array_get_item_at)); + + WCHAR *name; + HRESULT res_shell_item_get_display_name = item->GetDisplayName(SIGDN_FILESYSPATH, &name); + assert(SUCCEEDED(res_shell_item_get_display_name)); + + std::wstring file_name(name); + + CoTaskMemFree(name); + + item->Release(); + + file_names.push_back({}); + bool res_convert_utf16_To_utf8_string = llvm::convertUTF16ToUTF8String(file_name, file_names.back()); + assert(res_convert_utf16_To_utf8_string); + } + + item_array->Release(); + } + else + { + assert(HRESULT_FROM_WIN32(ERROR_CANCELLED) == res_file_open_dialog_show); + return 0; + } + + CoUninitialize(); + } + else + { + for (int arg_index = 1; arg_index < argc; ++arg_index) + { + std::wstring file_name(argv[1]); + + file_names.push_back({}); + bool res_convert_utf16_To_utf8_string = llvm::convertUTF16ToUTF8String(file_name, file_names.back()); + assert(res_convert_utf16_To_utf8_string); + } + } + } + + HINSTANCE hInstance = reinterpret_cast(&__ImageBase); + + g_window_width = 512; + g_window_height = 512; + + ATOM hWndCls; + { + WNDCLASSEXW Desc = { + sizeof(WNDCLASSEX), + CS_OWNDC, + wnd_proc, + 0, + 0, + hInstance, + LoadIconW(NULL, IDI_APPLICATION), + LoadCursorW(NULL, IDC_ARROW), + (HBRUSH)(COLOR_WINDOW + 1), + NULL, + L"glTF-Viewer:0XFFFFFFFF", + LoadIconW(NULL, IDI_APPLICATION), + }; + hWndCls = RegisterClassExW(&Desc); + } + + HWND hWnd; + { + HWND hDesktop = GetDesktopWindow(); + HMONITOR hMonitor = MonitorFromWindow(hDesktop, MONITOR_DEFAULTTONEAREST); + MONITORINFOEXW MonitorInfo; + MonitorInfo.cbSize = sizeof(MONITORINFOEXW); + GetMonitorInfoW(hMonitor, &MonitorInfo); + + constexpr DWORD const dw_style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME; + constexpr DWORD const dw_ex_style = WS_EX_APPWINDOW; + + RECT rect = {(MonitorInfo.rcWork.left + MonitorInfo.rcWork.right) / 2 - g_window_width / 2, + (MonitorInfo.rcWork.bottom + MonitorInfo.rcWork.top) / 2 - g_window_height / 2, + (MonitorInfo.rcWork.left + MonitorInfo.rcWork.right) / 2 + g_window_width / 2, + (MonitorInfo.rcWork.bottom + MonitorInfo.rcWork.top) / 2 + g_window_height / 2}; + AdjustWindowRectEx(&rect, dw_style, FALSE, dw_ex_style); + + hWnd = CreateWindowExW(dw_ex_style, MAKEINTATOM(hWndCls), L"glTF Viewer", dw_style, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hDesktop, NULL, hInstance, NULL); + } + + g_renderer = renderer_init(NULL, file_names); + + renderer_attach_window(g_renderer, hWnd); + + ShowWindow(hWnd, SW_SHOWDEFAULT); + + BOOL result_update_window = UpdateWindow(hWnd); + assert(FALSE != result_update_window); + } + + // Run + { + MSG msg; + while (GetMessageW(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + + // Destroy + { + renderer_dettach_window(g_renderer); + + renderer_destroy(g_renderer); + } + + return 0; +} + +static LRESULT CALLBACK wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_DESTROY: + { + PostQuitMessage(0); + } + return 0; + case WM_PAINT: + { + renderer_draw(g_renderer); + } + return 0; + case WM_SIZE: + { + WORD const new_width = LOWORD(lParam); + WORD const new_height = HIWORD(lParam); + + if (g_window_width != new_width || g_window_height != new_height) + { + renderer_on_window_resize(g_renderer); + g_window_width = new_width; + g_window_height = new_height; + } + } + return 0; + case WM_ERASEBKGND: + return 1; + case WM_KEYDOWN: + { + switch (wParam) + { + case 'W': + { + g_camera_controller.MoveForward(); + } + break; + case 'S': + { + g_camera_controller.MoveBack(); + } + break; + case 'A': + { + g_camera_controller.MoveLeft(); + } + break; + case 'D': + { + g_camera_controller.MoveRight(); + } + break; + case 'Q': + { + g_camera_controller.MoveDown(); + } + break; + case 'E': + { + g_camera_controller.MoveUp(); + } + break; + } + } + return 0; + case WM_MOUSEMOVE: + { + int Current_X = GET_X_LPARAM(lParam); + int Current_Y = GET_Y_LPARAM(lParam); + + float CurrentNormalized_X = static_cast(Current_X) / g_window_width; + float CurrentNormalized_Y = static_cast(Current_Y) / g_window_height; + + g_camera_controller.OnMouseMove(CurrentNormalized_X, CurrentNormalized_Y, (0 != (wParam & MK_RBUTTON))); + } + return 0; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } +} + +#else +#error Unknown Compiler +#endif \ No newline at end of file diff --git a/source/support/renderer.cpp b/source/support/renderer.cpp new file mode 100644 index 0000000..c94ed31 --- /dev/null +++ b/source/support/renderer.cpp @@ -0,0 +1,435 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#include +#include +#include +#include + +#include "renderer.h" +#include "frame_throttling.h" +#include "tick_count.h" +#include "../../thirdparty/Brioche/include/brx_device.h" +#include "../demo.h" + +class renderer +{ + brx_device *m_device; + + brx_graphics_queue *m_graphics_queue; + + uint32_t m_frame_throttling_index; + + brx_graphics_command_buffer *m_command_buffers[FRAME_THROTTLING_COUNT]; + brx_fence *m_fences[FRAME_THROTTLING_COUNT]; + + brx_surface *m_surface; + brx_swap_chain *m_swap_chain; + + Demo m_demo; + + brx_pipeline_layout *m_full_screen_transfer_pipeline_layout; + + brx_render_pass *m_full_screen_transfer_render_pass; + brx_graphics_pipeline *m_full_screen_transfer_pipeline; + + brx_descriptor_set_layout *m_full_screen_transfer_pipeline_none_update_descriptor_set_layout; + brx_descriptor_set *m_full_screen_transfer_pipeline_none_update_descriptor_set; + + BRX_COLOR_ATTACHMENT_IMAGE_FORMAT m_swap_chain_image_format; + uint32_t m_swap_chain_image_width; + uint32_t m_swap_chain_image_height; + std::vector m_swap_chain_frame_buffers; + + double m_tick_count_resolution; + uint64_t m_tick_count_previous_frame; + + void attach_swap_chain(); + + void dettach_swap_chain(); + + void create_swap_chain_render_pass_and_pipeline(); + + void destroy_swap_chain_render_pass_and_pipeline(); + +public: + renderer(); + + ~renderer(); + + void init(void *wsi_connection, std::vector const &file_names); + + void destroy(); + + void attach_window(void *wsi_window); + + void on_window_resize(); + + void dettach_window(); + + void draw(); +}; + +renderer::renderer() : m_surface(NULL), m_swap_chain(NULL) +{ +} + +renderer::~renderer() +{ + for (uint32_t frame_throtting_index = 0U; frame_throtting_index < FRAME_THROTTLING_COUNT; ++frame_throtting_index) + { + assert(NULL == this->m_command_buffers[frame_throtting_index]); + assert(NULL == this->m_fences[frame_throtting_index]); + } + + assert(NULL == this->m_surface); + assert(NULL == this->m_swap_chain); + + assert(NULL == this->m_device); +} + +extern renderer *renderer_init(void *wsi_connection, std::vector const &file_names) +{ + renderer *new_renderer = new (malloc(sizeof(renderer))) renderer{}; + new_renderer->init(wsi_connection, file_names); + return new_renderer; +} + +extern void renderer_destroy(renderer *renderer) +{ + renderer->destroy(); + renderer->~renderer(); + free(renderer); +} + +extern void renderer_attach_window(renderer *renderer, void *wsi_window) +{ + renderer->attach_window(wsi_window); +} + +extern void renderer_on_window_resize(renderer *renderer) +{ + renderer->on_window_resize(); +} + +extern void renderer_dettach_window(renderer *renderer) +{ + renderer->dettach_window(); +} + +extern void renderer_draw(renderer *renderer) +{ + renderer->draw(); +} + +void renderer::init(void *wsi_connection, std::vector const &file_names) +{ + this->m_device = brx_init_unknown_device(wsi_connection, false); + + this->m_graphics_queue = this->m_device->create_graphics_queue(); + + this->m_frame_throttling_index = 0U; + + for (uint32_t frame_throtting_index = 0U; frame_throtting_index < FRAME_THROTTLING_COUNT; ++frame_throtting_index) + { + this->m_command_buffers[frame_throtting_index] = this->m_device->create_graphics_command_buffer(); + this->m_fences[frame_throtting_index] = this->m_device->create_fence(true); + } + + // Demo Init + this->m_demo.init(this->m_device, file_names); + + // Descriptor Layout + { + BRX_DESCRIPTOR_SET_LAYOUT_BINDING full_screen_transfer_none_update_descriptor_set_layout_bindings[] = { + // texture and sampler + {0U, BRX_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1U}}; + this->m_full_screen_transfer_pipeline_none_update_descriptor_set_layout = this->m_device->create_descriptor_set_layout(sizeof(full_screen_transfer_none_update_descriptor_set_layout_bindings) / sizeof(full_screen_transfer_none_update_descriptor_set_layout_bindings[0]), full_screen_transfer_none_update_descriptor_set_layout_bindings); + + brx_descriptor_set_layout *const full_screen_transfer_descriptor_set_layouts[] = {this->m_full_screen_transfer_pipeline_none_update_descriptor_set_layout}; + this->m_full_screen_transfer_pipeline_layout = this->m_device->create_pipeline_layout(sizeof(full_screen_transfer_descriptor_set_layouts) / sizeof(full_screen_transfer_descriptor_set_layouts[0]), full_screen_transfer_descriptor_set_layouts); + } + + // Pipeline + { + this->m_swap_chain_image_format = BRX_COLOR_ATTACHMENT_FORMAT_B8G8R8A8_UNORM; + this->m_full_screen_transfer_render_pass = NULL; + this->m_full_screen_transfer_pipeline = NULL; + this->create_swap_chain_render_pass_and_pipeline(); + } + + // Descriptor + { + this->m_full_screen_transfer_pipeline_none_update_descriptor_set = this->m_device->create_descriptor_set(this->m_full_screen_transfer_pipeline_none_update_descriptor_set_layout); + } + + // Init SwapChain Related + this->m_swap_chain_image_width = 0U; + this->m_swap_chain_image_height = 0U; + assert(0U == this->m_swap_chain_frame_buffers.size()); + + // Tick Count + this->m_tick_count_resolution = (1.0 / static_cast(tick_count_per_second())); + this->m_tick_count_previous_frame = tick_count_now(); +} + +void renderer::destroy() +{ + for (uint32_t frame_throtting_index = 0U; frame_throtting_index < FRAME_THROTTLING_COUNT; ++frame_throtting_index) + { + this->m_device->wait_for_fence(this->m_fences[frame_throtting_index]); + } + + this->m_demo.destroy(this->m_device); + + this->m_device->destroy_descriptor_set(this->m_full_screen_transfer_pipeline_none_update_descriptor_set); + + this->m_device->destroy_descriptor_set_layout(this->m_full_screen_transfer_pipeline_none_update_descriptor_set_layout); + + this->destroy_swap_chain_render_pass_and_pipeline(); + + this->m_device->destroy_pipeline_layout(this->m_full_screen_transfer_pipeline_layout); + + for (uint32_t frame_throtting_index = 0U; frame_throtting_index < FRAME_THROTTLING_COUNT; ++frame_throtting_index) + { + this->m_device->destroy_graphics_command_buffer(this->m_command_buffers[frame_throtting_index]); + this->m_command_buffers[frame_throtting_index] = NULL; + this->m_device->destroy_fence(this->m_fences[frame_throtting_index]); + this->m_fences[frame_throtting_index] = NULL; + } + + brx_destroy_unknown_device(this->m_device); + this->m_device = NULL; +} + +void renderer::attach_window(void *wsi_window) +{ + assert(NULL == this->m_surface); + + this->m_surface = this->m_device->create_surface(wsi_window); + this->attach_swap_chain(); +} + +void renderer::on_window_resize() +{ + for (uint32_t frame_throtting_index = 0U; frame_throtting_index < FRAME_THROTTLING_COUNT; ++frame_throtting_index) + { + this->m_device->wait_for_fence(this->m_fences[frame_throtting_index]); + } + + this->dettach_swap_chain(); + this->attach_swap_chain(); +} + +void renderer::dettach_window() +{ + for (uint32_t frame_throtting_index = 0U; frame_throtting_index < FRAME_THROTTLING_COUNT; ++frame_throtting_index) + { + this->m_device->wait_for_fence(this->m_fences[frame_throtting_index]); + } + + this->dettach_swap_chain(); + this->m_device->destroy_surface(this->m_surface); + + this->m_surface = NULL; + this->m_swap_chain = NULL; +} + +void renderer::attach_swap_chain() +{ + assert(NULL == this->m_swap_chain); + this->m_swap_chain = this->m_device->create_swap_chain(this->m_surface); + + assert(0U == this->m_swap_chain_image_width); + assert(0U == this->m_swap_chain_image_height); + this->m_swap_chain_image_width = this->m_swap_chain->get_image_width(); + this->m_swap_chain_image_height = this->m_swap_chain->get_image_height(); + + if (this->m_swap_chain_image_format != this->m_swap_chain->get_image_format()) + { + this->m_swap_chain_image_format = this->m_swap_chain->get_image_format(); + this->destroy_swap_chain_render_pass_and_pipeline(); + this->create_swap_chain_render_pass_and_pipeline(); + } + + uint32_t const swap_chain_image_count = this->m_swap_chain->get_image_count(); + assert(0U == this->m_swap_chain_frame_buffers.size()); + this->m_swap_chain_frame_buffers.resize(swap_chain_image_count); + + for (uint32_t swap_chain_image_index = 0U; swap_chain_image_index < swap_chain_image_count; ++swap_chain_image_index) + { + brx_color_attachment_image const *const swap_chain_color_attachment_image = this->m_swap_chain->get_image(swap_chain_image_index); + + this->m_swap_chain_frame_buffers[swap_chain_image_index] = this->m_device->create_frame_buffer(this->m_full_screen_transfer_render_pass, this->m_swap_chain_image_width, this->m_swap_chain_image_height, 1U, &swap_chain_color_attachment_image, NULL); + } + + this->m_demo.on_swap_chain_attach(this->m_device, this->m_swap_chain_image_width, this->m_swap_chain_image_height); + + // Descriptor + { + // Full Screen Transfer Pipeline + { + // The VkDescriptorSetLayout should still be valid when perform write update on VkDescriptorSet + assert(NULL != this->m_full_screen_transfer_pipeline_none_update_descriptor_set_layout); + { + brx_sampled_image const *const sampled_images[] = { + this->m_demo.get_sampled_image_for_present()}; + this->m_device->write_descriptor_set(this->m_full_screen_transfer_pipeline_none_update_descriptor_set, 0U, BRX_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0U, sizeof(sampled_images) / sizeof(sampled_images[0]), NULL, NULL, NULL, NULL, sampled_images, NULL, NULL, NULL); + } + } + } +} + +void renderer::dettach_swap_chain() +{ + this->m_demo.on_swap_chain_dettach(this->m_device); + + uint32_t const swap_chain_image_count = static_cast(this->m_swap_chain_frame_buffers.size()); + assert(this->m_swap_chain->get_image_count() == swap_chain_image_count); + + for (uint32_t swap_chain_image_index = 0U; swap_chain_image_index < swap_chain_image_count; ++swap_chain_image_index) + { + this->m_device->destroy_frame_buffer(this->m_swap_chain_frame_buffers[swap_chain_image_index]); + } + + this->m_swap_chain_frame_buffers.clear(); + + this->m_swap_chain_image_width = 0U; + this->m_swap_chain_image_height = 0U; + + this->m_device->destroy_swap_chain(this->m_swap_chain); + this->m_swap_chain = NULL; +} + +void renderer::create_swap_chain_render_pass_and_pipeline() +{ + assert(NULL == this->m_full_screen_transfer_render_pass); + assert(NULL == this->m_full_screen_transfer_pipeline); + + // Render Pass + { + BRX_RENDER_PASS_COLOR_ATTACHMENT color_attachments[1] = { + {this->m_swap_chain_image_format, + BRX_RENDER_PASS_COLOR_ATTACHMENT_LOAD_OPERATION_CLEAR, + BRX_RENDER_PASS_COLOR_ATTACHMENT_STORE_OPERATION_FLUSH_FOR_PRESENT}}; + + this->m_full_screen_transfer_render_pass = this->m_device->create_render_pass(sizeof(color_attachments) / sizeof(color_attachments[0]), color_attachments, NULL); + } + + // Pipeline + { +#include +#include + this->m_full_screen_transfer_pipeline = this->m_device->create_graphics_pipeline(this->m_full_screen_transfer_render_pass, this->m_full_screen_transfer_pipeline_layout, sizeof(full_screen_transfer_vertex_shader_module_code), full_screen_transfer_vertex_shader_module_code, sizeof(full_screen_transfer_fragment_shader_module_code), full_screen_transfer_fragment_shader_module_code, 0U, NULL, 0U, NULL, false, BRX_GRAPHICS_PIPELINE_COMPARE_OPERATION_ALWAYS); + } +} + +void renderer::destroy_swap_chain_render_pass_and_pipeline() +{ + this->m_device->destroy_render_pass(this->m_full_screen_transfer_render_pass); + this->m_device->destroy_graphics_pipeline(this->m_full_screen_transfer_pipeline); + + this->m_full_screen_transfer_render_pass = NULL; + this->m_full_screen_transfer_pipeline = NULL; +} + +void renderer::draw() +{ + if (NULL == this->m_surface) + { + // skip this frame + return; + } + + assert(NULL != this->m_swap_chain); + + this->m_device->wait_for_fence(this->m_fences[this->m_frame_throttling_index]); + + this->m_device->reset_graphics_command_buffer(this->m_command_buffers[this->m_frame_throttling_index]); + + this->m_command_buffers[this->m_frame_throttling_index]->begin(); + + { + uint64_t const tick_count_current_frame = tick_count_now(); + float const interval_time = static_cast(static_cast(tick_count_current_frame - this->m_tick_count_previous_frame) * this->m_tick_count_resolution); + this->m_tick_count_previous_frame = tick_count_current_frame; + + this->m_demo.draw(this->m_command_buffers[this->m_frame_throttling_index], interval_time, this->m_frame_throttling_index); + } + + uint32_t swap_chain_image_index = -1; + bool acquire_next_image_not_out_of_date = this->m_device->acquire_next_image(this->m_command_buffers[this->m_frame_throttling_index], this->m_swap_chain, &swap_chain_image_index); + if (!acquire_next_image_not_out_of_date) + { + // NOTE: we should end the command buffer before we destroy the bound image + this->m_command_buffers[this->m_frame_throttling_index]->end(); + + for (uint32_t frame_throtting_index = 0U; frame_throtting_index < FRAME_THROTTLING_COUNT; ++frame_throtting_index) + { + this->m_device->wait_for_fence(this->m_fences[frame_throtting_index]); + } + + this->dettach_swap_chain(); + this->attach_swap_chain(); + + // skip this frame + return; + } + + // draw full screen triangle + { + this->m_command_buffers[this->m_frame_throttling_index]->begin_debug_utils_label("Full Screen Transfer Pass"); + + float color_clear_values[4] = {0.0F, 0.0F, 0.0F, 0.0F}; + this->m_command_buffers[this->m_frame_throttling_index]->begin_render_pass(this->m_full_screen_transfer_render_pass, this->m_swap_chain_frame_buffers[swap_chain_image_index], this->m_swap_chain_image_width, this->m_swap_chain_image_height, 1U, &color_clear_values, NULL, NULL); + + this->m_command_buffers[this->m_frame_throttling_index]->bind_graphics_pipeline(this->m_full_screen_transfer_pipeline); + + this->m_command_buffers[this->m_frame_throttling_index]->set_view_port(this->m_swap_chain_image_width, this->m_swap_chain_image_height); + + this->m_command_buffers[this->m_frame_throttling_index]->set_scissor(this->m_swap_chain_image_width, this->m_swap_chain_image_height); + + brx_descriptor_set *const descritor_sets[1] = {this->m_full_screen_transfer_pipeline_none_update_descriptor_set}; + this->m_command_buffers[this->m_frame_throttling_index]->bind_graphics_descriptor_sets(this->m_full_screen_transfer_pipeline_layout, sizeof(descritor_sets) / sizeof(descritor_sets[0]), descritor_sets, 0U, NULL); + this->m_command_buffers[this->m_frame_throttling_index]->draw(3U, 1U); + + this->m_command_buffers[this->m_frame_throttling_index]->end_render_pass(); + + this->m_command_buffers[this->m_frame_throttling_index]->end_debug_utils_label(); + } + + this->m_command_buffers[this->m_frame_throttling_index]->end(); + + this->m_device->reset_fence(this->m_fences[this->m_frame_throttling_index]); + + bool present_not_out_of_date = this->m_graphics_queue->submit_and_present(this->m_command_buffers[this->m_frame_throttling_index], this->m_swap_chain, swap_chain_image_index, this->m_fences[this->m_frame_throttling_index]); + if (!present_not_out_of_date) + { + for (uint32_t frame_throtting_index = 0U; frame_throtting_index < FRAME_THROTTLING_COUNT; ++frame_throtting_index) + { + this->m_device->wait_for_fence(this->m_fences[frame_throtting_index]); + } + + this->dettach_swap_chain(); + this->attach_swap_chain(); + + // continue this frame + } + + ++this->m_frame_throttling_index; + this->m_frame_throttling_index %= FRAME_THROTTLING_COUNT; +} diff --git a/source/support/renderer.h b/source/support/renderer.h new file mode 100644 index 0000000..d01a053 --- /dev/null +++ b/source/support/renderer.h @@ -0,0 +1,31 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _RENDERER_H_ +#define _RENDERER_H_ 1 + +#include +#include + +extern class renderer *renderer_init(void *wsi_connection, std::vector const &file_names); +extern void renderer_destroy(class renderer *renderer); +extern void renderer_attach_window(class renderer *renderer, void *wsi_window); +extern void renderer_on_window_resize(class renderer *renderer); +extern void renderer_dettach_window(class renderer *renderer); +extern void renderer_draw(class renderer *renderer); + +#endif \ No newline at end of file diff --git a/source/support/tick_count.cpp b/source/support/tick_count.cpp new file mode 100644 index 0000000..08f2f3e --- /dev/null +++ b/source/support/tick_count.cpp @@ -0,0 +1,70 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#include "tick_count.h" +#include + +#if defined(__GNUC__) + +#include + +extern uint64_t tick_count_per_second() +{ + constexpr uint64_t const tick_count_per_second = 1000000000ULL; + return tick_count_per_second; +} + +extern uint64_t tick_count_now() +{ + struct timespec time_monotonic; + int result_clock_get_time_monotonic = clock_gettime(CLOCK_MONOTONIC, &time_monotonic); + assert(0 == result_clock_get_time_monotonic); + + uint64_t const tick_count_now = static_cast(1000000000ULL) * static_cast(time_monotonic.tv_sec) + static_cast(time_monotonic.tv_nsec); + return tick_count_now; +} + +#elif defined(_MSC_VER) + +#define NOMINMAX 1 +#define WIN32_LEAN_AND_MEAN 1 +#include +#include + +extern uint64_t tick_count_per_second() +{ + LARGE_INTEGER int64_frequency; + BOOL result_query_performance_frequency = QueryPerformanceFrequency(&int64_frequency); + assert(NULL != result_query_performance_frequency); + + uint64_t const tick_count_per_second = static_cast(int64_frequency.QuadPart); + return tick_count_per_second; +} + +extern uint64_t tick_count_now() +{ + LARGE_INTEGER int64_performance_count; + BOOL result_query_performance_counter = QueryPerformanceCounter(&int64_performance_count); + assert(NULL != result_query_performance_counter); + + uint64_t const tick_count_now = static_cast(int64_performance_count.QuadPart); + return tick_count_now; +} + +#else +#error Unknown Compiler +#endif \ No newline at end of file diff --git a/source/support/tick_count.h b/source/support/tick_count.h new file mode 100644 index 0000000..db67e45 --- /dev/null +++ b/source/support/tick_count.h @@ -0,0 +1,28 @@ +// +// Copyright (C) YuqiaoZhang(HanetakaChou) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +#ifndef _TICK_COUNT_H_ +#define _TICK_COUNT_H_ 1 + +#include +#include + +extern uint64_t tick_count_per_second(); + +extern uint64_t tick_count_now(); + +#endif diff --git a/spirv/.gitignore b/spirv/.gitignore new file mode 100644 index 0000000..70a618f --- /dev/null +++ b/spirv/.gitignore @@ -0,0 +1,2 @@ +/debug +/release diff --git a/spirv/deferred_shading_fragment.inl b/spirv/deferred_shading_fragment.inl new file mode 100644 index 0000000..ce8113c --- /dev/null +++ b/spirv/deferred_shading_fragment.inl @@ -0,0 +1,3 @@ +constexpr uint32_t const deferred_shading_fragment_shader_module_code[] = { +#include <_internal_deferred_shading_fragment.inl> +}; \ No newline at end of file diff --git a/spirv/deferred_shading_vertex.inl b/spirv/deferred_shading_vertex.inl new file mode 100644 index 0000000..d23507d --- /dev/null +++ b/spirv/deferred_shading_vertex.inl @@ -0,0 +1,3 @@ +constexpr uint32_t const deferred_shading_vertex_shader_module_code[] = { +#include <_internal_deferred_shading_vertex.inl> +}; \ No newline at end of file diff --git a/spirv/full_screen_transfer_fragment.inl b/spirv/full_screen_transfer_fragment.inl new file mode 100644 index 0000000..3a023d3 --- /dev/null +++ b/spirv/full_screen_transfer_fragment.inl @@ -0,0 +1,3 @@ +constexpr uint32_t const full_screen_transfer_fragment_shader_module_code[] = { +#include <_internal_full_screen_transfer_fragment.inl> +}; diff --git a/spirv/full_screen_transfer_vertex.inl b/spirv/full_screen_transfer_vertex.inl new file mode 100644 index 0000000..1df7edb --- /dev/null +++ b/spirv/full_screen_transfer_vertex.inl @@ -0,0 +1,3 @@ +constexpr uint32_t const full_screen_transfer_vertex_shader_module_code[] = { +#include <_internal_full_screen_transfer_vertex.inl> +}; diff --git a/spirv/gbuffer_fragment.inl b/spirv/gbuffer_fragment.inl new file mode 100644 index 0000000..a65f9fb --- /dev/null +++ b/spirv/gbuffer_fragment.inl @@ -0,0 +1,3 @@ +constexpr uint32_t const gbuffer_fragment_shader_module_code[] = { +#include <_internal_gbuffer_fragment.inl> +}; \ No newline at end of file diff --git a/spirv/gbuffer_vertex.inl b/spirv/gbuffer_vertex.inl new file mode 100644 index 0000000..59dce69 --- /dev/null +++ b/spirv/gbuffer_vertex.inl @@ -0,0 +1,3 @@ +constexpr uint32_t const gbuffer_vertex_shader_module_code[] = { +#include <_internal_gbuffer_vertex.inl> +}; \ No newline at end of file diff --git a/thirdparty/Brioche b/thirdparty/Brioche new file mode 160000 index 0000000..fcbf7da --- /dev/null +++ b/thirdparty/Brioche @@ -0,0 +1 @@ +Subproject commit fcbf7dae47bedbbe6c8bb5595bec3d96db7e4854 diff --git a/thirdparty/ConvertUTF b/thirdparty/ConvertUTF new file mode 160000 index 0000000..5b93321 --- /dev/null +++ b/thirdparty/ConvertUTF @@ -0,0 +1 @@ +Subproject commit 5b93321790018086ff99eb9d51acc0d0a95215eb diff --git a/thirdparty/CoreRT b/thirdparty/CoreRT new file mode 160000 index 0000000..a4d26a9 --- /dev/null +++ b/thirdparty/CoreRT @@ -0,0 +1 @@ +Subproject commit a4d26a90cba87a966769e154fcb01464800bd9ad diff --git a/thirdparty/DirectXMath b/thirdparty/DirectXMath new file mode 160000 index 0000000..0ab21b3 --- /dev/null +++ b/thirdparty/DirectXMath @@ -0,0 +1 @@ +Subproject commit 0ab21b3808cba7c009d7a086b000469ba0e83f73 diff --git a/thirdparty/ImportAsset b/thirdparty/ImportAsset new file mode 160000 index 0000000..3ce903f --- /dev/null +++ b/thirdparty/ImportAsset @@ -0,0 +1 @@ +Subproject commit 3ce903f925464ce3cb99efdea6e8b930259be669 diff --git a/thirdparty/cgltf b/thirdparty/cgltf new file mode 160000 index 0000000..da2dc36 --- /dev/null +++ b/thirdparty/cgltf @@ -0,0 +1 @@ +Subproject commit da2dc3687beed033d1576c9675434bce247a0457