From e68b8f9586ec15df6a2e812b4e145fb32b970123 Mon Sep 17 00:00:00 2001 From: Yizhou Jiang Date: Fri, 2 Aug 2019 15:53:53 +0800 Subject: [PATCH 1/2] Update shaderc to latest commit Extra semicolon warning error is fixed in latest shaderc, and it's a third party of dawn. So we have to move shaderc to upper folder, and maintain shaderc by Aquarium. This patch also add .gitattributes file to specify format of files because the ending of line should be specified to LF, otherwise it will become CRLF on Windows. --- .gitattributes | 44 + .gn | 1 - BUILD.gn | 488 ++-- DEPS | 285 +-- build_overrides/dawn.gni | 24 +- src/aquarium-direct-map/AttribBuffer.cpp | 64 +- src/aquarium-direct-map/AttribBuffer.h | 81 +- src/aquarium-direct-map/Buffer.cpp | 116 +- src/aquarium-direct-map/Buffer.h | 86 +- src/aquarium-direct-map/Globals.h | 460 ++-- src/aquarium-direct-map/Main.cpp | 1371 +++++------ src/aquarium-direct-map/Matrix.h | 829 +++---- src/aquarium-direct-map/Model.cpp | 321 ++- src/aquarium-direct-map/Model.h | 105 +- src/aquarium-direct-map/Program.cpp | 553 +++-- src/aquarium-direct-map/Program.h | 100 +- src/aquarium-direct-map/Scene.cpp | 444 ++-- src/aquarium-direct-map/Scene.h | 83 +- src/aquarium-direct-map/Texture.cpp | 251 +- src/aquarium-direct-map/Texture.h | 90 +- src/aquarium-direct-map/Uniform.cpp | 26 +- src/aquarium-direct-map/Uniform.h | 68 +- src/aquarium-optimized/Aquarium.cpp | 1584 ++++++------- src/aquarium-optimized/Aquarium.h | 946 ++++---- src/aquarium-optimized/Buffer.h | 46 +- src/aquarium-optimized/Context.h | 170 +- src/aquarium-optimized/ContextFactory.cpp | 112 +- src/aquarium-optimized/ContextFactory.h | 50 +- src/aquarium-optimized/FishModel.h | 60 +- src/aquarium-optimized/Main.cpp | 41 +- src/aquarium-optimized/Matrix.h | 767 +++--- src/aquarium-optimized/Model.cpp | 63 +- src/aquarium-optimized/Model.h | 107 +- src/aquarium-optimized/Program.h | 63 +- src/aquarium-optimized/ResourceHelper.cpp | 176 +- src/aquarium-optimized/ResourceHelper.h | 60 +- src/aquarium-optimized/SeaweedModel.h | 44 +- src/aquarium-optimized/Texture.cpp | 262 +-- src/aquarium-optimized/Texture.h | 110 +- src/aquarium-optimized/d3d12/BufferD3D12.cpp | 80 +- src/aquarium-optimized/d3d12/BufferD3D12.h | 118 +- src/aquarium-optimized/d3d12/ContextD3D12.cpp | 2092 ++++++++--------- src/aquarium-optimized/d3d12/ContextD3D12.h | 350 +-- .../d3d12/FishModelD3D12.cpp | 402 ++-- src/aquarium-optimized/d3d12/FishModelD3D12.h | 220 +- .../d3d12/FishModelInstancedDrawD3D12.cpp | 410 ++-- .../d3d12/FishModelInstancedDrawD3D12.h | 212 +- .../d3d12/GenericModelD3D12.cpp | 389 +-- .../d3d12/GenericModelD3D12.h | 166 +- .../d3d12/InnerModelD3D12.cpp | 272 +-- .../d3d12/InnerModelD3D12.h | 152 +- .../d3d12/OutsideModelD3D12.cpp | 256 +- .../d3d12/OutsideModelD3D12.h | 150 +- src/aquarium-optimized/d3d12/ProgramD3D12.cpp | 68 +- src/aquarium-optimized/d3d12/ProgramD3D12.h | 87 +- .../d3d12/SeaweedModelD3D12.cpp | 302 +-- .../d3d12/SeaweedModelD3D12.h | 182 +- src/aquarium-optimized/d3d12/TextureD3D12.cpp | 192 +- src/aquarium-optimized/d3d12/TextureD3D12.h | 100 +- .../d3d12/imgui_impl_dx12.cpp | 1462 ++++++------ .../d3d12/imgui_impl_dx12.h | 88 +- src/aquarium-optimized/dawn/BufferDawn.cpp | 121 +- src/aquarium-optimized/dawn/BufferDawn.h | 103 +- src/aquarium-optimized/dawn/ContextDawn.cpp | 1422 +++++------ src/aquarium-optimized/dawn/ContextDawn.h | 289 +-- src/aquarium-optimized/dawn/FishModelDawn.cpp | 568 ++--- src/aquarium-optimized/dawn/FishModelDawn.h | 208 +- .../dawn/FishModelInstancedDrawDawn.cpp | 476 ++-- .../dawn/FishModelInstancedDrawDawn.h | 200 +- .../dawn/GenericModelDawn.cpp | 484 ++-- .../dawn/GenericModelDawn.h | 158 +- .../dawn/InnerModelDawn.cpp | 320 ++- src/aquarium-optimized/dawn/InnerModelDawn.h | 146 +- .../dawn/OutsideModelDawn.cpp | 314 ++- .../dawn/OutsideModelDawn.h | 142 +- src/aquarium-optimized/dawn/ProgramDawn.cpp | 92 +- src/aquarium-optimized/dawn/ProgramDawn.h | 87 +- .../dawn/SeaweedModelDawn.cpp | 303 +-- .../dawn/SeaweedModelDawn.h | 166 +- src/aquarium-optimized/dawn/TextureDawn.cpp | 384 +-- src/aquarium-optimized/dawn/TextureDawn.h | 92 +- .../dawn/imgui_impl_dawn.cpp | 770 +++--- src/aquarium-optimized/dawn/imgui_impl_dawn.h | 42 +- src/aquarium-optimized/opengl/BufferGL.cpp | 92 +- src/aquarium-optimized/opengl/BufferGL.h | 136 +- src/aquarium-optimized/opengl/ContextGL.cpp | 1538 ++++++------ src/aquarium-optimized/opengl/ContextGL.h | 232 +- src/aquarium-optimized/opengl/FishModelGL.cpp | 362 +-- src/aquarium-optimized/opengl/FishModelGL.h | 165 +- .../opengl/GenericModelGL.cpp | 272 +-- .../opengl/GenericModelGL.h | 128 +- .../opengl/InnerModelGL.cpp | 264 +-- src/aquarium-optimized/opengl/InnerModelGL.h | 126 +- .../opengl/OutsideModelGL.cpp | 232 +- .../opengl/OutsideModelGL.h | 120 +- src/aquarium-optimized/opengl/ProgramGL.cpp | 199 +- src/aquarium-optimized/opengl/ProgramGL.h | 89 +- .../opengl/SeaweedModelGL.cpp | 238 +- .../opengl/SeaweedModelGL.h | 126 +- src/aquarium-optimized/opengl/TextureGL.cpp | 142 +- src/aquarium-optimized/opengl/TextureGL.h | 109 +- .../opengl/imgui_impl_opengl3.cpp | 1464 ++++++------ .../opengl/imgui_impl_opengl3.h | 100 +- src/common/AQUARIUM_ASSERT.h | 76 +- src/common/FPSTimer.cpp | 89 +- src/common/FPSTimer.h | 76 +- 106 files changed, 15838 insertions(+), 15725 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d7b7979 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,44 @@ +# +# Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# + +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto +* text eol=lf + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + diff --git a/.gn b/.gn index 7ce62e5..2e6268c 100644 --- a/.gn +++ b/.gn @@ -8,7 +8,6 @@ buildconfig = "//build/config/BUILDCONFIG.gn" default_args = { clang_use_chrome_plugins = false - treat_warnings_as_errors = false } check_targets = [ diff --git a/BUILD.gn b/BUILD.gn index be2dad1..884a859 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1,245 +1,245 @@ -# -# Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# - -declare_args() { - enable_dawn = is_win || is_linux || is_mac - enable_angle = false - enable_d3d12 = is_win - enable_opengl = is_win || is_linux || is_mac -} - -executable("aquarium") { - libs = [] - - sources = [ - "src/common/AQUARIUM_ASSERT.h", - "src/common/FPSTimer.cpp", - "src/common/FPSTimer.h", - "src/aquarium-optimized/Aquarium.cpp", - "src/aquarium-optimized/Aquarium.h", - "src/aquarium-optimized/Buffer.h", - "src/aquarium-optimized/Context.h", - "src/aquarium-optimized/ContextFactory.cpp", - "src/aquarium-optimized/ContextFactory.h", - "src/aquarium-optimized/FishModel.h", - "src/aquarium-optimized/Main.cpp", - "src/aquarium-optimized/Matrix.h", - "src/aquarium-optimized/Model.cpp", - "src/aquarium-optimized/Model.h", - "src/aquarium-optimized/Program.h", - "src/aquarium-optimized/ResourceHelper.h", - "src/aquarium-optimized/ResourceHelper.cpp", - "src/aquarium-optimized/SeaweedModel.h", - "src/aquarium-optimized/Texture.cpp", - "src/aquarium-optimized/Texture.h", - ] - - deps = [ - "third_party:stb", - "third_party:imgui", - ] - - include_dirs = [ - "third_party/rapidjson/include", - "third_party/stb", - "src", - "third_party/imgui", - "third_party/imgui/examples", - ] - - if(enable_angle || enable_opengl) { - sources += [ - "src/aquarium-optimized/opengl/BufferGL.cpp", - "src/aquarium-optimized/opengl/BufferGL.h", - "src/aquarium-optimized/opengl/ContextGL.cpp", - "src/aquarium-optimized/opengl/ContextGL.h", - "src/aquarium-optimized/opengl/FishModelGL.cpp", - "src/aquarium-optimized/opengl/FishModelGL.h", - "src/aquarium-optimized/opengl/GenericModelGL.cpp", - "src/aquarium-optimized/opengl/GenericModelGL.h", - "src/aquarium-optimized/opengl/InnerModelGL.cpp", - "src/aquarium-optimized/opengl/InnerModelGL.h", - "src/aquarium-optimized/opengl/OutsideModelGL.cpp", - "src/aquarium-optimized/opengl/OutsideModelGL.h", - "src/aquarium-optimized/opengl/ProgramGL.cpp", - "src/aquarium-optimized/opengl/ProgramGL.h", - "src/aquarium-optimized/opengl/SeaweedModelGL.cpp", - "src/aquarium-optimized/opengl/SeaweedModelGL.h", - "src/aquarium-optimized/opengl/TextureGL.cpp", - "src/aquarium-optimized/opengl/TextureGL.h", - "src/aquarium-optimized/opengl/imgui_impl_opengl3.h", - "src/aquarium-optimized/opengl/imgui_impl_opengl3.cpp", - ] - } - - defines = [] - - if (enable_angle) { - enable_dawn = false - enable_d3d12 = false - - defines += [ "EGL_EGL_PROTOTYPES", - "IMGUI_IMPL_OPENGL_LOADER_CUSTOM", - "IMGUI_IMPL_OPENGL_ES3", ] - - include_dirs += [ - "third_party/angle/include", - "third_party/angle/util", - ] - - deps += [ - "third_party/angle:libANGLE", - "third_party/angle:libGLESv2", - "third_party/angle:libEGL", - "third_party/angle:angle_util_static", - ] - } else { - deps += [ "third_party:glad" ] - - include_dirs += [ "third_party/glad/include" ] - defines += [ "IMGUI_IMPL_OPENGL_LOADER_GLAD", ] - } - - if (enable_dawn) { - defines += [ "ENABLE_DAWN_BACKEND" ] - - include_dirs += [ "third_party/dawn/src" ] - - sources += [ - "src/aquarium-optimized/dawn/BufferDawn.cpp", - "src/aquarium-optimized/dawn/BufferDawn.h", - "src/aquarium-optimized/dawn/ContextDawn.cpp", - "src/aquarium-optimized/dawn/ContextDawn.h", - "src/aquarium-optimized/dawn/FishModelDawn.cpp", - "src/aquarium-optimized/dawn/FishModelDawn.h", - "src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.cpp", - "src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.h", - "src/aquarium-optimized/dawn/GenericModelDawn.cpp", - "src/aquarium-optimized/dawn/GenericModelDawn.h", - "src/aquarium-optimized/dawn/InnerModelDawn.cpp", - "src/aquarium-optimized/dawn/InnerModelDawn.h", - "src/aquarium-optimized/dawn/OutsideModelDawn.cpp", - "src/aquarium-optimized/dawn/OutsideModelDawn.h", - "src/aquarium-optimized/dawn/ProgramDawn.cpp", - "src/aquarium-optimized/dawn/ProgramDawn.h", - "src/aquarium-optimized/dawn/SeaweedModelDawn.cpp", - "src/aquarium-optimized/dawn/SeaweedModelDawn.h", - "src/aquarium-optimized/dawn/TextureDawn.cpp", - "src/aquarium-optimized/dawn/TextureDawn.h", - "src/aquarium-optimized/dawn/imgui_impl_dawn.cpp", - "src/aquarium-optimized/dawn/imgui_impl_dawn.h", - ] - - deps += [ - "third_party/dawn/src/dawn:dawn_headers", - "third_party/dawn:dawn_utils", - "third_party/dawn/src/dawn:libdawn", - "third_party/dawn:libdawn_native", - "third_party/dawn/third_party/shaderc:libshaderc", - ] - - include_dirs += [ - "third_party/dawn/third_party/glfw/include", - "third_party/dawn/third_party/shaderc/libshaderc/include", - ] - } else { - deps += [ "third_party:glfw" ] - - include_dirs += [ - "third_party/glfw/include", - ] - } - - if (enable_d3d12) { - defines += [ "ENABLE_D3D12_BACKEND" ] - - include_dirs += [ - "src/include/d3d12", - ] - - libs += [ - "d3d12.lib", - "dxgi.lib", - "d3dcompiler.lib", - ] - - sources += [ - "src/aquarium-optimized/d3d12/BufferD3D12.cpp", - "src/aquarium-optimized/d3d12/BufferD3D12.h", - "src/aquarium-optimized/d3d12/ContextD3D12.cpp", - "src/aquarium-optimized/d3d12/ContextD3D12.h", - "src/aquarium-optimized/d3d12/FishModelD3D12.cpp", - "src/aquarium-optimized/d3d12/FishModelD3D12.h", - "src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.cpp", - "src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.h", - "src/aquarium-optimized/d3d12/GenericModelD3D12.cpp", - "src/aquarium-optimized/d3d12/GenericModelD3D12.h", - "src/aquarium-optimized/d3d12/InnerModelD3D12.cpp", - "src/aquarium-optimized/d3d12/InnerModelD3D12.h", - "src/aquarium-optimized/d3d12/OutsideModelD3D12.cpp", - "src/aquarium-optimized/d3d12/OutsideModelD3D12.h", - "src/aquarium-optimized/d3d12/ProgramD3D12.cpp", - "src/aquarium-optimized/d3d12/ProgramD3D12.h", - "src/aquarium-optimized/d3d12/SeaweedModelD3D12.cpp", - "src/aquarium-optimized/d3d12/SeaweedModelD3D12.h", - "src/aquarium-optimized/d3d12/TextureD3D12.cpp", - "src/aquarium-optimized/d3d12/TextureD3D12.h", - "src/aquarium-optimized/d3d12/imgui_impl_dx12.h", - "src/aquarium-optimized/d3d12/imgui_impl_dx12.cpp", - ] - } - - cflags_cc = [ - "-Wno-string-conversion", - "-Wno-unused-result", - "-Wno-format-security", - "-Wno-microsoft-enum-forward-reference", - ] -} - -executable("aquarium-direct-map") { - sources = [ - "src/common/AQUARIUM_ASSERT.h", - "src/common/FPSTimer.h", - "src/common/FPSTimer.cpp", - "src/aquarium-direct-map/AttribBuffer.h", - "src/aquarium-direct-map/AttribBuffer.cpp", - "src/aquarium-direct-map/Buffer.h", - "src/aquarium-direct-map/Buffer.cpp", - "src/aquarium-direct-map/Globals.h", - "src/aquarium-direct-map/Main.cpp", - "src/aquarium-direct-map/Matrix.h", - "src/aquarium-direct-map/Model.h", - "src/aquarium-direct-map/Model.cpp", - "src/aquarium-direct-map/Program.h", - "src/aquarium-direct-map/Program.cpp", - "src/aquarium-direct-map/Scene.h", - "src/aquarium-direct-map/Scene.cpp", - "src/aquarium-direct-map/Texture.h", - "src/aquarium-direct-map/Texture.cpp", - "src/aquarium-direct-map/Uniform.h", - "src/aquarium-direct-map/Uniform.cpp", - ] - - deps = [ - "third_party:stb", - "third_party:glad", - "third_party:glfw", - ] - - include_dirs = [ - "third_party/glad/include", - "third_party/rapidjson/include", - "third_party/stb", - "third_party/glfw/include", - "src", - ] - - cflags_cc = [ - "-Wno-string-conversion", - "-Wno-unused-result", - ] +# +# Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# + +declare_args() { + enable_dawn = is_win || is_linux || is_mac + enable_angle = false + enable_d3d12 = is_win + enable_opengl = is_win || is_linux || is_mac +} + +executable("aquarium") { + libs = [] + + sources = [ + "src/common/AQUARIUM_ASSERT.h", + "src/common/FPSTimer.cpp", + "src/common/FPSTimer.h", + "src/aquarium-optimized/Aquarium.cpp", + "src/aquarium-optimized/Aquarium.h", + "src/aquarium-optimized/Buffer.h", + "src/aquarium-optimized/Context.h", + "src/aquarium-optimized/ContextFactory.cpp", + "src/aquarium-optimized/ContextFactory.h", + "src/aquarium-optimized/FishModel.h", + "src/aquarium-optimized/Main.cpp", + "src/aquarium-optimized/Matrix.h", + "src/aquarium-optimized/Model.cpp", + "src/aquarium-optimized/Model.h", + "src/aquarium-optimized/Program.h", + "src/aquarium-optimized/ResourceHelper.h", + "src/aquarium-optimized/ResourceHelper.cpp", + "src/aquarium-optimized/SeaweedModel.h", + "src/aquarium-optimized/Texture.cpp", + "src/aquarium-optimized/Texture.h", + ] + + deps = [ + "third_party:stb", + "third_party:imgui", + ] + + include_dirs = [ + "third_party/rapidjson/include", + "third_party/stb", + "src", + "third_party/imgui", + "third_party/imgui/examples", + ] + + if(enable_angle || enable_opengl) { + sources += [ + "src/aquarium-optimized/opengl/BufferGL.cpp", + "src/aquarium-optimized/opengl/BufferGL.h", + "src/aquarium-optimized/opengl/ContextGL.cpp", + "src/aquarium-optimized/opengl/ContextGL.h", + "src/aquarium-optimized/opengl/FishModelGL.cpp", + "src/aquarium-optimized/opengl/FishModelGL.h", + "src/aquarium-optimized/opengl/GenericModelGL.cpp", + "src/aquarium-optimized/opengl/GenericModelGL.h", + "src/aquarium-optimized/opengl/InnerModelGL.cpp", + "src/aquarium-optimized/opengl/InnerModelGL.h", + "src/aquarium-optimized/opengl/OutsideModelGL.cpp", + "src/aquarium-optimized/opengl/OutsideModelGL.h", + "src/aquarium-optimized/opengl/ProgramGL.cpp", + "src/aquarium-optimized/opengl/ProgramGL.h", + "src/aquarium-optimized/opengl/SeaweedModelGL.cpp", + "src/aquarium-optimized/opengl/SeaweedModelGL.h", + "src/aquarium-optimized/opengl/TextureGL.cpp", + "src/aquarium-optimized/opengl/TextureGL.h", + "src/aquarium-optimized/opengl/imgui_impl_opengl3.h", + "src/aquarium-optimized/opengl/imgui_impl_opengl3.cpp", + ] + } + + defines = [] + + if (enable_angle) { + enable_dawn = false + enable_d3d12 = false + + defines += [ "EGL_EGL_PROTOTYPES", + "IMGUI_IMPL_OPENGL_LOADER_CUSTOM", + "IMGUI_IMPL_OPENGL_ES3", ] + + include_dirs += [ + "third_party/angle/include", + "third_party/angle/util", + ] + + deps += [ + "third_party/angle:libANGLE", + "third_party/angle:libGLESv2", + "third_party/angle:libEGL", + "third_party/angle:angle_util_static", + ] + } else { + deps += [ "third_party:glad" ] + + include_dirs += [ "third_party/glad/include" ] + defines += [ "IMGUI_IMPL_OPENGL_LOADER_GLAD", ] + } + + if (enable_dawn) { + defines += [ "ENABLE_DAWN_BACKEND" ] + + include_dirs += [ "third_party/dawn/src" ] + + sources += [ + "src/aquarium-optimized/dawn/BufferDawn.cpp", + "src/aquarium-optimized/dawn/BufferDawn.h", + "src/aquarium-optimized/dawn/ContextDawn.cpp", + "src/aquarium-optimized/dawn/ContextDawn.h", + "src/aquarium-optimized/dawn/FishModelDawn.cpp", + "src/aquarium-optimized/dawn/FishModelDawn.h", + "src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.cpp", + "src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.h", + "src/aquarium-optimized/dawn/GenericModelDawn.cpp", + "src/aquarium-optimized/dawn/GenericModelDawn.h", + "src/aquarium-optimized/dawn/InnerModelDawn.cpp", + "src/aquarium-optimized/dawn/InnerModelDawn.h", + "src/aquarium-optimized/dawn/OutsideModelDawn.cpp", + "src/aquarium-optimized/dawn/OutsideModelDawn.h", + "src/aquarium-optimized/dawn/ProgramDawn.cpp", + "src/aquarium-optimized/dawn/ProgramDawn.h", + "src/aquarium-optimized/dawn/SeaweedModelDawn.cpp", + "src/aquarium-optimized/dawn/SeaweedModelDawn.h", + "src/aquarium-optimized/dawn/TextureDawn.cpp", + "src/aquarium-optimized/dawn/TextureDawn.h", + "src/aquarium-optimized/dawn/imgui_impl_dawn.cpp", + "src/aquarium-optimized/dawn/imgui_impl_dawn.h", + ] + + deps += [ + "third_party/dawn/src/dawn:dawn_headers", + "third_party/dawn:dawn_utils", + "third_party/dawn/src/dawn:libdawn", + "third_party/dawn:libdawn_native", + "third_party/shaderc:libshaderc", + ] + + include_dirs += [ + "third_party/dawn/third_party/glfw/include", + "third_party/shaderc/libshaderc/include", + ] + } else { + deps += [ "third_party:glfw" ] + + include_dirs += [ + "third_party/glfw/include", + ] + } + + if (enable_d3d12) { + defines += [ "ENABLE_D3D12_BACKEND" ] + + include_dirs += [ + "src/include/d3d12", + ] + + libs += [ + "d3d12.lib", + "dxgi.lib", + "d3dcompiler.lib", + ] + + sources += [ + "src/aquarium-optimized/d3d12/BufferD3D12.cpp", + "src/aquarium-optimized/d3d12/BufferD3D12.h", + "src/aquarium-optimized/d3d12/ContextD3D12.cpp", + "src/aquarium-optimized/d3d12/ContextD3D12.h", + "src/aquarium-optimized/d3d12/FishModelD3D12.cpp", + "src/aquarium-optimized/d3d12/FishModelD3D12.h", + "src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.cpp", + "src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.h", + "src/aquarium-optimized/d3d12/GenericModelD3D12.cpp", + "src/aquarium-optimized/d3d12/GenericModelD3D12.h", + "src/aquarium-optimized/d3d12/InnerModelD3D12.cpp", + "src/aquarium-optimized/d3d12/InnerModelD3D12.h", + "src/aquarium-optimized/d3d12/OutsideModelD3D12.cpp", + "src/aquarium-optimized/d3d12/OutsideModelD3D12.h", + "src/aquarium-optimized/d3d12/ProgramD3D12.cpp", + "src/aquarium-optimized/d3d12/ProgramD3D12.h", + "src/aquarium-optimized/d3d12/SeaweedModelD3D12.cpp", + "src/aquarium-optimized/d3d12/SeaweedModelD3D12.h", + "src/aquarium-optimized/d3d12/TextureD3D12.cpp", + "src/aquarium-optimized/d3d12/TextureD3D12.h", + "src/aquarium-optimized/d3d12/imgui_impl_dx12.h", + "src/aquarium-optimized/d3d12/imgui_impl_dx12.cpp", + ] + } + + cflags_cc = [ + "-Wno-string-conversion", + "-Wno-unused-result", + "-Wno-format-security", + "-Wno-microsoft-enum-forward-reference", + ] +} + +executable("aquarium-direct-map") { + sources = [ + "src/common/AQUARIUM_ASSERT.h", + "src/common/FPSTimer.h", + "src/common/FPSTimer.cpp", + "src/aquarium-direct-map/AttribBuffer.h", + "src/aquarium-direct-map/AttribBuffer.cpp", + "src/aquarium-direct-map/Buffer.h", + "src/aquarium-direct-map/Buffer.cpp", + "src/aquarium-direct-map/Globals.h", + "src/aquarium-direct-map/Main.cpp", + "src/aquarium-direct-map/Matrix.h", + "src/aquarium-direct-map/Model.h", + "src/aquarium-direct-map/Model.cpp", + "src/aquarium-direct-map/Program.h", + "src/aquarium-direct-map/Program.cpp", + "src/aquarium-direct-map/Scene.h", + "src/aquarium-direct-map/Scene.cpp", + "src/aquarium-direct-map/Texture.h", + "src/aquarium-direct-map/Texture.cpp", + "src/aquarium-direct-map/Uniform.h", + "src/aquarium-direct-map/Uniform.cpp", + ] + + deps = [ + "third_party:stb", + "third_party:glad", + "third_party:glfw", + ] + + include_dirs = [ + "third_party/glad/include", + "third_party/rapidjson/include", + "third_party/stb", + "third_party/glfw/include", + "src", + ] + + cflags_cc = [ + "-Wno-string-conversion", + "-Wno-unused-result", + ] } \ No newline at end of file diff --git a/DEPS b/DEPS index 0f8c55a..7834e14 100644 --- a/DEPS +++ b/DEPS @@ -1,140 +1,145 @@ -# -# Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# - -vars = { - 'chromium_git': 'https://chromium.googlesource.com', - 'github_git': 'https://github.com', - 'dawn_git': 'https://dawn.googlesource.com', - 'dawn_revision': '9d2ccaf65c2a370c5f203e119e194a44fa039481', - 'imgui_git': 'https://github.com/ocornut', - 'imgui_revision': 'e16564e67a2e88d4cbe3afa6594650712790fba3', - 'angle_root': 'third_party/angle', - 'angle_revision': '6c824a1bc17b286b86cf05a0228ec549875351eb', - 'glslang_revision': '11805e41d992a9950a9f7f84c505bb7305fbd09f', - 'build_revision': '54ea0e7fd122348de2f73ac21d1b6eafb9b78969', - 'buildtools_revision': 'd5c58b84d50d256968271db459cd29b22bff1ba2', - 'tools_clang_revision': '210f1dc3ebf8504ae246d925e9110ec427eef43f', - 'spirv_tools_revision': '2090d7a2d26cb9bb0b8738f36a156ed3084a7ab0', - 'spirv_headers_revision': 'de99d4d834aeb51dd9f099baa285bd44fd04bb3d', -} - -deps = { - # Dependencies required to use GN/Clang in standalone - # This revision should be the same as the one in third_party/angle/DEPS - 'build': { - 'url': '{chromium_git}/chromium/src/build@{build_revision}', - }, - # This revision should be the same as the one in third_party/angle/DEPS - 'buildtools': { - 'url': '{chromium_git}/chromium/src/buildtools@{buildtools_revision}', - }, - # This revision should be the same as the one in third_party/angle/DEPS - 'tools/clang': { - 'url': '{chromium_git}/chromium/src/tools/clang@{tools_clang_revision}', - }, - # This revision should be the same as the one in third_party/angle/DEPS - 'testing': { - 'url': '{chromium_git}/chromium/src/testing@083d633e752e7a57cbe62a468a06e51e28c49ee9', - }, - # This revision should be the same as the one in third_party/angle/DEPS - 'third_party/glslang': { - 'url': '{chromium_git}/external/github.com/KhronosGroup/glslang@{glslang_revision}', - }, - - 'third_party/googletest': { - 'url': '{chromium_git}/external/github.com/google/googletest@5ec7f0c4a113e2f18ac2c6cc7df51ad6afc24081', - }, - 'third_party/stb': { - 'url': '{github_git}/nothings/stb.git@c7110588a4d24c4bb5155c184fbb77dd90b3116e', - }, - 'third_party/glfw': { - 'url': '{chromium_git}/external/github.com/glfw/glfw@2de2589f910b1a85905f425be4d32f33cec092df', - 'condition': 'dawn_standalone', - }, - 'third_party/rapidjson': { - 'url': '{github_git}/Tencent/rapidjson.git', - }, - 'third_party/dawn': { - 'url': '{dawn_git}/dawn.git@{dawn_revision}', - }, - 'third_party/angle': { - 'url': '{chromium_git}/angle/angle.git@{angle_revision}', - }, - 'third_party/spirv-tools': { - 'url': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Tools@{spirv_tools_revision}', - }, - 'third_party/spirv-headers': { - 'url': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Headers@{spirv_headers_revision}', - }, - 'third_party/imgui': { - 'url': '{imgui_git}/imgui.git@{imgui_revision}', - }, -} - -hooks = [ - # Pull the compilers and system libraries for hermetic builds - { - 'name': 'sysroot_x86', - 'pattern': '.', - 'condition': 'checkout_linux and ((checkout_x86 or checkout_x64))', - 'action': ['python', 'build/linux/sysroot_scripts/install-sysroot.py', - '--arch=x86'], - }, - { - 'name': 'sysroot_x64', - 'pattern': '.', - 'condition': 'checkout_linux and (checkout_x64)', - 'action': ['python', 'build/linux/sysroot_scripts/install-sysroot.py', - '--arch=x64'], - }, - { - # Update the Windows toolchain if necessary. Must run before 'clang' below. - 'name': 'win_toolchain', - 'pattern': '.', - 'condition': 'checkout_win', - 'action': ['python', 'build/vs_toolchain.py', 'update', '--force'], - }, - { - # Update the Mac toolchain if necessary. - 'name': 'mac_toolchain', - 'pattern': '.', - 'condition': 'checkout_mac', - 'action': ['python', '{angle_root}/build/mac_toolchain.py'], - }, - { - # Note: On Win, this should run after win_toolchain, as it may use it. - 'name': 'clang', - 'pattern': '.', - 'action': ['python', 'tools/clang/scripts/update.py'], - 'condition': 'dawn_standalone', - }, - { - # Pull rc binaries using checked-in hashes. - 'name': 'rc_win', - 'pattern': '.', - 'condition': 'checkout_win and (host_os == "win")', - 'action': [ 'download_from_google_storage', - '--no_resume', - '--no_auth', - '--bucket', 'chromium-browser-clang/rc', - '-s', 'build/toolchain/win/rc/win/rc.exe.sha1', - ], - }, - # Update build/util/LASTCHANGE. - { - 'name': 'lastchange', - 'pattern': '.', - 'action': ['python', 'build/util/lastchange.py', - '-o', 'build/util/LASTCHANGE'], - }, -] - -recursedeps = [ - # buildtools provides clang_format, libc++, and libc++abi - 'buildtools', - 'third_party/dawn', - 'third_party/angle', -] +# +# Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# + +vars = { + 'chromium_git': 'https://chromium.googlesource.com', + 'github_git': 'https://github.com', + 'dawn_git': 'https://dawn.googlesource.com', + 'dawn_revision': '9d2ccaf65c2a370c5f203e119e194a44fa039481', + 'imgui_git': 'https://github.com/ocornut', + 'imgui_revision': 'e16564e67a2e88d4cbe3afa6594650712790fba3', + 'angle_root': 'third_party/angle', + 'angle_revision': '6c824a1bc17b286b86cf05a0228ec549875351eb', + 'glslang_revision': '11805e41d992a9950a9f7f84c505bb7305fbd09f', + 'build_revision': '54ea0e7fd122348de2f73ac21d1b6eafb9b78969', + 'buildtools_revision': 'd5c58b84d50d256968271db459cd29b22bff1ba2', + 'tools_clang_revision': '210f1dc3ebf8504ae246d925e9110ec427eef43f', + 'spirv_tools_revision': '2090d7a2d26cb9bb0b8738f36a156ed3084a7ab0', + 'spirv_headers_revision': 'de99d4d834aeb51dd9f099baa285bd44fd04bb3d', + 'shaderc_git': 'https://github.com/google', + 'shaderc_revision': 'd289a55e46ff1c931ca0d90785218370f5ce68e0', +} + +deps = { + # Dependencies required to use GN/Clang in standalone + # This revision should be the same as the one in third_party/angle/DEPS + 'build': { + 'url': '{chromium_git}/chromium/src/build@{build_revision}', + }, + # This revision should be the same as the one in third_party/angle/DEPS + 'buildtools': { + 'url': '{chromium_git}/chromium/src/buildtools@{buildtools_revision}', + }, + # This revision should be the same as the one in third_party/angle/DEPS + 'tools/clang': { + 'url': '{chromium_git}/chromium/src/tools/clang@{tools_clang_revision}', + }, + # This revision should be the same as the one in third_party/angle/DEPS + 'testing': { + 'url': '{chromium_git}/chromium/src/testing@083d633e752e7a57cbe62a468a06e51e28c49ee9', + }, + # This revision should be the same as the one in third_party/angle/DEPS + 'third_party/glslang': { + 'url': '{chromium_git}/external/github.com/KhronosGroup/glslang@{glslang_revision}', + }, + + 'third_party/googletest': { + 'url': '{chromium_git}/external/github.com/google/googletest@5ec7f0c4a113e2f18ac2c6cc7df51ad6afc24081', + }, + 'third_party/stb': { + 'url': '{github_git}/nothings/stb.git@c7110588a4d24c4bb5155c184fbb77dd90b3116e', + }, + 'third_party/glfw': { + 'url': '{chromium_git}/external/github.com/glfw/glfw@2de2589f910b1a85905f425be4d32f33cec092df', + 'condition': 'dawn_standalone', + }, + 'third_party/rapidjson': { + 'url': '{github_git}/Tencent/rapidjson.git', + }, + 'third_party/dawn': { + 'url': '{dawn_git}/dawn.git@{dawn_revision}', + }, + 'third_party/angle': { + 'url': '{chromium_git}/angle/angle.git@{angle_revision}', + }, + 'third_party/spirv-tools': { + 'url': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Tools@{spirv_tools_revision}', + }, + 'third_party/spirv-headers': { + 'url': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Headers@{spirv_headers_revision}', + }, + 'third_party/imgui': { + 'url': '{imgui_git}/imgui.git@{imgui_revision}', + }, + 'third_party/shaderc': { + 'url': '{shaderc_git}/shaderc.git@{shaderc_revision}', + }, +} + +hooks = [ + # Pull the compilers and system libraries for hermetic builds + { + 'name': 'sysroot_x86', + 'pattern': '.', + 'condition': 'checkout_linux and ((checkout_x86 or checkout_x64))', + 'action': ['python', 'build/linux/sysroot_scripts/install-sysroot.py', + '--arch=x86'], + }, + { + 'name': 'sysroot_x64', + 'pattern': '.', + 'condition': 'checkout_linux and (checkout_x64)', + 'action': ['python', 'build/linux/sysroot_scripts/install-sysroot.py', + '--arch=x64'], + }, + { + # Update the Windows toolchain if necessary. Must run before 'clang' below. + 'name': 'win_toolchain', + 'pattern': '.', + 'condition': 'checkout_win', + 'action': ['python', 'build/vs_toolchain.py', 'update', '--force'], + }, + { + # Update the Mac toolchain if necessary. + 'name': 'mac_toolchain', + 'pattern': '.', + 'condition': 'checkout_mac', + 'action': ['python', '{angle_root}/build/mac_toolchain.py'], + }, + { + # Note: On Win, this should run after win_toolchain, as it may use it. + 'name': 'clang', + 'pattern': '.', + 'action': ['python', 'tools/clang/scripts/update.py'], + 'condition': 'dawn_standalone', + }, + { + # Pull rc binaries using checked-in hashes. + 'name': 'rc_win', + 'pattern': '.', + 'condition': 'checkout_win and (host_os == "win")', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--no_auth', + '--bucket', 'chromium-browser-clang/rc', + '-s', 'build/toolchain/win/rc/win/rc.exe.sha1', + ], + }, + # Update build/util/LASTCHANGE. + { + 'name': 'lastchange', + 'pattern': '.', + 'action': ['python', 'build/util/lastchange.py', + '-o', 'build/util/LASTCHANGE'], + }, +] + +recursedeps = [ + # buildtools provides clang_format, libc++, and libc++abi + 'buildtools', + 'third_party/dawn', + 'third_party/angle', +] diff --git a/build_overrides/dawn.gni b/build_overrides/dawn.gni index 61bb34b..973588e 100644 --- a/build_overrides/dawn.gni +++ b/build_overrides/dawn.gni @@ -1,12 +1,12 @@ -# -# Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# - -dawn_glfw_dir = "//third_party/dawn/third_party/glfw" -dawn_jinja2_dir = "//third_party/dawn/third_party/jinja2" -dawn_googletest_dir = "//third_party/dawn/third_party/googletest" -dawn_shaderc_dir = "//third_party/dawn/third_party/shaderc" -dawn_spirv_cross_dir = "//third_party/dawn/third_party/spirv-cross" -dawn_spirv_tools_dir = "//third_party/spirv-tools" +# +# Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# + +dawn_glfw_dir = "//third_party/dawn/third_party/glfw" +dawn_jinja2_dir = "//third_party/dawn/third_party/jinja2" +dawn_googletest_dir = "//third_party/dawn/third_party/googletest" +dawn_shaderc_dir = "//third_party/shaderc" +dawn_spirv_cross_dir = "//third_party/dawn/third_party/spirv-cross" +dawn_spirv_tools_dir = "//third_party/spirv-tools" diff --git a/src/aquarium-direct-map/AttribBuffer.cpp b/src/aquarium-direct-map/AttribBuffer.cpp index 33e1568..2159528 100644 --- a/src/aquarium-direct-map/AttribBuffer.cpp +++ b/src/aquarium-direct-map/AttribBuffer.cpp @@ -1,32 +1,32 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// AttribBuffer.cpp: Implement AttribBuffer. - -#include "AttribBuffer.h" - -AttribBuffer::AttribBuffer(int numComponents, - const std::vector &buffer, - int size, - const std::string &opt_type) - : type(opt_type), - bufferFloat(buffer), - bufferUShort(), - numComponents(numComponents), - numElements(size / numComponents) -{ -} - -AttribBuffer::AttribBuffer(int numComponents, - const std::vector &buffer, - int size, - const std::string &opt_type) - : type(opt_type), - bufferFloat(), - bufferUShort(buffer), - numComponents(numComponents), - numElements(size / numComponents) -{ -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// AttribBuffer.cpp: Implement AttribBuffer. + +#include "AttribBuffer.h" + +AttribBuffer::AttribBuffer(int numComponents, + const std::vector &buffer, + int size, + const std::string &opt_type) + : type(opt_type), + bufferFloat(buffer), + bufferUShort(), + numComponents(numComponents), + numElements(size / numComponents) +{ +} + +AttribBuffer::AttribBuffer(int numComponents, + const std::vector &buffer, + int size, + const std::string &opt_type) + : type(opt_type), + bufferFloat(), + bufferUShort(buffer), + numComponents(numComponents), + numElements(size / numComponents) +{ +} diff --git a/src/aquarium-direct-map/AttribBuffer.h b/src/aquarium-direct-map/AttribBuffer.h index ffdff1d..de2d10b 100644 --- a/src/aquarium-direct-map/AttribBuffer.h +++ b/src/aquarium-direct-map/AttribBuffer.h @@ -1,39 +1,42 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// AttribBuffer.h: Define AttribBuffer Class. Store vertex attributes such as positions and indexes. - -#ifndef ATTRIBBUFFER_H -#define ATTRIBBUFFER_H - -#include -#include - -class AttribBuffer -{ -public: - AttribBuffer() {} - AttribBuffer(int numComponents, const std::vector &buffer, int size, const std::string &opt_type); - AttribBuffer(int numComponents, - const std::vector &buffer, - int size, - const std::string &opt_type); - - int getNumComponents() const { return numComponents; } - int getNumElements() const { return numElements; } - - const std::vector &getBufferFloat() const { return bufferFloat; } - const std::vector &getBufferUShort() const { return bufferUShort; } - const std::string &getType() const { return type; } - -private: - std::string type; - std::vector bufferFloat; - std::vector bufferUShort; - int numComponents; - int numElements; -}; - -#endif // ATTRIBBUFFER_H +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// AttribBuffer.h: Define AttribBuffer Class. Store vertex attributes such as positions and indexes. + +#ifndef ATTRIBBUFFER_H +#define ATTRIBBUFFER_H + +#include +#include + +class AttribBuffer +{ + public: + AttribBuffer() {} + AttribBuffer(int numComponents, + const std::vector &buffer, + int size, + const std::string &opt_type); + AttribBuffer(int numComponents, + const std::vector &buffer, + int size, + const std::string &opt_type); + + int getNumComponents() const { return numComponents; } + int getNumElements() const { return numElements; } + + const std::vector &getBufferFloat() const { return bufferFloat; } + const std::vector &getBufferUShort() const { return bufferUShort; } + const std::string &getType() const { return type; } + + private: + std::string type; + std::vector bufferFloat; + std::vector bufferUShort; + int numComponents; + int numElements; +}; + +#endif // ATTRIBBUFFER_H diff --git a/src/aquarium-direct-map/Buffer.cpp b/src/aquarium-direct-map/Buffer.cpp index a5d17d6..17d8505 100644 --- a/src/aquarium-direct-map/Buffer.cpp +++ b/src/aquarium-direct-map/Buffer.cpp @@ -1,58 +1,58 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Buffer.cpp: Implement the index or vertex buffer wrappers and resource bindings of OpenGL. - -#include - -#include "Buffer.h" - -#include "common/AQUARIUM_ASSERT.h" - -Buffer::Buffer(const AttribBuffer &attribBuffer, GLenum target) - : mBuf(0), - mNumComponents(attribBuffer.getNumComponents()), - mNumElements(attribBuffer.getNumElements()), - mTotalComponents(0), - mType(0), - mNormalize(true), - mStride(0), - mOffset(nullptr) - -{ - glGenBuffers(1, &mBuf); - - glBindBuffer(target, mBuf); - - mTotalComponents = mNumComponents * mNumElements; - - auto bufferFloat = attribBuffer.getBufferFloat(); - auto bufferUShort = attribBuffer.getBufferUShort(); - - if (attribBuffer.getType() == "Float32Array") - { - mType = GL_FLOAT; - mNormalize = false; - glBufferData(target, sizeof(GLfloat) * bufferFloat.size(), bufferFloat.data(), - GL_STATIC_DRAW); - } - else if (attribBuffer.getType() == "Uint16Array") - { - mType = GL_UNSIGNED_SHORT; - glBufferData(target, sizeof(GLushort) * bufferUShort.size(), bufferUShort.data(), - GL_STATIC_DRAW); - } - else - { - std::cout << "bindBufferData undefined type." << std::endl; - } - - ASSERT(glGetError() == GL_NO_ERROR); -} - -Buffer::~Buffer() -{ - glDeleteBuffers(1, &mBuf); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Buffer.cpp: Implement the index or vertex buffer wrappers and resource bindings of OpenGL. + +#include + +#include "Buffer.h" + +#include "common/AQUARIUM_ASSERT.h" + +Buffer::Buffer(const AttribBuffer &attribBuffer, GLenum target) + : mBuf(0), + mNumComponents(attribBuffer.getNumComponents()), + mNumElements(attribBuffer.getNumElements()), + mTotalComponents(0), + mType(0), + mNormalize(true), + mStride(0), + mOffset(nullptr) + +{ + glGenBuffers(1, &mBuf); + + glBindBuffer(target, mBuf); + + mTotalComponents = mNumComponents * mNumElements; + + auto bufferFloat = attribBuffer.getBufferFloat(); + auto bufferUShort = attribBuffer.getBufferUShort(); + + if (attribBuffer.getType() == "Float32Array") + { + mType = GL_FLOAT; + mNormalize = false; + glBufferData(target, sizeof(GLfloat) * bufferFloat.size(), bufferFloat.data(), + GL_STATIC_DRAW); + } + else if (attribBuffer.getType() == "Uint16Array") + { + mType = GL_UNSIGNED_SHORT; + glBufferData(target, sizeof(GLushort) * bufferUShort.size(), bufferUShort.data(), + GL_STATIC_DRAW); + } + else + { + std::cout << "bindBufferData undefined type." << std::endl; + } + + ASSERT(glGetError() == GL_NO_ERROR); +} + +Buffer::~Buffer() +{ + glDeleteBuffers(1, &mBuf); +} diff --git a/src/aquarium-direct-map/Buffer.h b/src/aquarium-direct-map/Buffer.h index 4bfffb0..9e2b5e2 100644 --- a/src/aquarium-direct-map/Buffer.h +++ b/src/aquarium-direct-map/Buffer.h @@ -1,43 +1,43 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Buffer.h : Define Buffer Class and upload buffers to gpu. - -#ifndef BUFFER_H -#define BUFFER_H - -#include - -#include "AttribBuffer.h" -#include "glad/glad.h" - -class Buffer -{ -public: - Buffer() {} - Buffer(const AttribBuffer &array, GLenum target); - ~Buffer(); - - GLuint getBuffer() const { return mBuf; } - int getNumComponents() const { return mNumComponents; } - int getNumElements() const { return mNumElements; } - int getTotalComponents() const { return mTotalComponents; } - GLenum getType() const { return mType; } - bool getNormalize() const { return mNormalize; } - GLsizei getStride() const { return mStride; } - void *getOffset() const { return mOffset; } - -private: - GLuint mBuf; - int mNumComponents; - int mNumElements; - int mTotalComponents; - GLenum mType; - bool mNormalize; - GLsizei mStride; - void *mOffset; -}; - -#endif // !BUFFER_H +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Buffer.h : Define Buffer Class and upload buffers to gpu. + +#ifndef BUFFER_H +#define BUFFER_H + +#include + +#include "AttribBuffer.h" +#include "glad/glad.h" + +class Buffer +{ + public: + Buffer() {} + Buffer(const AttribBuffer &array, GLenum target); + ~Buffer(); + + GLuint getBuffer() const { return mBuf; } + int getNumComponents() const { return mNumComponents; } + int getNumElements() const { return mNumElements; } + int getTotalComponents() const { return mTotalComponents; } + GLenum getType() const { return mType; } + bool getNormalize() const { return mNormalize; } + GLsizei getStride() const { return mStride; } + void *getOffset() const { return mOffset; } + + private: + GLuint mBuf; + int mNumComponents; + int mNumElements; + int mTotalComponents; + GLenum mType; + bool mNormalize; + GLsizei mStride; + void *mOffset; +}; + +#endif // !BUFFER_H diff --git a/src/aquarium-direct-map/Globals.h b/src/aquarium-direct-map/Globals.h index b1d0291..b5ce6a9 100644 --- a/src/aquarium-direct-map/Globals.h +++ b/src/aquarium-direct-map/Globals.h @@ -1,229 +1,231 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Globals.h: Define global variables, constant variables, global texture map, program map and -// scene map. - -#pragma once -#ifndef GLOBALS_H -#define GLOBALS_H - -#include -#include -#include -#include -#include - -#include "Scene.h" - -#include "common/FPSTimer.h" - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -const std::string slash = "\\"; -#define M_PI 3.141592653589793 -#else -const std::string slash = "/"; -#endif - -class Scene; -class Program; -class Texture; - -static FPSTimer g_fpsTimer; // object to measure frames per second; -static std::unordered_map g_scenes; // each of the models -static std::unordered_map>> - g_sceneGroups; // the placement of the models -static std::unordered_map - g_programMap; // store all compiled program in this map -static std::unordered_map - g_textureMap; // store all loaded textures in this map -constexpr bool g_fog = true; - -constexpr float g_tailOffsetMult = 1.0f; -constexpr float g_speed = 1.0f; - -constexpr int numFishSmall = 100; -constexpr int numFishMedium = 1000; -constexpr int numFishBig = 10000; -constexpr int numFishLeftSmall = 80; -constexpr int numFishLeftBig = 160; -constexpr float sand_shininess = 5.0f; -constexpr float sand_specularFactor = 0.3f; -constexpr float generic_shininess = 50.0f; -constexpr float generic_specularFactor = 1.0f; -constexpr float outside_shininess = 50.0f; -constexpr float outside_specularFactor = 0.0f; -constexpr float seaweed_shininess = 50.0f; -constexpr float seaweed_specularFactor = 1.0f; -constexpr float inner_shininess = 50.0f; -constexpr float inner_specularFactor = 1.0f; -constexpr float fish_shininess = 5.0f; -constexpr float fish_specularFactor = 0.3f; - -struct G_ui_per -{ - const char* obj; - const char* name; - float value; - float max; - float min; -}; - -static std::unordered_map> - g; // set min value as initialize value - -constexpr float g_fovFudge = 1.0f; -constexpr float g_net_offset[3] = { 0.0f, 0.0f, 0.0f }; -constexpr float g_net_offsetMult = 1.21f; - -struct G_viewSettings { - float targetHeight = 63.3f; - float targetRadius = 91.6f; - float eyeHeight = 7.5f; - float eyeRadius = 13.2f; - float eyeSpeed = 0.0258f; - float fieldOfView = 82.699f; - float ambientRed = 0.218f; - float ambientGreen = 0.502f; - float ambientBlue = 0.706f; - float fogPower = 16.5f; - float fogMult = 1.5f; //2.02, - float fogOffset = 0.738f; - float fogRed = 0.338f; - float fogGreen = 0.81f; - float fogBlue = 1.0f; - float refractionFudge = 3.0f; - float eta = 1.0f; - float tankColorFudge = 0.796f; -}constexpr g_viewSettings; - -static std::vector projection(16); -static std::vector view(16); -static std::vector world(16); -static std::vector worldInverse(16); -static std::vector worldInverseTraspose(16); -static std::vector viewProjection(16); -static std::vector worldViewProjection(16); -static std::vector viewInverse(16); -static std::vector viewProjectionInverse(16); -static std::vector skyView(16); -static std::vector skyViewProjection(16); -static std::vector skyViewProjectionInverse(16); -static std::vector eyePosition(3); -static std::vector target(3); -static std::vector up = {0, 1, 0}; -static std::vector lightWorldPos(3); -static std::vector v3t0(3); -static std::vector v3t1(3); -static std::vector m4t0(16); -static std::vector m4t1(16); -static std::vector m4t2(16); -static std::vector m4t3(16); -static std::vector colorMult = {1, 1, 1, 1}; -static std::vector lightColor = {1.0f, 1.0f, 1.0f, 1.0f}; -static std::vector specular = {1.0f, 1.0f, 1.0f, 1.0f}; -static std::vector ambient(4); -static std::vector fogColor = {1.0f, 1.0f, 1.0f, 1.0f}; - -//Generic uniforms -struct GenericConst -{ - std::vector *viewProjection; - std::vector *viewInverse; - std::vector *lightWorldPos; - std::vector *lightColor; - std::vector *specular; - std::vector *ambient; - std::vector *fogColor; - float shininess; - float specularFactor; - float fogPower; - float fogMult; - float fogOffset; - - float eta; - float tankColorFudge; - float refractionFudge; -}; -static GenericConst sandConst, genericConst, seaweedConst, outsideConst, innerConst; - -struct GenericPer -{ - std::vector *world; - std::vector *worldViewProjection; - std::vector *worldInverse; - std::vector *worldInverseTranspose; - float time; -}; - -static GenericPer sandPer, genericPer, seaweedPer, outsidePer, innerPer, laserPer, skyPer; - -struct SkyConst -{ - std::vector *viewProjectionInverse; -}; - -static SkyConst skyConst; - -struct FishPer -{ - std::vector worldPosition; - std::vector nextPosition; - float scale; - float time; -}; - -static FishPer fishPer; - -struct G_sceneInfo -{ - std::string name; - std::string program[2]; - bool fog; - std::string group; - bool blend; -}; - -struct ConstUniforms -{ - float fishLength; - float fishWaveLength; - float fishBendAmount; -}; - -struct Fish { - std::string name; - float speed; - float speedRange; - float radius; - float radiusRange; - float tailSpeed; - float heightOffset; - float heightRange; - - ConstUniforms constUniforms; - - bool lasers; - float laserRot; - float laserOff[3]; - float laserScale[3]; - int num; -}; - -struct FishConst -{ - GenericConst genericConst; - ConstUniforms constUniforms; -}; - -static FishConst fishConst; - -const std::string repoFolder = "aquarium-native"; -const std::string sourceFolder = "src"; -const std::string shaderFolder = "shaders"; -const std::string shaderVersion = "opengl/450"; -const std::string resourceFolder = "assets"; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Globals.h: Define global variables, constant variables, global texture map, program map and +// scene map. + +#pragma once +#ifndef GLOBALS_H +#define GLOBALS_H + +#include +#include +#include +#include +#include + +#include "Scene.h" + +#include "common/FPSTimer.h" + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) +const std::string slash = "\\"; +#define M_PI 3.141592653589793 +#else +const std::string slash = "/"; +#endif + +class Scene; +class Program; +class Texture; + +static FPSTimer g_fpsTimer; // object to measure frames per second; +static std::unordered_map g_scenes; // each of the models +static std::unordered_map>> + g_sceneGroups; // the placement of the models +static std::unordered_map + g_programMap; // store all compiled program in this map +static std::unordered_map + g_textureMap; // store all loaded textures in this map +constexpr bool g_fog = true; + +constexpr float g_tailOffsetMult = 1.0f; +constexpr float g_speed = 1.0f; + +constexpr int numFishSmall = 100; +constexpr int numFishMedium = 1000; +constexpr int numFishBig = 10000; +constexpr int numFishLeftSmall = 80; +constexpr int numFishLeftBig = 160; +constexpr float sand_shininess = 5.0f; +constexpr float sand_specularFactor = 0.3f; +constexpr float generic_shininess = 50.0f; +constexpr float generic_specularFactor = 1.0f; +constexpr float outside_shininess = 50.0f; +constexpr float outside_specularFactor = 0.0f; +constexpr float seaweed_shininess = 50.0f; +constexpr float seaweed_specularFactor = 1.0f; +constexpr float inner_shininess = 50.0f; +constexpr float inner_specularFactor = 1.0f; +constexpr float fish_shininess = 5.0f; +constexpr float fish_specularFactor = 0.3f; + +struct G_ui_per +{ + const char *obj; + const char *name; + float value; + float max; + float min; +}; + +static std::unordered_map> + g; // set min value as initialize value + +constexpr float g_fovFudge = 1.0f; +constexpr float g_net_offset[3] = {0.0f, 0.0f, 0.0f}; +constexpr float g_net_offsetMult = 1.21f; + +struct G_viewSettings +{ + float targetHeight = 63.3f; + float targetRadius = 91.6f; + float eyeHeight = 7.5f; + float eyeRadius = 13.2f; + float eyeSpeed = 0.0258f; + float fieldOfView = 82.699f; + float ambientRed = 0.218f; + float ambientGreen = 0.502f; + float ambientBlue = 0.706f; + float fogPower = 16.5f; + float fogMult = 1.5f; // 2.02, + float fogOffset = 0.738f; + float fogRed = 0.338f; + float fogGreen = 0.81f; + float fogBlue = 1.0f; + float refractionFudge = 3.0f; + float eta = 1.0f; + float tankColorFudge = 0.796f; +} constexpr g_viewSettings; + +static std::vector projection(16); +static std::vector view(16); +static std::vector world(16); +static std::vector worldInverse(16); +static std::vector worldInverseTraspose(16); +static std::vector viewProjection(16); +static std::vector worldViewProjection(16); +static std::vector viewInverse(16); +static std::vector viewProjectionInverse(16); +static std::vector skyView(16); +static std::vector skyViewProjection(16); +static std::vector skyViewProjectionInverse(16); +static std::vector eyePosition(3); +static std::vector target(3); +static std::vector up = {0, 1, 0}; +static std::vector lightWorldPos(3); +static std::vector v3t0(3); +static std::vector v3t1(3); +static std::vector m4t0(16); +static std::vector m4t1(16); +static std::vector m4t2(16); +static std::vector m4t3(16); +static std::vector colorMult = {1, 1, 1, 1}; +static std::vector lightColor = {1.0f, 1.0f, 1.0f, 1.0f}; +static std::vector specular = {1.0f, 1.0f, 1.0f, 1.0f}; +static std::vector ambient(4); +static std::vector fogColor = {1.0f, 1.0f, 1.0f, 1.0f}; + +// Generic uniforms +struct GenericConst +{ + std::vector *viewProjection; + std::vector *viewInverse; + std::vector *lightWorldPos; + std::vector *lightColor; + std::vector *specular; + std::vector *ambient; + std::vector *fogColor; + float shininess; + float specularFactor; + float fogPower; + float fogMult; + float fogOffset; + + float eta; + float tankColorFudge; + float refractionFudge; +}; +static GenericConst sandConst, genericConst, seaweedConst, outsideConst, innerConst; + +struct GenericPer +{ + std::vector *world; + std::vector *worldViewProjection; + std::vector *worldInverse; + std::vector *worldInverseTranspose; + float time; +}; + +static GenericPer sandPer, genericPer, seaweedPer, outsidePer, innerPer, laserPer, skyPer; + +struct SkyConst +{ + std::vector *viewProjectionInverse; +}; + +static SkyConst skyConst; + +struct FishPer +{ + std::vector worldPosition; + std::vector nextPosition; + float scale; + float time; +}; + +static FishPer fishPer; + +struct G_sceneInfo +{ + std::string name; + std::string program[2]; + bool fog; + std::string group; + bool blend; +}; + +struct ConstUniforms +{ + float fishLength; + float fishWaveLength; + float fishBendAmount; +}; + +struct Fish +{ + std::string name; + float speed; + float speedRange; + float radius; + float radiusRange; + float tailSpeed; + float heightOffset; + float heightRange; + + ConstUniforms constUniforms; + + bool lasers; + float laserRot; + float laserOff[3]; + float laserScale[3]; + int num; +}; + +struct FishConst +{ + GenericConst genericConst; + ConstUniforms constUniforms; +}; + +static FishConst fishConst; + +const std::string repoFolder = "aquarium-native"; +const std::string sourceFolder = "src"; +const std::string shaderFolder = "shaders"; +const std::string shaderVersion = "opengl/450"; +const std::string resourceFolder = "assets"; + +#endif diff --git a/src/aquarium-direct-map/Main.cpp b/src/aquarium-direct-map/Main.cpp index 79d372a..ce02e34 100644 --- a/src/aquarium-direct-map/Main.cpp +++ b/src/aquarium-direct-map/Main.cpp @@ -1,669 +1,702 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Main.cpp: Create context and window for OpenGL graphics API. -// Data preparation, load resources and wrap them into scenes. -// Implements logic of rendering background, fishes, seaweeds and -// other models. Calculate fish count for each type of fish. -// Update uniforms for each frame. Show fps for each frame. - -#ifdef _WIN32 -#include -#include "Windows.h" -#elif __APPLE__ -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include - -#include "Globals.h" -#include "Matrix.h" -#include "Model.h" -#include "Program.h" - -#include "GLFW/glfw3.h" -#include "common/AQUARIUM_ASSERT.h" -#include "include/CmdArgsHelper.h" -#include "rapidjson/document.h" -#include "rapidjson/istreamwrapper.h" -#include "rapidjson/stringbuffer.h" -#include "rapidjson/writer.h" - -#define min(a,b) ((a)<(b)?(a):(b)) - -void render(); - -// Define glfw window and the size of window -GLFWwindow *window; -int clientWidth; -int clientHeight; - -// Get current path of the binary -std::string mPath; - -// The number of fish is passed from cmd args directly -int g_numFish; - -// Variables calculate time -float then = 0.0f; -float mClock = 0.0f; -float eyeClock = 0.0f; - -const G_ui_per g_ui[] = { - { "globals", "speed", 1.0f, 4.0f },{ "globals", "targetHeight", 0.0f, 150.0f }, - { "globals", "targetRadius", 88.0f, 200.0f },{ "globals", "eyeHeight", 19.0f, 150.0f }, - { "globals", "eyeSpeed", 0.06f, 1.0f },{ "globals", "fieldOfView", 85.0f, 179.0f, 1.0f }, - { "globals", "ambientRed", 0.22f, 1.0f },{ "globals", "ambientGreen", 0.25f, 1.0f }, - { "globals", "ambientBlue", 0.39f, 1.0f },{ "globals", "fogPower", 14.5f, 50.0f }, - { "globals", "fogMult", 1.66f, 10.0f },{ "globals", "fogOffset", 0.53f, 3.0f }, - { "globals", "fogRed", 0.54f, 1.0f },{ "globals", "fogGreen", 0.86f, 1.0f }, - { "globals", "fogBlue", 1.0f, 1.0f },{ "fish", "fishHeightRange", 1.0f, 3.0f }, - { "fish", "fishHeight", 25.0f, 50.0f },{ "fish", "fishSpeed", 0.124f, 2.0f }, - { "fish", "fishOffset", 0.52f, 2.0f },{ "fish", "fishXClock", 1.0f, 2.0f }, - { "fish", "fishYClock", 0.556f, 2.0f },{ "fish", "fishZClock", 1.0f, 2.0f }, - { "fish", "fishTailSpeed", 1.0f, 30.0f },{ "innerConst", "refractionFudge", 3.0f, 50.0f }, - { "innerConst", "eta", 1.0f, 1.20f },{ "innerConst", "tankColorFudge", 0.8f, 2.0f } }; - -G_sceneInfo g_sceneInfo[] = { { "SmallFishA",{ "fishVertexShader", "fishReflectionFragmentShader" }, true }, -{ "MediumFishA",{ "fishVertexShader", "fishNormalMapFragmentShader" }, true }, -{ "MediumFishB",{ "fishVertexShader", "fishReflectionFragmentShader" }, true }, -{ "BigFishA",{ "fishVertexShader", "fishNormalMapFragmentShader" }, true }, -{ "BigFishB",{ "fishVertexShader", "fishNormalMapFragmentShader" }, true }, -{ "Arch",{ "", "" }, true }, -{ "Coral",{ "", "" }, true }, -{ "CoralStoneA",{ "", "" }, true }, -{ "CoralStoneB",{ "", "" }, true }, -{ "EnvironmentBox",{ "diffuseVertexShader", "diffuseFragmentShader" }, false, "outside" }, -{ "FloorBase_Baked",{ "", "" }, true }, -{ "FloorCenter",{ "", "" }, true }, -{ "GlobeBase",{ "diffuseVertexShader", "diffuseFragmentShader" } }, -{ "GlobeInner",{ "innerRefractionMapVertexShader", "innerRefractionMapFragmentShader" }, true, "inner" }, -{ "RockA",{ "", "" }, true }, -{ "RockB",{ "", "" }, true }, -{ "RockC",{ "", "" }, true }, -{ "RuinColumn",{ "", "" }, true }, -{ "Skybox",{ "diffuseVertexShader", "diffuseFragmentShader" }, false, "outside" }, -{ "Stone",{ "", "" }, true }, -{ "Stones",{ "", "" }, true }, -{ "SunknShip",{ "", "" }, true }, -{ "SunknSub",{ "", "" }, true }, -{ "SupportBeams",{ "", "" }, false, "outside" }, -{ "SeaweedA",{ "seaweedVertexShader", "seaweedFragmentShader" }, false, "seaweed", true }, -{ "SeaweedB",{ "seaweedVertexShader", "seaweedFragmentShader" }, false, "seaweed", true }, -{ "TreasureChest",{ "", "" }, true } }; - -std::unordered_map g_sceneInfoByName; - -Fish g_fishTable[] = { { "SmallFishA", 1.0f, 1.5f, 30.0f, 25.0f, 10.0f, 0.0f, 16.0f,{ 10.0f, 1.0f, 2.0f } }, -{ "MediumFishA", 1.0f, 2.0f, 10.0f, 20.0f, 1.0f, 0.0f, 16.0f,{ 10.0f, -2.0f, 2.0f } }, -{ "MediumFishB", 0.5f, 4.0f, 10.0f, 20.0f, 3.0f, -8.0f, 5.0f,{ 10.0f, -2.0f, 2.0f } }, -{ "BigFishA", 0.5f, 0.5f, 50.0f, 3.0f, 1.5f, 0.0f, 16.0f,{ 10.0f, -1.0f, 0.5f }, true, 0.04f,{ 0.0f, 0.1f, 9.0f },{ 0.3f, 0.3f, 1000.0f } }, -{ "BigFishB", 0.5f, 0.5f, 45.0f, 3.0f, 1.0f, 0.0f, 16.0f,{ 10.0f, -0.7f, 0.3f }, true, 0.04f,{ 0.0f, -0.3f, 9.0f },{ 0.3f, 0.3f, 1000.0f } } }; - -void setGenericConstMatrix(GenericConst *genericConst) { - genericConst->viewProjection = &viewProjection; - genericConst->viewInverse = &viewInverse; - genericConst->lightWorldPos = &lightWorldPos; - genericConst->lightColor = &lightColor; - genericConst->specular = &specular; - genericConst->ambient = &ambient; - genericConst->fogColor = &fogColor; -} - -void setGenericPer(GenericPer *genericPer) -{ - genericPer->world = &world; - genericPer->worldViewProjection = &worldViewProjection; - genericPer->worldInverse = &worldInverse; - genericPer->worldInverseTranspose = &worldInverseTraspose; -} - -void initializeUniforms() { - sandConst.shininess = sand_shininess; - sandConst.specularFactor = sand_specularFactor; - - genericConst.shininess = generic_shininess; - genericConst.specularFactor = generic_specularFactor; - - outsideConst.shininess = outside_shininess; - outsideConst.specularFactor = outside_shininess; - - seaweedConst.shininess = seaweed_shininess; - seaweedConst.specularFactor = seaweed_specularFactor; - - innerConst.shininess = inner_shininess; - innerConst.specularFactor = inner_specularFactor; - innerConst.eta = g_viewSettings.eta; - innerConst.refractionFudge = g_viewSettings.refractionFudge; - innerConst.tankColorFudge = g_viewSettings.tankColorFudge; - - fishConst.genericConst.shininess = fish_shininess; - fishConst.genericConst.specularFactor = fish_specularFactor; - - setGenericConstMatrix(&sandConst); - setGenericConstMatrix(&genericConst); - setGenericConstMatrix(&seaweedConst); - setGenericConstMatrix(&innerConst); - setGenericConstMatrix(&outsideConst); - setGenericConstMatrix(&fishConst.genericConst); - setGenericPer(&sandPer); - setGenericPer(&genericPer); - setGenericPer(&seaweedPer); - setGenericPer(&innerPer); - setGenericPer(&outsidePer); - setGenericPer(&laserPer); - - skyConst.viewProjectionInverse = &viewProjectionInverse; - - fishPer.worldPosition.resize(3); - fishPer.nextPosition.resize(3); -} - -void initializeGlobalInfo() -{ - for (auto &value : g_ui) - { - g[value.obj][value.name] = value.value; - } -} - -// Load json file from assets. Initialize g_sceneGroups and classify groups. -void LoadPlacement() -{ - std::ostringstream oss; - oss << mPath << resourceFolder << slash << "PropPlacement.js"; - std::string proppath = oss.str(); - std::ifstream PlacementStream(proppath, std::ios::in); - rapidjson::IStreamWrapper isPlacement(PlacementStream); - rapidjson::Document document; - document.ParseStream(isPlacement); - - ASSERT(document.IsObject()); - - ASSERT(document.HasMember("objects")); - const rapidjson::Value &objects = document["objects"]; - ASSERT(objects.IsArray()); - - for (auto &info : g_sceneInfo) - { - g_sceneInfoByName[info.name] = info; - } - - for (rapidjson::SizeType i = 0; i < objects.Size(); ++i) - { - const rapidjson::Value &name = objects[i]["name"]; - const rapidjson::Value &worldMatrix = objects[i]["worldMatrix"]; - ASSERT(worldMatrix.IsArray() && worldMatrix.Size() == 16); - - std::string groupName = g_sceneInfoByName[name.GetString()].group; - if (groupName == "") - { - groupName = "base"; - } - - std::multimap> &group = g_sceneGroups[groupName]; - - std::vector matrix; - for (rapidjson::SizeType j = 0; j < worldMatrix.Size(); ++j) - { - matrix.push_back(worldMatrix[j].GetFloat()); - } - group.insert(make_pair(name.GetString(), matrix)); - } -} - -Scene *loadScene(const std::string &name, const std::string opt_programIds[2]) -{ - Scene *scene = new Scene(opt_programIds); - scene->load(mPath, name); - return scene; -} - -// Initialize g_scenes. -void LoadScenes() -{ - for (auto &info : g_sceneInfo) - { - g_scenes[info.name] = loadScene(info.name, info.program); - } -} - -void onDestroy() -{ - for (auto &program : g_programMap) - { - if (program.second != nullptr) - { - delete program.second; - program.second = nullptr; - } - } - - for (auto &texture : g_textureMap) - { - if (texture.second != nullptr) - { - delete texture.second; - texture.second = nullptr; - } - } - - for (auto &scene : g_scenes) - { - delete scene.second; - } -} - -void getCurrentPath() -{ - // Get path of current build. -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) - TCHAR temp[200]; - GetModuleFileName(NULL, temp, MAX_PATH); - std::wstring ws(temp); - mPath = std::string(ws.begin(), ws.end()); - size_t nPos = mPath.find_last_of(slash); - mPath = mPath.substr(0, nPos) + slash + ".." + slash + ".." + slash; -#elif __APPLE__ - char temp[200]; - uint32_t size = sizeof(temp); - _NSGetExecutablePath(temp, &size); - mPath = std::string(temp); - int nPos = mPath.find_last_of(slash); - mPath = mPath.substr(0, nPos) + slash + ".." + slash + ".." + slash; -#else - char temp[200]; - readlink("/proc/self/exe", temp, sizeof(temp)); - mPath = std::string(temp); - int nPos = mPath.find_last_of(slash); - mPath = mPath.substr(0, nPos) + slash + ".." + slash + ".." + slash; -#endif -} - -bool initialize(int argc, char **argv) -{ - getCurrentPath(); - - glEnable(GL_DEPTH_TEST); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - initializeGlobalInfo(); - initializeUniforms(); - LoadPlacement(); - - LoadScenes(); - - // "--num-fish" {numfish}: imply rendering fish count. - char* pNext; - for (int i = 1; i < argc; ++i) - { - std::string cmd(argv[i]); - if (cmd == "--h" || cmd == "-h") - { - std::cout << cmdArgsStrAquariumDirectMap << std::endl; - return false; - } - else if (cmd == "--num-fish") - { - g_numFish = strtol(argv[i++ + 1], &pNext, 10); - } - } - - // Calculate fish count for each float of fish - std::string floats[3] = {"Big", "Medium", "Small"}; - int totalFish = g_numFish; - int numLeft = totalFish; - for (auto &type : floats) - { - for (auto &fishInfo : g_fishTable) - { - std::string &fishName = fishInfo.name; - if (fishName.find(type)) - { - continue; - } - int numfloat = numLeft; - if (type == "Big") - { - int temp = totalFish < numFishSmall ? 1 : 2; - numfloat = min(numLeft, temp); - } - else if (type == "Medium") - { - if (totalFish < numFishMedium) - { - numfloat = min(numLeft, totalFish / 10); - } - else if (totalFish < numFishBig) - { - numfloat = min(numLeft, numFishLeftSmall); - } - else - { - numfloat = min(numLeft, numFishLeftBig); - } - } - numLeft = numLeft - numfloat; - fishInfo.num = numfloat; - } - } - - return true; -} - -int main(int argc, char **argv) { - - // initialize GLFW - if (!glfwInit()) - { - std::cout << stderr << "Failed to initialize GLFW" << std::endl; - return -1; - } - - glfwWindowHint(GLFW_SAMPLES, 4); - -#ifdef __APPLE__ - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); -#elif _WIN32 || __linux__ - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); -#endif - - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); - glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - - GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); - const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); - clientWidth = mode->width; - clientHeight = mode->height; - - window = glfwCreateWindow(clientWidth, clientHeight, "Aquarium", NULL, NULL); - if (window == NULL) - { - std::cout << "Failed to open GLFW window." << std::endl; - glfwTerminate(); - return -1; - } - glfwWindowHint(GLFW_DECORATED, GL_FALSE); - glfwMakeContextCurrent(window); - - if (!gladLoadGL()) - { - std::cout << "Something went wrong!" << std::endl; - exit(-1); - } - - if (!initialize(argc, argv)) - { - return -1; - } - - const char *renderer = (const char *)glGetString(GL_RENDERER); - std::cout << renderer << std::endl; - - // Get the resolution of screen. The resolution on mac is about 4 times larger than size of - // window. - glfwGetFramebufferSize(window, &clientWidth, &clientHeight); - glViewport(0, 0, clientWidth, clientHeight); - - glfwShowWindow(window); - - while (!glfwWindowShouldClose(window)) - { - if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) - glfwSetWindowShouldClose(window, GL_TRUE); - - render(); - - glfwSwapBuffers(window); - glfwPollEvents(); - } - - glfwTerminate(); - - onDestroy(); - - return 0; -} - -void DrawGroup(const std::multimap> &group, - const GenericConst &constUniforms, - GenericPer *perUniforms) -{ - Model *currentModel = nullptr; - int ii = 0; - for (auto &object : group) - { - if (g_scenes.find(object.first) == g_scenes.end()) - { - continue; - } - auto &scene = g_scenes[object.first]; - auto &info = g_sceneInfoByName[object.first]; - - if (info.blend) - { - glEnable(GL_BLEND); - } - else - { - glDisable(GL_BLEND); - } - - auto &models = scene->getModels(); - for (auto &model : models) - { - if (model != currentModel) - { - currentModel = model; - model->prepareForDraw(constUniforms); - } - - world = std::vector(object.second.begin(), object.second.end()); - matrix::mulMatrixMatrix4(worldViewProjection, world, viewProjection); - matrix::inverse4(worldInverse, world); - matrix::transpose4(worldInverseTraspose, worldInverse); - perUniforms->time = mClock + (ii++); - model->draw(*perUniforms); - } - } -} - -void render() { - // Update our time -#ifdef _WIN32 - float now = GetTickCount64() / 1000.0f; -#else - float now = clock() / 1000000.0f; -#endif - float elapsedTime = 0.0f; - if (then == 0.0f) - { - elapsedTime = 0.0f; - } - else - { - elapsedTime = now - then; - } - then = now; - - g_fpsTimer.update(elapsedTime); - std::string text = - "Aquarium FPS: " + std::to_string(static_cast(g_fpsTimer.getAverageFPS())); - glfwSetWindowTitle(window, text.c_str()); - - mClock += elapsedTime * g_speed; - eyeClock += elapsedTime * g_viewSettings.eyeSpeed; - - eyePosition[0] = sin(eyeClock) * g_viewSettings.eyeRadius; - eyePosition[1] = g_viewSettings.eyeHeight; - eyePosition[2] = cos(eyeClock) * g_viewSettings.eyeRadius; - target[0] = static_cast(sin(eyeClock + M_PI)) * g_viewSettings.targetRadius; - target[1] = g_viewSettings.targetHeight; - target[2] = static_cast(cos(eyeClock + M_PI)) * g_viewSettings.targetRadius; - - ambient[0] = g_viewSettings.ambientRed; - ambient[1] = g_viewSettings.ambientGreen; - ambient[2] = g_viewSettings.ambientBlue; - - glColorMask(true, true, true, true); - glClearColor(0, 0.8f, 1, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - - float nearPlane = 1; - float farPlane = 25000.0f; - float aspect = static_cast(clientWidth) / static_cast(clientHeight); - float top = tan(matrix::degToRad(g_viewSettings.fieldOfView * g_fovFudge) * 0.5f) * nearPlane; - float bottom = -top; - float left = aspect * bottom; - float right = aspect * top; - float width = abs(right - left); - float height = abs(top - bottom); - float xOff = width * g_net_offset[0] * g_net_offsetMult; - float yOff = height * g_net_offset[1] * g_net_offsetMult; - - matrix::frustum(projection, left + xOff, right + xOff, bottom + yOff, top + yOff, nearPlane, - farPlane); - matrix::cameraLookAt(viewInverse, eyePosition, target, up); - matrix::inverse4(view, viewInverse); - matrix::mulMatrixMatrix4(viewProjection, view, projection); - matrix::inverse4(viewProjectionInverse, viewProjection); - - skyView = view; - skyView[12] = 0.0; - skyView[13] = 0.0; - skyView[14] = 0.0; - matrix::mulMatrixMatrix4(skyViewProjection, skyView, projection); - matrix::inverse4(skyViewProjectionInverse, skyViewProjection); - - matrix::getAxis(v3t0, viewInverse, 0); - matrix::getAxis(v3t1, viewInverse, 1); - matrix::mulScalarVector(20.0f, v3t0); - matrix::mulScalarVector(30.0f, v3t1); - matrix::addVector(lightWorldPos, eyePosition, v3t0); - matrix::addVector(lightWorldPos, lightWorldPos, v3t1); - - glDisable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBlendEquation(GL_FUNC_ADD); - glEnable(GL_CULL_FACE); - - matrix::resetPseudoRandom(); - - glDepthMask(true); - - if (g_fog) - { - genericConst.fogPower = g_viewSettings.fogPower; - genericConst.fogMult = g_viewSettings.fogMult; - genericConst.fogOffset = g_viewSettings.fogOffset; - fishConst.genericConst.fogPower = g_viewSettings.fogPower; - fishConst.genericConst.fogMult = g_viewSettings.fogMult; - fishConst.genericConst.fogOffset = g_viewSettings.fogOffset; - innerConst.fogPower = g_viewSettings.fogPower; - innerConst.fogMult = g_viewSettings.fogMult; - innerConst.fogOffset = g_viewSettings.fogOffset; - seaweedConst.fogPower = g_viewSettings.fogPower; - seaweedConst.fogMult = g_viewSettings.fogMult; - seaweedConst.fogOffset = g_viewSettings.fogOffset; - fogColor[0] = g_viewSettings.fogRed; - fogColor[1] = g_viewSettings.fogGreen; - fogColor[2] = g_viewSettings.fogBlue; - } - - // Draw Scene - if (g_sceneGroups.find("base") != g_sceneGroups.end()) - { - DrawGroup(g_sceneGroups["base"], genericConst, &genericPer); - } - - // Draw Fishes - glEnable(GL_BLEND); - for (auto &fishInfo : g_fishTable) - { - std::string &fishName = fishInfo.name; - int numFish = fishInfo.num; - - Scene *scene = g_scenes[fishName]; - if (scene->loaded) - { - Model *fish = scene->getModels()[0]; - auto &f = g["fish"]; - fishConst.constUniforms = fishInfo.constUniforms; - fish->prepareForDraw(fishConst); - float fishBaseClock = mClock * f["fishSpeed"]; - float fishRadius = fishInfo.radius; - float fishRadiusRange = fishInfo.radiusRange; - float fishSpeed = fishInfo.speed; - float fishSpeedRange = fishInfo.speedRange; - float fishTailSpeed = fishInfo.tailSpeed * f["fishTailSpeed"]; - float fishOffset = f["fishOffset"]; - // float fishClockSpeed = f["fishSpeed"]; - float fishHeight = f["fishHeight"] + fishInfo.heightOffset; - float fishHeightRange = f["fishHeightRange"] * fishInfo.heightRange; - float fishXClock = f["fishXClock"]; - float fishYClock = f["fishYClock"]; - float fishZClock = f["fishZClock"]; - std::vector &fishPosition = fishPer.worldPosition; - std::vector &fishNextPosition = fishPer.nextPosition; - for (int ii = 0; ii < numFish; ++ii) - { - float fishClock = fishBaseClock + ii * fishOffset; - float speed = - fishSpeed + static_cast(matrix::pseudoRandom()) * fishSpeedRange; - float scale = 1.0f + static_cast(matrix::pseudoRandom()) * 1; - float xRadius = - fishRadius + static_cast(matrix::pseudoRandom()) * fishRadiusRange; - float yRadius = 2.0f + static_cast(matrix::pseudoRandom()) * fishHeightRange; - float zRadius = - fishRadius + static_cast(matrix::pseudoRandom()) * fishRadiusRange; - float fishSpeedClock = fishClock * speed; - float xClock = fishSpeedClock * fishXClock; - float yClock = fishSpeedClock * fishYClock; - float zClock = fishSpeedClock * fishZClock; - - fishPosition[0] = sin(xClock) * xRadius; - fishPosition[1] = sin(yClock) * yRadius + fishHeight; - fishPosition[2] = cos(zClock) * zRadius; - fishNextPosition[0] = sin(xClock - 0.04f) * xRadius; - fishNextPosition[1] = sin(yClock - 0.01f) * yRadius + fishHeight; - fishNextPosition[2] = cos(zClock - 0.04f) * zRadius; - fishPer.scale = scale; - - fishPer.time = fmod((mClock + ii * g_tailOffsetMult) * fishTailSpeed * speed, - static_cast(M_PI) * 2); - fish->draw(fishPer); - } - } - } - - // Draw tank - if (g_sceneGroups.find("inner") != g_sceneGroups.end()) - { - DrawGroup(g_sceneGroups["inner"], innerConst, &innerPer); - } - - // Draw seaweed - if (g_sceneGroups.find("seaweed") != g_sceneGroups.end()) - { - DrawGroup(g_sceneGroups["seaweed"], seaweedConst, &seaweedPer); - } - - // Draw outside - if (g_sceneGroups.find("outside") != g_sceneGroups.end()) - { - DrawGroup(g_sceneGroups["outside"], outsideConst, &outsidePer); - } -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Main.cpp: Create context and window for OpenGL graphics API. +// Data preparation, load resources and wrap them into scenes. +// Implements logic of rendering background, fishes, seaweeds and +// other models. Calculate fish count for each type of fish. +// Update uniforms for each frame. Show fps for each frame. + +#ifdef _WIN32 +#include +#include "Windows.h" +#elif __APPLE__ +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "Globals.h" +#include "Matrix.h" +#include "Model.h" +#include "Program.h" + +#include "GLFW/glfw3.h" +#include "common/AQUARIUM_ASSERT.h" +#include "include/CmdArgsHelper.h" +#include "rapidjson/document.h" +#include "rapidjson/istreamwrapper.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/writer.h" + +#define min(a, b) ((a) < (b) ? (a) : (b)) + +void render(); + +// Define glfw window and the size of window +GLFWwindow *window; +int clientWidth; +int clientHeight; + +// Get current path of the binary +std::string mPath; + +// The number of fish is passed from cmd args directly +int g_numFish; + +// Variables calculate time +float then = 0.0f; +float mClock = 0.0f; +float eyeClock = 0.0f; + +const G_ui_per g_ui[] = { + {"globals", "speed", 1.0f, 4.0f}, {"globals", "targetHeight", 0.0f, 150.0f}, + {"globals", "targetRadius", 88.0f, 200.0f}, {"globals", "eyeHeight", 19.0f, 150.0f}, + {"globals", "eyeSpeed", 0.06f, 1.0f}, {"globals", "fieldOfView", 85.0f, 179.0f, 1.0f}, + {"globals", "ambientRed", 0.22f, 1.0f}, {"globals", "ambientGreen", 0.25f, 1.0f}, + {"globals", "ambientBlue", 0.39f, 1.0f}, {"globals", "fogPower", 14.5f, 50.0f}, + {"globals", "fogMult", 1.66f, 10.0f}, {"globals", "fogOffset", 0.53f, 3.0f}, + {"globals", "fogRed", 0.54f, 1.0f}, {"globals", "fogGreen", 0.86f, 1.0f}, + {"globals", "fogBlue", 1.0f, 1.0f}, {"fish", "fishHeightRange", 1.0f, 3.0f}, + {"fish", "fishHeight", 25.0f, 50.0f}, {"fish", "fishSpeed", 0.124f, 2.0f}, + {"fish", "fishOffset", 0.52f, 2.0f}, {"fish", "fishXClock", 1.0f, 2.0f}, + {"fish", "fishYClock", 0.556f, 2.0f}, {"fish", "fishZClock", 1.0f, 2.0f}, + {"fish", "fishTailSpeed", 1.0f, 30.0f}, {"innerConst", "refractionFudge", 3.0f, 50.0f}, + {"innerConst", "eta", 1.0f, 1.20f}, {"innerConst", "tankColorFudge", 0.8f, 2.0f}}; + +G_sceneInfo g_sceneInfo[] = { + {"SmallFishA", {"fishVertexShader", "fishReflectionFragmentShader"}, true}, + {"MediumFishA", {"fishVertexShader", "fishNormalMapFragmentShader"}, true}, + {"MediumFishB", {"fishVertexShader", "fishReflectionFragmentShader"}, true}, + {"BigFishA", {"fishVertexShader", "fishNormalMapFragmentShader"}, true}, + {"BigFishB", {"fishVertexShader", "fishNormalMapFragmentShader"}, true}, + {"Arch", {"", ""}, true}, + {"Coral", {"", ""}, true}, + {"CoralStoneA", {"", ""}, true}, + {"CoralStoneB", {"", ""}, true}, + {"EnvironmentBox", {"diffuseVertexShader", "diffuseFragmentShader"}, false, "outside"}, + {"FloorBase_Baked", {"", ""}, true}, + {"FloorCenter", {"", ""}, true}, + {"GlobeBase", {"diffuseVertexShader", "diffuseFragmentShader"}}, + {"GlobeInner", + {"innerRefractionMapVertexShader", "innerRefractionMapFragmentShader"}, + true, + "inner"}, + {"RockA", {"", ""}, true}, + {"RockB", {"", ""}, true}, + {"RockC", {"", ""}, true}, + {"RuinColumn", {"", ""}, true}, + {"Skybox", {"diffuseVertexShader", "diffuseFragmentShader"}, false, "outside"}, + {"Stone", {"", ""}, true}, + {"Stones", {"", ""}, true}, + {"SunknShip", {"", ""}, true}, + {"SunknSub", {"", ""}, true}, + {"SupportBeams", {"", ""}, false, "outside"}, + {"SeaweedA", {"seaweedVertexShader", "seaweedFragmentShader"}, false, "seaweed", true}, + {"SeaweedB", {"seaweedVertexShader", "seaweedFragmentShader"}, false, "seaweed", true}, + {"TreasureChest", {"", ""}, true}}; + +std::unordered_map g_sceneInfoByName; + +Fish g_fishTable[] = { + {"SmallFishA", 1.0f, 1.5f, 30.0f, 25.0f, 10.0f, 0.0f, 16.0f, {10.0f, 1.0f, 2.0f}}, + {"MediumFishA", 1.0f, 2.0f, 10.0f, 20.0f, 1.0f, 0.0f, 16.0f, {10.0f, -2.0f, 2.0f}}, + {"MediumFishB", 0.5f, 4.0f, 10.0f, 20.0f, 3.0f, -8.0f, 5.0f, {10.0f, -2.0f, 2.0f}}, + {"BigFishA", + 0.5f, + 0.5f, + 50.0f, + 3.0f, + 1.5f, + 0.0f, + 16.0f, + {10.0f, -1.0f, 0.5f}, + true, + 0.04f, + {0.0f, 0.1f, 9.0f}, + {0.3f, 0.3f, 1000.0f}}, + {"BigFishB", + 0.5f, + 0.5f, + 45.0f, + 3.0f, + 1.0f, + 0.0f, + 16.0f, + {10.0f, -0.7f, 0.3f}, + true, + 0.04f, + {0.0f, -0.3f, 9.0f}, + {0.3f, 0.3f, 1000.0f}}}; + +void setGenericConstMatrix(GenericConst *genericConst) +{ + genericConst->viewProjection = &viewProjection; + genericConst->viewInverse = &viewInverse; + genericConst->lightWorldPos = &lightWorldPos; + genericConst->lightColor = &lightColor; + genericConst->specular = &specular; + genericConst->ambient = &ambient; + genericConst->fogColor = &fogColor; +} + +void setGenericPer(GenericPer *genericPer) +{ + genericPer->world = &world; + genericPer->worldViewProjection = &worldViewProjection; + genericPer->worldInverse = &worldInverse; + genericPer->worldInverseTranspose = &worldInverseTraspose; +} + +void initializeUniforms() +{ + sandConst.shininess = sand_shininess; + sandConst.specularFactor = sand_specularFactor; + + genericConst.shininess = generic_shininess; + genericConst.specularFactor = generic_specularFactor; + + outsideConst.shininess = outside_shininess; + outsideConst.specularFactor = outside_shininess; + + seaweedConst.shininess = seaweed_shininess; + seaweedConst.specularFactor = seaweed_specularFactor; + + innerConst.shininess = inner_shininess; + innerConst.specularFactor = inner_specularFactor; + innerConst.eta = g_viewSettings.eta; + innerConst.refractionFudge = g_viewSettings.refractionFudge; + innerConst.tankColorFudge = g_viewSettings.tankColorFudge; + + fishConst.genericConst.shininess = fish_shininess; + fishConst.genericConst.specularFactor = fish_specularFactor; + + setGenericConstMatrix(&sandConst); + setGenericConstMatrix(&genericConst); + setGenericConstMatrix(&seaweedConst); + setGenericConstMatrix(&innerConst); + setGenericConstMatrix(&outsideConst); + setGenericConstMatrix(&fishConst.genericConst); + setGenericPer(&sandPer); + setGenericPer(&genericPer); + setGenericPer(&seaweedPer); + setGenericPer(&innerPer); + setGenericPer(&outsidePer); + setGenericPer(&laserPer); + + skyConst.viewProjectionInverse = &viewProjectionInverse; + + fishPer.worldPosition.resize(3); + fishPer.nextPosition.resize(3); +} + +void initializeGlobalInfo() +{ + for (auto &value : g_ui) + { + g[value.obj][value.name] = value.value; + } +} + +// Load json file from assets. Initialize g_sceneGroups and classify groups. +void LoadPlacement() +{ + std::ostringstream oss; + oss << mPath << resourceFolder << slash << "PropPlacement.js"; + std::string proppath = oss.str(); + std::ifstream PlacementStream(proppath, std::ios::in); + rapidjson::IStreamWrapper isPlacement(PlacementStream); + rapidjson::Document document; + document.ParseStream(isPlacement); + + ASSERT(document.IsObject()); + + ASSERT(document.HasMember("objects")); + const rapidjson::Value &objects = document["objects"]; + ASSERT(objects.IsArray()); + + for (auto &info : g_sceneInfo) + { + g_sceneInfoByName[info.name] = info; + } + + for (rapidjson::SizeType i = 0; i < objects.Size(); ++i) + { + const rapidjson::Value &name = objects[i]["name"]; + const rapidjson::Value &worldMatrix = objects[i]["worldMatrix"]; + ASSERT(worldMatrix.IsArray() && worldMatrix.Size() == 16); + + std::string groupName = g_sceneInfoByName[name.GetString()].group; + if (groupName == "") + { + groupName = "base"; + } + + std::multimap> &group = g_sceneGroups[groupName]; + + std::vector matrix; + for (rapidjson::SizeType j = 0; j < worldMatrix.Size(); ++j) + { + matrix.push_back(worldMatrix[j].GetFloat()); + } + group.insert(make_pair(name.GetString(), matrix)); + } +} + +Scene *loadScene(const std::string &name, const std::string opt_programIds[2]) +{ + Scene *scene = new Scene(opt_programIds); + scene->load(mPath, name); + return scene; +} + +// Initialize g_scenes. +void LoadScenes() +{ + for (auto &info : g_sceneInfo) + { + g_scenes[info.name] = loadScene(info.name, info.program); + } +} + +void onDestroy() +{ + for (auto &program : g_programMap) + { + if (program.second != nullptr) + { + delete program.second; + program.second = nullptr; + } + } + + for (auto &texture : g_textureMap) + { + if (texture.second != nullptr) + { + delete texture.second; + texture.second = nullptr; + } + } + + for (auto &scene : g_scenes) + { + delete scene.second; + } +} + +void getCurrentPath() +{ + // Get path of current build. +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) + TCHAR temp[200]; + GetModuleFileName(NULL, temp, MAX_PATH); + std::wstring ws(temp); + mPath = std::string(ws.begin(), ws.end()); + size_t nPos = mPath.find_last_of(slash); + mPath = mPath.substr(0, nPos) + slash + ".." + slash + ".." + slash; +#elif __APPLE__ + char temp[200]; + uint32_t size = sizeof(temp); + _NSGetExecutablePath(temp, &size); + mPath = std::string(temp); + int nPos = mPath.find_last_of(slash); + mPath = mPath.substr(0, nPos) + slash + ".." + slash + ".." + slash; +#else + char temp[200]; + readlink("/proc/self/exe", temp, sizeof(temp)); + mPath = std::string(temp); + int nPos = mPath.find_last_of(slash); + mPath = mPath.substr(0, nPos) + slash + ".." + slash + ".." + slash; +#endif +} + +bool initialize(int argc, char **argv) +{ + getCurrentPath(); + + glEnable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + initializeGlobalInfo(); + initializeUniforms(); + LoadPlacement(); + + LoadScenes(); + + // "--num-fish" {numfish}: imply rendering fish count. + char *pNext; + for (int i = 1; i < argc; ++i) + { + std::string cmd(argv[i]); + if (cmd == "--h" || cmd == "-h") + { + std::cout << cmdArgsStrAquariumDirectMap << std::endl; + return false; + } + else if (cmd == "--num-fish") + { + g_numFish = strtol(argv[i++ + 1], &pNext, 10); + } + } + + // Calculate fish count for each float of fish + std::string floats[3] = {"Big", "Medium", "Small"}; + int totalFish = g_numFish; + int numLeft = totalFish; + for (auto &type : floats) + { + for (auto &fishInfo : g_fishTable) + { + std::string &fishName = fishInfo.name; + if (fishName.find(type)) + { + continue; + } + int numfloat = numLeft; + if (type == "Big") + { + int temp = totalFish < numFishSmall ? 1 : 2; + numfloat = min(numLeft, temp); + } + else if (type == "Medium") + { + if (totalFish < numFishMedium) + { + numfloat = min(numLeft, totalFish / 10); + } + else if (totalFish < numFishBig) + { + numfloat = min(numLeft, numFishLeftSmall); + } + else + { + numfloat = min(numLeft, numFishLeftBig); + } + } + numLeft = numLeft - numfloat; + fishInfo.num = numfloat; + } + } + + return true; +} + +int main(int argc, char **argv) +{ + + // initialize GLFW + if (!glfwInit()) + { + std::cout << stderr << "Failed to initialize GLFW" << std::endl; + return -1; + } + + glfwWindowHint(GLFW_SAMPLES, 4); + +#ifdef __APPLE__ + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); +#elif _WIN32 || __linux__ + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); +#endif + + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + + GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); + const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); + clientWidth = mode->width; + clientHeight = mode->height; + + window = glfwCreateWindow(clientWidth, clientHeight, "Aquarium", NULL, NULL); + if (window == NULL) + { + std::cout << "Failed to open GLFW window." << std::endl; + glfwTerminate(); + return -1; + } + glfwWindowHint(GLFW_DECORATED, GL_FALSE); + glfwMakeContextCurrent(window); + + if (!gladLoadGL()) + { + std::cout << "Something went wrong!" << std::endl; + exit(-1); + } + + if (!initialize(argc, argv)) + { + return -1; + } + + const char *renderer = (const char *)glGetString(GL_RENDERER); + std::cout << renderer << std::endl; + + // Get the resolution of screen. The resolution on mac is about 4 times larger than size of + // window. + glfwGetFramebufferSize(window, &clientWidth, &clientHeight); + glViewport(0, 0, clientWidth, clientHeight); + + glfwShowWindow(window); + + while (!glfwWindowShouldClose(window)) + { + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(window, GL_TRUE); + + render(); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwTerminate(); + + onDestroy(); + + return 0; +} + +void DrawGroup(const std::multimap> &group, + const GenericConst &constUniforms, + GenericPer *perUniforms) +{ + Model *currentModel = nullptr; + int ii = 0; + for (auto &object : group) + { + if (g_scenes.find(object.first) == g_scenes.end()) + { + continue; + } + auto &scene = g_scenes[object.first]; + auto &info = g_sceneInfoByName[object.first]; + + if (info.blend) + { + glEnable(GL_BLEND); + } + else + { + glDisable(GL_BLEND); + } + + auto &models = scene->getModels(); + for (auto &model : models) + { + if (model != currentModel) + { + currentModel = model; + model->prepareForDraw(constUniforms); + } + + world = std::vector(object.second.begin(), object.second.end()); + matrix::mulMatrixMatrix4(worldViewProjection, world, viewProjection); + matrix::inverse4(worldInverse, world); + matrix::transpose4(worldInverseTraspose, worldInverse); + perUniforms->time = mClock + (ii++); + model->draw(*perUniforms); + } + } +} + +void render() +{ + // Update our time +#ifdef _WIN32 + float now = GetTickCount64() / 1000.0f; +#else + float now = clock() / 1000000.0f; +#endif + float elapsedTime = 0.0f; + if (then == 0.0f) + { + elapsedTime = 0.0f; + } + else + { + elapsedTime = now - then; + } + then = now; + + g_fpsTimer.update(elapsedTime); + std::string text = + "Aquarium FPS: " + std::to_string(static_cast(g_fpsTimer.getAverageFPS())); + glfwSetWindowTitle(window, text.c_str()); + + mClock += elapsedTime * g_speed; + eyeClock += elapsedTime * g_viewSettings.eyeSpeed; + + eyePosition[0] = sin(eyeClock) * g_viewSettings.eyeRadius; + eyePosition[1] = g_viewSettings.eyeHeight; + eyePosition[2] = cos(eyeClock) * g_viewSettings.eyeRadius; + target[0] = static_cast(sin(eyeClock + M_PI)) * g_viewSettings.targetRadius; + target[1] = g_viewSettings.targetHeight; + target[2] = static_cast(cos(eyeClock + M_PI)) * g_viewSettings.targetRadius; + + ambient[0] = g_viewSettings.ambientRed; + ambient[1] = g_viewSettings.ambientGreen; + ambient[2] = g_viewSettings.ambientBlue; + + glColorMask(true, true, true, true); + glClearColor(0, 0.8f, 1, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + float nearPlane = 1; + float farPlane = 25000.0f; + float aspect = static_cast(clientWidth) / static_cast(clientHeight); + float top = tan(matrix::degToRad(g_viewSettings.fieldOfView * g_fovFudge) * 0.5f) * nearPlane; + float bottom = -top; + float left = aspect * bottom; + float right = aspect * top; + float width = abs(right - left); + float height = abs(top - bottom); + float xOff = width * g_net_offset[0] * g_net_offsetMult; + float yOff = height * g_net_offset[1] * g_net_offsetMult; + + matrix::frustum(projection, left + xOff, right + xOff, bottom + yOff, top + yOff, nearPlane, + farPlane); + matrix::cameraLookAt(viewInverse, eyePosition, target, up); + matrix::inverse4(view, viewInverse); + matrix::mulMatrixMatrix4(viewProjection, view, projection); + matrix::inverse4(viewProjectionInverse, viewProjection); + + skyView = view; + skyView[12] = 0.0; + skyView[13] = 0.0; + skyView[14] = 0.0; + matrix::mulMatrixMatrix4(skyViewProjection, skyView, projection); + matrix::inverse4(skyViewProjectionInverse, skyViewProjection); + + matrix::getAxis(v3t0, viewInverse, 0); + matrix::getAxis(v3t1, viewInverse, 1); + matrix::mulScalarVector(20.0f, v3t0); + matrix::mulScalarVector(30.0f, v3t1); + matrix::addVector(lightWorldPos, eyePosition, v3t0); + matrix::addVector(lightWorldPos, lightWorldPos, v3t1); + + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + glEnable(GL_CULL_FACE); + + matrix::resetPseudoRandom(); + + glDepthMask(true); + + if (g_fog) + { + genericConst.fogPower = g_viewSettings.fogPower; + genericConst.fogMult = g_viewSettings.fogMult; + genericConst.fogOffset = g_viewSettings.fogOffset; + fishConst.genericConst.fogPower = g_viewSettings.fogPower; + fishConst.genericConst.fogMult = g_viewSettings.fogMult; + fishConst.genericConst.fogOffset = g_viewSettings.fogOffset; + innerConst.fogPower = g_viewSettings.fogPower; + innerConst.fogMult = g_viewSettings.fogMult; + innerConst.fogOffset = g_viewSettings.fogOffset; + seaweedConst.fogPower = g_viewSettings.fogPower; + seaweedConst.fogMult = g_viewSettings.fogMult; + seaweedConst.fogOffset = g_viewSettings.fogOffset; + fogColor[0] = g_viewSettings.fogRed; + fogColor[1] = g_viewSettings.fogGreen; + fogColor[2] = g_viewSettings.fogBlue; + } + + // Draw Scene + if (g_sceneGroups.find("base") != g_sceneGroups.end()) + { + DrawGroup(g_sceneGroups["base"], genericConst, &genericPer); + } + + // Draw Fishes + glEnable(GL_BLEND); + for (auto &fishInfo : g_fishTable) + { + std::string &fishName = fishInfo.name; + int numFish = fishInfo.num; + + Scene *scene = g_scenes[fishName]; + if (scene->loaded) + { + Model *fish = scene->getModels()[0]; + auto &f = g["fish"]; + fishConst.constUniforms = fishInfo.constUniforms; + fish->prepareForDraw(fishConst); + float fishBaseClock = mClock * f["fishSpeed"]; + float fishRadius = fishInfo.radius; + float fishRadiusRange = fishInfo.radiusRange; + float fishSpeed = fishInfo.speed; + float fishSpeedRange = fishInfo.speedRange; + float fishTailSpeed = fishInfo.tailSpeed * f["fishTailSpeed"]; + float fishOffset = f["fishOffset"]; + // float fishClockSpeed = f["fishSpeed"]; + float fishHeight = f["fishHeight"] + fishInfo.heightOffset; + float fishHeightRange = f["fishHeightRange"] * fishInfo.heightRange; + float fishXClock = f["fishXClock"]; + float fishYClock = f["fishYClock"]; + float fishZClock = f["fishZClock"]; + std::vector &fishPosition = fishPer.worldPosition; + std::vector &fishNextPosition = fishPer.nextPosition; + for (int ii = 0; ii < numFish; ++ii) + { + float fishClock = fishBaseClock + ii * fishOffset; + float speed = + fishSpeed + static_cast(matrix::pseudoRandom()) * fishSpeedRange; + float scale = 1.0f + static_cast(matrix::pseudoRandom()) * 1; + float xRadius = + fishRadius + static_cast(matrix::pseudoRandom()) * fishRadiusRange; + float yRadius = 2.0f + static_cast(matrix::pseudoRandom()) * fishHeightRange; + float zRadius = + fishRadius + static_cast(matrix::pseudoRandom()) * fishRadiusRange; + float fishSpeedClock = fishClock * speed; + float xClock = fishSpeedClock * fishXClock; + float yClock = fishSpeedClock * fishYClock; + float zClock = fishSpeedClock * fishZClock; + + fishPosition[0] = sin(xClock) * xRadius; + fishPosition[1] = sin(yClock) * yRadius + fishHeight; + fishPosition[2] = cos(zClock) * zRadius; + fishNextPosition[0] = sin(xClock - 0.04f) * xRadius; + fishNextPosition[1] = sin(yClock - 0.01f) * yRadius + fishHeight; + fishNextPosition[2] = cos(zClock - 0.04f) * zRadius; + fishPer.scale = scale; + + fishPer.time = fmod((mClock + ii * g_tailOffsetMult) * fishTailSpeed * speed, + static_cast(M_PI) * 2); + fish->draw(fishPer); + } + } + } + + // Draw tank + if (g_sceneGroups.find("inner") != g_sceneGroups.end()) + { + DrawGroup(g_sceneGroups["inner"], innerConst, &innerPer); + } + + // Draw seaweed + if (g_sceneGroups.find("seaweed") != g_sceneGroups.end()) + { + DrawGroup(g_sceneGroups["seaweed"], seaweedConst, &seaweedPer); + } + + // Draw outside + if (g_sceneGroups.find("outside") != g_sceneGroups.end()) + { + DrawGroup(g_sceneGroups["outside"], outsideConst, &outsidePer); + } +} diff --git a/src/aquarium-direct-map/Matrix.h b/src/aquarium-direct-map/Matrix.h index b8c57e1..3226163 100644 --- a/src/aquarium-direct-map/Matrix.h +++ b/src/aquarium-direct-map/Matrix.h @@ -1,414 +1,415 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Matrix.h: Do matrix calculations including multiply, addition, substraction, -// transpose, inverse, translation, etc. - -#ifndef MATRIX_H -#define MATIRX_H 1 - -#include -#include - -namespace matrix { -static long long RANDOM_RANGE_ = 4294967296; - -template -void mulMatrixMatrix4(std::vector &dst, const std::vector &a, const std::vector &b) -{ - T a00 = a[0]; - T a01 = a[1]; - T a02 = a[2]; - T a03 = a[3]; - T a10 = a[4 + 0]; - T a11 = a[4 + 1]; - T a12 = a[4 + 2]; - T a13 = a[4 + 3]; - T a20 = a[8 + 0]; - T a21 = a[8 + 1]; - T a22 = a[8 + 2]; - T a23 = a[8 + 3]; - T a30 = a[12 + 0]; - T a31 = a[12 + 1]; - T a32 = a[12 + 2]; - T a33 = a[12 + 3]; - T b00 = b[0]; - T b01 = b[1]; - T b02 = b[2]; - T b03 = b[3]; - T b10 = b[4 + 0]; - T b11 = b[4 + 1]; - T b12 = b[4 + 2]; - T b13 = b[4 + 3]; - T b20 = b[8 + 0]; - T b21 = b[8 + 1]; - T b22 = b[8 + 2]; - T b23 = b[8 + 3]; - T b30 = b[12 + 0]; - T b31 = b[12 + 1]; - T b32 = b[12 + 2]; - T b33 = b[12 + 3]; - dst[0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30; - dst[1] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31; - dst[2] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32; - dst[3] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33; - dst[4] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30; - dst[5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31; - dst[6] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32; - dst[7] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33; - dst[8] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30; - dst[9] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31; - dst[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32; - dst[11] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33; - dst[12] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30; - dst[13] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31; - dst[14] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32; - dst[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33; -} - -template -void inverse4(std::vector &dst, const std::vector &m) -{ - T m00 = m[0 * 4 + 0]; - T m01 = m[0 * 4 + 1]; - T m02 = m[0 * 4 + 2]; - T m03 = m[0 * 4 + 3]; - T m10 = m[1 * 4 + 0]; - T m11 = m[1 * 4 + 1]; - T m12 = m[1 * 4 + 2]; - T m13 = m[1 * 4 + 3]; - T m20 = m[2 * 4 + 0]; - T m21 = m[2 * 4 + 1]; - T m22 = m[2 * 4 + 2]; - T m23 = m[2 * 4 + 3]; - T m30 = m[3 * 4 + 0]; - T m31 = m[3 * 4 + 1]; - T m32 = m[3 * 4 + 2]; - T m33 = m[3 * 4 + 3]; - T tmp_0 = m22 * m33; - T tmp_1 = m32 * m23; - T tmp_2 = m12 * m33; - T tmp_3 = m32 * m13; - T tmp_4 = m12 * m23; - T tmp_5 = m22 * m13; - T tmp_6 = m02 * m33; - T tmp_7 = m32 * m03; - T tmp_8 = m02 * m23; - T tmp_9 = m22 * m03; - T tmp_10 = m02 * m13; - T tmp_11 = m12 * m03; - T tmp_12 = m20 * m31; - T tmp_13 = m30 * m21; - T tmp_14 = m10 * m31; - T tmp_15 = m30 * m11; - T tmp_16 = m10 * m21; - T tmp_17 = m20 * m11; - T tmp_18 = m00 * m31; - T tmp_19 = m30 * m01; - T tmp_20 = m00 * m21; - T tmp_21 = m20 * m01; - T tmp_22 = m00 * m11; - T tmp_23 = m10 * m01; - - T t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) - (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31); - T t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) - (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31); - T t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) - (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31); - T t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) - (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21); - - T d = static_cast(1.0) / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3); - - dst[0] = d * t0; - dst[1] = d * t1; - dst[2] = d * t2; - dst[3] = d * t3; - dst[4] = - d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) - (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)); - dst[5] = - d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) - (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)); - dst[6] = d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) - - (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)); - dst[7] = d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) - - (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20)); - dst[8] = d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) - - (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)); - dst[9] = d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) - - (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)); - dst[10] = d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) - - (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)); - dst[11] = d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) - - (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23)); - dst[12] = d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) - - (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)); - dst[13] = d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) - - (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)); - dst[14] = d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) - - (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)); - dst[15] = d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) - - (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02)); -} - -template -void transpose4(std::vector &dst, std::vector &m) -{ - if (dst == m) - { - T t; - - t = m[1]; - m[1] = m[4]; - m[4] = t; - - t = m[2]; - m[2] = m[8]; - m[8] = t; - - t = m[3]; - m[3] = m[12]; - m[12] = t; - - t = m[6]; - m[6] = m[9]; - m[9] = t; - - t = m[7]; - m[7] = m[13]; - m[13] = t; - - t = m[11]; - m[11] = m[14]; - m[14] = t; - } - - T m00 = m[0 * 4 + 0]; - T m01 = m[0 * 4 + 1]; - T m02 = m[0 * 4 + 2]; - T m03 = m[0 * 4 + 3]; - T m10 = m[1 * 4 + 0]; - T m11 = m[1 * 4 + 1]; - T m12 = m[1 * 4 + 2]; - T m13 = m[1 * 4 + 3]; - T m20 = m[2 * 4 + 0]; - T m21 = m[2 * 4 + 1]; - T m22 = m[2 * 4 + 2]; - T m23 = m[2 * 4 + 3]; - T m30 = m[3 * 4 + 0]; - T m31 = m[3 * 4 + 1]; - T m32 = m[3 * 4 + 2]; - T m33 = m[3 * 4 + 3]; - - dst[0] = m00; - dst[1] = m10; - dst[2] = m20; - dst[3] = m30; - dst[4] = m01; - dst[5] = m11; - dst[6] = m21; - dst[7] = m31; - dst[8] = m02; - dst[9] = m12; - dst[10] = m22; - dst[11] = m32; - dst[12] = m03; - dst[13] = m13; - dst[14] = m23; - dst[15] = m33; -} - -template -void frustum(std::vector &dst, T left, T right, T bottom, T top, T near_, T far_) -{ - T dx = right - left; - T dy = top - bottom; - T dz = near_ - far_; - - dst[0] = 2 * near_ / dx; - dst[1] = 0; - dst[2] = 0; - dst[3] = 0; - dst[4] = 0; - dst[5] = 2 * near_ / dy; - dst[6] = 0; - dst[7] = 0; - dst[8] = (left + right) / dx; - dst[9] = (top + bottom) / dy; - dst[10] = far_ / dz; - dst[11] = -1; - dst[12] = 0; - dst[13] = 0; - dst[14] = near_ * far_ / dz; - dst[15] = 0; -} - -template -void getAxis(std::vector &dst, const std::vector &m, int axis) -{ - int off = axis * 4; - dst[0] = m[off + 0]; - dst[1] = m[off + 1]; - dst[2] = m[off + 2]; -} - -template -void mulScalarVector(T k, std::vector &v) -{ - for (auto &value : v) - { - value = value * k; - } -} - -template -void addVector(std::vector &dst, const std::vector &a, const std::vector &b) -{ - int aLength = static_cast(a.size()); - for (int i = 0; i < aLength; ++i) - { - dst[i] = a[i] + b[i]; - } -} - -template -void normalize(std::vector &dst, const std::vector &a) -{ - T n = 0.0; - size_t aLength = a.size(); - for (size_t i = 0; i < aLength; ++i) - n += a[i] * a[i]; - n = sqrt(n); - if (n > 0.00001) - { - for (size_t i = 0; i < aLength; ++i) - dst[i] = a[i] / n; - } - else - { - for (size_t i = 0; i < aLength; ++i) - dst[i] = 0; - } -} - -template -void subVector(std::vector &dst, const std::vector &a, const std::vector &b) -{ - size_t aLength = a.size(); - for (size_t i = 0; i < aLength; ++i) - { - dst[i] = a[i] - b[i]; - } -} - -template -void cross(std::vector &dst, const std::vector &a, const std::vector &b) -{ - dst[0] = a[1] * b[2] - a[2] * b[1]; - dst[1] = a[2] * b[0] - a[0] * b[2]; - dst[2] = a[0] * b[1] - a[1] * b[0]; -} - -template -T dot(std::vector &a, std::vector &b) -{ - return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]); -} - -template -void cameraLookAt(std::vector &dst, - const std::vector &eye, - const std::vector &target, - const std::vector &up) -{ - std::vector t0(3), t1(3), t2(3); - subVector(t0, eye, target); - normalize(t0, t0); - cross(t1, up, t0); - normalize(t1, t1); - cross(t2, t0, t1); - - dst[0] = t1[0]; - dst[1] = t1[1]; - dst[2] = t1[2]; - dst[3] = 0; - dst[4] = t2[0]; - dst[5] = t2[1]; - dst[6] = t2[2]; - dst[7] = 0; - dst[8] = t0[0]; - dst[9] = t0[1]; - dst[10] = t0[2]; - dst[11] = 0; - dst[12] = eye[0]; - dst[13] = eye[1]; - dst[14] = eye[2]; - dst[15] = 1; -} - -static long long randomSeed_; -static void resetPseudoRandom() -{ - randomSeed_ = 0; -} - -static double pseudoRandom() -{ - randomSeed_ = (134775813 * randomSeed_ + 1) % RANDOM_RANGE_; - return static_cast(randomSeed_) / static_cast(RANDOM_RANGE_); -} - -template -void translation(std::vector &dst, const std::vector &v) -{ - dst[0] = 1; - dst[1] = 0; - dst[2] = 0; - dst[3] = 0; - dst[4] = 0; - dst[5] = 1; - dst[6] = 0; - dst[7] = 0; - dst[8] = 0; - dst[9] = 0; - dst[10] = 1; - dst[11] = 0; - dst[12] = v[0]; - dst[13] = v[1]; - dst[14] = v[2]; - dst[15] = 1; -} - -template -void translate(std::vector &m, const std::vector &v) -{ - T v0 = v[0]; - T v1 = v[1]; - T v2 = v[2]; - T m00 = m[0]; - T m01 = m[1]; - T m02 = m[2]; - T m03 = m[3]; - T m10 = m[1 * 4 + 0]; - T m11 = m[1 * 4 + 1]; - T m12 = m[1 * 4 + 2]; - T m13 = m[1 * 4 + 3]; - T m20 = m[2 * 4 + 0]; - T m21 = m[2 * 4 + 1]; - T m22 = m[2 * 4 + 2]; - T m23 = m[2 * 4 + 3]; - T m30 = m[3 * 4 + 0]; - T m31 = m[3 * 4 + 1]; - T m32 = m[3 * 4 + 2]; - T m33 = m[3 * 4 + 3]; - - m[12] = m00 * v0 + m10 * v1 + m20 * v2 + m30; - m[13] = m01 * v0 + m11 * v1 + m21 * v2 + m31; - m[14] = m02 * v0 + m12 * v1 + m22 * v2 + m32; - m[15] = m03 * v0 + m13 * v1 + m23 * v2 + m33; -} - -float degToRad(float degrees) -{ - return static_cast(degrees * M_PI / 180.0); -} -} -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Matrix.h: Do matrix calculations including multiply, addition, substraction, +// transpose, inverse, translation, etc. + +#ifndef MATRIX_H +#define MATIRX_H 1 + +#include +#include + +namespace matrix +{ +static long long RANDOM_RANGE_ = 4294967296; + +template +void mulMatrixMatrix4(std::vector &dst, const std::vector &a, const std::vector &b) +{ + T a00 = a[0]; + T a01 = a[1]; + T a02 = a[2]; + T a03 = a[3]; + T a10 = a[4 + 0]; + T a11 = a[4 + 1]; + T a12 = a[4 + 2]; + T a13 = a[4 + 3]; + T a20 = a[8 + 0]; + T a21 = a[8 + 1]; + T a22 = a[8 + 2]; + T a23 = a[8 + 3]; + T a30 = a[12 + 0]; + T a31 = a[12 + 1]; + T a32 = a[12 + 2]; + T a33 = a[12 + 3]; + T b00 = b[0]; + T b01 = b[1]; + T b02 = b[2]; + T b03 = b[3]; + T b10 = b[4 + 0]; + T b11 = b[4 + 1]; + T b12 = b[4 + 2]; + T b13 = b[4 + 3]; + T b20 = b[8 + 0]; + T b21 = b[8 + 1]; + T b22 = b[8 + 2]; + T b23 = b[8 + 3]; + T b30 = b[12 + 0]; + T b31 = b[12 + 1]; + T b32 = b[12 + 2]; + T b33 = b[12 + 3]; + dst[0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30; + dst[1] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31; + dst[2] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32; + dst[3] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33; + dst[4] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30; + dst[5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31; + dst[6] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32; + dst[7] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33; + dst[8] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30; + dst[9] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31; + dst[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32; + dst[11] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33; + dst[12] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30; + dst[13] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31; + dst[14] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32; + dst[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33; +} + +template +void inverse4(std::vector &dst, const std::vector &m) +{ + T m00 = m[0 * 4 + 0]; + T m01 = m[0 * 4 + 1]; + T m02 = m[0 * 4 + 2]; + T m03 = m[0 * 4 + 3]; + T m10 = m[1 * 4 + 0]; + T m11 = m[1 * 4 + 1]; + T m12 = m[1 * 4 + 2]; + T m13 = m[1 * 4 + 3]; + T m20 = m[2 * 4 + 0]; + T m21 = m[2 * 4 + 1]; + T m22 = m[2 * 4 + 2]; + T m23 = m[2 * 4 + 3]; + T m30 = m[3 * 4 + 0]; + T m31 = m[3 * 4 + 1]; + T m32 = m[3 * 4 + 2]; + T m33 = m[3 * 4 + 3]; + T tmp_0 = m22 * m33; + T tmp_1 = m32 * m23; + T tmp_2 = m12 * m33; + T tmp_3 = m32 * m13; + T tmp_4 = m12 * m23; + T tmp_5 = m22 * m13; + T tmp_6 = m02 * m33; + T tmp_7 = m32 * m03; + T tmp_8 = m02 * m23; + T tmp_9 = m22 * m03; + T tmp_10 = m02 * m13; + T tmp_11 = m12 * m03; + T tmp_12 = m20 * m31; + T tmp_13 = m30 * m21; + T tmp_14 = m10 * m31; + T tmp_15 = m30 * m11; + T tmp_16 = m10 * m21; + T tmp_17 = m20 * m11; + T tmp_18 = m00 * m31; + T tmp_19 = m30 * m01; + T tmp_20 = m00 * m21; + T tmp_21 = m20 * m01; + T tmp_22 = m00 * m11; + T tmp_23 = m10 * m01; + + T t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) - (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31); + T t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) - (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31); + T t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) - (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31); + T t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) - (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21); + + T d = static_cast(1.0) / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3); + + dst[0] = d * t0; + dst[1] = d * t1; + dst[2] = d * t2; + dst[3] = d * t3; + dst[4] = + d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) - (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)); + dst[5] = + d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) - (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)); + dst[6] = d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) - + (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)); + dst[7] = d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) - + (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20)); + dst[8] = d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) - + (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)); + dst[9] = d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) - + (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)); + dst[10] = d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) - + (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)); + dst[11] = d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) - + (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23)); + dst[12] = d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) - + (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)); + dst[13] = d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) - + (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)); + dst[14] = d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) - + (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)); + dst[15] = d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) - + (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02)); +} + +template +void transpose4(std::vector &dst, std::vector &m) +{ + if (dst == m) + { + T t; + + t = m[1]; + m[1] = m[4]; + m[4] = t; + + t = m[2]; + m[2] = m[8]; + m[8] = t; + + t = m[3]; + m[3] = m[12]; + m[12] = t; + + t = m[6]; + m[6] = m[9]; + m[9] = t; + + t = m[7]; + m[7] = m[13]; + m[13] = t; + + t = m[11]; + m[11] = m[14]; + m[14] = t; + } + + T m00 = m[0 * 4 + 0]; + T m01 = m[0 * 4 + 1]; + T m02 = m[0 * 4 + 2]; + T m03 = m[0 * 4 + 3]; + T m10 = m[1 * 4 + 0]; + T m11 = m[1 * 4 + 1]; + T m12 = m[1 * 4 + 2]; + T m13 = m[1 * 4 + 3]; + T m20 = m[2 * 4 + 0]; + T m21 = m[2 * 4 + 1]; + T m22 = m[2 * 4 + 2]; + T m23 = m[2 * 4 + 3]; + T m30 = m[3 * 4 + 0]; + T m31 = m[3 * 4 + 1]; + T m32 = m[3 * 4 + 2]; + T m33 = m[3 * 4 + 3]; + + dst[0] = m00; + dst[1] = m10; + dst[2] = m20; + dst[3] = m30; + dst[4] = m01; + dst[5] = m11; + dst[6] = m21; + dst[7] = m31; + dst[8] = m02; + dst[9] = m12; + dst[10] = m22; + dst[11] = m32; + dst[12] = m03; + dst[13] = m13; + dst[14] = m23; + dst[15] = m33; +} + +template +void frustum(std::vector &dst, T left, T right, T bottom, T top, T near_, T far_) +{ + T dx = right - left; + T dy = top - bottom; + T dz = near_ - far_; + + dst[0] = 2 * near_ / dx; + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + dst[4] = 0; + dst[5] = 2 * near_ / dy; + dst[6] = 0; + dst[7] = 0; + dst[8] = (left + right) / dx; + dst[9] = (top + bottom) / dy; + dst[10] = far_ / dz; + dst[11] = -1; + dst[12] = 0; + dst[13] = 0; + dst[14] = near_ * far_ / dz; + dst[15] = 0; +} + +template +void getAxis(std::vector &dst, const std::vector &m, int axis) +{ + int off = axis * 4; + dst[0] = m[off + 0]; + dst[1] = m[off + 1]; + dst[2] = m[off + 2]; +} + +template +void mulScalarVector(T k, std::vector &v) +{ + for (auto &value : v) + { + value = value * k; + } +} + +template +void addVector(std::vector &dst, const std::vector &a, const std::vector &b) +{ + int aLength = static_cast(a.size()); + for (int i = 0; i < aLength; ++i) + { + dst[i] = a[i] + b[i]; + } +} + +template +void normalize(std::vector &dst, const std::vector &a) +{ + T n = 0.0; + size_t aLength = a.size(); + for (size_t i = 0; i < aLength; ++i) + n += a[i] * a[i]; + n = sqrt(n); + if (n > 0.00001) + { + for (size_t i = 0; i < aLength; ++i) + dst[i] = a[i] / n; + } + else + { + for (size_t i = 0; i < aLength; ++i) + dst[i] = 0; + } +} + +template +void subVector(std::vector &dst, const std::vector &a, const std::vector &b) +{ + size_t aLength = a.size(); + for (size_t i = 0; i < aLength; ++i) + { + dst[i] = a[i] - b[i]; + } +} + +template +void cross(std::vector &dst, const std::vector &a, const std::vector &b) +{ + dst[0] = a[1] * b[2] - a[2] * b[1]; + dst[1] = a[2] * b[0] - a[0] * b[2]; + dst[2] = a[0] * b[1] - a[1] * b[0]; +} + +template +T dot(std::vector &a, std::vector &b) +{ + return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]); +} + +template +void cameraLookAt(std::vector &dst, + const std::vector &eye, + const std::vector &target, + const std::vector &up) +{ + std::vector t0(3), t1(3), t2(3); + subVector(t0, eye, target); + normalize(t0, t0); + cross(t1, up, t0); + normalize(t1, t1); + cross(t2, t0, t1); + + dst[0] = t1[0]; + dst[1] = t1[1]; + dst[2] = t1[2]; + dst[3] = 0; + dst[4] = t2[0]; + dst[5] = t2[1]; + dst[6] = t2[2]; + dst[7] = 0; + dst[8] = t0[0]; + dst[9] = t0[1]; + dst[10] = t0[2]; + dst[11] = 0; + dst[12] = eye[0]; + dst[13] = eye[1]; + dst[14] = eye[2]; + dst[15] = 1; +} + +static long long randomSeed_; +static void resetPseudoRandom() +{ + randomSeed_ = 0; +} + +static double pseudoRandom() +{ + randomSeed_ = (134775813 * randomSeed_ + 1) % RANDOM_RANGE_; + return static_cast(randomSeed_) / static_cast(RANDOM_RANGE_); +} + +template +void translation(std::vector &dst, const std::vector &v) +{ + dst[0] = 1; + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + dst[4] = 0; + dst[5] = 1; + dst[6] = 0; + dst[7] = 0; + dst[8] = 0; + dst[9] = 0; + dst[10] = 1; + dst[11] = 0; + dst[12] = v[0]; + dst[13] = v[1]; + dst[14] = v[2]; + dst[15] = 1; +} + +template +void translate(std::vector &m, const std::vector &v) +{ + T v0 = v[0]; + T v1 = v[1]; + T v2 = v[2]; + T m00 = m[0]; + T m01 = m[1]; + T m02 = m[2]; + T m03 = m[3]; + T m10 = m[1 * 4 + 0]; + T m11 = m[1 * 4 + 1]; + T m12 = m[1 * 4 + 2]; + T m13 = m[1 * 4 + 3]; + T m20 = m[2 * 4 + 0]; + T m21 = m[2 * 4 + 1]; + T m22 = m[2 * 4 + 2]; + T m23 = m[2 * 4 + 3]; + T m30 = m[3 * 4 + 0]; + T m31 = m[3 * 4 + 1]; + T m32 = m[3 * 4 + 2]; + T m33 = m[3 * 4 + 3]; + + m[12] = m00 * v0 + m10 * v1 + m20 * v2 + m30; + m[13] = m01 * v0 + m11 * v1 + m21 * v2 + m31; + m[14] = m02 * v0 + m12 * v1 + m22 * v2 + m32; + m[15] = m03 * v0 + m13 * v1 + m23 * v2 + m33; +} + +float degToRad(float degrees) +{ + return static_cast(degrees * M_PI / 180.0); +} +} // namespace matrix +#endif diff --git a/src/aquarium-direct-map/Model.cpp b/src/aquarium-direct-map/Model.cpp index 873652a..d1dd79d 100644 --- a/src/aquarium-direct-map/Model.cpp +++ b/src/aquarium-direct-map/Model.cpp @@ -1,162 +1,159 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Model.cpp: Implements Model class. Apply program for its model. -// Update uniforms, textures and buffers for each frame. - -#include "Model.h" -#include "Globals.h" - -#include "common/AQUARIUM_ASSERT.h" - -Model::Model(Program *program_, - const std::unordered_map &arrays, - const std::unordered_map *textures) - : buffers(), - textures(textures), - program(program_), - mode(GL_TRIANGLES) -{ - setBuffers(arrays); - - program->setTextureUnits(*textures); -} - -Model::~Model() -{ - for (auto &buffer : buffers) - { - delete buffer.second; - buffer.second = nullptr; - } -} - -void Model::setBuffer(const std::string &name, const AttribBuffer &array) -{ - GLenum target = name == "indices" ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER; - - if (buffers.find(name) == buffers.end()) - { - buffers[name] = new Buffer(array, target); - } -} - -void Model::setBuffers(const std::unordered_map &arrays) -{ - for (auto iter = arrays.cbegin(); iter != arrays.cend(); ++iter) - { - setBuffer(iter->first, *iter->second); - } -} - -void Model::applyBuffers() const -{ - GLuint mVAO; - glGenVertexArrays(1, &mVAO); - glBindVertexArray(mVAO); - - // Apply array buffer and element buffer - for (const auto &buffer : buffers) - { - if (buffer.first == "indices") - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.second->getBuffer()); - } - else - { - glBindBuffer(GL_ARRAY_BUFFER, buffer.second->getBuffer()); - auto &attribLocs = program->getAttribLocs(); - if (attribLocs.find(buffer.first) == attribLocs.end()) - { - continue; - } - program->setAttrib(*buffer.second, buffer.first); - } - } -} - -void Model::applyTextures() const -{ - // Apply textures - for (auto it = textures->cbegin(); it != textures->cend(); ++it) - { - program->setUniform(it->first, *it->second); - } -} - -void Model::prepareForDraw(const GenericConst &constUniforms) -{ - program->use(); - - applyBuffers(); - applyTextures(); - - // Apply other uniforms - program->setUniform("ambient", *constUniforms.ambient); - program->setUniform("fogColor", *constUniforms.fogColor); - program->setUniform("fogMult", constUniforms.fogMult); - program->setUniform("fogOffset", constUniforms.fogOffset); - program->setUniform("fogPower", constUniforms.fogPower); - program->setUniform("lightColor", *constUniforms.lightColor); - program->setUniform("shininess", constUniforms.shininess); - program->setUniform("specular", *constUniforms.specular); - program->setUniform("specularFactor", constUniforms.specularFactor); - program->setUniform("lightWorldPos", *constUniforms.lightWorldPos); - program->setUniform("viewInverse", *constUniforms.viewInverse); - program->setUniform("viewProjection", *constUniforms.viewProjection); - - // The belowing uniforms belongs to innerConst - program->setUniform("eta", constUniforms.eta); - program->setUniform("refractionFudge", constUniforms.refractionFudge); - program->setUniform("tankColorFudge", constUniforms.tankColorFudge); -} - -void Model::prepareForDraw(const FishConst &fishConst) -{ - prepareForDraw(fishConst.genericConst); - - program->setUniform("fishBendAmount", fishConst.constUniforms.fishBendAmount); - program->setUniform("fishLength", fishConst.constUniforms.fishLength); - program->setUniform("fishWaveLength", fishConst.constUniforms.fishWaveLength); -} - -void Model::drawFunc() -{ - int totalComponents = 0; - - if (buffers.find("indices") != buffers.end()) - { - totalComponents = buffers["indices"]->getTotalComponents(); - GLenum type = buffers["indices"]->getType(); - glDrawElements(mode, totalComponents, type, 0); - } - else - { - totalComponents = buffers["positions"]->getNumElements(); - glDrawArrays(mode, 0, totalComponents); - } -} - -void Model::draw(const GenericPer &perUniforms) -{ - program->setUniform("world", *perUniforms.world); - program->setUniform("worldInverse", *perUniforms.worldInverse); - program->setUniform("worldInverseTranspose", *perUniforms.worldInverseTranspose); - program->setUniform("worldViewProjection", *perUniforms.worldViewProjection); - - drawFunc(); - ASSERT(glGetError() == GL_NO_ERROR); -} - -void Model::draw(const FishPer &fishPer) -{ - program->setUniform("worldPosition", fishPer.worldPosition); - program->setUniform("nextPosition", fishPer.nextPosition); - program->setUniform("scale", fishPer.scale); - program->setUniform("time", fishPer.time); - - drawFunc(); - ASSERT(glGetError() == GL_NO_ERROR); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Model.cpp: Implements Model class. Apply program for its model. +// Update uniforms, textures and buffers for each frame. + +#include "Model.h" +#include "Globals.h" + +#include "common/AQUARIUM_ASSERT.h" + +Model::Model(Program *program_, + const std::unordered_map &arrays, + const std::unordered_map *textures) + : buffers(), textures(textures), program(program_), mode(GL_TRIANGLES) +{ + setBuffers(arrays); + + program->setTextureUnits(*textures); +} + +Model::~Model() +{ + for (auto &buffer : buffers) + { + delete buffer.second; + buffer.second = nullptr; + } +} + +void Model::setBuffer(const std::string &name, const AttribBuffer &array) +{ + GLenum target = name == "indices" ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER; + + if (buffers.find(name) == buffers.end()) + { + buffers[name] = new Buffer(array, target); + } +} + +void Model::setBuffers(const std::unordered_map &arrays) +{ + for (auto iter = arrays.cbegin(); iter != arrays.cend(); ++iter) + { + setBuffer(iter->first, *iter->second); + } +} + +void Model::applyBuffers() const +{ + GLuint mVAO; + glGenVertexArrays(1, &mVAO); + glBindVertexArray(mVAO); + + // Apply array buffer and element buffer + for (const auto &buffer : buffers) + { + if (buffer.first == "indices") + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.second->getBuffer()); + } + else + { + glBindBuffer(GL_ARRAY_BUFFER, buffer.second->getBuffer()); + auto &attribLocs = program->getAttribLocs(); + if (attribLocs.find(buffer.first) == attribLocs.end()) + { + continue; + } + program->setAttrib(*buffer.second, buffer.first); + } + } +} + +void Model::applyTextures() const +{ + // Apply textures + for (auto it = textures->cbegin(); it != textures->cend(); ++it) + { + program->setUniform(it->first, *it->second); + } +} + +void Model::prepareForDraw(const GenericConst &constUniforms) +{ + program->use(); + + applyBuffers(); + applyTextures(); + + // Apply other uniforms + program->setUniform("ambient", *constUniforms.ambient); + program->setUniform("fogColor", *constUniforms.fogColor); + program->setUniform("fogMult", constUniforms.fogMult); + program->setUniform("fogOffset", constUniforms.fogOffset); + program->setUniform("fogPower", constUniforms.fogPower); + program->setUniform("lightColor", *constUniforms.lightColor); + program->setUniform("shininess", constUniforms.shininess); + program->setUniform("specular", *constUniforms.specular); + program->setUniform("specularFactor", constUniforms.specularFactor); + program->setUniform("lightWorldPos", *constUniforms.lightWorldPos); + program->setUniform("viewInverse", *constUniforms.viewInverse); + program->setUniform("viewProjection", *constUniforms.viewProjection); + + // The belowing uniforms belongs to innerConst + program->setUniform("eta", constUniforms.eta); + program->setUniform("refractionFudge", constUniforms.refractionFudge); + program->setUniform("tankColorFudge", constUniforms.tankColorFudge); +} + +void Model::prepareForDraw(const FishConst &fishConst) +{ + prepareForDraw(fishConst.genericConst); + + program->setUniform("fishBendAmount", fishConst.constUniforms.fishBendAmount); + program->setUniform("fishLength", fishConst.constUniforms.fishLength); + program->setUniform("fishWaveLength", fishConst.constUniforms.fishWaveLength); +} + +void Model::drawFunc() +{ + int totalComponents = 0; + + if (buffers.find("indices") != buffers.end()) + { + totalComponents = buffers["indices"]->getTotalComponents(); + GLenum type = buffers["indices"]->getType(); + glDrawElements(mode, totalComponents, type, 0); + } + else + { + totalComponents = buffers["positions"]->getNumElements(); + glDrawArrays(mode, 0, totalComponents); + } +} + +void Model::draw(const GenericPer &perUniforms) +{ + program->setUniform("world", *perUniforms.world); + program->setUniform("worldInverse", *perUniforms.worldInverse); + program->setUniform("worldInverseTranspose", *perUniforms.worldInverseTranspose); + program->setUniform("worldViewProjection", *perUniforms.worldViewProjection); + + drawFunc(); + ASSERT(glGetError() == GL_NO_ERROR); +} + +void Model::draw(const FishPer &fishPer) +{ + program->setUniform("worldPosition", fishPer.worldPosition); + program->setUniform("nextPosition", fishPer.nextPosition); + program->setUniform("scale", fishPer.scale); + program->setUniform("time", fishPer.time); + + drawFunc(); + ASSERT(glGetError() == GL_NO_ERROR); +} diff --git a/src/aquarium-direct-map/Model.h b/src/aquarium-direct-map/Model.h index 73fb968..6948a8f 100644 --- a/src/aquarium-direct-map/Model.h +++ b/src/aquarium-direct-map/Model.h @@ -1,53 +1,52 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Model.h: Define Class Model for all of the models. -// Contains programs, textures and buffers info of models. - -#ifndef MODEL_H -#define MODEL_H - -#include -#include - -#include "Buffer.h" -#include "Program.h" -#include "Texture.h" - -struct FishConst; -struct FishPer; -struct GenericConst; -struct GenericPer; - -class Model -{ -public: - Model() {} - ~Model(); - Model(Program *program, - const std::unordered_map &arrays, - const std::unordered_map *textures); - - void prepareForDraw(const GenericConst &constUniforms); - void prepareForDraw(const FishConst &fishConst); - void draw(const GenericPer &perUniforms); - void draw(const FishPer &fishPer); - -private: - void setBuffers(const std::unordered_map &arrays); - void setBuffer(const std::string &name, const AttribBuffer &array); - void applyBuffers() const; - void applyTextures() const; - void drawFunc(); - - std::unordered_map buffers; - const std::unordered_map *textures; - Program *program; - - GLenum mode; - -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Model.h: Define Class Model for all of the models. +// Contains programs, textures and buffers info of models. + +#ifndef MODEL_H +#define MODEL_H + +#include +#include + +#include "Buffer.h" +#include "Program.h" +#include "Texture.h" + +struct FishConst; +struct FishPer; +struct GenericConst; +struct GenericPer; + +class Model +{ + public: + Model() {} + ~Model(); + Model(Program *program, + const std::unordered_map &arrays, + const std::unordered_map *textures); + + void prepareForDraw(const GenericConst &constUniforms); + void prepareForDraw(const FishConst &fishConst); + void draw(const GenericPer &perUniforms); + void draw(const FishPer &fishPer); + + private: + void setBuffers(const std::unordered_map &arrays); + void setBuffer(const std::string &name, const AttribBuffer &array); + void applyBuffers() const; + void applyTextures() const; + void drawFunc(); + + std::unordered_map buffers; + const std::unordered_map *textures; + Program *program; + + GLenum mode; +}; + +#endif diff --git a/src/aquarium-direct-map/Program.cpp b/src/aquarium-direct-map/Program.cpp index 8778109..1fbb28a 100644 --- a/src/aquarium-direct-map/Program.cpp +++ b/src/aquarium-direct-map/Program.cpp @@ -1,277 +1,276 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Program.cpp: Implements Program class. -// Load shaders from folder shaders. -// Compiles OpenGL shaders and check if compiled success. -// Apply Buffers, Textures and Uniforms to program. - -#include -#include -#include -#include - -#include "Program.h" - -#include "common/AQUARIUM_ASSERT.h" - -Program::Program(const std::string &vId, const std::string &fId) - : program(0u), - attribLocs(), - uniforms(), - textureUnits() -{ - createProgramFromTags(vId, fId); - createSetters(); -} - -Program::~Program() -{ - glDeleteProgram(program); - - for (auto &uniform : uniforms) - { - if (uniform.second != nullptr) - { - delete uniform.second; - uniform.second = nullptr; - } - } -} - -void Program::createProgramFromTags(const std::string &vId, const std::string &fId) -{ - std::ifstream VertexShaderStream(vId, std::ios::in); - std::string VertexShaderCode((std::istreambuf_iterator(VertexShaderStream)), - std::istreambuf_iterator()); - VertexShaderStream.close(); - - std::ifstream FragmentShaderStream(fId, std::ios::in); - std::string FragmentShaderCode((std::istreambuf_iterator(FragmentShaderStream)), - std::istreambuf_iterator()); - FragmentShaderStream.close(); - - const std::string fogUniforms = - R"(uniform float fogPower; - uniform float fogMult; - uniform float fogOffset; - uniform vec4 fogColor;)"; - const std::string fogCode = - R"(outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), - clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0));)"; - -#ifdef __APPLE__ - VertexShaderCode = std::regex_replace(VertexShaderCode, std::regex(R"(#version 450 core)"), R"(#version 410 core)"); - FragmentShaderCode = std::regex_replace(FragmentShaderCode, std::regex(R"(#version 450 core)"), R"(#version 410 core)"); - #endif - - // enable fog, reflection and normalMaps - FragmentShaderCode = - std::regex_replace(FragmentShaderCode, std::regex(R"(// #fogUniforms)"), fogUniforms); - FragmentShaderCode = - std::regex_replace(FragmentShaderCode, std::regex(R"(// #fogCode)"), fogCode); - - FragmentShaderCode = - std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noReflection)"), ""); - FragmentShaderCode = - std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noNormalMap)"), ""); - - program = LoadProgram(VertexShaderCode, FragmentShaderCode); -} - -void Program::createSetters() -{ - int params; - GLsizei length, size; - GLenum type; - char name[100]; - - glUseProgram(program); - - // Look up attributes - glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, ¶ms); - for (int i = 0; i < params; ++i) - { - glGetActiveAttrib(program, i, 1024, &length, &size, &type, name); - GLint index = glGetAttribLocation(program, name); - ASSERT(index != -1); - std::string namestr(name); - namestr.erase(namestr.find_last_not_of(' ') + 1); - attribLocs[namestr] = index; - } - - // Look up uniforms - glGetProgramiv(program, GL_ACTIVE_UNIFORMS, ¶ms); - for (int i = 0; i < params; ++i) - { - glGetActiveUniform(program, i, 1024, &length, &size, &type, name); - std::string namestr(name); - GLint index = glGetUniformLocation(program, name); - ASSERT(index != -1); - uniforms[namestr] = new Uniform(namestr, type, length, size, index); - } -} - -void Program::setAttrib(const Buffer &buf, const std::string &name) -{ - glBindBuffer(GL_ARRAY_BUFFER, buf.getBuffer()); - GLuint index = attribLocs[name]; - glEnableVertexAttribArray(index); - glVertexAttribPointer(index, static_cast(buf.getNumComponents()), buf.getType(), - buf.getNormalize(), buf.getStride(), buf.getOffset()); - - ASSERT(glGetError() == GL_NO_ERROR); -} - -GLuint Program::LoadProgram(const std::string &VertexShaderCode, - const std::string &FragmentShaderCode) -{ - - // Create the shaders - GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); - GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); - - GLint Result = GL_FALSE; - int InfoLogLength; - - // Compile Vertex Shader - char const *VertexSourcePointer = VertexShaderCode.c_str(); - glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL); - glCompileShader(VertexShaderID); - - // Check Vertex Shader - glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); - if (!Result) - { - glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); - std::vector VertexShaderErrorMessage(InfoLogLength); - glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); - std::cout << stdout << &VertexShaderErrorMessage[0] << std::endl; - } - - // Compile Fragment Shader - char const *FragmentSourcePointer = FragmentShaderCode.c_str(); - glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL); - glCompileShader(FragmentShaderID); - - // Check Fragment Shader - glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); - if (!Result) - { - glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); - std::vector FragmentShaderErrorMessage(InfoLogLength); - glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); - std::cout << stdout << &FragmentShaderErrorMessage[0] << std::endl; - } - - // Link the program - GLuint ProgramID = glCreateProgram(); - glAttachShader(ProgramID, VertexShaderID); - glAttachShader(ProgramID, FragmentShaderID); - glLinkProgram(ProgramID); - - // Check the program - glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); - if (!Result) - { - glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); - std::vector ProgramErrorMessage(std::max(InfoLogLength, int(1))); - glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); - std::cout << stdout << &ProgramErrorMessage[0] << std::endl; - } - glDeleteShader(VertexShaderID); - glDeleteShader(FragmentShaderID); - - return ProgramID; -} - -void Program::use() -{ - glUseProgram(program); -} - -void Program::setUniform(const std::string &name, float v) -{ - if (uniforms.find(name) == uniforms.end()) - { - return; - } - Uniform *uniform = uniforms[name]; - GLint loc = uniform->getIndex(); - ASSERT(uniform->getType() == GL_FLOAT); - glUniform1f(loc, v); - - ASSERT(glGetError() == GL_NO_ERROR); -} - -void Program::setUniform(const std::string &name, const std::vector &v) -{ - if (uniforms.find(name) == uniforms.end()) - { - return; - } - - Uniform *uniform = uniforms[name]; - GLenum type = uniform->getType(); - GLint loc = uniform->getIndex(); - - switch (type) - { - case GL_FLOAT_VEC4: - { - glUniform4fv(loc, 1, v.data()); - break; - } - case GL_FLOAT_VEC3: - { - glUniform3fv(loc, 1, v.data()); - break; - } - case GL_FLOAT_VEC2: - { - glUniform2fv(loc, 1, v.data()); - break; - } - case GL_FLOAT_MAT4: - { - glUniformMatrix4fv(loc, 1, false, v.data()); - break; - } - default: - { - std::cout << "set uniform error" << std::endl; - } - } - - ASSERT(glGetError() == GL_NO_ERROR); -} - -void Program::setUniform(const std::string &name, const Texture &texture) -{ - if (uniforms.find(name) == uniforms.end()) - { - return; - } - - Uniform *uniform = uniforms[name]; - ASSERT(uniform->getType() == GL_SAMPLER_2D || uniform->getType() == GL_SAMPLER_CUBE); - GLint loc = uniform->getIndex(); - - glUniform1i(loc, textureUnits[name]); - glActiveTexture(GL_TEXTURE0 + textureUnits[name]); - ASSERT(textureUnits[name] < 16); - glBindTexture(texture.getTarget(), texture.getTexture()); - - ASSERT(glGetError() == GL_NO_ERROR); -} - -void Program::setTextureUnits(const std::unordered_map &textureMap) -{ - int unit = 0; - for (auto &texture : textureMap) - { - textureUnits[texture.first] = unit++; - } -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Program.cpp: Implements Program class. +// Load shaders from folder shaders. +// Compiles OpenGL shaders and check if compiled success. +// Apply Buffers, Textures and Uniforms to program. + +#include +#include +#include +#include + +#include "Program.h" + +#include "common/AQUARIUM_ASSERT.h" + +Program::Program(const std::string &vId, const std::string &fId) + : program(0u), attribLocs(), uniforms(), textureUnits() +{ + createProgramFromTags(vId, fId); + createSetters(); +} + +Program::~Program() +{ + glDeleteProgram(program); + + for (auto &uniform : uniforms) + { + if (uniform.second != nullptr) + { + delete uniform.second; + uniform.second = nullptr; + } + } +} + +void Program::createProgramFromTags(const std::string &vId, const std::string &fId) +{ + std::ifstream VertexShaderStream(vId, std::ios::in); + std::string VertexShaderCode((std::istreambuf_iterator(VertexShaderStream)), + std::istreambuf_iterator()); + VertexShaderStream.close(); + + std::ifstream FragmentShaderStream(fId, std::ios::in); + std::string FragmentShaderCode((std::istreambuf_iterator(FragmentShaderStream)), + std::istreambuf_iterator()); + FragmentShaderStream.close(); + + const std::string fogUniforms = + R"(uniform float fogPower; + uniform float fogMult; + uniform float fogOffset; + uniform vec4 fogColor;)"; + const std::string fogCode = + R"(outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0));)"; + +#ifdef __APPLE__ + VertexShaderCode = std::regex_replace(VertexShaderCode, std::regex(R"(#version 450 core)"), + R"(#version 410 core)"); + FragmentShaderCode = std::regex_replace(FragmentShaderCode, std::regex(R"(#version 450 core)"), + R"(#version 410 core)"); +#endif + + // enable fog, reflection and normalMaps + FragmentShaderCode = + std::regex_replace(FragmentShaderCode, std::regex(R"(// #fogUniforms)"), fogUniforms); + FragmentShaderCode = + std::regex_replace(FragmentShaderCode, std::regex(R"(// #fogCode)"), fogCode); + + FragmentShaderCode = + std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noReflection)"), ""); + FragmentShaderCode = + std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noNormalMap)"), ""); + + program = LoadProgram(VertexShaderCode, FragmentShaderCode); +} + +void Program::createSetters() +{ + int params; + GLsizei length, size; + GLenum type; + char name[100]; + + glUseProgram(program); + + // Look up attributes + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, ¶ms); + for (int i = 0; i < params; ++i) + { + glGetActiveAttrib(program, i, 1024, &length, &size, &type, name); + GLint index = glGetAttribLocation(program, name); + ASSERT(index != -1); + std::string namestr(name); + namestr.erase(namestr.find_last_not_of(' ') + 1); + attribLocs[namestr] = index; + } + + // Look up uniforms + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, ¶ms); + for (int i = 0; i < params; ++i) + { + glGetActiveUniform(program, i, 1024, &length, &size, &type, name); + std::string namestr(name); + GLint index = glGetUniformLocation(program, name); + ASSERT(index != -1); + uniforms[namestr] = new Uniform(namestr, type, length, size, index); + } +} + +void Program::setAttrib(const Buffer &buf, const std::string &name) +{ + glBindBuffer(GL_ARRAY_BUFFER, buf.getBuffer()); + GLuint index = attribLocs[name]; + glEnableVertexAttribArray(index); + glVertexAttribPointer(index, static_cast(buf.getNumComponents()), buf.getType(), + buf.getNormalize(), buf.getStride(), buf.getOffset()); + + ASSERT(glGetError() == GL_NO_ERROR); +} + +GLuint Program::LoadProgram(const std::string &VertexShaderCode, + const std::string &FragmentShaderCode) +{ + + // Create the shaders + GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + GLint Result = GL_FALSE; + int InfoLogLength; + + // Compile Vertex Shader + char const *VertexSourcePointer = VertexShaderCode.c_str(); + glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL); + glCompileShader(VertexShaderID); + + // Check Vertex Shader + glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + if (!Result) + { + glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + std::vector VertexShaderErrorMessage(InfoLogLength); + glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); + std::cout << stdout << &VertexShaderErrorMessage[0] << std::endl; + } + + // Compile Fragment Shader + char const *FragmentSourcePointer = FragmentShaderCode.c_str(); + glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL); + glCompileShader(FragmentShaderID); + + // Check Fragment Shader + glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + if (!Result) + { + glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + std::vector FragmentShaderErrorMessage(InfoLogLength); + glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); + std::cout << stdout << &FragmentShaderErrorMessage[0] << std::endl; + } + + // Link the program + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + // Check the program + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + if (!Result) + { + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + std::vector ProgramErrorMessage(std::max(InfoLogLength, int(1))); + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); + std::cout << stdout << &ProgramErrorMessage[0] << std::endl; + } + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} + +void Program::use() +{ + glUseProgram(program); +} + +void Program::setUniform(const std::string &name, float v) +{ + if (uniforms.find(name) == uniforms.end()) + { + return; + } + Uniform *uniform = uniforms[name]; + GLint loc = uniform->getIndex(); + ASSERT(uniform->getType() == GL_FLOAT); + glUniform1f(loc, v); + + ASSERT(glGetError() == GL_NO_ERROR); +} + +void Program::setUniform(const std::string &name, const std::vector &v) +{ + if (uniforms.find(name) == uniforms.end()) + { + return; + } + + Uniform *uniform = uniforms[name]; + GLenum type = uniform->getType(); + GLint loc = uniform->getIndex(); + + switch (type) + { + case GL_FLOAT_VEC4: + { + glUniform4fv(loc, 1, v.data()); + break; + } + case GL_FLOAT_VEC3: + { + glUniform3fv(loc, 1, v.data()); + break; + } + case GL_FLOAT_VEC2: + { + glUniform2fv(loc, 1, v.data()); + break; + } + case GL_FLOAT_MAT4: + { + glUniformMatrix4fv(loc, 1, false, v.data()); + break; + } + default: + { + std::cout << "set uniform error" << std::endl; + } + } + + ASSERT(glGetError() == GL_NO_ERROR); +} + +void Program::setUniform(const std::string &name, const Texture &texture) +{ + if (uniforms.find(name) == uniforms.end()) + { + return; + } + + Uniform *uniform = uniforms[name]; + ASSERT(uniform->getType() == GL_SAMPLER_2D || uniform->getType() == GL_SAMPLER_CUBE); + GLint loc = uniform->getIndex(); + + glUniform1i(loc, textureUnits[name]); + glActiveTexture(GL_TEXTURE0 + textureUnits[name]); + ASSERT(textureUnits[name] < 16); + glBindTexture(texture.getTarget(), texture.getTexture()); + + ASSERT(glGetError() == GL_NO_ERROR); +} + +void Program::setTextureUnits(const std::unordered_map &textureMap) +{ + int unit = 0; + for (auto &texture : textureMap) + { + textureUnits[texture.first] = unit++; + } +} diff --git a/src/aquarium-direct-map/Program.h b/src/aquarium-direct-map/Program.h index c5d4fba..499402e 100644 --- a/src/aquarium-direct-map/Program.h +++ b/src/aquarium-direct-map/Program.h @@ -1,50 +1,50 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Program.h: Defines Program Class. - -#ifndef PROGRAM_H -#define PROGRAM_H - -#include -#include -#include - -#include "Buffer.h" -#include "Texture.h" -#include "Uniform.h" - -class Program -{ -public: - Program() {} - Program(const std::string &vId, const std::string &fId); - ~Program(); - void use(); - void setUniform(const std::string &name, float v); - void setUniform(const std::string &name, const std::vector &v); - void setUniform(const std::string &name, const Texture &texture); - - const std::unordered_map &getAttribLocs() const { return attribLocs; } - const std::unordered_map &getUniforms() const { return uniforms; } - - void setTextureUnits(const std::unordered_map &textureMap); - void setAttrib(const Buffer &buf, const std::string &name); - - GLuint getProgramId() { return program; } - -private: - void createProgramFromTags(const std::string &vId, const std::string &fId); - GLuint LoadProgram(const std::string &vertexShader, const std::string &fragmentShader); - void createSetters(); - - GLuint program; - std::unordered_map attribLocs; // name, location - std::unordered_map uniforms; // name, type - - std::unordered_map textureUnits; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Program.h: Defines Program Class. + +#ifndef PROGRAM_H +#define PROGRAM_H + +#include +#include +#include + +#include "Buffer.h" +#include "Texture.h" +#include "Uniform.h" + +class Program +{ + public: + Program() {} + Program(const std::string &vId, const std::string &fId); + ~Program(); + void use(); + void setUniform(const std::string &name, float v); + void setUniform(const std::string &name, const std::vector &v); + void setUniform(const std::string &name, const Texture &texture); + + const std::unordered_map &getAttribLocs() const { return attribLocs; } + const std::unordered_map &getUniforms() const { return uniforms; } + + void setTextureUnits(const std::unordered_map &textureMap); + void setAttrib(const Buffer &buf, const std::string &name); + + GLuint getProgramId() { return program; } + + private: + void createProgramFromTags(const std::string &vId, const std::string &fId); + GLuint LoadProgram(const std::string &vertexShader, const std::string &fragmentShader); + void createSetters(); + + GLuint program; + std::unordered_map attribLocs; // name, location + std::unordered_map uniforms; // name, type + + std::unordered_map textureUnits; +}; + +#endif diff --git a/src/aquarium-direct-map/Scene.cpp b/src/aquarium-direct-map/Scene.cpp index a265979..e3ff238 100644 --- a/src/aquarium-direct-map/Scene.cpp +++ b/src/aquarium-direct-map/Scene.cpp @@ -1,222 +1,222 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Scene.cpp: Implements Scene. -// Load resources including images, vertexes and programs, then group them into models. - -#include -#include -#include -#include - -#include "Globals.h" -#include "Model.h" -#include "Program.h" -#include "Scene.h" -#include "common/AQUARIUM_ASSERT.h" - -#include "rapidjson/document.h" -#include "rapidjson/filereadstream.h" -#include "rapidjson/istreamwrapper.h" -#include "rapidjson/stringbuffer.h" - -std::vector g_skyBoxUrls = { - "GlobeOuter_EM_positive_x.jpg", "GlobeOuter_EM_negative_x.jpg", "GlobeOuter_EM_positive_y.jpg", - "GlobeOuter_EM_negative_y.jpg", "GlobeOuter_EM_positive_z.jpg", "GlobeOuter_EM_negative_z.jpg"}; - -Scene::Scene(const std::string opt_programIds[2]) : url(), models(), textureMap(), arrayMap() -{ - programIds[0] = opt_programIds[0]; - programIds[1] = opt_programIds[1]; -} - -Scene::~Scene() -{ - for (auto &program : g_programMap) - { - if (program.second != nullptr) - { - delete program.second; - program.second = nullptr; - } - } - - for (auto &texture : g_textureMap) - { - if (texture.second != nullptr) - { - delete texture.second; - texture.second = nullptr; - } - } - - for (auto &arr : arrayMap) - { - if (arr.second != nullptr) - { - delete arr.second; - arr.second = nullptr; - } - } - - for (auto &model : models) - { - if (model != nullptr) - { - delete model; - model = nullptr; - } - } -} - -void Scene::setupSkybox(const std::string &path) -{ - for (auto &v : g_skyBoxUrls) - { - std::ostringstream url; - url << path << resourceFolder << slash << v; - - v = url.str(); - } -} - -void Scene::load(const std::string &path, const std::string &name) -{ - std::ostringstream oss; - oss << path << resourceFolder << slash; - std::string imagePath = oss.str(); - oss << name << ".js"; - std::string modelPath = oss.str(); - oss.str(""); - oss << path << shaderFolder << slash << shaderVersion << slash; - std::string programPath = oss.str(); - - this->url = modelPath; - this->loaded = true; - - std::ifstream PlacementStream(modelPath, std::ios::in); - rapidjson::IStreamWrapper is(PlacementStream); - rapidjson::Document document; - document.ParseStream(is); - ASSERT(document.IsObject()); - - for (auto &value : document["models"].GetArray()) - { - // set up textures - const rapidjson::Value &textures = value["textures"]; - for (rapidjson::Value::ConstMemberIterator itr = textures.MemberBegin(); - itr != textures.MemberEnd(); ++itr) - { - std::string name = itr->name.GetString(); - std::string image = itr->value.GetString(); - - if (g_textureMap.find(image) == g_textureMap.end()) - { - g_textureMap[image] = new Texture(imagePath + image, true); - } - - textureMap[name] = g_textureMap[image]; - } - - // set up vertices - const rapidjson::Value &arrays = value["fields"]; - for (rapidjson::Value::ConstMemberIterator itr = arrays.MemberBegin(); - itr != arrays.MemberEnd(); ++itr) - { - std::string name = itr->name.GetString(); - int numComponents = itr->value["numComponents"].GetInt(); - std::string type = itr->value["type"].GetString(); - - if (name == "indices") - { - std::vector vec; - for (auto &data : itr->value["data"].GetArray()) - { - vec.push_back(data.GetInt()); - } - arrayMap[name] = - new AttribBuffer(numComponents, vec, static_cast(vec.size()), type); - } - else - { - std::vector vec; - for (auto &data : itr->value["data"].GetArray()) - { - vec.push_back(data.GetFloat()); - } - arrayMap[name] = - new AttribBuffer(numComponents, vec, static_cast(vec.size()), type); - } - } - - // setup program - // There are 3 programs - // DM - // DM+NM - // DM+NM+RM - std::string type; - std::string vsId; - std::string fsId; - - if (textureMap.find("diffuse") == textureMap.end()) - { - std::cout << "missing diffuse texture for" << url.c_str() << std::endl; - } - - if (g_textureMap.find("skybox") == g_textureMap.end()) - { - setupSkybox(path); - g_textureMap["skybox"] = new Texture(g_skyBoxUrls); - } - - if (programIds[0] != "" && programIds[1] != "") - { - type = "custom"; - vsId = programIds[0]; - fsId = programIds[1]; - - textureMap["skybox"] = g_textureMap["skybox"]; - } - else if (textureMap.find("reflectionMap") != textureMap.end()) - { - if (textureMap.find("normalMap") != textureMap.end()) - { - std::cout << "missing normal Map for" << url.c_str() << std::endl; - } - - type = "reflection"; - vsId = "reflectionMapVertexShader"; - fsId = "reflectionMapFragmentShader"; - - textureMap["skybox"] = g_textureMap["skybox"]; - } - else if (textureMap.find("normalMap") != textureMap.end()) - { - type = "normalMap"; - vsId = "normalMapVertexShader"; - fsId = "normalMapFragmentShader"; - } - else - { - type = "diffuse"; - vsId = "diffuseVertexShader"; - fsId = "diffuseFragmentShader"; - } - - Program *program; - if (g_programMap.find(vsId + fsId) != g_programMap.end()) - { - program = g_programMap[vsId + fsId]; - } - else - { - program = new Program(programPath + vsId, programPath + fsId); - g_programMap[vsId + fsId] = program; - } - - Model *model = new Model(program, arrayMap, &textureMap); - models.push_back(model); - } -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Scene.cpp: Implements Scene. +// Load resources including images, vertexes and programs, then group them into models. + +#include +#include +#include +#include + +#include "Globals.h" +#include "Model.h" +#include "Program.h" +#include "Scene.h" +#include "common/AQUARIUM_ASSERT.h" + +#include "rapidjson/document.h" +#include "rapidjson/filereadstream.h" +#include "rapidjson/istreamwrapper.h" +#include "rapidjson/stringbuffer.h" + +std::vector g_skyBoxUrls = { + "GlobeOuter_EM_positive_x.jpg", "GlobeOuter_EM_negative_x.jpg", "GlobeOuter_EM_positive_y.jpg", + "GlobeOuter_EM_negative_y.jpg", "GlobeOuter_EM_positive_z.jpg", "GlobeOuter_EM_negative_z.jpg"}; + +Scene::Scene(const std::string opt_programIds[2]) : url(), models(), textureMap(), arrayMap() +{ + programIds[0] = opt_programIds[0]; + programIds[1] = opt_programIds[1]; +} + +Scene::~Scene() +{ + for (auto &program : g_programMap) + { + if (program.second != nullptr) + { + delete program.second; + program.second = nullptr; + } + } + + for (auto &texture : g_textureMap) + { + if (texture.second != nullptr) + { + delete texture.second; + texture.second = nullptr; + } + } + + for (auto &arr : arrayMap) + { + if (arr.second != nullptr) + { + delete arr.second; + arr.second = nullptr; + } + } + + for (auto &model : models) + { + if (model != nullptr) + { + delete model; + model = nullptr; + } + } +} + +void Scene::setupSkybox(const std::string &path) +{ + for (auto &v : g_skyBoxUrls) + { + std::ostringstream url; + url << path << resourceFolder << slash << v; + + v = url.str(); + } +} + +void Scene::load(const std::string &path, const std::string &name) +{ + std::ostringstream oss; + oss << path << resourceFolder << slash; + std::string imagePath = oss.str(); + oss << name << ".js"; + std::string modelPath = oss.str(); + oss.str(""); + oss << path << shaderFolder << slash << shaderVersion << slash; + std::string programPath = oss.str(); + + this->url = modelPath; + this->loaded = true; + + std::ifstream PlacementStream(modelPath, std::ios::in); + rapidjson::IStreamWrapper is(PlacementStream); + rapidjson::Document document; + document.ParseStream(is); + ASSERT(document.IsObject()); + + for (auto &value : document["models"].GetArray()) + { + // set up textures + const rapidjson::Value &textures = value["textures"]; + for (rapidjson::Value::ConstMemberIterator itr = textures.MemberBegin(); + itr != textures.MemberEnd(); ++itr) + { + std::string name = itr->name.GetString(); + std::string image = itr->value.GetString(); + + if (g_textureMap.find(image) == g_textureMap.end()) + { + g_textureMap[image] = new Texture(imagePath + image, true); + } + + textureMap[name] = g_textureMap[image]; + } + + // set up vertices + const rapidjson::Value &arrays = value["fields"]; + for (rapidjson::Value::ConstMemberIterator itr = arrays.MemberBegin(); + itr != arrays.MemberEnd(); ++itr) + { + std::string name = itr->name.GetString(); + int numComponents = itr->value["numComponents"].GetInt(); + std::string type = itr->value["type"].GetString(); + + if (name == "indices") + { + std::vector vec; + for (auto &data : itr->value["data"].GetArray()) + { + vec.push_back(data.GetInt()); + } + arrayMap[name] = + new AttribBuffer(numComponents, vec, static_cast(vec.size()), type); + } + else + { + std::vector vec; + for (auto &data : itr->value["data"].GetArray()) + { + vec.push_back(data.GetFloat()); + } + arrayMap[name] = + new AttribBuffer(numComponents, vec, static_cast(vec.size()), type); + } + } + + // setup program + // There are 3 programs + // DM + // DM+NM + // DM+NM+RM + std::string type; + std::string vsId; + std::string fsId; + + if (textureMap.find("diffuse") == textureMap.end()) + { + std::cout << "missing diffuse texture for" << url.c_str() << std::endl; + } + + if (g_textureMap.find("skybox") == g_textureMap.end()) + { + setupSkybox(path); + g_textureMap["skybox"] = new Texture(g_skyBoxUrls); + } + + if (programIds[0] != "" && programIds[1] != "") + { + type = "custom"; + vsId = programIds[0]; + fsId = programIds[1]; + + textureMap["skybox"] = g_textureMap["skybox"]; + } + else if (textureMap.find("reflectionMap") != textureMap.end()) + { + if (textureMap.find("normalMap") != textureMap.end()) + { + std::cout << "missing normal Map for" << url.c_str() << std::endl; + } + + type = "reflection"; + vsId = "reflectionMapVertexShader"; + fsId = "reflectionMapFragmentShader"; + + textureMap["skybox"] = g_textureMap["skybox"]; + } + else if (textureMap.find("normalMap") != textureMap.end()) + { + type = "normalMap"; + vsId = "normalMapVertexShader"; + fsId = "normalMapFragmentShader"; + } + else + { + type = "diffuse"; + vsId = "diffuseVertexShader"; + fsId = "diffuseFragmentShader"; + } + + Program *program; + if (g_programMap.find(vsId + fsId) != g_programMap.end()) + { + program = g_programMap[vsId + fsId]; + } + else + { + program = new Program(programPath + vsId, programPath + fsId); + g_programMap[vsId + fsId] = program; + } + + Model *model = new Model(program, arrayMap, &textureMap); + models.push_back(model); + } +} diff --git a/src/aquarium-direct-map/Scene.h b/src/aquarium-direct-map/Scene.h index 30e5317..eaf496c 100644 --- a/src/aquarium-direct-map/Scene.h +++ b/src/aquarium-direct-map/Scene.h @@ -1,41 +1,42 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Scene.h: Defines Scene class. - -#ifndef SCENE_H -#define SCENE_H - -#include -#include -#include - -#include "AttribBuffer.h" -#include "Texture.h" - -class Model; - -class Scene { -public: - Scene() {} - ~Scene(); - Scene(const std::string opt_programIds[2]); - - void load(const std::string &path, const std::string &name); - const std::vector &getModels() const { return models; } - - bool loaded; - -private: - void setupSkybox(const std::string &path); - - std::string programIds[2]; - std::string url; - std::vector models; - std::unordered_map textureMap; - std::unordered_map arrayMap; -}; - -#endif // !SCENE_H +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Scene.h: Defines Scene class. + +#ifndef SCENE_H +#define SCENE_H + +#include +#include +#include + +#include "AttribBuffer.h" +#include "Texture.h" + +class Model; + +class Scene +{ + public: + Scene() {} + ~Scene(); + Scene(const std::string opt_programIds[2]); + + void load(const std::string &path, const std::string &name); + const std::vector &getModels() const { return models; } + + bool loaded; + + private: + void setupSkybox(const std::string &path); + + std::string programIds[2]; + std::string url; + std::vector models; + std::unordered_map textureMap; + std::unordered_map arrayMap; +}; + +#endif // !SCENE_H diff --git a/src/aquarium-direct-map/Texture.cpp b/src/aquarium-direct-map/Texture.cpp index 3d008c0..cadb125 100644 --- a/src/aquarium-direct-map/Texture.cpp +++ b/src/aquarium-direct-map/Texture.cpp @@ -1,128 +1,123 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Texture.cpp: Load images by stb lib, flip the texture if needed. -// Create texture2D or textureCubeMap, then upload the texture to gpu. - -#include - -#include "Texture.h" - -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - -#include "common/AQUARIUM_ASSERT.h" - -// initializs texture 2d -Texture::Texture(const std::string &url, bool flip) - : urls(), - target(GL_TEXTURE_2D), - texture(0u), - params(), - width(0), - height(0), - flip(flip) -{ - std::string urlpath = url; - urls.push_back(urlpath); - glGenTextures(1, &texture); - - uploadTextures(); -} - -// initializs cube map -Texture::Texture(const std::vector &urls) : urls(urls) -{ - ASSERT(urls.size() == 6); - target = GL_TEXTURE_CUBE_MAP; - glGenTextures(1, &texture); - - uploadTextures(); -} - -Texture::~Texture() -{ - glDeleteTextures(1, &texture); -} - -void Texture::setParameter(GLenum pname, GLint param) -{ - params[pname] = param; - - glTexParameteri(target, pname, param); -} - -bool Texture::isPowerOf2(int value) -{ - return (value & (value - 1)) == 0; -} - -// Force loading 3 channel images to 4 channel by stb becasue Dawn doesn't support 3 channel -// formats currently. The group is discussing on whether webgpu shoud support 3 channel format. -// https://github.com/gpuweb/gpuweb/issues/66#issuecomment-410021505 -bool Texture::loadImageBySTB(const std::string &filename, uint8_t **pixels) -{ - stbi_set_flip_vertically_on_load(flip); - *pixels = stbi_load(filename.c_str(), &width, &height, 0, 4); - if (*pixels == 0) - { - std::cout << stderr << "Couldn't open input file" << filename << std::endl; - return false; - } - return true; -} - -// Free image data after upload to gpu -void Texture::DestroyImageData(uint8_t *pixels) -{ - free(pixels); - pixels = nullptr; -} - -void Texture::uploadTextures() -{ - glBindTexture(target, texture); - unsigned char *pixels = nullptr; - - // create Texture2D - if (target == GL_TEXTURE_2D) - { - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - loadImageBySTB(urls[0], &pixels); - glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - DestroyImageData(pixels); - ASSERT(glGetError() == GL_NO_ERROR); - - if (isPowerOf2(width) && isPowerOf2(height)) - { - setParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glGenerateMipmap(target); - } - else - { - setParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - setParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - setParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - } - // create TextureCubeMap - else if (target == GL_TEXTURE_CUBE_MAP) - { - for (unsigned int i = 0; i < 6; i++) - { - loadImageBySTB(urls[i], &pixels); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - DestroyImageData(pixels); - } - ASSERT(glGetError() == GL_NO_ERROR); - - setParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); - setParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); - setParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - setParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - ASSERT(glGetError() == GL_NO_ERROR); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Texture.cpp: Load images by stb lib, flip the texture if needed. +// Create texture2D or textureCubeMap, then upload the texture to gpu. + +#include + +#include "Texture.h" + +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +#include "common/AQUARIUM_ASSERT.h" + +// initializs texture 2d +Texture::Texture(const std::string &url, bool flip) + : urls(), target(GL_TEXTURE_2D), texture(0u), params(), width(0), height(0), flip(flip) +{ + std::string urlpath = url; + urls.push_back(urlpath); + glGenTextures(1, &texture); + + uploadTextures(); +} + +// initializs cube map +Texture::Texture(const std::vector &urls) : urls(urls) +{ + ASSERT(urls.size() == 6); + target = GL_TEXTURE_CUBE_MAP; + glGenTextures(1, &texture); + + uploadTextures(); +} + +Texture::~Texture() +{ + glDeleteTextures(1, &texture); +} + +void Texture::setParameter(GLenum pname, GLint param) +{ + params[pname] = param; + + glTexParameteri(target, pname, param); +} + +bool Texture::isPowerOf2(int value) +{ + return (value & (value - 1)) == 0; +} + +// Force loading 3 channel images to 4 channel by stb becasue Dawn doesn't support 3 channel +// formats currently. The group is discussing on whether webgpu shoud support 3 channel format. +// https://github.com/gpuweb/gpuweb/issues/66#issuecomment-410021505 +bool Texture::loadImageBySTB(const std::string &filename, uint8_t **pixels) +{ + stbi_set_flip_vertically_on_load(flip); + *pixels = stbi_load(filename.c_str(), &width, &height, 0, 4); + if (*pixels == 0) + { + std::cout << stderr << "Couldn't open input file" << filename << std::endl; + return false; + } + return true; +} + +// Free image data after upload to gpu +void Texture::DestroyImageData(uint8_t *pixels) +{ + free(pixels); + pixels = nullptr; +} + +void Texture::uploadTextures() +{ + glBindTexture(target, texture); + unsigned char *pixels = nullptr; + + // create Texture2D + if (target == GL_TEXTURE_2D) + { + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + loadImageBySTB(urls[0], &pixels); + glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + DestroyImageData(pixels); + ASSERT(glGetError() == GL_NO_ERROR); + + if (isPowerOf2(width) && isPowerOf2(height)) + { + setParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glGenerateMipmap(target); + } + else + { + setParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + setParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + setParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + } + // create TextureCubeMap + else if (target == GL_TEXTURE_CUBE_MAP) + { + for (unsigned int i = 0; i < 6; i++) + { + loadImageBySTB(urls[i], &pixels); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, pixels); + DestroyImageData(pixels); + } + ASSERT(glGetError() == GL_NO_ERROR); + + setParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); + setParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); + setParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + setParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + ASSERT(glGetError() == GL_NO_ERROR); +} diff --git a/src/aquarium-direct-map/Texture.h b/src/aquarium-direct-map/Texture.h index 166a21e..5421596 100644 --- a/src/aquarium-direct-map/Texture.h +++ b/src/aquarium-direct-map/Texture.h @@ -1,45 +1,45 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Texture.h: Define Texture class. - -#ifndef TEXTURE_H -#define TEXTURE_H - -#include -#include -#include - -#include "glad/glad.h" - -class Texture -{ -public: - Texture() {} - ~Texture(); - Texture(const std::string &url, bool flip); - Texture(const std::vector &urls); - - GLuint getTexture() const { return texture; } - GLenum getTarget() const { return target; } - void setTexture(GLuint texId) { texture = texId; } - bool loadImageBySTB(const std::string &filename, uint8_t **pixels); - void DestroyImageData(uint8_t *pixels); - -private: - void setParameter(GLenum, GLint); - void uploadTextures(); - bool isPowerOf2(int value); - - std::vector urls; - GLenum target; - GLuint texture; - std::unordered_map params; - int width; - int height; - bool flip; -}; - -#endif // !TEXTURE_H +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Texture.h: Define Texture class. + +#ifndef TEXTURE_H +#define TEXTURE_H + +#include +#include +#include + +#include "glad/glad.h" + +class Texture +{ + public: + Texture() {} + ~Texture(); + Texture(const std::string &url, bool flip); + Texture(const std::vector &urls); + + GLuint getTexture() const { return texture; } + GLenum getTarget() const { return target; } + void setTexture(GLuint texId) { texture = texId; } + bool loadImageBySTB(const std::string &filename, uint8_t **pixels); + void DestroyImageData(uint8_t *pixels); + + private: + void setParameter(GLenum, GLint); + void uploadTextures(); + bool isPowerOf2(int value); + + std::vector urls; + GLenum target; + GLuint texture; + std::unordered_map params; + int width; + int height; + bool flip; +}; + +#endif // !TEXTURE_H diff --git a/src/aquarium-direct-map/Uniform.cpp b/src/aquarium-direct-map/Uniform.cpp index 3a2895b..efaea47 100644 --- a/src/aquarium-direct-map/Uniform.cpp +++ b/src/aquarium-direct-map/Uniform.cpp @@ -1,15 +1,11 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -#include "Uniform.h" - -Uniform::Uniform(const std::string &name, GLenum type, int length, int size, GLint index) - : name(name), - type(type), - length(length), - size(size), - index(index) -{ -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +#include "Uniform.h" + +Uniform::Uniform(const std::string &name, GLenum type, int length, int size, GLint index) + : name(name), type(type), length(length), size(size), index(index) +{ +} diff --git a/src/aquarium-direct-map/Uniform.h b/src/aquarium-direct-map/Uniform.h index eed3672..5192d35 100644 --- a/src/aquarium-direct-map/Uniform.h +++ b/src/aquarium-direct-map/Uniform.h @@ -1,34 +1,34 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Uniform.h: Define Uniform Class. Store uniform infos queried from shaders. - -#ifndef UNIFORM_H -#define UNIFORM_H - -#include - -#include "glad/glad.h" - -class Uniform -{ -public: - Uniform(){} - Uniform(const std::string &name, GLenum type, int length, int size, GLint index); - - std::string getName() const { return name; } - GLenum getType() const { return type; } - GLsizei getLength() const { return length; } - GLsizei getSize() const { return size; } - GLint getIndex() const { return index; } - -private: - std::string name; - GLenum type; - GLsizei length, size; - GLint index; -}; - -#endif // UNIFORM_H +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Uniform.h: Define Uniform Class. Store uniform infos queried from shaders. + +#ifndef UNIFORM_H +#define UNIFORM_H + +#include + +#include "glad/glad.h" + +class Uniform +{ + public: + Uniform() {} + Uniform(const std::string &name, GLenum type, int length, int size, GLint index); + + std::string getName() const { return name; } + GLenum getType() const { return type; } + GLsizei getLength() const { return length; } + GLsizei getSize() const { return size; } + GLint getIndex() const { return index; } + + private: + std::string name; + GLenum type; + GLsizei length, size; + GLint index; +}; + +#endif // UNIFORM_H diff --git a/src/aquarium-optimized/Aquarium.cpp b/src/aquarium-optimized/Aquarium.cpp index 763ba3a..c22ef8c 100644 --- a/src/aquarium-optimized/Aquarium.cpp +++ b/src/aquarium-optimized/Aquarium.cpp @@ -1,792 +1,792 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Aquarium.cpp: Create context for specific graphics API. -// Data preparation, load vertex and index buffer, images and shaders. -// Implements logic of rendering background, fishes, seaweeds and -// other models. Calculate fish count for each type of fish. -// Update uniforms for each frame. - -#include -#include -#include -#include - -#include "Aquarium.h" -#include "ContextFactory.h" -#include "FishModel.h" -#include "Matrix.h" -#include "Program.h" -#include "SeaweedModel.h" -#include "Texture.h" - -#include "common/AQUARIUM_ASSERT.h" -#include "include/CmdArgsHelper.h" -#include "opengl/ContextGL.h" - -#include "rapidjson/document.h" -#include "rapidjson/istreamwrapper.h" -#include "rapidjson/stringbuffer.h" -#include "rapidjson/writer.h" - -Aquarium::Aquarium() - : mModelEnumMap(), - mTextureMap(), - mProgramMap(), - mAquariumModels(), - mContext(nullptr), - mFpsTimer(), - mFishCount(1), - mBackendType(BACKENDTYPE::BACKENDTYPELAST), - mFactory(nullptr) -{ - g.then = 0.0f; - g.mclock = 0.0f; - g.eyeClock = 0.0f; - - lightUniforms.lightColor[0] = 1.0f; - lightUniforms.lightColor[1] = 1.0f; - lightUniforms.lightColor[2] = 1.0f; - lightUniforms.lightColor[3] = 1.0f; - - lightUniforms.specular[0] = 1.0f; - lightUniforms.specular[1] = 1.0f; - lightUniforms.specular[2] = 1.0f; - lightUniforms.specular[3] = 1.0f; - - fogUniforms.fogColor[0] = g_fogRed; - fogUniforms.fogColor[1] = g_fogGreen; - fogUniforms.fogColor[2] = g_fogBlue; - fogUniforms.fogColor[3] = 1.0f; - - fogUniforms.fogPower = g_fogPower; - fogUniforms.fogMult = g_fogMult; - fogUniforms.fogOffset = g_fogOffset; - - lightUniforms.ambient[0] = g_ambientRed; - lightUniforms.ambient[1] = g_ambientGreen; - lightUniforms.ambient[2] = g_ambientBlue; - lightUniforms.ambient[3] = 0.0f; - - memset(fishCount, 0, 5); -} - -Aquarium::~Aquarium() -{ - for (auto &tex : mTextureMap) - { - if (tex.second != nullptr) - { - delete tex.second; - tex.second = nullptr; - } - } - - for (auto &program : mProgramMap) - { - if (program.second != nullptr) - { - delete program.second; - program.second = nullptr; - } - } - - for (int i = 0; i < MODELNAME::MODELMAX; ++i) - { - delete mAquariumModels[i]; - } - - delete mFactory; -} - -BACKENDTYPE Aquarium::getBackendType(const std::string& backendPath) -{ - if (backendPath == "opengl") - { - return BACKENDTYPE::BACKENDTYPEOPENGL; - } - else if (backendPath == "dawn_d3d12") - { -#if defined(WIN32) || defined(_WIN32) - return BACKENDTYPE::BACKENDTYPEDAWND3D12; -#endif - } - else if (backendPath == "dawn_metal") - { -#if defined(__APPLE__) - return BACKENDTYPE::BACKENDTYPEDAWNMETAL; -#endif - } - else if (backendPath == "dawn_vulkan") - { -#if defined(WIN32) || defined(_WIN32) || defined(__linux__) - return BACKENDTYPE::BACKENDTYPEDAWNVULKAN; -#endif - } - else if (backendPath == "angle") - { -#if defined(WIN32) || defined(_WIN32) - return BACKENDTYPE::BACKENDTYPEANGLE; -#endif - } - else if (backendPath == "d3d12") - { -#if defined(WIN32) || defined(_WIN32) - return BACKENDTYPED3D12; -#endif - } - - return BACKENDTYPELAST; -} - -bool Aquarium::init(int argc, char **argv) -{ - mFactory = new ContextFactory(); - - // Create context of different backends through the cmd args. - // "--backend" {backend}: create different backends. currently opengl is supported. - // "--num-fish" {numfish}: imply rendering fish count. - // "--enable-msaa": enable 4 times MSAA. - // "--enable-instanced-draws": use instanced draw. By default, it's individual draw. - char *pNext; - for (int i = 1; i < argc; ++i) - { - std::string cmd(argv[i]); - if (cmd == "-h" || cmd == "--h") - { - std::cout << cmdArgsStrAquarium << std::endl; - - return false; - } - if (cmd == "--backend") - { - std::string backend = argv[i++ + 1]; - mBackendType = getBackendType(backend); - - if (mBackendType == BACKENDTYPE::BACKENDTYPELAST) - { - std::cout << "Can not create " << backend << " backend" << std::endl; - return false; - } - - mContext = mFactory->createContext(mBackendType); - } - else - { - } - } - - if (mContext == nullptr) - { - std::cout << "Failed to create context." << std::endl; - return false; - } - - std::bitset(TOGGLE::TOGGLEMAX)> availableToggleBitset = - mContext->getAvailableToggleBitset(); - if (availableToggleBitset.test(static_cast(TOGGLE::UPATEANDDRAWFOREACHMODEL))) - { - toggleBitset.set(static_cast(TOGGLE::UPATEANDDRAWFOREACHMODEL)); - } - if (availableToggleBitset.test(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET))) - { - toggleBitset.set(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET)); - } - - for (int i = 1; i < argc; ++i) - { - std::string cmd(argv[i]); - if (cmd == "--num-fish") - { - mFishCount = strtol(argv[i++ + 1], &pNext, 10); - if (mFishCount < 0) - { - std::cerr << "Fish count should larger or equal to 0." << std::endl; - return false; - } - } - else if (cmd == "--enable-msaa") - { - if (!availableToggleBitset.test(static_cast(TOGGLE::ENABLEMSAAx4))) - { - std::cerr << "MSAA isn't implemented for the backend." << std::endl; - return false; - } - toggleBitset.set(static_cast(TOGGLE::ENABLEMSAAx4)); - } - else if (cmd == "--enable-instanced-draws") - { - if (!availableToggleBitset.test(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS))) - { - std::cerr << "Instanced draw path isn't implemented for the backend." << std::endl; - return false; - } - toggleBitset.set(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)); - } - else if (cmd == "--disable-dynamic-buffer-offset") - { - if (!availableToggleBitset.test(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET))) - { - std::cerr << "Dynamic buffer offset is only implemented for Dawn Vulkan, Dawn " - "Metal and D3D12 backend." - << std::endl; - return false; - } - toggleBitset.set(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET), false); - } - else if (cmd == "--integrated-gpu") - { - if (!availableToggleBitset.test(static_cast(TOGGLE::INTEGRATEDGPU)) && - !availableToggleBitset.test(static_cast(TOGGLE::DISCRETEGPU))) - { - std::cerr << "Dynamically choose gpu isn't supported for the backend." << std::endl; - return false; - } - - if (toggleBitset.test(static_cast(TOGGLE::DISCRETEGPU))) - { - std::cerr << "Integrated and Discrete gpu cannot be used simultaneosly."; - } - toggleBitset.set(static_cast(TOGGLE::INTEGRATEDGPU)); - } - else if (cmd == "--discrete-gpu") - { - if (!availableToggleBitset.test(static_cast(TOGGLE::INTEGRATEDGPU)) && - !availableToggleBitset.test(static_cast(TOGGLE::DISCRETEGPU))) - { - std::cerr << "Dynamically choose gpu isn't supported for the backend." << std::endl; - return false; - } - - if (toggleBitset.test(static_cast(TOGGLE::INTEGRATEDGPU))) - { - std::cerr << "Integrated and Discrete gpu cannot be used simultaneosly."; - } - - toggleBitset.set(static_cast(TOGGLE::DISCRETEGPU)); - } - else if (cmd == "--enable-full-screen-mode") - { - if (!availableToggleBitset.test(static_cast(TOGGLE::ENABLEFULLSCREENMODE))) - { - std::cerr << "Full screen mode isn't supported for the backend." << std::endl; - return false; - } - - toggleBitset.set(static_cast(TOGGLE::ENABLEFULLSCREENMODE)); - } - else - { - } - } - - if (!mContext->initialize(mBackendType, toggleBitset)) - { - return false; - } - - calculateFishCount(); - - std::cout << "Init resources ..." << std::endl; - getElapsedTime(); - - const ResourceHelper *resourceHelper = mContext->getResourceHelper(); - std::vector skyUrls; - resourceHelper->getSkyBoxUrls(&skyUrls); - mTextureMap["skybox"] = mContext->createTexture("skybox", skyUrls); - - // Init general buffer and binding groups for dawn backend. - mContext->initGeneralResources(this); - - setupModelEnumMap(); - loadReource(); - mContext->FlushInit(); - - std::cout << "End loading.\nCost " << getElapsedTime() << "s totally." << std::endl; - mContext->showWindow(); - - return true; -} - -void Aquarium::display() -{ - while (!mContext->ShouldQuit()) - { - mContext->KeyBoardQuit(); - render(); - - mContext->DoFlush(); - } - - mContext->Terminate(); -} - -void Aquarium::loadReource() -{ - loadModels(); - loadPlacement(); -} - -void Aquarium::setupModelEnumMap() -{ - for (auto &info : g_sceneInfo) - { - mModelEnumMap[info.namestr] = info.name; - } -} - -// Load world matrices of models from json file. -void Aquarium::loadPlacement() -{ - const ResourceHelper *resourceHelper = mContext->getResourceHelper(); - std::string proppath = resourceHelper->getPropPlacementPath(); - std::ifstream PlacementStream(proppath, std::ios::in); - rapidjson::IStreamWrapper isPlacement(PlacementStream); - rapidjson::Document document; - document.ParseStream(isPlacement); - - ASSERT(document.IsObject()); - - ASSERT(document.HasMember("objects")); - const rapidjson::Value &objects = document["objects"]; - ASSERT(objects.IsArray()); - - for (rapidjson::SizeType i = 0; i < objects.Size(); ++i) - { - const rapidjson::Value &name = objects[i]["name"]; - const rapidjson::Value &worldMatrix = objects[i]["worldMatrix"]; - ASSERT(worldMatrix.IsArray() && worldMatrix.Size() == 16); - - std::vector matrix; - for (rapidjson::SizeType j = 0; j < worldMatrix.Size(); ++j) - { - matrix.push_back(worldMatrix[j].GetFloat()); - } - - MODELNAME modelname = mModelEnumMap[name.GetString()]; - // MODELFIRST means the model is not found in the Map - if (modelname != MODELNAME::MODELFIRST) - { - mAquariumModels[modelname]->worldmatrices.push_back(matrix); - } - } -} - -void Aquarium::loadModels() -{ - bool enableInstanceddraw = toggleBitset.test(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)); - for (const auto &info : g_sceneInfo) - { - if ((enableInstanceddraw && info.type == MODELGROUP::FISH) || - ((!enableInstanceddraw) && info.type == MODELGROUP::FISHINSTANCEDDRAW)) - { - continue; - } - loadModel(info); - } -} - -// Load vertex and index buffers, textures and program for each model. -void Aquarium::loadModel(const G_sceneInfo &info) -{ - const ResourceHelper *resourceHelper = mContext->getResourceHelper(); - const std::string &imagePath = resourceHelper->getImagePath(); - const std::string &programPath = resourceHelper->getProgramPath(); - const std::string &modelPath = resourceHelper->getModelPath(std::string(info.namestr)); - - std::ifstream ModelStream(modelPath, std::ios::in); - rapidjson::IStreamWrapper is(ModelStream); - rapidjson::Document document; - document.ParseStream(is); - ASSERT(document.IsObject()); - const rapidjson::Value &models = document["models"]; - ASSERT(models.IsArray()); - - Model *model = mContext->createModel(this, info.type, info.name, info.blend); - mAquariumModels[info.name] = model; - - auto &value = models.GetArray()[models.GetArray().Size() - 1]; - { - // set up textures - const rapidjson::Value &textures = value["textures"]; - for (rapidjson::Value::ConstMemberIterator itr = textures.MemberBegin(); - itr != textures.MemberEnd(); ++itr) - { - std::string name = itr->name.GetString(); - std::string image = itr->value.GetString(); - - if (mTextureMap.find(image) == mTextureMap.end()) - { - mTextureMap[image] = mContext->createTexture(name, imagePath + image); - } - - model->textureMap[name] = mTextureMap[image]; - } - - // set up vertices - const rapidjson::Value &arrays = value["fields"]; - for (rapidjson::Value::ConstMemberIterator itr = arrays.MemberBegin(); - itr != arrays.MemberEnd(); ++itr) - { - std::string name = itr->name.GetString(); - int numComponents = itr->value["numComponents"].GetInt(); - std::string type = itr->value["type"].GetString(); - Buffer *buffer; - if (name == "indices") - { - std::vector vec; - for (auto &data : itr->value["data"].GetArray()) - { - vec.push_back(data.GetInt()); - } - buffer = mContext->createBuffer(numComponents, &vec, true); - } - else - { - std::vector vec; - for (auto &data : itr->value["data"].GetArray()) - { - vec.push_back(data.GetFloat()); - } - buffer = mContext->createBuffer(numComponents, &vec, false); - } - - model->bufferMap[name] = buffer; - } - - // setup program - // There are 3 programs - // DM - // DM+NM - // DM+NM+RM - std::string vsId; - std::string fsId; - - vsId = info.program[0]; - fsId = info.program[1]; - - if (vsId != "" && fsId != "") - { - model->textureMap["skybox"] = mTextureMap["skybox"]; - } - else if (model->textureMap["reflection"] != nullptr) - { - vsId = "reflectionMapVertexShader"; - fsId = "reflectionMapFragmentShader"; - - model->textureMap["skybox"] = mTextureMap["skybox"]; - } - else if (model->textureMap["normalMap"] != nullptr) - { - vsId = "normalMapVertexShader"; - fsId = "normalMapFragmentShader"; - } - else - { - vsId = "diffuseVertexShader"; - fsId = "diffuseFragmentShader"; - } - - Program *program; - if (mProgramMap.find(vsId + fsId) != mProgramMap.end()) - { - program = mProgramMap[vsId + fsId]; - } - else - { - program = mContext->createProgram(programPath + vsId, programPath + fsId); - mProgramMap[vsId + fsId] = program; - } - - model->setProgram(program); - model->init(); - } -} - -void Aquarium::calculateFishCount() -{ - // Calculate fish count for each type of fish - int numLeft = mFishCount; - for (int i = 0; i < FISHENUM::MAX; ++i) - { - for (auto &fishInfo : fishTable) - { - if (fishInfo.type != i) - { - continue; - } - int numfloat = numLeft; - if (i == FISHENUM::BIG) - { - int temp = mFishCount < g_numFishSmall ? 1 : 2; - numfloat = std::min(numLeft, temp); - } - else if (i == FISHENUM::MEDIUM) - { - if (mFishCount < g_numFishMedium) - { - numfloat = std::min(numLeft, mFishCount / 10); - } - else if (mFishCount < g_numFishBig) - { - numfloat = std::min(numLeft, g_numFishLeftSmall); - } - else - { - numfloat = std::min(numLeft, g_numFishLeftBig); - } - } - numLeft = numLeft - numfloat; - fishCount[fishInfo.modelName - MODELNAME::MODELSMALLFISHA] = numfloat; - } - } -} - -float Aquarium::getElapsedTime() -{ - // Update our time -#ifdef _WIN32 - float now = GetTickCount64() / 1000.0f; -#else - float now = clock() / 1000000.0f; -#endif - float elapsedTime = 0.0f; - if (g.then == 0.0f) - { - elapsedTime = 0.0f; - } - else - { - elapsedTime = now - g.then; - } - g.then = now; - - return elapsedTime; -} - -void Aquarium::updateGlobalUniforms() -{ - - float elapsedTime = getElapsedTime(); - mFpsTimer.update(elapsedTime); - - g.mclock += elapsedTime * g_speed; - g.eyeClock += elapsedTime * g_eyeSpeed; - - g.eyePosition[0] = sin(g.eyeClock) * g_eyeRadius; - g.eyePosition[1] = g_eyeHeight; - g.eyePosition[2] = cos(g.eyeClock) * g_eyeRadius; - g.target[0] = static_cast(sin(g.eyeClock + M_PI)) * g_targetRadius; - g.target[1] = g_targetHeight; - g.target[2] = static_cast(cos(g.eyeClock + M_PI)) * g_targetRadius; - - float nearPlane = 1; - float farPlane = 25000.0f; - float aspect = static_cast(mContext->getClientWidth()) / - static_cast(mContext->getclientHeight()); - float top = tan(matrix::degToRad(g_fieldOfView * g_fovFudge) * 0.5f) * nearPlane; - float bottom = -top; - float left = aspect * bottom; - float right = aspect * top; - float width = abs(right - left); - float height = abs(top - bottom); - float xOff = width * g_net_offset[0] * g_net_offsetMult; - float yOff = height * g_net_offset[1] * g_net_offsetMult; - - // set frustm and camera look at - matrix::frustum(g.projection, left + xOff, right + xOff, bottom + yOff, top + yOff, nearPlane, - farPlane); - matrix::cameraLookAt(lightWorldPositionUniform.viewInverse, g.eyePosition, g.target, g.up); - matrix::inverse4(g.view, lightWorldPositionUniform.viewInverse); - matrix::mulMatrixMatrix4(lightWorldPositionUniform.viewProjection, g.view, g.projection); - matrix::inverse4(g.viewProjectionInverse, lightWorldPositionUniform.viewProjection); - - memcpy(g.skyView, g.view, 16 * sizeof(float)); - g.skyView[12] = 0.0; - g.skyView[13] = 0.0; - g.skyView[14] = 0.0; - matrix::mulMatrixMatrix4(g.skyViewProjection, g.skyView, g.projection); - matrix::inverse4(g.skyViewProjectionInverse, g.skyViewProjection); - - matrix::getAxis(g.v3t0, lightWorldPositionUniform.viewInverse, 0); - matrix::getAxis(g.v3t1, lightWorldPositionUniform.viewInverse, 1); - matrix::mulScalarVector(20.0f, g.v3t0, 3); - matrix::mulScalarVector(30.0f, g.v3t1, 3); - matrix::addVector(lightWorldPositionUniform.lightWorldPos, g.eyePosition, g.v3t0, 3); - matrix::addVector(lightWorldPositionUniform.lightWorldPos, - lightWorldPositionUniform.lightWorldPos, g.v3t1, 3); - - // update world uniforms for dawn backend - mContext->updateWorldlUniforms(this); -} - -void Aquarium::render() -{ - updateGlobalUniforms(); - - matrix::resetPseudoRandom(); - - mContext->preFrame(); - - drawBackground(); - - drawFishes(); - - drawInner(); - - drawSeaweed(); - - drawOutside(); - - mContext->showFPS(mFpsTimer); -} - -void Aquarium::drawBackground() -{ - Model *model = mAquariumModels[MODELNAME::MODELRUINCOlOMN]; - for (int i = MODELNAME::MODELRUINCOlOMN; i <= MODELNAME::MODELTREASURECHEST; ++i) - { - model = mAquariumModels[i]; - updateWorldMatrixAndDraw(model); - } -} - -void Aquarium::drawSeaweed() -{ - SeaweedModel *model = static_cast(mAquariumModels[MODELNAME::MODELSEAWEEDA]); - for (int i = MODELNAME::MODELSEAWEEDA; i <= MODELNAME::MODELSEAWEEDB; ++i) - { - // model->updateSeaweedModelTime(g.mclock); - model = static_cast(mAquariumModels[i]); - updateWorldMatrixAndDraw(model); - } -} - -void Aquarium::drawFishes() -{ - int begin = toggleBitset.test(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)) - ? MODELNAME::MODELSMALLFISHAINSTANCEDDRAWS - : MODELNAME::MODELSMALLFISHA; - int end = toggleBitset.test(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)) - ? MODELNAME::MODELBIGFISHBINSTANCEDDRAWS - : MODELNAME::MODELBIGFISHB; - bool updateAndDrawForEachFish = - toggleBitset.test(static_cast(TOGGLE::UPATEANDDRAWFOREACHMODEL)); - - for (int i = begin; i <= end; ++i) - { - FishModel *model = static_cast(mAquariumModels[i]); - - const Fish &fishInfo = fishTable[i - begin]; - int numFish = fishCount[i - begin]; - - if (updateAndDrawForEachFish) - { - model->prepareForDraw(); - } - - float fishBaseClock = g.mclock * g_fishSpeed; - float fishRadius = fishInfo.radius; - float fishRadiusRange = fishInfo.radiusRange; - float fishSpeed = fishInfo.speed; - float fishSpeedRange = fishInfo.speedRange; - float fishTailSpeed = fishInfo.tailSpeed * g_fishTailSpeed; - float fishOffset = g_fishOffset; - // float fishClockSpeed = g_fishSpeed; - float fishHeight = g_fishHeight + fishInfo.heightOffset; - float fishHeightRange = g_fishHeightRange * fishInfo.heightRange; - float fishXClock = g_fishXClock; - float fishYClock = g_fishYClock; - float fishZClock = g_fishZClock; - - for (int ii = 0; ii < numFish; ++ii) - { - float fishClock = fishBaseClock + ii * fishOffset; - float speed = fishSpeed + static_cast(matrix::pseudoRandom()) * fishSpeedRange; - float scale = 1.0f + static_cast(matrix::pseudoRandom()) * 1; - float xRadius = - fishRadius + static_cast(matrix::pseudoRandom()) * fishRadiusRange; - float yRadius = 2.0f + static_cast(matrix::pseudoRandom()) * fishHeightRange; - float zRadius = - fishRadius + static_cast(matrix::pseudoRandom()) * fishRadiusRange; - float fishSpeedClock = fishClock * speed; - float xClock = fishSpeedClock * fishXClock; - float yClock = fishSpeedClock * fishYClock; - float zClock = fishSpeedClock * fishZClock; - - model->updateFishPerUniforms( - sin(xClock) * xRadius, sin(yClock) * yRadius + fishHeight, cos(zClock) * zRadius, - sin(xClock - 0.04f) * xRadius, sin(yClock - 0.01f) * yRadius + fishHeight, - cos(zClock - 0.04f) * zRadius, scale, - fmod((g.mclock + ii * g_tailOffsetMult) * fishTailSpeed * speed, - static_cast(M_PI) * 2), - ii); - if (updateAndDrawForEachFish) - { - model->updatePerInstanceUniforms(worldUniforms); - model->draw(); - } - } - // TODO(yizhou): If backend is dawn or d3d12, draw only once for every type of fish by - // drawInstance. If backend is opengl or angle, draw for exery fish. Update the logic the - // same as Dawn if uniform blocks are implemented for OpenGL. - if (!updateAndDrawForEachFish) - { - model->draw(); - } - } -} - -void Aquarium::drawInner() -{ - Model *model = mAquariumModels[MODELNAME::MODELGLOBEINNER]; - updateWorldMatrixAndDraw(model); -} - -void Aquarium::drawOutside() -{ - Model *model = mAquariumModels[MODELNAME::MODELENVIRONMENTBOX]; - updateWorldMatrixAndDraw(model); -} - -void Aquarium::updateWorldProjections(const std::vector &w) -{ - ASSERT(w.size() == 16); - memcpy(worldUniforms.world, w.data(), 16 * sizeof(float)); - matrix::mulMatrixMatrix4(worldUniforms.worldViewProjection, worldUniforms.world, - lightWorldPositionUniform.viewProjection); - matrix::inverse4(g.worldInverse, worldUniforms.world); - matrix::transpose4(worldUniforms.worldInverseTranspose, g.worldInverse); -} - -void Aquarium::updateWorldMatrixAndDraw(Model *model) -{ - bool updateAndDrawForEachFish = - toggleBitset.test(static_cast(TOGGLE::UPATEANDDRAWFOREACHMODEL)); - - if (model->worldmatrices.size()) - { - for (auto &world : model->worldmatrices) - { - updateWorldProjections(world); - if (updateAndDrawForEachFish) - { - model->prepareForDraw(); - model->updatePerInstanceUniforms(worldUniforms); - model->draw(); - } - else - { - model->updatePerInstanceUniforms(worldUniforms); - } - } - } - - if (!updateAndDrawForEachFish) - { - model->prepareForDraw(); - model->draw(); - } -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Aquarium.cpp: Create context for specific graphics API. +// Data preparation, load vertex and index buffer, images and shaders. +// Implements logic of rendering background, fishes, seaweeds and +// other models. Calculate fish count for each type of fish. +// Update uniforms for each frame. + +#include +#include +#include +#include + +#include "Aquarium.h" +#include "ContextFactory.h" +#include "FishModel.h" +#include "Matrix.h" +#include "Program.h" +#include "SeaweedModel.h" +#include "Texture.h" + +#include "common/AQUARIUM_ASSERT.h" +#include "include/CmdArgsHelper.h" +#include "opengl/ContextGL.h" + +#include "rapidjson/document.h" +#include "rapidjson/istreamwrapper.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/writer.h" + +Aquarium::Aquarium() + : mModelEnumMap(), + mTextureMap(), + mProgramMap(), + mAquariumModels(), + mContext(nullptr), + mFpsTimer(), + mFishCount(1), + mBackendType(BACKENDTYPE::BACKENDTYPELAST), + mFactory(nullptr) +{ + g.then = 0.0f; + g.mclock = 0.0f; + g.eyeClock = 0.0f; + + lightUniforms.lightColor[0] = 1.0f; + lightUniforms.lightColor[1] = 1.0f; + lightUniforms.lightColor[2] = 1.0f; + lightUniforms.lightColor[3] = 1.0f; + + lightUniforms.specular[0] = 1.0f; + lightUniforms.specular[1] = 1.0f; + lightUniforms.specular[2] = 1.0f; + lightUniforms.specular[3] = 1.0f; + + fogUniforms.fogColor[0] = g_fogRed; + fogUniforms.fogColor[1] = g_fogGreen; + fogUniforms.fogColor[2] = g_fogBlue; + fogUniforms.fogColor[3] = 1.0f; + + fogUniforms.fogPower = g_fogPower; + fogUniforms.fogMult = g_fogMult; + fogUniforms.fogOffset = g_fogOffset; + + lightUniforms.ambient[0] = g_ambientRed; + lightUniforms.ambient[1] = g_ambientGreen; + lightUniforms.ambient[2] = g_ambientBlue; + lightUniforms.ambient[3] = 0.0f; + + memset(fishCount, 0, 5); +} + +Aquarium::~Aquarium() +{ + for (auto &tex : mTextureMap) + { + if (tex.second != nullptr) + { + delete tex.second; + tex.second = nullptr; + } + } + + for (auto &program : mProgramMap) + { + if (program.second != nullptr) + { + delete program.second; + program.second = nullptr; + } + } + + for (int i = 0; i < MODELNAME::MODELMAX; ++i) + { + delete mAquariumModels[i]; + } + + delete mFactory; +} + +BACKENDTYPE Aquarium::getBackendType(const std::string &backendPath) +{ + if (backendPath == "opengl") + { + return BACKENDTYPE::BACKENDTYPEOPENGL; + } + else if (backendPath == "dawn_d3d12") + { +#if defined(WIN32) || defined(_WIN32) + return BACKENDTYPE::BACKENDTYPEDAWND3D12; +#endif + } + else if (backendPath == "dawn_metal") + { +#if defined(__APPLE__) + return BACKENDTYPE::BACKENDTYPEDAWNMETAL; +#endif + } + else if (backendPath == "dawn_vulkan") + { +#if defined(WIN32) || defined(_WIN32) || defined(__linux__) + return BACKENDTYPE::BACKENDTYPEDAWNVULKAN; +#endif + } + else if (backendPath == "angle") + { +#if defined(WIN32) || defined(_WIN32) + return BACKENDTYPE::BACKENDTYPEANGLE; +#endif + } + else if (backendPath == "d3d12") + { +#if defined(WIN32) || defined(_WIN32) + return BACKENDTYPED3D12; +#endif + } + + return BACKENDTYPELAST; +} + +bool Aquarium::init(int argc, char **argv) +{ + mFactory = new ContextFactory(); + + // Create context of different backends through the cmd args. + // "--backend" {backend}: create different backends. currently opengl is supported. + // "--num-fish" {numfish}: imply rendering fish count. + // "--enable-msaa": enable 4 times MSAA. + // "--enable-instanced-draws": use instanced draw. By default, it's individual draw. + char *pNext; + for (int i = 1; i < argc; ++i) + { + std::string cmd(argv[i]); + if (cmd == "-h" || cmd == "--h") + { + std::cout << cmdArgsStrAquarium << std::endl; + + return false; + } + if (cmd == "--backend") + { + std::string backend = argv[i++ + 1]; + mBackendType = getBackendType(backend); + + if (mBackendType == BACKENDTYPE::BACKENDTYPELAST) + { + std::cout << "Can not create " << backend << " backend" << std::endl; + return false; + } + + mContext = mFactory->createContext(mBackendType); + } + else + { + } + } + + if (mContext == nullptr) + { + std::cout << "Failed to create context." << std::endl; + return false; + } + + std::bitset(TOGGLE::TOGGLEMAX)> availableToggleBitset = + mContext->getAvailableToggleBitset(); + if (availableToggleBitset.test(static_cast(TOGGLE::UPATEANDDRAWFOREACHMODEL))) + { + toggleBitset.set(static_cast(TOGGLE::UPATEANDDRAWFOREACHMODEL)); + } + if (availableToggleBitset.test(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET))) + { + toggleBitset.set(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET)); + } + + for (int i = 1; i < argc; ++i) + { + std::string cmd(argv[i]); + if (cmd == "--num-fish") + { + mFishCount = strtol(argv[i++ + 1], &pNext, 10); + if (mFishCount < 0) + { + std::cerr << "Fish count should larger or equal to 0." << std::endl; + return false; + } + } + else if (cmd == "--enable-msaa") + { + if (!availableToggleBitset.test(static_cast(TOGGLE::ENABLEMSAAx4))) + { + std::cerr << "MSAA isn't implemented for the backend." << std::endl; + return false; + } + toggleBitset.set(static_cast(TOGGLE::ENABLEMSAAx4)); + } + else if (cmd == "--enable-instanced-draws") + { + if (!availableToggleBitset.test(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS))) + { + std::cerr << "Instanced draw path isn't implemented for the backend." << std::endl; + return false; + } + toggleBitset.set(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)); + } + else if (cmd == "--disable-dynamic-buffer-offset") + { + if (!availableToggleBitset.test(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET))) + { + std::cerr << "Dynamic buffer offset is only implemented for Dawn Vulkan, Dawn " + "Metal and D3D12 backend." + << std::endl; + return false; + } + toggleBitset.set(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET), false); + } + else if (cmd == "--integrated-gpu") + { + if (!availableToggleBitset.test(static_cast(TOGGLE::INTEGRATEDGPU)) && + !availableToggleBitset.test(static_cast(TOGGLE::DISCRETEGPU))) + { + std::cerr << "Dynamically choose gpu isn't supported for the backend." << std::endl; + return false; + } + + if (toggleBitset.test(static_cast(TOGGLE::DISCRETEGPU))) + { + std::cerr << "Integrated and Discrete gpu cannot be used simultaneosly."; + } + toggleBitset.set(static_cast(TOGGLE::INTEGRATEDGPU)); + } + else if (cmd == "--discrete-gpu") + { + if (!availableToggleBitset.test(static_cast(TOGGLE::INTEGRATEDGPU)) && + !availableToggleBitset.test(static_cast(TOGGLE::DISCRETEGPU))) + { + std::cerr << "Dynamically choose gpu isn't supported for the backend." << std::endl; + return false; + } + + if (toggleBitset.test(static_cast(TOGGLE::INTEGRATEDGPU))) + { + std::cerr << "Integrated and Discrete gpu cannot be used simultaneosly."; + } + + toggleBitset.set(static_cast(TOGGLE::DISCRETEGPU)); + } + else if (cmd == "--enable-full-screen-mode") + { + if (!availableToggleBitset.test(static_cast(TOGGLE::ENABLEFULLSCREENMODE))) + { + std::cerr << "Full screen mode isn't supported for the backend." << std::endl; + return false; + } + + toggleBitset.set(static_cast(TOGGLE::ENABLEFULLSCREENMODE)); + } + else + { + } + } + + if (!mContext->initialize(mBackendType, toggleBitset)) + { + return false; + } + + calculateFishCount(); + + std::cout << "Init resources ..." << std::endl; + getElapsedTime(); + + const ResourceHelper *resourceHelper = mContext->getResourceHelper(); + std::vector skyUrls; + resourceHelper->getSkyBoxUrls(&skyUrls); + mTextureMap["skybox"] = mContext->createTexture("skybox", skyUrls); + + // Init general buffer and binding groups for dawn backend. + mContext->initGeneralResources(this); + + setupModelEnumMap(); + loadReource(); + mContext->FlushInit(); + + std::cout << "End loading.\nCost " << getElapsedTime() << "s totally." << std::endl; + mContext->showWindow(); + + return true; +} + +void Aquarium::display() +{ + while (!mContext->ShouldQuit()) + { + mContext->KeyBoardQuit(); + render(); + + mContext->DoFlush(); + } + + mContext->Terminate(); +} + +void Aquarium::loadReource() +{ + loadModels(); + loadPlacement(); +} + +void Aquarium::setupModelEnumMap() +{ + for (auto &info : g_sceneInfo) + { + mModelEnumMap[info.namestr] = info.name; + } +} + +// Load world matrices of models from json file. +void Aquarium::loadPlacement() +{ + const ResourceHelper *resourceHelper = mContext->getResourceHelper(); + std::string proppath = resourceHelper->getPropPlacementPath(); + std::ifstream PlacementStream(proppath, std::ios::in); + rapidjson::IStreamWrapper isPlacement(PlacementStream); + rapidjson::Document document; + document.ParseStream(isPlacement); + + ASSERT(document.IsObject()); + + ASSERT(document.HasMember("objects")); + const rapidjson::Value &objects = document["objects"]; + ASSERT(objects.IsArray()); + + for (rapidjson::SizeType i = 0; i < objects.Size(); ++i) + { + const rapidjson::Value &name = objects[i]["name"]; + const rapidjson::Value &worldMatrix = objects[i]["worldMatrix"]; + ASSERT(worldMatrix.IsArray() && worldMatrix.Size() == 16); + + std::vector matrix; + for (rapidjson::SizeType j = 0; j < worldMatrix.Size(); ++j) + { + matrix.push_back(worldMatrix[j].GetFloat()); + } + + MODELNAME modelname = mModelEnumMap[name.GetString()]; + // MODELFIRST means the model is not found in the Map + if (modelname != MODELNAME::MODELFIRST) + { + mAquariumModels[modelname]->worldmatrices.push_back(matrix); + } + } +} + +void Aquarium::loadModels() +{ + bool enableInstanceddraw = toggleBitset.test(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)); + for (const auto &info : g_sceneInfo) + { + if ((enableInstanceddraw && info.type == MODELGROUP::FISH) || + ((!enableInstanceddraw) && info.type == MODELGROUP::FISHINSTANCEDDRAW)) + { + continue; + } + loadModel(info); + } +} + +// Load vertex and index buffers, textures and program for each model. +void Aquarium::loadModel(const G_sceneInfo &info) +{ + const ResourceHelper *resourceHelper = mContext->getResourceHelper(); + const std::string &imagePath = resourceHelper->getImagePath(); + const std::string &programPath = resourceHelper->getProgramPath(); + const std::string &modelPath = resourceHelper->getModelPath(std::string(info.namestr)); + + std::ifstream ModelStream(modelPath, std::ios::in); + rapidjson::IStreamWrapper is(ModelStream); + rapidjson::Document document; + document.ParseStream(is); + ASSERT(document.IsObject()); + const rapidjson::Value &models = document["models"]; + ASSERT(models.IsArray()); + + Model *model = mContext->createModel(this, info.type, info.name, info.blend); + mAquariumModels[info.name] = model; + + auto &value = models.GetArray()[models.GetArray().Size() - 1]; + { + // set up textures + const rapidjson::Value &textures = value["textures"]; + for (rapidjson::Value::ConstMemberIterator itr = textures.MemberBegin(); + itr != textures.MemberEnd(); ++itr) + { + std::string name = itr->name.GetString(); + std::string image = itr->value.GetString(); + + if (mTextureMap.find(image) == mTextureMap.end()) + { + mTextureMap[image] = mContext->createTexture(name, imagePath + image); + } + + model->textureMap[name] = mTextureMap[image]; + } + + // set up vertices + const rapidjson::Value &arrays = value["fields"]; + for (rapidjson::Value::ConstMemberIterator itr = arrays.MemberBegin(); + itr != arrays.MemberEnd(); ++itr) + { + std::string name = itr->name.GetString(); + int numComponents = itr->value["numComponents"].GetInt(); + std::string type = itr->value["type"].GetString(); + Buffer *buffer; + if (name == "indices") + { + std::vector vec; + for (auto &data : itr->value["data"].GetArray()) + { + vec.push_back(data.GetInt()); + } + buffer = mContext->createBuffer(numComponents, &vec, true); + } + else + { + std::vector vec; + for (auto &data : itr->value["data"].GetArray()) + { + vec.push_back(data.GetFloat()); + } + buffer = mContext->createBuffer(numComponents, &vec, false); + } + + model->bufferMap[name] = buffer; + } + + // setup program + // There are 3 programs + // DM + // DM+NM + // DM+NM+RM + std::string vsId; + std::string fsId; + + vsId = info.program[0]; + fsId = info.program[1]; + + if (vsId != "" && fsId != "") + { + model->textureMap["skybox"] = mTextureMap["skybox"]; + } + else if (model->textureMap["reflection"] != nullptr) + { + vsId = "reflectionMapVertexShader"; + fsId = "reflectionMapFragmentShader"; + + model->textureMap["skybox"] = mTextureMap["skybox"]; + } + else if (model->textureMap["normalMap"] != nullptr) + { + vsId = "normalMapVertexShader"; + fsId = "normalMapFragmentShader"; + } + else + { + vsId = "diffuseVertexShader"; + fsId = "diffuseFragmentShader"; + } + + Program *program; + if (mProgramMap.find(vsId + fsId) != mProgramMap.end()) + { + program = mProgramMap[vsId + fsId]; + } + else + { + program = mContext->createProgram(programPath + vsId, programPath + fsId); + mProgramMap[vsId + fsId] = program; + } + + model->setProgram(program); + model->init(); + } +} + +void Aquarium::calculateFishCount() +{ + // Calculate fish count for each type of fish + int numLeft = mFishCount; + for (int i = 0; i < FISHENUM::MAX; ++i) + { + for (auto &fishInfo : fishTable) + { + if (fishInfo.type != i) + { + continue; + } + int numfloat = numLeft; + if (i == FISHENUM::BIG) + { + int temp = mFishCount < g_numFishSmall ? 1 : 2; + numfloat = std::min(numLeft, temp); + } + else if (i == FISHENUM::MEDIUM) + { + if (mFishCount < g_numFishMedium) + { + numfloat = std::min(numLeft, mFishCount / 10); + } + else if (mFishCount < g_numFishBig) + { + numfloat = std::min(numLeft, g_numFishLeftSmall); + } + else + { + numfloat = std::min(numLeft, g_numFishLeftBig); + } + } + numLeft = numLeft - numfloat; + fishCount[fishInfo.modelName - MODELNAME::MODELSMALLFISHA] = numfloat; + } + } +} + +float Aquarium::getElapsedTime() +{ + // Update our time +#ifdef _WIN32 + float now = GetTickCount64() / 1000.0f; +#else + float now = clock() / 1000000.0f; +#endif + float elapsedTime = 0.0f; + if (g.then == 0.0f) + { + elapsedTime = 0.0f; + } + else + { + elapsedTime = now - g.then; + } + g.then = now; + + return elapsedTime; +} + +void Aquarium::updateGlobalUniforms() +{ + + float elapsedTime = getElapsedTime(); + mFpsTimer.update(elapsedTime); + + g.mclock += elapsedTime * g_speed; + g.eyeClock += elapsedTime * g_eyeSpeed; + + g.eyePosition[0] = sin(g.eyeClock) * g_eyeRadius; + g.eyePosition[1] = g_eyeHeight; + g.eyePosition[2] = cos(g.eyeClock) * g_eyeRadius; + g.target[0] = static_cast(sin(g.eyeClock + M_PI)) * g_targetRadius; + g.target[1] = g_targetHeight; + g.target[2] = static_cast(cos(g.eyeClock + M_PI)) * g_targetRadius; + + float nearPlane = 1; + float farPlane = 25000.0f; + float aspect = static_cast(mContext->getClientWidth()) / + static_cast(mContext->getclientHeight()); + float top = tan(matrix::degToRad(g_fieldOfView * g_fovFudge) * 0.5f) * nearPlane; + float bottom = -top; + float left = aspect * bottom; + float right = aspect * top; + float width = abs(right - left); + float height = abs(top - bottom); + float xOff = width * g_net_offset[0] * g_net_offsetMult; + float yOff = height * g_net_offset[1] * g_net_offsetMult; + + // set frustm and camera look at + matrix::frustum(g.projection, left + xOff, right + xOff, bottom + yOff, top + yOff, nearPlane, + farPlane); + matrix::cameraLookAt(lightWorldPositionUniform.viewInverse, g.eyePosition, g.target, g.up); + matrix::inverse4(g.view, lightWorldPositionUniform.viewInverse); + matrix::mulMatrixMatrix4(lightWorldPositionUniform.viewProjection, g.view, g.projection); + matrix::inverse4(g.viewProjectionInverse, lightWorldPositionUniform.viewProjection); + + memcpy(g.skyView, g.view, 16 * sizeof(float)); + g.skyView[12] = 0.0; + g.skyView[13] = 0.0; + g.skyView[14] = 0.0; + matrix::mulMatrixMatrix4(g.skyViewProjection, g.skyView, g.projection); + matrix::inverse4(g.skyViewProjectionInverse, g.skyViewProjection); + + matrix::getAxis(g.v3t0, lightWorldPositionUniform.viewInverse, 0); + matrix::getAxis(g.v3t1, lightWorldPositionUniform.viewInverse, 1); + matrix::mulScalarVector(20.0f, g.v3t0, 3); + matrix::mulScalarVector(30.0f, g.v3t1, 3); + matrix::addVector(lightWorldPositionUniform.lightWorldPos, g.eyePosition, g.v3t0, 3); + matrix::addVector(lightWorldPositionUniform.lightWorldPos, + lightWorldPositionUniform.lightWorldPos, g.v3t1, 3); + + // update world uniforms for dawn backend + mContext->updateWorldlUniforms(this); +} + +void Aquarium::render() +{ + updateGlobalUniforms(); + + matrix::resetPseudoRandom(); + + mContext->preFrame(); + + drawBackground(); + + drawFishes(); + + drawInner(); + + drawSeaweed(); + + drawOutside(); + + mContext->showFPS(mFpsTimer); +} + +void Aquarium::drawBackground() +{ + Model *model = mAquariumModels[MODELNAME::MODELRUINCOlOMN]; + for (int i = MODELNAME::MODELRUINCOlOMN; i <= MODELNAME::MODELTREASURECHEST; ++i) + { + model = mAquariumModels[i]; + updateWorldMatrixAndDraw(model); + } +} + +void Aquarium::drawSeaweed() +{ + SeaweedModel *model = static_cast(mAquariumModels[MODELNAME::MODELSEAWEEDA]); + for (int i = MODELNAME::MODELSEAWEEDA; i <= MODELNAME::MODELSEAWEEDB; ++i) + { + // model->updateSeaweedModelTime(g.mclock); + model = static_cast(mAquariumModels[i]); + updateWorldMatrixAndDraw(model); + } +} + +void Aquarium::drawFishes() +{ + int begin = toggleBitset.test(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)) + ? MODELNAME::MODELSMALLFISHAINSTANCEDDRAWS + : MODELNAME::MODELSMALLFISHA; + int end = toggleBitset.test(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)) + ? MODELNAME::MODELBIGFISHBINSTANCEDDRAWS + : MODELNAME::MODELBIGFISHB; + bool updateAndDrawForEachFish = + toggleBitset.test(static_cast(TOGGLE::UPATEANDDRAWFOREACHMODEL)); + + for (int i = begin; i <= end; ++i) + { + FishModel *model = static_cast(mAquariumModels[i]); + + const Fish &fishInfo = fishTable[i - begin]; + int numFish = fishCount[i - begin]; + + if (updateAndDrawForEachFish) + { + model->prepareForDraw(); + } + + float fishBaseClock = g.mclock * g_fishSpeed; + float fishRadius = fishInfo.radius; + float fishRadiusRange = fishInfo.radiusRange; + float fishSpeed = fishInfo.speed; + float fishSpeedRange = fishInfo.speedRange; + float fishTailSpeed = fishInfo.tailSpeed * g_fishTailSpeed; + float fishOffset = g_fishOffset; + // float fishClockSpeed = g_fishSpeed; + float fishHeight = g_fishHeight + fishInfo.heightOffset; + float fishHeightRange = g_fishHeightRange * fishInfo.heightRange; + float fishXClock = g_fishXClock; + float fishYClock = g_fishYClock; + float fishZClock = g_fishZClock; + + for (int ii = 0; ii < numFish; ++ii) + { + float fishClock = fishBaseClock + ii * fishOffset; + float speed = fishSpeed + static_cast(matrix::pseudoRandom()) * fishSpeedRange; + float scale = 1.0f + static_cast(matrix::pseudoRandom()) * 1; + float xRadius = + fishRadius + static_cast(matrix::pseudoRandom()) * fishRadiusRange; + float yRadius = 2.0f + static_cast(matrix::pseudoRandom()) * fishHeightRange; + float zRadius = + fishRadius + static_cast(matrix::pseudoRandom()) * fishRadiusRange; + float fishSpeedClock = fishClock * speed; + float xClock = fishSpeedClock * fishXClock; + float yClock = fishSpeedClock * fishYClock; + float zClock = fishSpeedClock * fishZClock; + + model->updateFishPerUniforms( + sin(xClock) * xRadius, sin(yClock) * yRadius + fishHeight, cos(zClock) * zRadius, + sin(xClock - 0.04f) * xRadius, sin(yClock - 0.01f) * yRadius + fishHeight, + cos(zClock - 0.04f) * zRadius, scale, + fmod((g.mclock + ii * g_tailOffsetMult) * fishTailSpeed * speed, + static_cast(M_PI) * 2), + ii); + if (updateAndDrawForEachFish) + { + model->updatePerInstanceUniforms(worldUniforms); + model->draw(); + } + } + // TODO(yizhou): If backend is dawn or d3d12, draw only once for every type of fish by + // drawInstance. If backend is opengl or angle, draw for exery fish. Update the logic the + // same as Dawn if uniform blocks are implemented for OpenGL. + if (!updateAndDrawForEachFish) + { + model->draw(); + } + } +} + +void Aquarium::drawInner() +{ + Model *model = mAquariumModels[MODELNAME::MODELGLOBEINNER]; + updateWorldMatrixAndDraw(model); +} + +void Aquarium::drawOutside() +{ + Model *model = mAquariumModels[MODELNAME::MODELENVIRONMENTBOX]; + updateWorldMatrixAndDraw(model); +} + +void Aquarium::updateWorldProjections(const std::vector &w) +{ + ASSERT(w.size() == 16); + memcpy(worldUniforms.world, w.data(), 16 * sizeof(float)); + matrix::mulMatrixMatrix4(worldUniforms.worldViewProjection, worldUniforms.world, + lightWorldPositionUniform.viewProjection); + matrix::inverse4(g.worldInverse, worldUniforms.world); + matrix::transpose4(worldUniforms.worldInverseTranspose, g.worldInverse); +} + +void Aquarium::updateWorldMatrixAndDraw(Model *model) +{ + bool updateAndDrawForEachFish = + toggleBitset.test(static_cast(TOGGLE::UPATEANDDRAWFOREACHMODEL)); + + if (model->worldmatrices.size()) + { + for (auto &world : model->worldmatrices) + { + updateWorldProjections(world); + if (updateAndDrawForEachFish) + { + model->prepareForDraw(); + model->updatePerInstanceUniforms(worldUniforms); + model->draw(); + } + else + { + model->updatePerInstanceUniforms(worldUniforms); + } + } + } + + if (!updateAndDrawForEachFish) + { + model->prepareForDraw(); + model->draw(); + } +} diff --git a/src/aquarium-optimized/Aquarium.h b/src/aquarium-optimized/Aquarium.h index 5932f78..c94c369 100644 --- a/src/aquarium-optimized/Aquarium.h +++ b/src/aquarium-optimized/Aquarium.h @@ -1,473 +1,473 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Aquarium.h: Define global variables, enums, constant variables and Class Aquarium. - -#ifndef AQUARIUM_H -#define AQUARIUM_H - -#include -#include -#include - -#include "../common/FPSTimer.h" - -class ContextFactory; -class Context; -class Texture; -class Program; -class Model; - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#define M_PI 3.141592653589793 -#else -#include "math.h" -#endif - -enum BACKENDTYPE : short -{ - BACKENDTYPEANGLE, - BACKENDTYPEDAWND3D12, - BACKENDTYPEDAWNMETAL, - BACKENDTYPEDAWNVULKAN, - BACKENDTYPED3D12, - BACKENDTYPEOPENGL, - BACKENDTYPELAST -}; - -enum MODELNAME : short -{ - MODELFIRST, - MODELRUINCOlOMN, - MODELARCH, - MODELROCKA, - MODELROCKB, - MODELROCKC, - MODELSUNKNSHIPBOXES, - MODELSUNKNSHIPDECK, - MODELSUNKNSHIPHULL, - MODELFLOORBASE_BAKED, - MODELSUNKNSUB, - MODELCORAL, - MODELSTONE, - MODELCORALSTONEA, - MODELCORALSTONEB, - MODELGLOBEBASE, - MODELTREASURECHEST, - MODELENVIRONMENTBOX, - MODELSUPPORTBEAMS, - MODELSKYBOX, - MODELGLOBEINNER, - MODELSEAWEEDA, - MODELSEAWEEDB, - MODELSMALLFISHA, - MODELMEDIUMFISHA, - MODELMEDIUMFISHB, - MODELBIGFISHA, - MODELBIGFISHB, - MODELSMALLFISHAINSTANCEDDRAWS, - MODELMEDIUMFISHAINSTANCEDDRAWS, - MODELMEDIUMFISHBINSTANCEDDRAWS, - MODELBIGFISHAINSTANCEDDRAWS, - MODELBIGFISHBINSTANCEDDRAWS, - MODELMAX -}; - -enum MODELGROUP : short -{ - FISH, - FISHINSTANCEDDRAW, - INNER, - SEAWEED, - GENERIC, - OUTSIDE, - GROUPMAX -}; - -struct G_sceneInfo -{ - const char *namestr; - MODELNAME name; - const char *program[2]; - bool fog; - MODELGROUP type; - bool blend; -}; - -enum FISHENUM : short -{ - BIG, - MEDIUM, - SMALL, - MAX -}; - -enum TOGGLE : short -{ - // Enable 4 times MSAA. - ENABLEMSAAx4, - // Go through instanced draw. - ENABLEINSTANCEDDRAWS, - // The toggle is only supported on Dawn backend. - // By default, the app will enable dynamic buffer offset. - // The toggle is to disable dbo feature. - ENABLEDYNAMICBUFFEROFFSET, - // Select integrated gpu if available. - INTEGRATEDGPU, - // Select discrete gpu if available. - DISCRETEGPU, - // Update and draw for each model on OpenGL and Angle backend, but draw once per frame on other - // backend. - UPATEANDDRAWFOREACHMODEL, - // Support Full Screen mode - ENABLEFULLSCREENMODE, - TOGGLEMAX -}; - -const G_sceneInfo g_sceneInfo[] = { - {"SmallFishA", - MODELNAME::MODELSMALLFISHA, - {"fishVertexShader", "fishReflectionFragmentShader"}, - true, - MODELGROUP::FISH}, - {"MediumFishA", - MODELNAME::MODELMEDIUMFISHA, - {"fishVertexShader", "fishNormalMapFragmentShader"}, - true, - MODELGROUP::FISH}, - {"MediumFishB", - MODELNAME::MODELMEDIUMFISHB, - {"fishVertexShader", "fishReflectionFragmentShader"}, - true, - MODELGROUP::FISH}, - {"BigFishA", - MODELNAME::MODELBIGFISHA, - {"fishVertexShader", "fishNormalMapFragmentShader"}, - true, - MODELGROUP::FISH}, - {"BigFishB", - MODELNAME::MODELBIGFISHB, - {"fishVertexShader", "fishNormalMapFragmentShader"}, - true, - MODELGROUP::FISH}, - {"SmallFishA", - MODELNAME::MODELSMALLFISHAINSTANCEDDRAWS, - {"fishVertexShaderInstancedDraws", "fishReflectionFragmentShader"}, - true, - MODELGROUP::FISHINSTANCEDDRAW}, - {"MediumFishA", - MODELNAME::MODELMEDIUMFISHAINSTANCEDDRAWS, - {"fishVertexShaderInstancedDraws", "fishNormalMapFragmentShader"}, - true, - MODELGROUP::FISHINSTANCEDDRAW}, - {"MediumFishB", - MODELNAME::MODELMEDIUMFISHBINSTANCEDDRAWS, - {"fishVertexShaderInstancedDraws", "fishReflectionFragmentShader"}, - true, - MODELGROUP::FISHINSTANCEDDRAW}, - {"BigFishA", - MODELNAME::MODELBIGFISHAINSTANCEDDRAWS, - {"fishVertexShaderInstancedDraws", "fishNormalMapFragmentShader"}, - true, - MODELGROUP::FISHINSTANCEDDRAW}, - {"BigFishB", - MODELNAME::MODELBIGFISHBINSTANCEDDRAWS, - {"fishVertexShaderInstancedDraws", "fishNormalMapFragmentShader"}, - true, - MODELGROUP::FISHINSTANCEDDRAW}, - {"Arch", MODELNAME::MODELARCH, {"", ""}, true, MODELGROUP::GENERIC}, - {"Coral", MODELNAME::MODELCORAL, {"", ""}, true, MODELGROUP::GENERIC}, - {"CoralStoneA", MODELNAME::MODELCORALSTONEA, {"", ""}, true, MODELGROUP::GENERIC}, - {"CoralStoneB", MODELNAME::MODELCORALSTONEB, {"", ""}, true, MODELGROUP::GENERIC}, - {"EnvironmentBox", - MODELNAME::MODELENVIRONMENTBOX, - {"diffuseVertexShader", "diffuseFragmentShader"}, - false, - MODELGROUP::OUTSIDE}, - {"FloorBase_Baked", MODELNAME::MODELFLOORBASE_BAKED, {"", ""}, true, MODELGROUP::GENERIC}, - {"GlobeBase", - MODELNAME::MODELGLOBEBASE, - {"diffuseVertexShader", "diffuseFragmentShader"}, - false, - MODELGROUP::GENERIC}, - {"GlobeInner", - MODELNAME::MODELGLOBEINNER, - {"innerRefractionMapVertexShader", "innerRefractionMapFragmentShader"}, - true, - MODELGROUP::INNER}, - {"RockA", MODELNAME::MODELROCKA, {"", ""}, true, MODELGROUP::GENERIC}, - {"RockB", MODELNAME::MODELROCKB, {"", ""}, true, MODELGROUP::GENERIC}, - {"RockC", MODELNAME::MODELROCKC, {"", ""}, true, MODELGROUP::GENERIC}, - {"RuinColumn", MODELNAME::MODELRUINCOlOMN, {"", ""}, true, MODELGROUP::GENERIC}, - {"Stone", MODELNAME::MODELSTONE, {"", ""}, true, MODELGROUP::GENERIC}, - {"SunknShipBoxes", MODELNAME::MODELSUNKNSHIPBOXES, {"", ""}, true, MODELGROUP::GENERIC}, - {"SunknShipDeck", MODELNAME::MODELSUNKNSHIPDECK, {"", ""}, true, MODELGROUP::GENERIC}, - {"SunknShipHull", MODELNAME::MODELSUNKNSHIPHULL, {"", ""}, true, MODELGROUP::GENERIC}, - {"SunknSub", MODELNAME::MODELSUNKNSUB, {"", ""}, true, MODELGROUP::GENERIC}, - {"SeaweedA", - MODELNAME::MODELSEAWEEDA, - {"seaweedVertexShader", "seaweedFragmentShader"}, - false, - MODELGROUP::SEAWEED, - true}, - {"SeaweedB", - MODELNAME::MODELSEAWEEDB, - {"seaweedVertexShader", "seaweedFragmentShader"}, - false, - MODELGROUP::SEAWEED, - true}, - {"Skybox", - MODELNAME::MODELSKYBOX, - {"diffuseVertexShader", "diffuseFragmentShader"}, - false, - MODELGROUP::OUTSIDE}, - {"SupportBeams", MODELNAME::MODELSUPPORTBEAMS, {"", ""}, false, MODELGROUP::OUTSIDE}, - {"TreasureChest", MODELNAME::MODELTREASURECHEST, {"", ""}, true, MODELGROUP::GENERIC}}; - -struct Fish -{ - const char *name; - MODELNAME modelName; - FISHENUM type; - float speed; - float speedRange; - float radius; - float radiusRange; - float tailSpeed; - float heightOffset; - float heightRange; - - float fishLength; - float fishWaveLength; - float fishBendAmount; - - bool lasers; - float laserRot; - float laserOff[3]; - float laserScale[3]; -}; - -const Fish fishTable[] = {{"SmallFishA", MODELNAME::MODELSMALLFISHA, FISHENUM::SMALL, 1.0f, 1.5f, - 30.0f, 25.0f, 10.0f, 0.0f, 16.0f, 10.0f, 1.0f, 2.0f}, - {"MediumFishA", MODELNAME::MODELMEDIUMFISHA, FISHENUM::MEDIUM, 1.0f, 2.0f, - 10.0f, 20.0f, 1.0f, 0.0f, 16.0f, 10.0f, -2.0f, 2.0f}, - {"MediumFishB", MODELNAME::MODELMEDIUMFISHB, FISHENUM::MEDIUM, 0.5f, 4.0f, - 10.0f, 20.0f, 3.0f, -8.0f, 5.0f, 10.0f, -2.0f, 2.0f}, - {"BigFishA", - MODELNAME::MODELBIGFISHA, - FISHENUM::BIG, - 0.5f, - 0.5f, - 50.0f, - 3.0f, - 1.5f, - 0.0f, - 16.0f, - 10.0f, - -1.0f, - 0.5f, - true, - 0.04f, - {0.0f, 0.1f, 9.0f}, - {0.3f, 0.3f, 1000.0f}}, - {"BigFishB", - MODELNAME::MODELBIGFISHB, - FISHENUM::BIG, - 0.5f, - 0.5f, - 45.0f, - 3.0f, - 1.0f, - 0.0f, - 16.0f, - 10.0f, - -0.7f, - 0.3f, - true, - 0.04f, - {0.0f, -0.3f, 9.0f}, - {0.3f, 0.3f, 1000.0f}}}; - -constexpr float g_tailOffsetMult = 1.0f; -constexpr float g_endOfDome = static_cast(M_PI / 8); -constexpr float g_tankRadius = 74.0f; -constexpr float g_tankHeight = 36.0f; -constexpr float g_standHeight = 25.0f; -constexpr float g_sharkSpeed = 0.3f; -constexpr float g_sharkClockOffset = 17.0f; -constexpr float g_sharkXClock = 1.0f; -constexpr float g_sharkYClock = 0.17f; -constexpr float g_sharkZClock = 1.0f; -constexpr int g_numBubbleSets = 10; -constexpr float g_laserEta = 1.2f; -constexpr float g_laserLenFudge = 1.0f; -constexpr int g_numLightRays = 5; -constexpr int g_lightRayY = 50; -constexpr int g_lightRayDurationMin = 1; -constexpr int g_lightRayDurationRange = 1; -constexpr int g_lightRaySpeed = 4; -constexpr int g_lightRaySpread = 7; -constexpr int g_lightRayPosRange = 20; -constexpr float g_lightRayRotRange = 1.0f; -constexpr float g_lightRayRotLerp = 0.2f; -constexpr float g_lightRayOffset = - static_cast(M_PI * 2 / static_cast(g_numLightRays)); -constexpr float g_bubbleTimer = 0.0f; -constexpr int g_bubbleIndex = 0; - -constexpr int g_numFishSmall = 100; -constexpr int g_numFishMedium = 1000; -constexpr int g_numFishBig = 10000; -constexpr int g_numFishLeftSmall = 80; -constexpr int g_numFishLeftBig = 160; -constexpr float g_sand_shininess = 5.0f; -constexpr float g_sand_specularFactor = 0.3f; -constexpr float g_generic_shininess = 50.0f; -constexpr float g_generic_specularFactor = 1.0f; -constexpr float g_outside_shininess = 50.0f; -constexpr float g_outside_specularFactor = 0.0f; -constexpr float g_seaweed_shininess = 50.0f; -constexpr float g_seaweed_specularFactor = 1.0f; -constexpr float g_inner_shininess = 50.0f; -constexpr float g_inner_specularFactor = 1.0f; -constexpr float g_fish_shininess = 5.0f; -constexpr float g_fish_specularFactor = 0.3f; - -constexpr float g_speed = 1.0f; -constexpr float g_targetHeight = 63.3f; -constexpr float g_targetRadius = 91.6f; -constexpr float g_eyeHeight = 7.5f; -constexpr float g_eyeSpeed = 0.0258f; -constexpr float g_filedOfView = 82.699f; -constexpr float g_ambientRed = 0.218f; -constexpr float g_ambientGreen = 0.502f; -constexpr float g_ambientBlue = 0.706f; -constexpr float g_fogPower = 16.5f; -constexpr float g_fogMult = 1.5f; -constexpr float g_fogOffset = 0.738f; -constexpr float g_fogRed = 0.338f; -constexpr float g_fogGreen = 0.81f; -constexpr float g_fogBlue = 1.0f; -constexpr float g_fishHeightRange = 1.0f; -constexpr float g_fishHeight = 25.0f; -constexpr float g_fishSpeed = 0.124f; -constexpr float g_fishOffset = 0.52f; -constexpr float g_fishXClock = 1.0f; -constexpr float g_fishYClock = 0.556f; -constexpr float g_fishZClock = 1.0f; -constexpr float g_fishTailSpeed = 1.0f; -constexpr float g_refractionFudge = 3.0f; -constexpr float g_eta = 1.0f; -constexpr float g_tankColorFudge = 0.796f; -constexpr float g_fovFudge = 1.0f; -constexpr float g_net_offset[3] = {0.0f, 0.0f, 0.0f}; -constexpr float g_net_offsetMult = 1.21f; -constexpr float g_eyeRadius = 13.2f; -constexpr float g_fieldOfView = 82.699f; - -struct Global -{ - float projection[16]; - float view[16]; - float worldInverse[16]; - float viewProjectionInverse[16]; - float skyView[16]; - float skyViewProjection[16]; - float skyViewProjectionInverse[16]; - float eyePosition[3]; - float target[3]; - float up[3] = {0, 1, 0}; - float v3t0[3]; - float v3t1[3]; - float m4t0[16]; - float m4t1[16]; - float m4t2[16]; - float m4t3[16]; - float colorMult[4] = {1, 1, 1, 1}; - float then; - float mclock; - float eyeClock; -}; - -struct LightWorldPositionUniform -{ - float lightWorldPos[3]; - float padding; - float viewProjection[16]; - float viewInverse[16]; -}; - -struct WorldUniforms -{ - float world[16]; - float worldInverseTranspose[16]; - float worldViewProjection[16]; -}; - -struct LightUniforms -{ - float lightColor[4]; - float specular[4]; - float ambient[4]; -}; - -struct FogUniforms -{ - float fogPower; - float fogMult; - float fogOffset; - float padding; - float fogColor[4]; -}; - -class Aquarium -{ - public: - Aquarium(); - ~Aquarium(); - bool init(int argc, char **argv); - void display(); - Texture *getSkybox() { return mTextureMap["skybox"]; } - - std::bitset(TOGGLE::TOGGLEMAX)> toggleBitset; - LightWorldPositionUniform lightWorldPositionUniform; - WorldUniforms worldUniforms; - LightUniforms lightUniforms; - FogUniforms fogUniforms; - Global g; - int fishCount[5]; - - private: - void render(); - void loadReource(); - void loadPlacement(); - void loadModels(); - void loadModel(const G_sceneInfo &info); - void setupModelEnumMap(); - void calculateFishCount(); - void updateWorldMatrixAndDraw(Model *model); - void updateGlobalUniforms(); - void drawBackground(); - void drawFishes(); - void drawSeaweed(); - void drawInner(); - void drawOutside(); - void updateWorldProjections(const std::vector &w); - BACKENDTYPE getBackendType(const std::string &backendPath); - float getElapsedTime(); - - std::unordered_map mModelEnumMap; - std::unordered_map mTextureMap; - std::unordered_map mProgramMap; - Model *mAquariumModels[MODELNAME::MODELMAX]; - Context *mContext; - FPSTimer mFpsTimer; // object to measure frames per second; - int mFishCount; - BACKENDTYPE mBackendType; - ContextFactory *mFactory; - std::vector mSkyUrls; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Aquarium.h: Define global variables, enums, constant variables and Class Aquarium. + +#ifndef AQUARIUM_H +#define AQUARIUM_H + +#include +#include +#include + +#include "../common/FPSTimer.h" + +class ContextFactory; +class Context; +class Texture; +class Program; +class Model; + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) +#define M_PI 3.141592653589793 +#else +#include "math.h" +#endif + +enum BACKENDTYPE : short +{ + BACKENDTYPEANGLE, + BACKENDTYPEDAWND3D12, + BACKENDTYPEDAWNMETAL, + BACKENDTYPEDAWNVULKAN, + BACKENDTYPED3D12, + BACKENDTYPEOPENGL, + BACKENDTYPELAST +}; + +enum MODELNAME : short +{ + MODELFIRST, + MODELRUINCOlOMN, + MODELARCH, + MODELROCKA, + MODELROCKB, + MODELROCKC, + MODELSUNKNSHIPBOXES, + MODELSUNKNSHIPDECK, + MODELSUNKNSHIPHULL, + MODELFLOORBASE_BAKED, + MODELSUNKNSUB, + MODELCORAL, + MODELSTONE, + MODELCORALSTONEA, + MODELCORALSTONEB, + MODELGLOBEBASE, + MODELTREASURECHEST, + MODELENVIRONMENTBOX, + MODELSUPPORTBEAMS, + MODELSKYBOX, + MODELGLOBEINNER, + MODELSEAWEEDA, + MODELSEAWEEDB, + MODELSMALLFISHA, + MODELMEDIUMFISHA, + MODELMEDIUMFISHB, + MODELBIGFISHA, + MODELBIGFISHB, + MODELSMALLFISHAINSTANCEDDRAWS, + MODELMEDIUMFISHAINSTANCEDDRAWS, + MODELMEDIUMFISHBINSTANCEDDRAWS, + MODELBIGFISHAINSTANCEDDRAWS, + MODELBIGFISHBINSTANCEDDRAWS, + MODELMAX +}; + +enum MODELGROUP : short +{ + FISH, + FISHINSTANCEDDRAW, + INNER, + SEAWEED, + GENERIC, + OUTSIDE, + GROUPMAX +}; + +struct G_sceneInfo +{ + const char *namestr; + MODELNAME name; + const char *program[2]; + bool fog; + MODELGROUP type; + bool blend; +}; + +enum FISHENUM : short +{ + BIG, + MEDIUM, + SMALL, + MAX +}; + +enum TOGGLE : short +{ + // Enable 4 times MSAA. + ENABLEMSAAx4, + // Go through instanced draw. + ENABLEINSTANCEDDRAWS, + // The toggle is only supported on Dawn backend. + // By default, the app will enable dynamic buffer offset. + // The toggle is to disable dbo feature. + ENABLEDYNAMICBUFFEROFFSET, + // Select integrated gpu if available. + INTEGRATEDGPU, + // Select discrete gpu if available. + DISCRETEGPU, + // Update and draw for each model on OpenGL and Angle backend, but draw once per frame on other + // backend. + UPATEANDDRAWFOREACHMODEL, + // Support Full Screen mode + ENABLEFULLSCREENMODE, + TOGGLEMAX +}; + +const G_sceneInfo g_sceneInfo[] = { + {"SmallFishA", + MODELNAME::MODELSMALLFISHA, + {"fishVertexShader", "fishReflectionFragmentShader"}, + true, + MODELGROUP::FISH}, + {"MediumFishA", + MODELNAME::MODELMEDIUMFISHA, + {"fishVertexShader", "fishNormalMapFragmentShader"}, + true, + MODELGROUP::FISH}, + {"MediumFishB", + MODELNAME::MODELMEDIUMFISHB, + {"fishVertexShader", "fishReflectionFragmentShader"}, + true, + MODELGROUP::FISH}, + {"BigFishA", + MODELNAME::MODELBIGFISHA, + {"fishVertexShader", "fishNormalMapFragmentShader"}, + true, + MODELGROUP::FISH}, + {"BigFishB", + MODELNAME::MODELBIGFISHB, + {"fishVertexShader", "fishNormalMapFragmentShader"}, + true, + MODELGROUP::FISH}, + {"SmallFishA", + MODELNAME::MODELSMALLFISHAINSTANCEDDRAWS, + {"fishVertexShaderInstancedDraws", "fishReflectionFragmentShader"}, + true, + MODELGROUP::FISHINSTANCEDDRAW}, + {"MediumFishA", + MODELNAME::MODELMEDIUMFISHAINSTANCEDDRAWS, + {"fishVertexShaderInstancedDraws", "fishNormalMapFragmentShader"}, + true, + MODELGROUP::FISHINSTANCEDDRAW}, + {"MediumFishB", + MODELNAME::MODELMEDIUMFISHBINSTANCEDDRAWS, + {"fishVertexShaderInstancedDraws", "fishReflectionFragmentShader"}, + true, + MODELGROUP::FISHINSTANCEDDRAW}, + {"BigFishA", + MODELNAME::MODELBIGFISHAINSTANCEDDRAWS, + {"fishVertexShaderInstancedDraws", "fishNormalMapFragmentShader"}, + true, + MODELGROUP::FISHINSTANCEDDRAW}, + {"BigFishB", + MODELNAME::MODELBIGFISHBINSTANCEDDRAWS, + {"fishVertexShaderInstancedDraws", "fishNormalMapFragmentShader"}, + true, + MODELGROUP::FISHINSTANCEDDRAW}, + {"Arch", MODELNAME::MODELARCH, {"", ""}, true, MODELGROUP::GENERIC}, + {"Coral", MODELNAME::MODELCORAL, {"", ""}, true, MODELGROUP::GENERIC}, + {"CoralStoneA", MODELNAME::MODELCORALSTONEA, {"", ""}, true, MODELGROUP::GENERIC}, + {"CoralStoneB", MODELNAME::MODELCORALSTONEB, {"", ""}, true, MODELGROUP::GENERIC}, + {"EnvironmentBox", + MODELNAME::MODELENVIRONMENTBOX, + {"diffuseVertexShader", "diffuseFragmentShader"}, + false, + MODELGROUP::OUTSIDE}, + {"FloorBase_Baked", MODELNAME::MODELFLOORBASE_BAKED, {"", ""}, true, MODELGROUP::GENERIC}, + {"GlobeBase", + MODELNAME::MODELGLOBEBASE, + {"diffuseVertexShader", "diffuseFragmentShader"}, + false, + MODELGROUP::GENERIC}, + {"GlobeInner", + MODELNAME::MODELGLOBEINNER, + {"innerRefractionMapVertexShader", "innerRefractionMapFragmentShader"}, + true, + MODELGROUP::INNER}, + {"RockA", MODELNAME::MODELROCKA, {"", ""}, true, MODELGROUP::GENERIC}, + {"RockB", MODELNAME::MODELROCKB, {"", ""}, true, MODELGROUP::GENERIC}, + {"RockC", MODELNAME::MODELROCKC, {"", ""}, true, MODELGROUP::GENERIC}, + {"RuinColumn", MODELNAME::MODELRUINCOlOMN, {"", ""}, true, MODELGROUP::GENERIC}, + {"Stone", MODELNAME::MODELSTONE, {"", ""}, true, MODELGROUP::GENERIC}, + {"SunknShipBoxes", MODELNAME::MODELSUNKNSHIPBOXES, {"", ""}, true, MODELGROUP::GENERIC}, + {"SunknShipDeck", MODELNAME::MODELSUNKNSHIPDECK, {"", ""}, true, MODELGROUP::GENERIC}, + {"SunknShipHull", MODELNAME::MODELSUNKNSHIPHULL, {"", ""}, true, MODELGROUP::GENERIC}, + {"SunknSub", MODELNAME::MODELSUNKNSUB, {"", ""}, true, MODELGROUP::GENERIC}, + {"SeaweedA", + MODELNAME::MODELSEAWEEDA, + {"seaweedVertexShader", "seaweedFragmentShader"}, + false, + MODELGROUP::SEAWEED, + true}, + {"SeaweedB", + MODELNAME::MODELSEAWEEDB, + {"seaweedVertexShader", "seaweedFragmentShader"}, + false, + MODELGROUP::SEAWEED, + true}, + {"Skybox", + MODELNAME::MODELSKYBOX, + {"diffuseVertexShader", "diffuseFragmentShader"}, + false, + MODELGROUP::OUTSIDE}, + {"SupportBeams", MODELNAME::MODELSUPPORTBEAMS, {"", ""}, false, MODELGROUP::OUTSIDE}, + {"TreasureChest", MODELNAME::MODELTREASURECHEST, {"", ""}, true, MODELGROUP::GENERIC}}; + +struct Fish +{ + const char *name; + MODELNAME modelName; + FISHENUM type; + float speed; + float speedRange; + float radius; + float radiusRange; + float tailSpeed; + float heightOffset; + float heightRange; + + float fishLength; + float fishWaveLength; + float fishBendAmount; + + bool lasers; + float laserRot; + float laserOff[3]; + float laserScale[3]; +}; + +const Fish fishTable[] = {{"SmallFishA", MODELNAME::MODELSMALLFISHA, FISHENUM::SMALL, 1.0f, 1.5f, + 30.0f, 25.0f, 10.0f, 0.0f, 16.0f, 10.0f, 1.0f, 2.0f}, + {"MediumFishA", MODELNAME::MODELMEDIUMFISHA, FISHENUM::MEDIUM, 1.0f, 2.0f, + 10.0f, 20.0f, 1.0f, 0.0f, 16.0f, 10.0f, -2.0f, 2.0f}, + {"MediumFishB", MODELNAME::MODELMEDIUMFISHB, FISHENUM::MEDIUM, 0.5f, 4.0f, + 10.0f, 20.0f, 3.0f, -8.0f, 5.0f, 10.0f, -2.0f, 2.0f}, + {"BigFishA", + MODELNAME::MODELBIGFISHA, + FISHENUM::BIG, + 0.5f, + 0.5f, + 50.0f, + 3.0f, + 1.5f, + 0.0f, + 16.0f, + 10.0f, + -1.0f, + 0.5f, + true, + 0.04f, + {0.0f, 0.1f, 9.0f}, + {0.3f, 0.3f, 1000.0f}}, + {"BigFishB", + MODELNAME::MODELBIGFISHB, + FISHENUM::BIG, + 0.5f, + 0.5f, + 45.0f, + 3.0f, + 1.0f, + 0.0f, + 16.0f, + 10.0f, + -0.7f, + 0.3f, + true, + 0.04f, + {0.0f, -0.3f, 9.0f}, + {0.3f, 0.3f, 1000.0f}}}; + +constexpr float g_tailOffsetMult = 1.0f; +constexpr float g_endOfDome = static_cast(M_PI / 8); +constexpr float g_tankRadius = 74.0f; +constexpr float g_tankHeight = 36.0f; +constexpr float g_standHeight = 25.0f; +constexpr float g_sharkSpeed = 0.3f; +constexpr float g_sharkClockOffset = 17.0f; +constexpr float g_sharkXClock = 1.0f; +constexpr float g_sharkYClock = 0.17f; +constexpr float g_sharkZClock = 1.0f; +constexpr int g_numBubbleSets = 10; +constexpr float g_laserEta = 1.2f; +constexpr float g_laserLenFudge = 1.0f; +constexpr int g_numLightRays = 5; +constexpr int g_lightRayY = 50; +constexpr int g_lightRayDurationMin = 1; +constexpr int g_lightRayDurationRange = 1; +constexpr int g_lightRaySpeed = 4; +constexpr int g_lightRaySpread = 7; +constexpr int g_lightRayPosRange = 20; +constexpr float g_lightRayRotRange = 1.0f; +constexpr float g_lightRayRotLerp = 0.2f; +constexpr float g_lightRayOffset = + static_cast(M_PI * 2 / static_cast(g_numLightRays)); +constexpr float g_bubbleTimer = 0.0f; +constexpr int g_bubbleIndex = 0; + +constexpr int g_numFishSmall = 100; +constexpr int g_numFishMedium = 1000; +constexpr int g_numFishBig = 10000; +constexpr int g_numFishLeftSmall = 80; +constexpr int g_numFishLeftBig = 160; +constexpr float g_sand_shininess = 5.0f; +constexpr float g_sand_specularFactor = 0.3f; +constexpr float g_generic_shininess = 50.0f; +constexpr float g_generic_specularFactor = 1.0f; +constexpr float g_outside_shininess = 50.0f; +constexpr float g_outside_specularFactor = 0.0f; +constexpr float g_seaweed_shininess = 50.0f; +constexpr float g_seaweed_specularFactor = 1.0f; +constexpr float g_inner_shininess = 50.0f; +constexpr float g_inner_specularFactor = 1.0f; +constexpr float g_fish_shininess = 5.0f; +constexpr float g_fish_specularFactor = 0.3f; + +constexpr float g_speed = 1.0f; +constexpr float g_targetHeight = 63.3f; +constexpr float g_targetRadius = 91.6f; +constexpr float g_eyeHeight = 7.5f; +constexpr float g_eyeSpeed = 0.0258f; +constexpr float g_filedOfView = 82.699f; +constexpr float g_ambientRed = 0.218f; +constexpr float g_ambientGreen = 0.502f; +constexpr float g_ambientBlue = 0.706f; +constexpr float g_fogPower = 16.5f; +constexpr float g_fogMult = 1.5f; +constexpr float g_fogOffset = 0.738f; +constexpr float g_fogRed = 0.338f; +constexpr float g_fogGreen = 0.81f; +constexpr float g_fogBlue = 1.0f; +constexpr float g_fishHeightRange = 1.0f; +constexpr float g_fishHeight = 25.0f; +constexpr float g_fishSpeed = 0.124f; +constexpr float g_fishOffset = 0.52f; +constexpr float g_fishXClock = 1.0f; +constexpr float g_fishYClock = 0.556f; +constexpr float g_fishZClock = 1.0f; +constexpr float g_fishTailSpeed = 1.0f; +constexpr float g_refractionFudge = 3.0f; +constexpr float g_eta = 1.0f; +constexpr float g_tankColorFudge = 0.796f; +constexpr float g_fovFudge = 1.0f; +constexpr float g_net_offset[3] = {0.0f, 0.0f, 0.0f}; +constexpr float g_net_offsetMult = 1.21f; +constexpr float g_eyeRadius = 13.2f; +constexpr float g_fieldOfView = 82.699f; + +struct Global +{ + float projection[16]; + float view[16]; + float worldInverse[16]; + float viewProjectionInverse[16]; + float skyView[16]; + float skyViewProjection[16]; + float skyViewProjectionInverse[16]; + float eyePosition[3]; + float target[3]; + float up[3] = {0, 1, 0}; + float v3t0[3]; + float v3t1[3]; + float m4t0[16]; + float m4t1[16]; + float m4t2[16]; + float m4t3[16]; + float colorMult[4] = {1, 1, 1, 1}; + float then; + float mclock; + float eyeClock; +}; + +struct LightWorldPositionUniform +{ + float lightWorldPos[3]; + float padding; + float viewProjection[16]; + float viewInverse[16]; +}; + +struct WorldUniforms +{ + float world[16]; + float worldInverseTranspose[16]; + float worldViewProjection[16]; +}; + +struct LightUniforms +{ + float lightColor[4]; + float specular[4]; + float ambient[4]; +}; + +struct FogUniforms +{ + float fogPower; + float fogMult; + float fogOffset; + float padding; + float fogColor[4]; +}; + +class Aquarium +{ + public: + Aquarium(); + ~Aquarium(); + bool init(int argc, char **argv); + void display(); + Texture *getSkybox() { return mTextureMap["skybox"]; } + + std::bitset(TOGGLE::TOGGLEMAX)> toggleBitset; + LightWorldPositionUniform lightWorldPositionUniform; + WorldUniforms worldUniforms; + LightUniforms lightUniforms; + FogUniforms fogUniforms; + Global g; + int fishCount[5]; + + private: + void render(); + void loadReource(); + void loadPlacement(); + void loadModels(); + void loadModel(const G_sceneInfo &info); + void setupModelEnumMap(); + void calculateFishCount(); + void updateWorldMatrixAndDraw(Model *model); + void updateGlobalUniforms(); + void drawBackground(); + void drawFishes(); + void drawSeaweed(); + void drawInner(); + void drawOutside(); + void updateWorldProjections(const std::vector &w); + BACKENDTYPE getBackendType(const std::string &backendPath); + float getElapsedTime(); + + std::unordered_map mModelEnumMap; + std::unordered_map mTextureMap; + std::unordered_map mProgramMap; + Model *mAquariumModels[MODELNAME::MODELMAX]; + Context *mContext; + FPSTimer mFpsTimer; // object to measure frames per second; + int mFishCount; + BACKENDTYPE mBackendType; + ContextFactory *mFactory; + std::vector mSkyUrls; +}; + +#endif diff --git a/src/aquarium-optimized/Buffer.h b/src/aquarium-optimized/Buffer.h index bae2fdb..a1ad138 100644 --- a/src/aquarium-optimized/Buffer.h +++ b/src/aquarium-optimized/Buffer.h @@ -1,23 +1,23 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Buffer.h: Define abstract Buffer Class and buffer type enum. - -#pragma once -#ifndef BUFFER_H -#define BUFFER_H 1 - -#include - -class Buffer -{ - public: - Buffer() {} - Buffer(int numComponents, int numElements, const std::vector &buffer){} - Buffer(int numComponents, int numElements, const std::vector &buffer){} - virtual ~Buffer(){} -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Buffer.h: Define abstract Buffer Class and buffer type enum. + +#pragma once +#ifndef BUFFER_H +#define BUFFER_H 1 + +#include + +class Buffer +{ + public: + Buffer() {} + Buffer(int numComponents, int numElements, const std::vector &buffer) {} + Buffer(int numComponents, int numElements, const std::vector &buffer) {} + virtual ~Buffer() {} +}; + +#endif diff --git a/src/aquarium-optimized/Context.h b/src/aquarium-optimized/Context.h index 4ea6f3e..1c2215b 100644 --- a/src/aquarium-optimized/Context.h +++ b/src/aquarium-optimized/Context.h @@ -1,85 +1,85 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Context.h: Defines the accessing to graphics API of a graphics backend. - -#pragma once -#ifndef Context_H -#define Context_H 1 - -#include -#include -#include - -#include "Aquarium.h" -#include "ResourceHelper.h" - -#include "common/FPSTimer.h" - -class Aquarium; -class Program; -class Buffer; -class Texture; -class Model; - -enum BACKENDTYPE : short; -enum MODELGROUP : short; -enum MODELNAME : short; -enum TOGGLE : short; - -struct Global; - -class Context -{ - public: - Context() {} - virtual ~Context() {} - virtual bool initialize( - BACKENDTYPE backend, - const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) = 0; - virtual Texture *createTexture(const std::string &name, const std::string &url) = 0; - virtual Texture *createTexture(const std::string &name, - const std::vector &urls) = 0; - virtual Buffer *createBuffer(int numComponents, std::vector *buffer, bool isIndex) = 0; - virtual Buffer *createBuffer(int numComponents, - std::vector *buffer, - bool isIndex) = 0; - virtual Program *createProgram(const std::string &mVId, const std::string &mFId) = 0; - virtual void setWindowTitle(const std::string &text) = 0; - virtual bool ShouldQuit() = 0; - virtual void KeyBoardQuit() = 0; - virtual void DoFlush() = 0; - virtual void Terminate() = 0; - virtual void FlushInit() {} - virtual void preFrame() = 0; - virtual void showWindow() = 0; - virtual void showFPS(const FPSTimer& fpsTimer) = 0; - virtual void destoryImgUI() = 0; - - int getClientWidth() const { return mClientWidth; } - int getclientHeight() const { return mClientHeight; } - std::bitset(TOGGLE::TOGGLEMAX)> getAvailableToggleBitset() - { - return mAvailableToggleBitset; - } - - virtual Model *createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) = 0; - - virtual void initGeneralResources(Aquarium *aquarium) {} - virtual void updateWorldlUniforms(Aquarium *aquarium) {} - - const ResourceHelper *getResourceHelper() { return mResourceHelper; } - - protected: - int mClientWidth; - int mClientHeight; - - ResourceHelper *mResourceHelper; - - std::bitset(TOGGLE::TOGGLEMAX)> mAvailableToggleBitset; - virtual void initAvailableToggleBitset(BACKENDTYPE backendType) = 0; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context.h: Defines the accessing to graphics API of a graphics backend. + +#pragma once +#ifndef Context_H +#define Context_H 1 + +#include +#include +#include + +#include "Aquarium.h" +#include "ResourceHelper.h" + +#include "common/FPSTimer.h" + +class Aquarium; +class Program; +class Buffer; +class Texture; +class Model; + +enum BACKENDTYPE : short; +enum MODELGROUP : short; +enum MODELNAME : short; +enum TOGGLE : short; + +struct Global; + +class Context +{ + public: + Context() {} + virtual ~Context() {} + virtual bool initialize( + BACKENDTYPE backend, + const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) = 0; + virtual Texture *createTexture(const std::string &name, const std::string &url) = 0; + virtual Texture *createTexture(const std::string &name, + const std::vector &urls) = 0; + virtual Buffer *createBuffer(int numComponents, std::vector *buffer, bool isIndex) = 0; + virtual Buffer *createBuffer(int numComponents, + std::vector *buffer, + bool isIndex) = 0; + virtual Program *createProgram(const std::string &mVId, const std::string &mFId) = 0; + virtual void setWindowTitle(const std::string &text) = 0; + virtual bool ShouldQuit() = 0; + virtual void KeyBoardQuit() = 0; + virtual void DoFlush() = 0; + virtual void Terminate() = 0; + virtual void FlushInit() {} + virtual void preFrame() = 0; + virtual void showWindow() = 0; + virtual void showFPS(const FPSTimer &fpsTimer) = 0; + virtual void destoryImgUI() = 0; + + int getClientWidth() const { return mClientWidth; } + int getclientHeight() const { return mClientHeight; } + std::bitset(TOGGLE::TOGGLEMAX)> getAvailableToggleBitset() + { + return mAvailableToggleBitset; + } + + virtual Model *createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) = 0; + + virtual void initGeneralResources(Aquarium *aquarium) {} + virtual void updateWorldlUniforms(Aquarium *aquarium) {} + + const ResourceHelper *getResourceHelper() { return mResourceHelper; } + + protected: + int mClientWidth; + int mClientHeight; + + ResourceHelper *mResourceHelper; + + std::bitset(TOGGLE::TOGGLEMAX)> mAvailableToggleBitset; + virtual void initAvailableToggleBitset(BACKENDTYPE backendType) = 0; +}; + +#endif diff --git a/src/aquarium-optimized/ContextFactory.cpp b/src/aquarium-optimized/ContextFactory.cpp index a6d1978..0e7fbd4 100644 --- a/src/aquarium-optimized/ContextFactory.cpp +++ b/src/aquarium-optimized/ContextFactory.cpp @@ -1,56 +1,56 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "Aquarium.h" -#include "ContextFactory.h" - -#include "opengl/ContextGL.h" -#ifdef ENABLE_DAWN_BACKEND -#include "dawn/ContextDawn.h" -#endif -#ifdef ENABLE_D3D12_BACKEND -#include "d3d12/ContextD3D12.h" -#endif - -ContextFactory::ContextFactory() : mContext(nullptr) {} - -ContextFactory::~ContextFactory() -{ - delete mContext; -} - -Context *ContextFactory::createContext(BACKENDTYPE backendType) -{ - switch (backendType) - { - case BACKENDTYPE::BACKENDTYPEOPENGL: - case BACKENDTYPE::BACKENDTYPEANGLE: - { - mContext = new ContextGL(backendType); - break; - } - case BACKENDTYPE::BACKENDTYPEDAWND3D12: - case BACKENDTYPE::BACKENDTYPEDAWNMETAL: - case BACKENDTYPE::BACKENDTYPEDAWNVULKAN: - { -#ifdef ENABLE_DAWN_BACKEND - mContext = new ContextDawn(backendType); -#endif - break; - } - case BACKENDTYPE::BACKENDTYPED3D12: - { -#ifdef ENABLE_D3D12_BACKEND - mContext = new ContextD3D12(backendType); - break; -#endif - } - default: - break; - } - - return mContext; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "ContextFactory.h" +#include "Aquarium.h" + +#include "opengl/ContextGL.h" +#ifdef ENABLE_DAWN_BACKEND +#include "dawn/ContextDawn.h" +#endif +#ifdef ENABLE_D3D12_BACKEND +#include "d3d12/ContextD3D12.h" +#endif + +ContextFactory::ContextFactory() : mContext(nullptr) {} + +ContextFactory::~ContextFactory() +{ + delete mContext; +} + +Context *ContextFactory::createContext(BACKENDTYPE backendType) +{ + switch (backendType) + { + case BACKENDTYPE::BACKENDTYPEOPENGL: + case BACKENDTYPE::BACKENDTYPEANGLE: + { + mContext = new ContextGL(backendType); + break; + } + case BACKENDTYPE::BACKENDTYPEDAWND3D12: + case BACKENDTYPE::BACKENDTYPEDAWNMETAL: + case BACKENDTYPE::BACKENDTYPEDAWNVULKAN: + { +#ifdef ENABLE_DAWN_BACKEND + mContext = new ContextDawn(backendType); +#endif + break; + } + case BACKENDTYPE::BACKENDTYPED3D12: + { +#ifdef ENABLE_D3D12_BACKEND + mContext = new ContextD3D12(backendType); + break; +#endif + } + default: + break; + } + + return mContext; +} diff --git a/src/aquarium-optimized/ContextFactory.h b/src/aquarium-optimized/ContextFactory.h index 65e6c84..ac51411 100644 --- a/src/aquarium-optimized/ContextFactory.h +++ b/src/aquarium-optimized/ContextFactory.h @@ -1,25 +1,25 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -#pragma once - -#ifndef CONTEXTFACTORY -#define CONTEXTFACTORY 1 - -class Context; -enum BACKENDTYPE : short; - -class ContextFactory -{ - public: - ContextFactory(); - ~ContextFactory(); - Context *createContext(BACKENDTYPE backendType); - - private: - Context *mContext; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +#pragma once + +#ifndef CONTEXTFACTORY +#define CONTEXTFACTORY 1 + +class Context; +enum BACKENDTYPE : short; + +class ContextFactory +{ + public: + ContextFactory(); + ~ContextFactory(); + Context *createContext(BACKENDTYPE backendType); + + private: + Context *mContext; +}; + +#endif diff --git a/src/aquarium-optimized/FishModel.h b/src/aquarium-optimized/FishModel.h index a260635..34aa957 100644 --- a/src/aquarium-optimized/FishModel.h +++ b/src/aquarium-optimized/FishModel.h @@ -1,30 +1,30 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FishModel.h: Define fish model. Update fish specific uniforms. - -#pragma once -#ifndef FISHMODEL_H -#define FISHMODEL_H 1 - -#include "Model.h" - -class FishModel : public Model -{ - public: - FishModel(MODELGROUP type, MODELNAME name, bool blend) : Model(type, name, blend){} - - virtual void updateFishPerUniforms(float x, - float y, - float z, - float nextX, - float nextY, - float nextZ, - float scale, - float time, - int index) = 0; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FishModel.h: Define fish model. Update fish specific uniforms. + +#pragma once +#ifndef FISHMODEL_H +#define FISHMODEL_H 1 + +#include "Model.h" + +class FishModel : public Model +{ + public: + FishModel(MODELGROUP type, MODELNAME name, bool blend) : Model(type, name, blend) {} + + virtual void updateFishPerUniforms(float x, + float y, + float z, + float nextX, + float nextY, + float nextZ, + float scale, + float time, + int index) = 0; +}; + +#endif diff --git a/src/aquarium-optimized/Main.cpp b/src/aquarium-optimized/Main.cpp index f6733fa..cae7ac9 100644 --- a/src/aquarium-optimized/Main.cpp +++ b/src/aquarium-optimized/Main.cpp @@ -1,20 +1,21 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Main.cpp: Entry class of Aquarium. - -#include "Aquarium.h" - -int main(int argc, char **argv) { - Aquarium aquarium; - if (!aquarium.init(argc, argv)) - { - return -1; - } - - aquarium.display(); - - return 0; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Main.cpp: Entry class of Aquarium. + +#include "Aquarium.h" + +int main(int argc, char **argv) +{ + Aquarium aquarium; + if (!aquarium.init(argc, argv)) + { + return -1; + } + + aquarium.display(); + + return 0; +} diff --git a/src/aquarium-optimized/Matrix.h b/src/aquarium-optimized/Matrix.h index bf4f23e..da7cbd8 100644 --- a/src/aquarium-optimized/Matrix.h +++ b/src/aquarium-optimized/Matrix.h @@ -1,383 +1,384 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Matrix.h: Do matrix calculations including multiply, addition, substraction, -// transpose, inverse, translation, etc. - -#pragma once -#ifndef MATRIX_H -#define MATIRX_H 1 - -#include - -namespace matrix { -static long long RANDOM_RANGE_ = 4294967296; - -template -void mulMatrixMatrix4(T *dst, const T *a, const T *b) -{ - T a00 = a[0]; - T a01 = a[1]; - T a02 = a[2]; - T a03 = a[3]; - T a10 = a[4 + 0]; - T a11 = a[4 + 1]; - T a12 = a[4 + 2]; - T a13 = a[4 + 3]; - T a20 = a[8 + 0]; - T a21 = a[8 + 1]; - T a22 = a[8 + 2]; - T a23 = a[8 + 3]; - T a30 = a[12 + 0]; - T a31 = a[12 + 1]; - T a32 = a[12 + 2]; - T a33 = a[12 + 3]; - T b00 = b[0]; - T b01 = b[1]; - T b02 = b[2]; - T b03 = b[3]; - T b10 = b[4 + 0]; - T b11 = b[4 + 1]; - T b12 = b[4 + 2]; - T b13 = b[4 + 3]; - T b20 = b[8 + 0]; - T b21 = b[8 + 1]; - T b22 = b[8 + 2]; - T b23 = b[8 + 3]; - T b30 = b[12 + 0]; - T b31 = b[12 + 1]; - T b32 = b[12 + 2]; - T b33 = b[12 + 3]; - dst[0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30; - dst[1] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31; - dst[2] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32; - dst[3] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33; - dst[4] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30; - dst[5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31; - dst[6] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32; - dst[7] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33; - dst[8] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30; - dst[9] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31; - dst[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32; - dst[11] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33; - dst[12] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30; - dst[13] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31; - dst[14] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32; - dst[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33; -} - -template -void inverse4(T *dst, const T *m) -{ - T m00 = m[0 * 4 + 0]; - T m01 = m[0 * 4 + 1]; - T m02 = m[0 * 4 + 2]; - T m03 = m[0 * 4 + 3]; - T m10 = m[1 * 4 + 0]; - T m11 = m[1 * 4 + 1]; - T m12 = m[1 * 4 + 2]; - T m13 = m[1 * 4 + 3]; - T m20 = m[2 * 4 + 0]; - T m21 = m[2 * 4 + 1]; - T m22 = m[2 * 4 + 2]; - T m23 = m[2 * 4 + 3]; - T m30 = m[3 * 4 + 0]; - T m31 = m[3 * 4 + 1]; - T m32 = m[3 * 4 + 2]; - T m33 = m[3 * 4 + 3]; - T tmp_0 = m22 * m33; - T tmp_1 = m32 * m23; - T tmp_2 = m12 * m33; - T tmp_3 = m32 * m13; - T tmp_4 = m12 * m23; - T tmp_5 = m22 * m13; - T tmp_6 = m02 * m33; - T tmp_7 = m32 * m03; - T tmp_8 = m02 * m23; - T tmp_9 = m22 * m03; - T tmp_10 = m02 * m13; - T tmp_11 = m12 * m03; - T tmp_12 = m20 * m31; - T tmp_13 = m30 * m21; - T tmp_14 = m10 * m31; - T tmp_15 = m30 * m11; - T tmp_16 = m10 * m21; - T tmp_17 = m20 * m11; - T tmp_18 = m00 * m31; - T tmp_19 = m30 * m01; - T tmp_20 = m00 * m21; - T tmp_21 = m20 * m01; - T tmp_22 = m00 * m11; - T tmp_23 = m10 * m01; - - T t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) - (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31); - T t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) - (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31); - T t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) - (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31); - T t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) - (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21); - - T d = static_cast(1.0) / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3); - - dst[0] = d * t0; - dst[1] = d * t1; - dst[2] = d * t2; - dst[3] = d * t3; - dst[4] = - d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) - (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)); - dst[5] = - d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) - (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)); - dst[6] = d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) - - (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)); - dst[7] = d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) - - (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20)); - dst[8] = d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) - - (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)); - dst[9] = d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) - - (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)); - dst[10] = d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) - - (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)); - dst[11] = d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) - - (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23)); - dst[12] = d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) - - (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)); - dst[13] = d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) - - (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)); - dst[14] = d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) - - (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)); - dst[15] = d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) - - (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02)); -} - -template -void transpose4(T *dst, const T *m) -{ - T m00 = m[0 * 4 + 0]; - T m01 = m[0 * 4 + 1]; - T m02 = m[0 * 4 + 2]; - T m03 = m[0 * 4 + 3]; - T m10 = m[1 * 4 + 0]; - T m11 = m[1 * 4 + 1]; - T m12 = m[1 * 4 + 2]; - T m13 = m[1 * 4 + 3]; - T m20 = m[2 * 4 + 0]; - T m21 = m[2 * 4 + 1]; - T m22 = m[2 * 4 + 2]; - T m23 = m[2 * 4 + 3]; - T m30 = m[3 * 4 + 0]; - T m31 = m[3 * 4 + 1]; - T m32 = m[3 * 4 + 2]; - T m33 = m[3 * 4 + 3]; - - dst[0] = m00; - dst[1] = m10; - dst[2] = m20; - dst[3] = m30; - dst[4] = m01; - dst[5] = m11; - dst[6] = m21; - dst[7] = m31; - dst[8] = m02; - dst[9] = m12; - dst[10] = m22; - dst[11] = m32; - dst[12] = m03; - dst[13] = m13; - dst[14] = m23; - dst[15] = m33; -} - -template -void frustum(T *dst, T left, T right, T bottom, T top, T near_, T far_) -{ - T dx = right - left; - T dy = top - bottom; - T dz = near_ - far_; - - dst[0] = 2 * near_ / dx; - dst[1] = 0; - dst[2] = 0; - dst[3] = 0; - dst[4] = 0; - dst[5] = 2 * near_ / dy; - dst[6] = 0; - dst[7] = 0; - dst[8] = (left + right) / dx; - dst[9] = (top + bottom) / dy; - dst[10] = far_ / dz; - dst[11] = -1; - dst[12] = 0; - dst[13] = 0; - dst[14] = near_ * far_ / dz; - dst[15] = 0; -} - -template -void getAxis(T *dst, const T *m, int axis) -{ - int off = axis * 4; - dst[0] = m[off + 0]; - dst[1] = m[off + 1]; - dst[2] = m[off + 2]; -} - -template -void mulScalarVector(T k, T *v, size_t length) -{ - for (size_t i = 0; i < length; ++i) - { - v[i] = v[i] * k; - } -} - -template -void addVector(T *dst, const T *a, const T *b, size_t length) -{ - for (size_t i = 0; i < length; ++i) - { - dst[i] = a[i] + b[i]; - } -} - -template -void normalize(T *dst, const T *a, size_t length) -{ - T n = 0.0; - - for (size_t i = 0; i < length; ++i) - n += a[i] * a[i]; - n = sqrt(n); - if (n > 0.00001) - { - for (size_t i = 0; i < length; ++i) - dst[i] = a[i] / n; - } - else - { - for (size_t i = 0; i < length; ++i) - dst[i] = 0; - } -} - -template -void subVector(T *dst, const T *a, const T *b, size_t length) -{ - - for (size_t i = 0; i < length; ++i) - { - dst[i] = a[i] - b[i]; - } -} - -template -void cross(T *dst, const T *a, const T *b) -{ - dst[0] = a[1] * b[2] - a[2] * b[1]; - dst[1] = a[2] * b[0] - a[0] * b[2]; - dst[2] = a[0] * b[1] - a[1] * b[0]; -} - -template -T dot(T *a, T *b) -{ - return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]); -} - -template -void cameraLookAt(T *dst, const T *eye, const T *target, const T *up) -{ - T t0[3]; - T t1[3]; - T t2[3]; - subVector(t0, eye, target, 3); - normalize(t0, t0, 3); - cross(t1, up, t0); - normalize(t1, t1, 3); - cross(t2, t0, t1); - - dst[0] = t1[0]; - dst[1] = t1[1]; - dst[2] = t1[2]; - dst[3] = 0; - dst[4] = t2[0]; - dst[5] = t2[1]; - dst[6] = t2[2]; - dst[7] = 0; - dst[8] = t0[0]; - dst[9] = t0[1]; - dst[10] = t0[2]; - dst[11] = 0; - dst[12] = eye[0]; - dst[13] = eye[1]; - dst[14] = eye[2]; - dst[15] = 1; -} - -static long long randomSeed_; -void resetPseudoRandom() -{ - randomSeed_ = 0; -} - -static double pseudoRandom() -{ - randomSeed_ = (134775813 * randomSeed_ + 1) % RANDOM_RANGE_; - return static_cast(randomSeed_) / static_cast(RANDOM_RANGE_); -} - -template -void translation(T *dst, const T *v) -{ - dst[0] = 1; - dst[1] = 0; - dst[2] = 0; - dst[3] = 0; - dst[4] = 0; - dst[5] = 1; - dst[6] = 0; - dst[7] = 0; - dst[8] = 0; - dst[9] = 0; - dst[10] = 1; - dst[11] = 0; - dst[12] = v[0]; - dst[13] = v[1]; - dst[14] = v[2]; - dst[15] = 1; -} - -template -void translate(float *m, const float *v) -{ - T v0 = v[0]; - T v1 = v[1]; - T v2 = v[2]; - T m00 = m[0]; - T m01 = m[1]; - T m02 = m[2]; - T m03 = m[3]; - T m10 = m[1 * 4 + 0]; - T m11 = m[1 * 4 + 1]; - T m12 = m[1 * 4 + 2]; - T m13 = m[1 * 4 + 3]; - T m20 = m[2 * 4 + 0]; - T m21 = m[2 * 4 + 1]; - T m22 = m[2 * 4 + 2]; - T m23 = m[2 * 4 + 3]; - T m30 = m[3 * 4 + 0]; - T m31 = m[3 * 4 + 1]; - T m32 = m[3 * 4 + 2]; - T m33 = m[3 * 4 + 3]; - - m[12] = m00 * v0 + m10 * v1 + m20 * v2 + m30; - m[13] = m01 * v0 + m11 * v1 + m21 * v2 + m31; - m[14] = m02 * v0 + m12 * v1 + m22 * v2 + m32; - m[15] = m03 * v0 + m13 * v1 + m23 * v2 + m33; -} - -float degToRad(float degrees) -{ - return static_cast(degrees * M_PI / 180.0); -} -} -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Matrix.h: Do matrix calculations including multiply, addition, substraction, +// transpose, inverse, translation, etc. + +#pragma once +#ifndef MATRIX_H +#define MATIRX_H 1 + +#include + +namespace matrix +{ +static long long RANDOM_RANGE_ = 4294967296; + +template +void mulMatrixMatrix4(T *dst, const T *a, const T *b) +{ + T a00 = a[0]; + T a01 = a[1]; + T a02 = a[2]; + T a03 = a[3]; + T a10 = a[4 + 0]; + T a11 = a[4 + 1]; + T a12 = a[4 + 2]; + T a13 = a[4 + 3]; + T a20 = a[8 + 0]; + T a21 = a[8 + 1]; + T a22 = a[8 + 2]; + T a23 = a[8 + 3]; + T a30 = a[12 + 0]; + T a31 = a[12 + 1]; + T a32 = a[12 + 2]; + T a33 = a[12 + 3]; + T b00 = b[0]; + T b01 = b[1]; + T b02 = b[2]; + T b03 = b[3]; + T b10 = b[4 + 0]; + T b11 = b[4 + 1]; + T b12 = b[4 + 2]; + T b13 = b[4 + 3]; + T b20 = b[8 + 0]; + T b21 = b[8 + 1]; + T b22 = b[8 + 2]; + T b23 = b[8 + 3]; + T b30 = b[12 + 0]; + T b31 = b[12 + 1]; + T b32 = b[12 + 2]; + T b33 = b[12 + 3]; + dst[0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30; + dst[1] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31; + dst[2] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32; + dst[3] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33; + dst[4] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30; + dst[5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31; + dst[6] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32; + dst[7] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33; + dst[8] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30; + dst[9] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31; + dst[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32; + dst[11] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33; + dst[12] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30; + dst[13] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31; + dst[14] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32; + dst[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33; +} + +template +void inverse4(T *dst, const T *m) +{ + T m00 = m[0 * 4 + 0]; + T m01 = m[0 * 4 + 1]; + T m02 = m[0 * 4 + 2]; + T m03 = m[0 * 4 + 3]; + T m10 = m[1 * 4 + 0]; + T m11 = m[1 * 4 + 1]; + T m12 = m[1 * 4 + 2]; + T m13 = m[1 * 4 + 3]; + T m20 = m[2 * 4 + 0]; + T m21 = m[2 * 4 + 1]; + T m22 = m[2 * 4 + 2]; + T m23 = m[2 * 4 + 3]; + T m30 = m[3 * 4 + 0]; + T m31 = m[3 * 4 + 1]; + T m32 = m[3 * 4 + 2]; + T m33 = m[3 * 4 + 3]; + T tmp_0 = m22 * m33; + T tmp_1 = m32 * m23; + T tmp_2 = m12 * m33; + T tmp_3 = m32 * m13; + T tmp_4 = m12 * m23; + T tmp_5 = m22 * m13; + T tmp_6 = m02 * m33; + T tmp_7 = m32 * m03; + T tmp_8 = m02 * m23; + T tmp_9 = m22 * m03; + T tmp_10 = m02 * m13; + T tmp_11 = m12 * m03; + T tmp_12 = m20 * m31; + T tmp_13 = m30 * m21; + T tmp_14 = m10 * m31; + T tmp_15 = m30 * m11; + T tmp_16 = m10 * m21; + T tmp_17 = m20 * m11; + T tmp_18 = m00 * m31; + T tmp_19 = m30 * m01; + T tmp_20 = m00 * m21; + T tmp_21 = m20 * m01; + T tmp_22 = m00 * m11; + T tmp_23 = m10 * m01; + + T t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) - (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31); + T t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) - (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31); + T t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) - (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31); + T t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) - (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21); + + T d = static_cast(1.0) / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3); + + dst[0] = d * t0; + dst[1] = d * t1; + dst[2] = d * t2; + dst[3] = d * t3; + dst[4] = + d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) - (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)); + dst[5] = + d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) - (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)); + dst[6] = d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) - + (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)); + dst[7] = d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) - + (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20)); + dst[8] = d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) - + (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)); + dst[9] = d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) - + (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)); + dst[10] = d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) - + (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)); + dst[11] = d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) - + (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23)); + dst[12] = d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) - + (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)); + dst[13] = d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) - + (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)); + dst[14] = d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) - + (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)); + dst[15] = d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) - + (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02)); +} + +template +void transpose4(T *dst, const T *m) +{ + T m00 = m[0 * 4 + 0]; + T m01 = m[0 * 4 + 1]; + T m02 = m[0 * 4 + 2]; + T m03 = m[0 * 4 + 3]; + T m10 = m[1 * 4 + 0]; + T m11 = m[1 * 4 + 1]; + T m12 = m[1 * 4 + 2]; + T m13 = m[1 * 4 + 3]; + T m20 = m[2 * 4 + 0]; + T m21 = m[2 * 4 + 1]; + T m22 = m[2 * 4 + 2]; + T m23 = m[2 * 4 + 3]; + T m30 = m[3 * 4 + 0]; + T m31 = m[3 * 4 + 1]; + T m32 = m[3 * 4 + 2]; + T m33 = m[3 * 4 + 3]; + + dst[0] = m00; + dst[1] = m10; + dst[2] = m20; + dst[3] = m30; + dst[4] = m01; + dst[5] = m11; + dst[6] = m21; + dst[7] = m31; + dst[8] = m02; + dst[9] = m12; + dst[10] = m22; + dst[11] = m32; + dst[12] = m03; + dst[13] = m13; + dst[14] = m23; + dst[15] = m33; +} + +template +void frustum(T *dst, T left, T right, T bottom, T top, T near_, T far_) +{ + T dx = right - left; + T dy = top - bottom; + T dz = near_ - far_; + + dst[0] = 2 * near_ / dx; + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + dst[4] = 0; + dst[5] = 2 * near_ / dy; + dst[6] = 0; + dst[7] = 0; + dst[8] = (left + right) / dx; + dst[9] = (top + bottom) / dy; + dst[10] = far_ / dz; + dst[11] = -1; + dst[12] = 0; + dst[13] = 0; + dst[14] = near_ * far_ / dz; + dst[15] = 0; +} + +template +void getAxis(T *dst, const T *m, int axis) +{ + int off = axis * 4; + dst[0] = m[off + 0]; + dst[1] = m[off + 1]; + dst[2] = m[off + 2]; +} + +template +void mulScalarVector(T k, T *v, size_t length) +{ + for (size_t i = 0; i < length; ++i) + { + v[i] = v[i] * k; + } +} + +template +void addVector(T *dst, const T *a, const T *b, size_t length) +{ + for (size_t i = 0; i < length; ++i) + { + dst[i] = a[i] + b[i]; + } +} + +template +void normalize(T *dst, const T *a, size_t length) +{ + T n = 0.0; + + for (size_t i = 0; i < length; ++i) + n += a[i] * a[i]; + n = sqrt(n); + if (n > 0.00001) + { + for (size_t i = 0; i < length; ++i) + dst[i] = a[i] / n; + } + else + { + for (size_t i = 0; i < length; ++i) + dst[i] = 0; + } +} + +template +void subVector(T *dst, const T *a, const T *b, size_t length) +{ + + for (size_t i = 0; i < length; ++i) + { + dst[i] = a[i] - b[i]; + } +} + +template +void cross(T *dst, const T *a, const T *b) +{ + dst[0] = a[1] * b[2] - a[2] * b[1]; + dst[1] = a[2] * b[0] - a[0] * b[2]; + dst[2] = a[0] * b[1] - a[1] * b[0]; +} + +template +T dot(T *a, T *b) +{ + return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]); +} + +template +void cameraLookAt(T *dst, const T *eye, const T *target, const T *up) +{ + T t0[3]; + T t1[3]; + T t2[3]; + subVector(t0, eye, target, 3); + normalize(t0, t0, 3); + cross(t1, up, t0); + normalize(t1, t1, 3); + cross(t2, t0, t1); + + dst[0] = t1[0]; + dst[1] = t1[1]; + dst[2] = t1[2]; + dst[3] = 0; + dst[4] = t2[0]; + dst[5] = t2[1]; + dst[6] = t2[2]; + dst[7] = 0; + dst[8] = t0[0]; + dst[9] = t0[1]; + dst[10] = t0[2]; + dst[11] = 0; + dst[12] = eye[0]; + dst[13] = eye[1]; + dst[14] = eye[2]; + dst[15] = 1; +} + +static long long randomSeed_; +void resetPseudoRandom() +{ + randomSeed_ = 0; +} + +static double pseudoRandom() +{ + randomSeed_ = (134775813 * randomSeed_ + 1) % RANDOM_RANGE_; + return static_cast(randomSeed_) / static_cast(RANDOM_RANGE_); +} + +template +void translation(T *dst, const T *v) +{ + dst[0] = 1; + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + dst[4] = 0; + dst[5] = 1; + dst[6] = 0; + dst[7] = 0; + dst[8] = 0; + dst[9] = 0; + dst[10] = 1; + dst[11] = 0; + dst[12] = v[0]; + dst[13] = v[1]; + dst[14] = v[2]; + dst[15] = 1; +} + +template +void translate(float *m, const float *v) +{ + T v0 = v[0]; + T v1 = v[1]; + T v2 = v[2]; + T m00 = m[0]; + T m01 = m[1]; + T m02 = m[2]; + T m03 = m[3]; + T m10 = m[1 * 4 + 0]; + T m11 = m[1 * 4 + 1]; + T m12 = m[1 * 4 + 2]; + T m13 = m[1 * 4 + 3]; + T m20 = m[2 * 4 + 0]; + T m21 = m[2 * 4 + 1]; + T m22 = m[2 * 4 + 2]; + T m23 = m[2 * 4 + 3]; + T m30 = m[3 * 4 + 0]; + T m31 = m[3 * 4 + 1]; + T m32 = m[3 * 4 + 2]; + T m33 = m[3 * 4 + 3]; + + m[12] = m00 * v0 + m10 * v1 + m20 * v2 + m30; + m[13] = m01 * v0 + m11 * v1 + m21 * v2 + m31; + m[14] = m02 * v0 + m12 * v1 + m22 * v2 + m32; + m[15] = m03 * v0 + m13 * v1 + m23 * v2 + m33; +} + +float degToRad(float degrees) +{ + return static_cast(degrees * M_PI / 180.0); +} +} // namespace matrix +#endif diff --git a/src/aquarium-optimized/Model.cpp b/src/aquarium-optimized/Model.cpp index 1d33d05..edb2212 100644 --- a/src/aquarium-optimized/Model.cpp +++ b/src/aquarium-optimized/Model.cpp @@ -1,34 +1,29 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Model.cpp: Implement common functions of Model. - -#include "Aquarium.h" -#include "Buffer.h" -#include "Model.h" - -Model::Model() - : mProgram(nullptr), - mBlend(false), - mName(MODELMAX) -{ -} - -Model::~Model() -{ - for (auto &buf : bufferMap) - { - if (buf.second != nullptr) - { - delete buf.second; - buf.second = nullptr; - } - } -} - -void Model::setProgram(Program *prgm) -{ - mProgram = prgm; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Model.cpp: Implement common functions of Model. + +#include "Model.h" +#include "Aquarium.h" +#include "Buffer.h" + +Model::Model() : mProgram(nullptr), mBlend(false), mName(MODELMAX) {} + +Model::~Model() +{ + for (auto &buf : bufferMap) + { + if (buf.second != nullptr) + { + delete buf.second; + buf.second = nullptr; + } + } +} + +void Model::setProgram(Program *prgm) +{ + mProgram = prgm; +} diff --git a/src/aquarium-optimized/Model.h b/src/aquarium-optimized/Model.h index a58ae20..b8ee292 100644 --- a/src/aquarium-optimized/Model.h +++ b/src/aquarium-optimized/Model.h @@ -1,53 +1,54 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Model.h: Define base Class Model for all of the models. -// Contains programs, textures and buffers info of models. -// Apply program for its model. Update uniforms, textures -// and buffers for each frame. - -#ifndef MODEL_H -#define MODEL_H 1 - -#include -#include - -#include "Aquarium.h" - -class Program; -class Context; -class Texture; -class Buffer; - -enum MODELGROUP : short; -enum MODELNAME : short; -struct WorldUniforms; - -class Model -{ - public: - Model(); - Model(MODELGROUP type, MODELNAME name, bool blend) - : mProgram(nullptr), mBlend(blend), mName(name) {} - virtual ~Model(); - virtual void prepareForDraw() const = 0; - virtual void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) = 0; - virtual void draw() = 0; - - void setProgram(Program *program); - virtual void init() = 0; - - std::vector> worldmatrices; - std::unordered_map textureMap; - std::unordered_map bufferMap; - - protected: - Program *mProgram; - bool mBlend; - MODELNAME mName; - -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Model.h: Define base Class Model for all of the models. +// Contains programs, textures and buffers info of models. +// Apply program for its model. Update uniforms, textures +// and buffers for each frame. + +#ifndef MODEL_H +#define MODEL_H 1 + +#include +#include + +#include "Aquarium.h" + +class Program; +class Context; +class Texture; +class Buffer; + +enum MODELGROUP : short; +enum MODELNAME : short; +struct WorldUniforms; + +class Model +{ + public: + Model(); + Model(MODELGROUP type, MODELNAME name, bool blend) + : mProgram(nullptr), mBlend(blend), mName(name) + { + } + virtual ~Model(); + virtual void prepareForDraw() const = 0; + virtual void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) = 0; + virtual void draw() = 0; + + void setProgram(Program *program); + virtual void init() = 0; + + std::vector> worldmatrices; + std::unordered_map textureMap; + std::unordered_map bufferMap; + + protected: + Program *mProgram; + bool mBlend; + MODELNAME mName; +}; + +#endif diff --git a/src/aquarium-optimized/Program.h b/src/aquarium-optimized/Program.h index cdd9f22..250d741 100644 --- a/src/aquarium-optimized/Program.h +++ b/src/aquarium-optimized/Program.h @@ -1,32 +1,31 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Program.h: Define base class for Programs of specific backends. - -#ifndef PROGRAM_H -#define PROGRAM_H 1 - -#include - -enum UNIFORMNAME : short; - -class Program -{ - public: - Program(){} - Program(const std::string &mVertexShader, const std::string &fragmentShader) - : mVId(mVertexShader), mFId(fragmentShader) - { - } - virtual ~Program() {} - virtual void setProgram() {} - - protected: - std::string mVId; - std::string mFId; -}; - -#endif // !PROGRAM_H - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Program.h: Define base class for Programs of specific backends. + +#ifndef PROGRAM_H +#define PROGRAM_H 1 + +#include + +enum UNIFORMNAME : short; + +class Program +{ + public: + Program() {} + Program(const std::string &mVertexShader, const std::string &fragmentShader) + : mVId(mVertexShader), mFId(fragmentShader) + { + } + virtual ~Program() {} + virtual void setProgram() {} + + protected: + std::string mVId; + std::string mFId; +}; + +#endif // !PROGRAM_H diff --git a/src/aquarium-optimized/ResourceHelper.cpp b/src/aquarium-optimized/ResourceHelper.cpp index bd8040e..f5a776c 100644 --- a/src/aquarium-optimized/ResourceHelper.cpp +++ b/src/aquarium-optimized/ResourceHelper.cpp @@ -1,88 +1,88 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -#include "ResourceHelper.h" - -#include - -#ifdef _WIN32 -#include -#include "Windows.h" -const std::string slash = "\\"; -#elif __APPLE__ -#include -const std::string slash = "/"; -#else -#include -const std::string slash = "/"; -#endif - -static const char *shaderFolder = "shaders"; -static const char *resourceFolder = "assets"; - -const std::vector skyBoxUrls = { - "GlobeOuter_EM_positive_x.jpg", "GlobeOuter_EM_negative_x.jpg", "GlobeOuter_EM_positive_y.jpg", - "GlobeOuter_EM_negative_y.jpg", "GlobeOuter_EM_positive_z.jpg", "GlobeOuter_EM_negative_z.jpg"}; - -ResourceHelper::ResourceHelper(const std::string &mBackendName, const std::string &mShaderVersion) - : mBackendName(mBackendName), mShaderVersion(mShaderVersion) -{ -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) - TCHAR temp[200]; - GetModuleFileName(nullptr, temp, MAX_PATH); - std::wstring ws(temp); - mPath = std::string(ws.begin(), ws.end()); -#elif __APPLE__ - char temp[200]; - uint32_t size = sizeof(temp); - _NSGetExecutablePath(temp, &size); - mPath = std::string(temp); -#else - char temp[200]; - readlink("/proc/self/exe", temp, sizeof(temp)); - mPath = std::string(temp); -#endif - - size_t nPos = mPath.find_last_of(slash); - std::ostringstream pathStream; - pathStream << mPath.substr(0, nPos) << slash << ".." << slash << ".." << slash; - mPath = pathStream.str(); - - std::ostringstream placementStream; - placementStream << mPath << resourceFolder << slash << "PropPlacement.js"; - mPropPlacementPath = placementStream.str(); - - std::ostringstream imageStream; - imageStream << mPath << resourceFolder << slash; - mImagePath = imageStream.str(); -} - -void ResourceHelper::getSkyBoxUrls(std::vector *skyUrls) const -{ - for (auto &str : skyBoxUrls) - { - std::ostringstream url; - url << mPath << resourceFolder << slash << str; - - skyUrls->emplace_back(url.str()); - } -} - -std::string ResourceHelper::getModelPath(const std::string &modelName) const -{ - std::ostringstream modelStream; - modelStream << mImagePath << modelName << ".js"; - std::string modelPath = modelStream.str(); - return modelPath; -} - -std::string ResourceHelper::getProgramPath() const -{ - std::ostringstream programStream; - programStream << mPath << shaderFolder << slash << mBackendName << slash << mShaderVersion - << slash; - std::string programPath = programStream.str(); - return programPath; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +#include "ResourceHelper.h" + +#include + +#ifdef _WIN32 +#include +#include "Windows.h" +const std::string slash = "\\"; +#elif __APPLE__ +#include +const std::string slash = "/"; +#else +#include +const std::string slash = "/"; +#endif + +static const char *shaderFolder = "shaders"; +static const char *resourceFolder = "assets"; + +const std::vector skyBoxUrls = { + "GlobeOuter_EM_positive_x.jpg", "GlobeOuter_EM_negative_x.jpg", "GlobeOuter_EM_positive_y.jpg", + "GlobeOuter_EM_negative_y.jpg", "GlobeOuter_EM_positive_z.jpg", "GlobeOuter_EM_negative_z.jpg"}; + +ResourceHelper::ResourceHelper(const std::string &mBackendName, const std::string &mShaderVersion) + : mBackendName(mBackendName), mShaderVersion(mShaderVersion) +{ +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) + TCHAR temp[200]; + GetModuleFileName(nullptr, temp, MAX_PATH); + std::wstring ws(temp); + mPath = std::string(ws.begin(), ws.end()); +#elif __APPLE__ + char temp[200]; + uint32_t size = sizeof(temp); + _NSGetExecutablePath(temp, &size); + mPath = std::string(temp); +#else + char temp[200]; + readlink("/proc/self/exe", temp, sizeof(temp)); + mPath = std::string(temp); +#endif + + size_t nPos = mPath.find_last_of(slash); + std::ostringstream pathStream; + pathStream << mPath.substr(0, nPos) << slash << ".." << slash << ".." << slash; + mPath = pathStream.str(); + + std::ostringstream placementStream; + placementStream << mPath << resourceFolder << slash << "PropPlacement.js"; + mPropPlacementPath = placementStream.str(); + + std::ostringstream imageStream; + imageStream << mPath << resourceFolder << slash; + mImagePath = imageStream.str(); +} + +void ResourceHelper::getSkyBoxUrls(std::vector *skyUrls) const +{ + for (auto &str : skyBoxUrls) + { + std::ostringstream url; + url << mPath << resourceFolder << slash << str; + + skyUrls->emplace_back(url.str()); + } +} + +std::string ResourceHelper::getModelPath(const std::string &modelName) const +{ + std::ostringstream modelStream; + modelStream << mImagePath << modelName << ".js"; + std::string modelPath = modelStream.str(); + return modelPath; +} + +std::string ResourceHelper::getProgramPath() const +{ + std::ostringstream programStream; + programStream << mPath << shaderFolder << slash << mBackendName << slash << mShaderVersion + << slash; + std::string programPath = programStream.str(); + return programPath; +} diff --git a/src/aquarium-optimized/ResourceHelper.h b/src/aquarium-optimized/ResourceHelper.h index d0725a1..22041cc 100644 --- a/src/aquarium-optimized/ResourceHelper.h +++ b/src/aquarium-optimized/ResourceHelper.h @@ -1,30 +1,30 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -#pragma once -#include -#include - -class ResourceHelper -{ - public: - ResourceHelper() {} - ResourceHelper(const std::string &mBackendName, const std::string &mShaderVersion); - void getSkyBoxUrls(std::vector *skyUrls) const; - const std::string &getPropPlacementPath() const { return mPropPlacementPath; } - const std::string &getImagePath() const { return mImagePath; } - std::string getModelPath(const std::string &modelName) const; - std::string getProgramPath() const; - const std::string& getBackendName() const { return mBackendName; } - const std::string& getShaderVersion() const { return mShaderVersion; } - - private: - std::string mPath; - std::string mImagePath; - std::string mProgramPath; - std::string mPropPlacementPath; - std::string mBackendName; - std::string mShaderVersion; -}; +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +#pragma once +#include +#include + +class ResourceHelper +{ + public: + ResourceHelper() {} + ResourceHelper(const std::string &mBackendName, const std::string &mShaderVersion); + void getSkyBoxUrls(std::vector *skyUrls) const; + const std::string &getPropPlacementPath() const { return mPropPlacementPath; } + const std::string &getImagePath() const { return mImagePath; } + std::string getModelPath(const std::string &modelName) const; + std::string getProgramPath() const; + const std::string &getBackendName() const { return mBackendName; } + const std::string &getShaderVersion() const { return mShaderVersion; } + + private: + std::string mPath; + std::string mImagePath; + std::string mProgramPath; + std::string mPropPlacementPath; + std::string mBackendName; + std::string mShaderVersion; +}; diff --git a/src/aquarium-optimized/SeaweedModel.h b/src/aquarium-optimized/SeaweedModel.h index 6e25b1f..bdda71e 100644 --- a/src/aquarium-optimized/SeaweedModel.h +++ b/src/aquarium-optimized/SeaweedModel.h @@ -1,22 +1,22 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// SeaweedModel.h: Define seaweed model. - -#pragma once -#ifndef SEAWEEDMODEL_H -#define SEAWEEDMODEL_H 1 - -#include "Model.h" - -class SeaweedModel : public Model -{ - public: - SeaweedModel(MODELGROUP type, MODELNAME name, bool blend) : Model(type, name, blend){} - - virtual void updateSeaweedModelTime(float time) = 0; -}; - -#endif // !SEAWEEDMODEL_H +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SeaweedModel.h: Define seaweed model. + +#pragma once +#ifndef SEAWEEDMODEL_H +#define SEAWEEDMODEL_H 1 + +#include "Model.h" + +class SeaweedModel : public Model +{ + public: + SeaweedModel(MODELGROUP type, MODELNAME name, bool blend) : Model(type, name, blend) {} + + virtual void updateSeaweedModelTime(float time) = 0; +}; + +#endif // !SEAWEEDMODEL_H diff --git a/src/aquarium-optimized/Texture.cpp b/src/aquarium-optimized/Texture.cpp index 7aae11d..e412c69 100644 --- a/src/aquarium-optimized/Texture.cpp +++ b/src/aquarium-optimized/Texture.cpp @@ -1,131 +1,131 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Texture.cpp: Use stb image loader to loading images from files. - -#include "Texture.h" - -#include -#include -#include - -#include "../common/AQUARIUM_ASSERT.h" - -#define STB_IMAGE_IMPLEMENTATION -#define STB_IMAGE_RESIZE_IMPLEMENTATION -#include "stb_image.h" -#include "stb_image_resize.h" - -Texture::Texture(const std::string &name, const std::string &url, bool flip) - : mUrls(), - mWidth(0), - mHeight(0), - mFlip(flip), - mName(name) -{ - std::string urlpath = url; - mUrls.push_back(urlpath); -} - -// Force loading 3 channel images to 4 channel by stb becasue Dawn doesn't support 3 channel -// formats currently. The group is discussing on whether webgpu shoud support 3 channel format. -// https://github.com/gpuweb/gpuweb/issues/66#issuecomment-410021505 -bool Texture::loadImage(const std::vector &urls, std::vector* pixels) -{ - stbi_set_flip_vertically_on_load(mFlip); - for (auto filename : urls) { - uint8_t *pixel = stbi_load(filename.c_str(), &mWidth, &mHeight, 0, 4); - if (pixel == 0) - { - std::cout << stderr << "Couldn't open input file" << filename << std::endl; - return false; - } - pixels->push_back(pixel); - } - return true; -} - -bool Texture::isPowerOf2(int value) -{ - return (value & (value - 1)) == 0; -} - -// Free image data after upload to gpu -void Texture::DestoryImageData(std::vector& pixelVec) -{ - for (auto& pixels : pixelVec) - { - free(pixels); - pixels = nullptr; - } -} - -void Texture::copyPaddingBuffer(unsigned char *dst, unsigned char *src, int width, int height, int kPadding) -{ - unsigned char *s = src; - unsigned char *d = dst; - for(int i = 0; i < height; ++i) - { - memcpy(d, s, width * 4); - s += width * 4; - d += kPadding * 4; - } -} - -void Texture::generateMipmap(uint8_t *input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - std::vector &output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - int num_channels, - bool is256padding) -{ - int mipmapLevel = - static_cast(floor(log2(std::max(output_w, output_h)))) + 1; - output_pixels.resize(mipmapLevel); - int height = output_h; - int width = output_w; - - if (!is256padding) - { - for (int i = 0; i < mipmapLevel; ++i) - { - output_pixels[i] = (unsigned char *)malloc(output_w * height * 4 * sizeof(char)); - stbir_resize_uint8(input_pixels, input_w, input_h, input_stride_in_bytes, - output_pixels[i], width, height, output_stride_in_bytes, - num_channels); - - height >>= 1; - width >>= 1; - if (height == 0) - { - height = 1; - } - } - } - else - { - uint8_t *pixels = (unsigned char *)malloc(output_w * height * 4 * sizeof(char)); - - for (int i = 0; i < mipmapLevel; ++i) - { - output_pixels[i] = (unsigned char *)malloc(output_w * height * 4 * sizeof(char)); - stbir_resize_uint8(input_pixels, input_w, input_h, input_stride_in_bytes, pixels, width, - height, output_stride_in_bytes, num_channels); - copyPaddingBuffer(output_pixels[i], pixels, width, height, output_w); - - height >>= 1; - width >>= 1; - if (height == 0) - { - height = 1; - } - } - free(pixels); - } -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Texture.cpp: Use stb image loader to loading images from files. + +#include "Texture.h" + +#include +#include +#include + +#include "../common/AQUARIUM_ASSERT.h" + +#define STB_IMAGE_IMPLEMENTATION +#define STB_IMAGE_RESIZE_IMPLEMENTATION +#include "stb_image.h" +#include "stb_image_resize.h" + +Texture::Texture(const std::string &name, const std::string &url, bool flip) + : mUrls(), mWidth(0), mHeight(0), mFlip(flip), mName(name) +{ + std::string urlpath = url; + mUrls.push_back(urlpath); +} + +// Force loading 3 channel images to 4 channel by stb becasue Dawn doesn't support 3 channel +// formats currently. The group is discussing on whether webgpu shoud support 3 channel format. +// https://github.com/gpuweb/gpuweb/issues/66#issuecomment-410021505 +bool Texture::loadImage(const std::vector &urls, std::vector *pixels) +{ + stbi_set_flip_vertically_on_load(mFlip); + for (auto filename : urls) + { + uint8_t *pixel = stbi_load(filename.c_str(), &mWidth, &mHeight, 0, 4); + if (pixel == 0) + { + std::cout << stderr << "Couldn't open input file" << filename << std::endl; + return false; + } + pixels->push_back(pixel); + } + return true; +} + +bool Texture::isPowerOf2(int value) +{ + return (value & (value - 1)) == 0; +} + +// Free image data after upload to gpu +void Texture::DestoryImageData(std::vector &pixelVec) +{ + for (auto &pixels : pixelVec) + { + free(pixels); + pixels = nullptr; + } +} + +void Texture::copyPaddingBuffer(unsigned char *dst, + unsigned char *src, + int width, + int height, + int kPadding) +{ + unsigned char *s = src; + unsigned char *d = dst; + for (int i = 0; i < height; ++i) + { + memcpy(d, s, width * 4); + s += width * 4; + d += kPadding * 4; + } +} + +void Texture::generateMipmap(uint8_t *input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + std::vector &output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + int num_channels, + bool is256padding) +{ + int mipmapLevel = static_cast(floor(log2(std::max(output_w, output_h)))) + 1; + output_pixels.resize(mipmapLevel); + int height = output_h; + int width = output_w; + + if (!is256padding) + { + for (int i = 0; i < mipmapLevel; ++i) + { + output_pixels[i] = (unsigned char *)malloc(output_w * height * 4 * sizeof(char)); + stbir_resize_uint8(input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels[i], width, height, output_stride_in_bytes, + num_channels); + + height >>= 1; + width >>= 1; + if (height == 0) + { + height = 1; + } + } + } + else + { + uint8_t *pixels = (unsigned char *)malloc(output_w * height * 4 * sizeof(char)); + + for (int i = 0; i < mipmapLevel; ++i) + { + output_pixels[i] = (unsigned char *)malloc(output_w * height * 4 * sizeof(char)); + stbir_resize_uint8(input_pixels, input_w, input_h, input_stride_in_bytes, pixels, width, + height, output_stride_in_bytes, num_channels); + copyPaddingBuffer(output_pixels[i], pixels, width, height, output_w); + + height >>= 1; + width >>= 1; + if (height == 0) + { + height = 1; + } + } + free(pixels); + } +} diff --git a/src/aquarium-optimized/Texture.h b/src/aquarium-optimized/Texture.h index ad4c5db..7e7ad43 100644 --- a/src/aquarium-optimized/Texture.h +++ b/src/aquarium-optimized/Texture.h @@ -1,54 +1,56 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Texture.h: Define abstract Texture for Aquarium. - -#pragma once -#ifndef TEXTURE_H -#define TEXTURE_H 1 - -#include -#include - -class Texture -{ - public: - virtual ~Texture(){} - Texture() {} - Texture(const std::string &name, const std::vector &urls, bool flip) : mUrls(urls), mFlip(flip), mName(name) {} - Texture(const std::string &name, const std::string &url, bool flip); - std::string getName() { return mName; } - virtual void loadTexture() = 0; - void generateMipmap(uint8_t *input_pixels, - int input_w, - int input_h, - int input_stride_in_bytes, - std::vector &output_pixels, - int output_w, - int output_h, - int output_stride_in_bytes, - int num_channels, - bool is256padding); - - protected: - bool isPowerOf2(int); - bool loadImage(const std::vector &urls, std::vector* pixels); - void DestoryImageData(std::vector& pixelVec); - void copyPaddingBuffer(unsigned char *dst, - unsigned char *src, - int width, - int height, - int kPadding); - - std::vector mUrls; - int mWidth; - int mHeight; - bool mFlip; - - std::string mName; -}; - -#endif // !TEXTURE_H - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Texture.h: Define abstract Texture for Aquarium. + +#pragma once +#ifndef TEXTURE_H +#define TEXTURE_H 1 + +#include +#include + +class Texture +{ + public: + virtual ~Texture() {} + Texture() {} + Texture(const std::string &name, const std::vector &urls, bool flip) + : mUrls(urls), mFlip(flip), mName(name) + { + } + Texture(const std::string &name, const std::string &url, bool flip); + std::string getName() { return mName; } + virtual void loadTexture() = 0; + void generateMipmap(uint8_t *input_pixels, + int input_w, + int input_h, + int input_stride_in_bytes, + std::vector &output_pixels, + int output_w, + int output_h, + int output_stride_in_bytes, + int num_channels, + bool is256padding); + + protected: + bool isPowerOf2(int); + bool loadImage(const std::vector &urls, std::vector *pixels); + void DestoryImageData(std::vector &pixelVec); + void copyPaddingBuffer(unsigned char *dst, + unsigned char *src, + int width, + int height, + int kPadding); + + std::vector mUrls; + int mWidth; + int mHeight; + bool mFlip; + + std::string mName; +}; + +#endif // !TEXTURE_H diff --git a/src/aquarium-optimized/d3d12/BufferD3D12.cpp b/src/aquarium-optimized/d3d12/BufferD3D12.cpp index d6a6211..6c13314 100644 --- a/src/aquarium-optimized/d3d12/BufferD3D12.cpp +++ b/src/aquarium-optimized/d3d12/BufferD3D12.cpp @@ -1,40 +1,40 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "BufferD3D12.h" -#include "ContextD3D12.h" - -BufferD3D12::BufferD3D12(ContextD3D12 *context, - int totalCmoponents, - int numComponents, - const std::vector &buffer, - bool isIndex) - : mIsIndex(isIndex), mTotoalComponents(totalCmoponents), mStride(0), mOffset(nullptr) -{ - mSize = totalCmoponents * sizeof(float); - mBuffer = context->createDefaultBuffer(buffer.data(), mSize, mUploadBuffer); - - // Initialize the vertex buffer view. - mVertexBufferView.BufferLocation = mBuffer->GetGPUVirtualAddress(); - mVertexBufferView.StrideInBytes = numComponents * sizeof(float); - mVertexBufferView.SizeInBytes = mSize; -} - -BufferD3D12::BufferD3D12(ContextD3D12 *context, - int totalCmoponents, - int numComponents, - const std::vector &buffer, - bool isIndex) - : mIsIndex(isIndex), mTotoalComponents(totalCmoponents), mStride(0), mOffset(nullptr) -{ - mSize = totalCmoponents * sizeof(unsigned short); - mBuffer = context->createDefaultBuffer(buffer.data(), mSize, mUploadBuffer); - - // Initialize the vertex buffer view. - mIndexBufferView.BufferLocation = mBuffer->GetGPUVirtualAddress(); - mIndexBufferView.SizeInBytes = mSize; - mIndexBufferView.Format = DXGI_FORMAT_R16_UINT; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "BufferD3D12.h" +#include "ContextD3D12.h" + +BufferD3D12::BufferD3D12(ContextD3D12 *context, + int totalCmoponents, + int numComponents, + const std::vector &buffer, + bool isIndex) + : mIsIndex(isIndex), mTotoalComponents(totalCmoponents), mStride(0), mOffset(nullptr) +{ + mSize = totalCmoponents * sizeof(float); + mBuffer = context->createDefaultBuffer(buffer.data(), mSize, mUploadBuffer); + + // Initialize the vertex buffer view. + mVertexBufferView.BufferLocation = mBuffer->GetGPUVirtualAddress(); + mVertexBufferView.StrideInBytes = numComponents * sizeof(float); + mVertexBufferView.SizeInBytes = mSize; +} + +BufferD3D12::BufferD3D12(ContextD3D12 *context, + int totalCmoponents, + int numComponents, + const std::vector &buffer, + bool isIndex) + : mIsIndex(isIndex), mTotoalComponents(totalCmoponents), mStride(0), mOffset(nullptr) +{ + mSize = totalCmoponents * sizeof(unsigned short); + mBuffer = context->createDefaultBuffer(buffer.data(), mSize, mUploadBuffer); + + // Initialize the vertex buffer view. + mIndexBufferView.BufferLocation = mBuffer->GetGPUVirtualAddress(); + mIndexBufferView.SizeInBytes = mSize; + mIndexBufferView.Format = DXGI_FORMAT_R16_UINT; +} diff --git a/src/aquarium-optimized/d3d12/BufferD3D12.h b/src/aquarium-optimized/d3d12/BufferD3D12.h index bc8b57e..7f3d073 100644 --- a/src/aquarium-optimized/d3d12/BufferD3D12.h +++ b/src/aquarium-optimized/d3d12/BufferD3D12.h @@ -1,59 +1,59 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// BufferD3D12.h: Defines the buffer wrapper of D3D12, abstracting the vetex and index buffer -// binding. - -#pragma once -#ifndef BUFFERD3D12_H -#define BUFFERD3D12_H 1 - -#include - -#include "stdafx.h" - -using Microsoft::WRL::ComPtr; - -#include "../Buffer.h" - -class ContextD3D12; - -class BufferD3D12 : public Buffer -{ - public: - BufferD3D12(ContextD3D12 *context, - int totalCmoponents, - int numComponents, - const std::vector &buffer, - bool isIndex); - BufferD3D12(ContextD3D12 *context, - int totalCmoponents, - int numComponents, - const std::vector &buffer, - bool isIndex); - - ComPtr getBuffer() const { return mBuffer; } - - int getTotalComponents() const { return mTotoalComponents; } - - uint32_t getStride() const { return mStride; } - void *getOffset() const { return mOffset; } - bool getIsIndex() const { return mIsIndex; } - int getDataSize() { return mSize; } - - D3D12_VERTEX_BUFFER_VIEW mVertexBufferView; - D3D12_INDEX_BUFFER_VIEW mIndexBufferView; - - private: - ComPtr mBuffer; - ComPtr mUploadBuffer; - bool mIsIndex; - int mTotoalComponents; - uint32_t mStride; - void *mOffset; - int mSize; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// BufferD3D12.h: Defines the buffer wrapper of D3D12, abstracting the vetex and index buffer +// binding. + +#pragma once +#ifndef BUFFERD3D12_H +#define BUFFERD3D12_H 1 + +#include + +#include "stdafx.h" + +using Microsoft::WRL::ComPtr; + +#include "../Buffer.h" + +class ContextD3D12; + +class BufferD3D12 : public Buffer +{ + public: + BufferD3D12(ContextD3D12 *context, + int totalCmoponents, + int numComponents, + const std::vector &buffer, + bool isIndex); + BufferD3D12(ContextD3D12 *context, + int totalCmoponents, + int numComponents, + const std::vector &buffer, + bool isIndex); + + ComPtr getBuffer() const { return mBuffer; } + + int getTotalComponents() const { return mTotoalComponents; } + + uint32_t getStride() const { return mStride; } + void *getOffset() const { return mOffset; } + bool getIsIndex() const { return mIsIndex; } + int getDataSize() { return mSize; } + + D3D12_VERTEX_BUFFER_VIEW mVertexBufferView; + D3D12_INDEX_BUFFER_VIEW mIndexBufferView; + + private: + ComPtr mBuffer; + ComPtr mUploadBuffer; + bool mIsIndex; + int mTotoalComponents; + uint32_t mStride; + void *mOffset; + int mSize; +}; + +#endif diff --git a/src/aquarium-optimized/d3d12/ContextD3D12.cpp b/src/aquarium-optimized/d3d12/ContextD3D12.cpp index a162f7b..8eba51b 100644 --- a/src/aquarium-optimized/d3d12/ContextD3D12.cpp +++ b/src/aquarium-optimized/d3d12/ContextD3D12.cpp @@ -1,1046 +1,1046 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "ContextD3D12.h" - -#include -#include - -#define GLFW_EXPOSE_NATIVE_WIN32 -#include - -#include "BufferD3D12.h" -#include "FishModelD3D12.h" -#include "FishModelInstancedDrawD3D12.h" -#include "GenericModelD3D12.h" -#include "InnerModelD3D12.h" -#include "OutsideModelD3D12.h" -#include "ProgramD3D12.h" -#include "SeaweedModelD3D12.h" -#include "TextureD3D12.h" - -#include "imgui.h" -#include "imgui_impl_dx12.h" -#include "imgui_impl_glfw.h" - -const CD3DX12_HEAP_PROPERTIES defaultheapProperties = - CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); -const CD3DX12_HEAP_PROPERTIES uploadheapProperties = - CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD); - -inline void ThrowIfFailed(HRESULT hr) -{ - if (FAILED(hr)) - { - printf("D3D12 backend failed: file \"%s\", line %d\n", __FILE__, __LINE__); - } -} - -ContextD3D12::ContextD3D12(BACKENDTYPE backendType) - : lightWorldPositionView({}), - mWindow(nullptr), - mDevice(nullptr), - mCommandQueue(nullptr), - mSwapChain(nullptr), - mPreferredSwapChainFormat(DXGI_FORMAT_R8G8B8A8_UNORM), - mCompileFlags(0), - m_frameIndex(0), - mRtvHeap(nullptr), - mDsvHeap(nullptr), - mCbvsrvHeap(nullptr), - mRtvDescriptorSize(0), - mCbvmSrvDescriptorSize(0), - mFenceValue(0), - mRootSignature({}), - mViewport(0.0f, 0.0f, 0.0f, 0.0f), - mScissorRect(0.0f, 0.0f, 0.0f, 0.0f), - mLightView({}), - mFogView({}), - mSceneRenderTargetView({}), - mEnableMSAA(false) -{ - for (UINT n = 0; n < mFrameCount; n++) - { - mBufferSerias[n] = 0; - } - - mResourceHelper = new ResourceHelper("d3d12", ""); - initAvailableToggleBitset(backendType); -} - -ContextD3D12::~ContextD3D12() -{ - delete mResourceHelper; - destoryImgUI(); -} - -bool ContextD3D12::initialize( - BACKENDTYPE backend, - const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) -{ - mEnableMSAA = toggleBitset.test(static_cast(TOGGLE::ENABLEMSAAx4)); - - // initialise GLFW - if (!glfwInit()) - { - std::cout << "Failed to initialise GLFW" << std::endl; - return false; - } - - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - // set full screen - // glfwWindowHint(GLFW_DECORATED, GL_FALSE); - - GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); - const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); - mClientWidth = mode->width; - mClientHeight = mode->height; - - if (toggleBitset.test(static_cast(TOGGLE::ENABLEFULLSCREENMODE))) - { - mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", pMonitor, nullptr); - } - else - { - mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", nullptr, nullptr); - } - - if (mWindow == nullptr) - { - std::cout << "Failed to open GLFW window." << std::endl; - glfwTerminate(); - return false; - } - - HWND hwnd = glfwGetWin32Window(mWindow); - - // Get the resolution of screen - glfwGetFramebufferSize(mWindow, &mClientWidth, &mClientHeight); - - UINT dxgiFactoryFlags = 0; -#if defined(_DEBUG) - // Enable the debug layer (requires the Graphics Tools "optional feature"). - // NOTE: Enabling the debug layer after mDevice creation will invalidate the active mDevice. - { - ComPtr debugController; - if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) - { - debugController->EnableDebugLayer(); - - // Enable additional debug layers. - dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; - } - - mCompileFlags = - D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_ENABLE_STRICTNESS; - } -#endif - - ComPtr mFactory; - ThrowIfFailed(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&mFactory))); - - ComPtr hardwareAdapter; - ThrowIfFailed(GetHardwareAdapter(mFactory.Get(), &hardwareAdapter, toggleBitset)); - - ThrowIfFailed( - D3D12CreateDevice(hardwareAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&mDevice))); - // Describe and create the command queue. - D3D12_COMMAND_QUEUE_DESC queueDesc = {}; - queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; - queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - - ThrowIfFailed(mDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue))); - - // Describe and create the swap chain. - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; - swapChainDesc.BufferCount = mFrameCount; - swapChainDesc.Width = mClientWidth; - swapChainDesc.Height = mClientHeight; - swapChainDesc.Format = mPreferredSwapChainFormat; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.SampleDesc.Count = 1; - - mViewport.Width = static_cast(mClientWidth); - mViewport.Height = static_cast(mClientHeight); - mScissorRect.right = static_cast(mClientWidth); - mScissorRect.bottom = static_cast(mClientHeight); - - ComPtr swapChain; - ThrowIfFailed(mFactory->CreateSwapChainForHwnd( - mCommandQueue.Get(), // Swap chain needs the queue so that it can force a flush on it. - hwnd, &swapChainDesc, nullptr, nullptr, &swapChain)); - - // This sample does not support fullscreen transitions. - ThrowIfFailed(mFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER)); - - ThrowIfFailed(swapChain.As(&mSwapChain)); - - m_frameIndex = mSwapChain->GetCurrentBackBufferIndex(); - - // Describe and create a render target view (RTV) descriptor heap. - D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {}; - rtvHeapDesc.NumDescriptors = mEnableMSAA ? mFrameCount + 1 : mFrameCount; - rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; - rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - ThrowIfFailed(mDevice->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&mRtvHeap))); - - mRtvDescriptorSize = mDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - - CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle; - // Create frame resources. - { - rtvHandle = mRtvHeap->GetCPUDescriptorHandleForHeapStart(); - - // Create a RTV for each frame. - for (UINT n = 0; n < mFrameCount; n++) - { - ThrowIfFailed(mSwapChain->GetBuffer(n, IID_PPV_ARGS(&mRenderTargets[n]))); - mDevice->CreateRenderTargetView(mRenderTargets[n].Get(), nullptr, rtvHandle); - rtvHandle.Offset(1, mRtvDescriptorSize); - } - } - - // Describe and create a depth stencil view (DSV) descriptor heap. - D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {}; - dsvHeapDesc.NumDescriptors = 1; - dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; - dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - ThrowIfFailed(mDevice->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&mDsvHeap))); - - // Init cbvuav descriptor heap - // Create a shader resource view (SRV) and constant - // buffer view (CBV) descriptor heap. - D3D12_DESCRIPTOR_HEAP_DESC cbvSrvHeapDesc = {}; - cbvSrvHeapDesc.NumDescriptors = cbvsrvCount; - cbvSrvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - cbvSrvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - ThrowIfFailed(mDevice->CreateDescriptorHeap(&cbvSrvHeapDesc, IID_PPV_ARGS(&mCbvsrvHeap))); - - mCbvmSrvDescriptorSize = - mDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - - cbvsrvCPUHandle = mCbvsrvHeap->GetCPUDescriptorHandleForHeapStart(); - cbvsrvGPUHandle = mCbvsrvHeap->GetGPUDescriptorHandleForHeapStart(); - - // Init 3 command allocators for 3 back buffers - for (UINT n = 0; n < mFrameCount; n++) - { - ThrowIfFailed(mDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, - IID_PPV_ARGS(&mCommandAllocators[n]))); - } - - createCommandList(nullptr, mCommandList); - - // Check highest version of root signature. - mRootSignature.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1; - - if (FAILED(mDevice->CheckFeatureSupport(D3D12_FEATURE_ROOT_SIGNATURE, &mRootSignature, - sizeof(mRootSignature)))) - { - mRootSignature.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0; - } - - if (mEnableMSAA) - { - D3D12_RESOURCE_DESC textureDesc = {}; - textureDesc.MipLevels = 1; - textureDesc.Format = mPreferredSwapChainFormat; - textureDesc.Width = mClientWidth; - textureDesc.Height = mClientHeight; - textureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; - textureDesc.DepthOrArraySize = 1; - textureDesc.SampleDesc.Count = 4u; - textureDesc.SampleDesc.Quality = 0; - textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - - ThrowIfFailed(mDevice->CreateCommittedResource( - &defaultheapProperties, D3D12_HEAP_FLAG_NONE, &textureDesc, - D3D12_RESOURCE_STATE_RENDER_TARGET, nullptr, IID_PPV_ARGS(&mSceneRenderTargetTexture))); - - mSceneRenderTargetView.Format = mPreferredSwapChainFormat; - mSceneRenderTargetView.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS; - mSceneRenderTargetView.Texture2D.MipSlice = 1; - - mDevice->CreateRenderTargetView(mSceneRenderTargetTexture.Get(), &mSceneRenderTargetView, - rtvHandle); - } - createDepthStencilView(); - - // Setup Dear ImGui context - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - - // Setup Dear ImGui style - ImGui::StyleColorsDark(); - - // Setup Platform/Renderer bindings - // We use glfw for d3d12 backend as well, but imgui only expose glfw to OpenGL and Vulkan. - // However, the glfw api is totoally independent of Graphics API, so we could just ingnore the - // name of the function. - ImGui_ImplGlfw_InitForOpenGL(mWindow, true); - ImGui_ImplDX12_Init(mDevice.Get(), mFrameCount, mPreferredSwapChainFormat, cbvsrvCPUHandle, - cbvsrvGPUHandle); - cbvsrvCPUHandle.Offset(mCbvmSrvDescriptorSize); - cbvsrvGPUHandle.Offset(mCbvmSrvDescriptorSize); - - return true; -} - -// Helper function for acquiring the first available hardware adapter that supports Direct3D 12. -// If no such adapter can be found, *ppAdapter will be set to nullptr. -bool ContextD3D12::GetHardwareAdapter( - IDXGIFactory2 *pFactory, - IDXGIAdapter1 **ppAdapter, - const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) -{ - ComPtr adapter; - *ppAdapter = nullptr; - - bool enableIntegratedGpu = toggleBitset.test(static_cast(TOGGLE::INTEGRATEDGPU)); - bool enableDiscreteGpu = toggleBitset.test(static_cast(TOGGLE::DISCRETEGPU)); - bool useDefaultGpu = (enableDiscreteGpu | enableIntegratedGpu) == false ? true : false; - - for (UINT adapterIndex = 0; - DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex) - { - DXGI_ADAPTER_DESC1 desc; - adapter->GetDesc1(&desc); - - if (useDefaultGpu || - (enableDiscreteGpu && (desc.VendorId == 0x10DE || desc.VendorId == 0x1002)) || - (enableIntegratedGpu && desc.VendorId == 0x8086)) - { - if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) - { - // Don't select the Basic Render Driver adapter. - continue; - } - - if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, - _uuidof(ID3D12Device), nullptr))) - { - std::wstring str = desc.Description; - mRenderer = std::string(str.begin(), str.end()); - std::cout << mRenderer << std::endl; - break; - } - } - } - - *ppAdapter = adapter.Detach(); - if (ppAdapter == nullptr) - { - std::cerr << "Failed to create adapter." << std::endl; - return false; - } - return true; -} - -void ContextD3D12::setWindowTitle(const std::string &text) -{ - glfwSetWindowTitle(mWindow, text.c_str()); -} - -bool ContextD3D12::ShouldQuit() -{ - return glfwWindowShouldClose(mWindow); -} - -void ContextD3D12::KeyBoardQuit() -{ - if (glfwGetKey(mWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS) - glfwSetWindowShouldClose(mWindow, GL_TRUE); -} - -void ContextD3D12::stateTransition(ComPtr &resource, - D3D12_RESOURCE_STATES preState, - D3D12_RESOURCE_STATES transferState) const -{ - CD3DX12_RESOURCE_BARRIER barrier = - CD3DX12_RESOURCE_BARRIER::Transition(resource.Get(), preState, transferState); - mCommandList->ResourceBarrier(1, &barrier); -} - -void ContextD3D12::initAvailableToggleBitset(BACKENDTYPE backendType) -{ - mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEMSAAx4)); - mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)); - mAvailableToggleBitset.set(static_cast(TOGGLE::DISCRETEGPU)); - mAvailableToggleBitset.set(static_cast(TOGGLE::INTEGRATEDGPU)); - mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEFULLSCREENMODE)); -} - -void ContextD3D12::DoFlush() -{ - // Resolve MSAA texture to non MSAA texture, and then present. - if (mEnableMSAA) - { - stateTransition(mSceneRenderTargetTexture, D3D12_RESOURCE_STATE_RENDER_TARGET, - D3D12_RESOURCE_STATE_RESOLVE_SOURCE); - stateTransition(mRenderTargets[m_frameIndex], D3D12_RESOURCE_STATE_COMMON, - D3D12_RESOURCE_STATE_RESOLVE_DEST); - - mCommandList->ResolveSubresource(mRenderTargets[m_frameIndex].Get(), 0, - mSceneRenderTargetTexture.Get(), 0, - mPreferredSwapChainFormat); - - stateTransition(mSceneRenderTargetTexture, D3D12_RESOURCE_STATE_RESOLVE_SOURCE, - D3D12_RESOURCE_STATE_RENDER_TARGET); - stateTransition(mRenderTargets[m_frameIndex], D3D12_RESOURCE_STATE_RESOLVE_DEST, - D3D12_RESOURCE_STATE_COMMON); - } - else - { - stateTransition(mRenderTargets[m_frameIndex], D3D12_RESOURCE_STATE_RENDER_TARGET, - D3D12_RESOURCE_STATE_COMMON); - } - - ThrowIfFailed(mCommandList->Close()); - - // Execute the command list. - ID3D12CommandList *ppCommandLists[] = {mCommandList.Get()}; - mCommandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); - - // Present the frame. - ThrowIfFailed(mSwapChain->Present(1, 0)); - - WaitForPreviousFrame(); - - glfwPollEvents(); -} - -void ContextD3D12::FlushInit() -{ - // Close the command list and execute it to begin the initial GPU setup. - ThrowIfFailed(mCommandList->Close()); - ID3D12CommandList *ppCommandLists[] = {mCommandList.Get()}; - mCommandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); - - // Create synchronization objects and wait until assets have been uploaded to the GPU. - { - ThrowIfFailed( - mDevice->CreateFence(mFenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence))); - - // Create an event handle to use for frame synchronization. - mFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (mFenceEvent == nullptr) - { - ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); - } - - ThrowIfFailed(mSwapChain->Present(1, 0)); - m_frameIndex = mSwapChain->GetCurrentBackBufferIndex(); - - WaitForPreviousFrame(); - } -} - -void ContextD3D12::Terminate() -{ - UINT lastSerias = 0; - if (m_frameIndex == 0) - { - lastSerias = mBufferSerias[2]; - } - else - { - lastSerias = mBufferSerias[m_frameIndex - 1]; - } - - if (mFence->GetCompletedValue() < lastSerias) - { - ThrowIfFailed(mFence->SetEventOnCompletion(lastSerias, mFenceEvent)); - WaitForSingleObject(mFenceEvent, INFINITE); - } - - glfwTerminate(); -} - -void ContextD3D12::showWindow() -{ - glfwShowWindow(mWindow); -} - -void ContextD3D12::showFPS(const FPSTimer &fpsTimer) -{ - // Start the Dear ImGui frame - ImGui_ImplDX12_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - { - ImGui::Begin("Aquarium Native"); - - std::ostringstream rendererStream; - std::string backend = mResourceHelper->getBackendName(); - for (auto &c : backend) - c = toupper(c); - rendererStream << mRenderer << " " << backend << " " << mResourceHelper->getShaderVersion(); - std::string renderer = rendererStream.str(); - ImGui::Text(renderer.c_str()); - - std::ostringstream resolutionStream; - resolutionStream << "Resolution " << mClientWidth << "x" << mClientHeight; - std::string resolution = resolutionStream.str(); - ImGui::Text(resolution.c_str()); - - ImGui::PlotLines("[0,100 FPS]", fpsTimer.getHistoryFps(), NUM_HISTORY_DATA, 0, NULL, 0.0f, - 100.0f, ImVec2(0, 40)); - - ImGui::PlotHistogram("[0,100 ms/frame]", fpsTimer.getHistoryFrameTime(), NUM_HISTORY_DATA, - 0, NULL, 0.0f, 100.0f, ImVec2(0, 40)); - - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", - 1000.0f / fpsTimer.getAverageFPS(), fpsTimer.getAverageFPS()); - ImGui::End(); - } - - ImGui::Render(); - ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), mCommandList.Get()); -} - -void ContextD3D12::destoryImgUI() -{ - ImGui_ImplDX12_Shutdown(); - ImGui_ImplGlfw_Shutdown(); - ImGui::DestroyContext(); -} - -void ContextD3D12::preFrame() -{ - // Reuse the memory associated with command recording. - // We can only reset when the associated command lists have finished execution on the GPU. - ThrowIfFailed(mCommandAllocators[m_frameIndex]->Reset()); - - // A command list can be reset after it has been added to the command queue via - // ExecuteCommandList. - // Reusing the command list reuses memory. - ThrowIfFailed(mCommandList->Reset(mCommandAllocators[m_frameIndex].Get(), nullptr)); - - // Set descriptor heaps related to command list. - ID3D12DescriptorHeap *mDescriptorHeaps[] = {mCbvsrvHeap.Get()}; - - mCommandList->SetDescriptorHeaps(_countof(mDescriptorHeaps), mDescriptorHeaps); - mCommandList->RSSetViewports(1, &mViewport); - mCommandList->RSSetScissorRects(1, &mScissorRect); - - CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle; - CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle; - if (mEnableMSAA) - { - rtvHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(mRtvHeap->GetCPUDescriptorHandleForHeapStart(), - mFrameCount, mRtvDescriptorSize); - } - else - { - rtvHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(mRtvHeap->GetCPUDescriptorHandleForHeapStart(), - m_frameIndex, mRtvDescriptorSize); - - stateTransition(mRenderTargets[m_frameIndex], D3D12_RESOURCE_STATE_COMMON, - D3D12_RESOURCE_STATE_RENDER_TARGET); - } - - dsvHandle = mDsvHeap->GetCPUDescriptorHandleForHeapStart(); - - mCommandList->ClearDepthStencilView(mDsvHeap->GetCPUDescriptorHandleForHeapStart(), - D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0, - 0, nullptr); - - mCommandList->OMSetRenderTargets(1, &rtvHandle, true, &dsvHandle); -} - -Model *ContextD3D12::createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) -{ - Model *model; - switch (type) - { - case MODELGROUP::FISH: - model = new FishModelD3D12(this, aquarium, type, name, blend); - break; - case MODELGROUP::FISHINSTANCEDDRAW: - model = new FishModelInstancedDrawD3D12(this, aquarium, type, name, blend); - break; - case MODELGROUP::GENERIC: - model = new GenericModelD3D12(this, aquarium, type, name, blend); - break; - case MODELGROUP::INNER: - model = new InnerModelD3D12(this, aquarium, type, name, blend); - break; - case MODELGROUP::SEAWEED: - model = new SeaweedModelD3D12(this, aquarium, type, name, blend); - break; - case MODELGROUP::OUTSIDE: - model = new OutsideModelD3D12(this, aquarium, type, name, blend); - break; - default: - model = nullptr; - std::cerr << "can not create model type" << std::endl; - } - - return model; -} - -Buffer *ContextD3D12::createBuffer(int numComponents, std::vector *buf, bool isIndex) -{ - Buffer *buffer = - new BufferD3D12(this, static_cast(buf->size()), numComponents, *buf, isIndex); - return buffer; -} - -Buffer *ContextD3D12::createBuffer(int numComponents, - std::vector *buf, - bool isIndex) -{ - Buffer *buffer = - new BufferD3D12(this, static_cast(buf->size()), numComponents, *buf, isIndex); - return buffer; -} - -Program *ContextD3D12::createProgram(const std::string &mVId, const std::string &mFId) -{ - ProgramD3D12 *program = new ProgramD3D12(this, mVId, mFId); - program->loadProgram(); - - return program; -} - -Texture *ContextD3D12::createTexture(const std::string &name, const std::string &url) -{ - Texture *texture = new TextureD3D12(this, name, url); - texture->loadTexture(); - return texture; -} - -Texture *ContextD3D12::createTexture(const std::string &name, const std::vector &urls) -{ - Texture *texture = new TextureD3D12(this, name, urls); - texture->loadTexture(); - return texture; -} - -void ContextD3D12::initGeneralResources(Aquarium *aquarium) -{ - // create common constant buffer, desc and view. - mLightBuffer = - createDefaultBuffer(&aquarium->lightUniforms, - CalcConstantBufferByteSize(sizeof(LightUniforms)), mLightUploadBuffer); - mLightView.BufferLocation = mLightBuffer->GetGPUVirtualAddress(); - mLightView.SizeInBytes = CalcConstantBufferByteSize(sizeof(LightUniforms)); - buildCbvDescriptor(mLightView, &lightGPUHandle); - - mFogBuffer = createDefaultBuffer( - &aquarium->fogUniforms, CalcConstantBufferByteSize(sizeof(FogUniforms)), mFogUploadBuffer); - mFogView.BufferLocation = mFogBuffer->GetGPUVirtualAddress(); - mFogView.SizeInBytes = CalcConstantBufferByteSize( - sizeof(FogUniforms)); // CB size is required to be 256-byte aligned. - buildCbvDescriptor(mFogView, &fogGPUHandle); - - TextureD3D12 *skybox = static_cast(aquarium->getSkybox()); - skybox->createSrvDescriptor(); - - rangeGeneral[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0, 0, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rangeGeneral[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 0, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rootParameterGeneral.InitAsDescriptorTable(2, rangeGeneral, D3D12_SHADER_VISIBILITY_PIXEL); - - mLightWorldPositionBuffer = - createUploadBuffer(&aquarium->lightWorldPositionUniform, - CalcConstantBufferByteSize(sizeof(LightWorldPositionUniform))); - lightWorldPositionView.BufferLocation = mLightWorldPositionBuffer->GetGPUVirtualAddress(); - lightWorldPositionView.SizeInBytes = - CalcConstantBufferByteSize(sizeof(LightWorldPositionUniform)); - - rootParameterWorld.InitAsConstantBufferView(0, 1, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, - D3D12_SHADER_VISIBILITY_VERTEX); - - CD3DX12_STATIC_SAMPLER_DESC sampler2D(0u, // shaderRegister - D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT, // filter - D3D12_TEXTURE_ADDRESS_MODE_MIRROR, // addressU - D3D12_TEXTURE_ADDRESS_MODE_MIRROR, // addressV - D3D12_TEXTURE_ADDRESS_MODE_MIRROR, 0.0f, 0u, - D3D12_COMPARISON_FUNC_ALWAYS, - D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK, 0.0f, - D3D12_FLOAT32_MAX, D3D12_SHADER_VISIBILITY_PIXEL, 0u); - - CD3DX12_STATIC_SAMPLER_DESC samplerCube(1u, // shaderRegister - D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT, // filter - D3D12_TEXTURE_ADDRESS_MODE_CLAMP, // addressU - D3D12_TEXTURE_ADDRESS_MODE_CLAMP, // addressV - D3D12_TEXTURE_ADDRESS_MODE_CLAMP, 0.0f, 0u, - D3D12_COMPARISON_FUNC_NEVER, - D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK, 0.0f, - D3D12_FLOAT32_MAX, D3D12_SHADER_VISIBILITY_PIXEL, 0u); - staticSamplers.emplace_back(std::move(sampler2D)); - staticSamplers.emplace_back(std::move(samplerCube)); -} - -void ContextD3D12::updateWorldlUniforms(Aquarium *aquarium) -{ - CD3DX12_RANGE readRange(0, 0); - UINT8 *m_pCbvDataBegin; - mLightWorldPositionBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); - memcpy(m_pCbvDataBegin, &aquarium->lightWorldPositionUniform, - sizeof(LightWorldPositionUniform)); -} - -ComPtr ContextD3D12::createShaderModule(const std::string &type, - const std::string &shaderStr) -{ - ComPtr shader; - ComPtr errors; - HRESULT hr; - - if (type == "VS") - { - hr = (D3DCompile(shaderStr.c_str(), shaderStr.length(), nullptr, nullptr, nullptr, "main", - "vs_5_1", mCompileFlags, 0, &shader, &errors)); - } - else // "FS" - { - hr = (D3DCompile(shaderStr.c_str(), shaderStr.length(), nullptr, nullptr, nullptr, "main", - "ps_5_1", mCompileFlags, 0, &shader, &errors)); - } - - if (FAILED(hr)) - { - if (nullptr != errors) - { - std::cerr << ((char *)errors->GetBufferPointer()); - errors->Release(); - } - } - - return shader; -} - -void ContextD3D12::createCommittedResource(const D3D12_HEAP_PROPERTIES &properties, - const D3D12_RESOURCE_DESC &desc, - D3D12_RESOURCE_STATES state, - ComPtr &resource) -{ - if (FAILED(mDevice->CreateCommittedResource(&properties, D3D12_HEAP_FLAG_NONE, &desc, state, - nullptr, IID_PPV_ARGS(&resource)))) - { - std::cout << "failed to create Resource" << std::endl; - } -} - -void ContextD3D12::updateSubresources(ID3D12GraphicsCommandList *pCmdList, - ID3D12Resource *pDestinationResource, - ID3D12Resource *pIntermediate, - UINT64 IntermediateOffset, - UINT FirstSubresource, - UINT NumSubresources, - D3D12_SUBRESOURCE_DATA *pSrcData) -{ - UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, IntermediateOffset, - FirstSubresource, NumSubresources, pSrcData); -} - -void ContextD3D12::executeCommandLists(UINT NumCommandLists, - ID3D12CommandList *const *ppCommandLists) -{ - mCommandQueue->ExecuteCommandLists(NumCommandLists, ppCommandLists); -} - -void ContextD3D12::WaitForPreviousFrame() -{ - mFenceValue++; - // Signal and increment the fence value. - const UINT64 fence = mFenceValue; - ThrowIfFailed(mCommandQueue->Signal(mFence.Get(), fence)); - mBufferSerias[m_frameIndex] = mFenceValue; - - // Aquarium uses 3 back buffers for better performance. - // Wait until the previous before previous frame is finished. - int prepreIndex = (m_frameIndex + 1) % 3; - UINT prepreSerias = mBufferSerias[prepreIndex]; - if (mFence->GetCompletedValue() < prepreSerias) - { - ThrowIfFailed(mFence->SetEventOnCompletion(fence, mFenceEvent)); - WaitForSingleObject(mFenceEvent, INFINITE); - } - - // Get frame index for the next frame - m_frameIndex = mSwapChain->GetCurrentBackBufferIndex(); -} - -void ContextD3D12::createDepthStencilView() -{ - D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = {}; - depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - depthStencilViewDesc.ViewDimension = - mEnableMSAA ? D3D12_DSV_DIMENSION_TEXTURE2DMS : D3D12_DSV_DIMENSION_TEXTURE2D; - depthStencilViewDesc.Flags = D3D12_DSV_FLAG_NONE; - - D3D12_CLEAR_VALUE depthOptimizedClearValue = {}; - depthOptimizedClearValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - depthOptimizedClearValue.DepthStencil.Depth = 1.0f; - depthOptimizedClearValue.DepthStencil.Stencil = 0; - - D3D12_RESOURCE_DESC depthStencilDesc; - depthStencilDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - depthStencilDesc.Alignment = 0; - depthStencilDesc.Width = mClientWidth; - depthStencilDesc.Height = mClientHeight; - depthStencilDesc.DepthOrArraySize = 1; - depthStencilDesc.MipLevels = 1; - depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - depthStencilDesc.SampleDesc.Count = mEnableMSAA ? 4 : 1; - depthStencilDesc.SampleDesc.Quality = 0; - depthStencilDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - depthStencilDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; - - ThrowIfFailed(mDevice->CreateCommittedResource( - &defaultheapProperties, D3D12_HEAP_FLAG_NONE, &depthStencilDesc, - D3D12_RESOURCE_STATE_DEPTH_WRITE, &depthOptimizedClearValue, IID_PPV_ARGS(&mDepthStencil))); - - mDevice->CreateDepthStencilView(mDepthStencil.Get(), &depthStencilViewDesc, - mDsvHeap->GetCPUDescriptorHandleForHeapStart()); -} - -void ContextD3D12::createCommandList(ID3D12PipelineState *pInitialState, - ComPtr &commandList) -{ - ThrowIfFailed(mDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, - mCommandAllocators[0].Get(), pInitialState, - IID_PPV_ARGS(&commandList))); -} - -ComPtr ContextD3D12::createDefaultBuffer(const void *initData, - UINT64 byteSize, - ComPtr &uploadBuffer) const -{ - ComPtr defaultBuffer; - - CD3DX12_RESOURCE_DESC resourceDescriptor = CD3DX12_RESOURCE_DESC::Buffer(byteSize); - - // Create the actual default buffer resource. - ThrowIfFailed(mDevice->CreateCommittedResource( - &defaultheapProperties, D3D12_HEAP_FLAG_NONE, &resourceDescriptor, - D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(defaultBuffer.GetAddressOf()))); - - // In order to copy CPU memory data into our default buffer, we need to create - // an intermediate upload heap. - ThrowIfFailed(mDevice->CreateCommittedResource( - &uploadheapProperties, D3D12_HEAP_FLAG_NONE, &resourceDescriptor, - D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(uploadBuffer.GetAddressOf()))); - - // Describe the data we want to copy into the default buffer. - D3D12_SUBRESOURCE_DATA subResourceData = {}; - subResourceData.pData = initData; - subResourceData.RowPitch = byteSize; - subResourceData.SlicePitch = subResourceData.RowPitch; - - // Schedule to copy the data to the default buffer resource. - stateTransition(defaultBuffer, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST); - - UpdateSubresources<1>(mCommandList.Get(), defaultBuffer.Get(), uploadBuffer.Get(), 0, 0, 1, - &subResourceData); - - stateTransition(defaultBuffer, D3D12_RESOURCE_STATE_COPY_DEST, - D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); - - return defaultBuffer; -} - -ComPtr ContextD3D12::createUploadBuffer(const void *initData, UINT64 byteSize) const -{ - // create an uploadBuffer for dynamic data. - ComPtr uploadBuffer; - CD3DX12_RESOURCE_DESC resourceDesc = CD3DX12_RESOURCE_DESC::Buffer(byteSize); - mDevice->CreateCommittedResource(&uploadheapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, - IID_PPV_ARGS(uploadBuffer.GetAddressOf())); - - // Copy the triangle data to the vertex buffer. - UINT8 *pVertexDataBegin; - CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU. - uploadBuffer->Map(0, &readRange, reinterpret_cast(&pVertexDataBegin)); - memcpy(pVertexDataBegin, initData, byteSize); - uploadBuffer->Unmap(0, nullptr); - return uploadBuffer; -} - -void ContextD3D12::createRootSignature( - const D3D12_VERSIONED_ROOT_SIGNATURE_DESC &pRootSignatureDesc, - ComPtr &rootSignature) const -{ - ComPtr signature = nullptr; - ComPtr error = nullptr; - ThrowIfFailed( - D3DX12SerializeVersionedRootSignature(&pRootSignatureDesc, mRootSignature.HighestVersion, - signature.GetAddressOf(), error.GetAddressOf())); - if (error != nullptr) - { - ::OutputDebugStringA((char *)error->GetBufferPointer()); - } - ThrowIfFailed(mDevice->CreateRootSignature(0, signature->GetBufferPointer(), - signature->GetBufferSize(), - IID_PPV_ARGS(&rootSignature))); -} - -void ContextD3D12::createTexture(const D3D12_RESOURCE_DESC &textureDesc, - const std::vector &texture, - ComPtr &m_texture, - ComPtr &textureUploadHeap, - int TextureWidth, - int TextureHeight, - int TexturePixelSize, - int mipLevels, - int arraySize) -{ - ThrowIfFailed(mDevice->CreateCommittedResource(&defaultheapProperties, D3D12_HEAP_FLAG_NONE, - &textureDesc, D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, IID_PPV_ARGS(&m_texture))); - - int num2DSubresources = mipLevels * arraySize; - const UINT64 uploadBufferSize = - GetRequiredIntermediateSize(m_texture.Get(), 0, num2DSubresources); - - CD3DX12_RESOURCE_DESC resourceDesc = CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize); - // Create the GPU upload buffer. - ThrowIfFailed(mDevice->CreateCommittedResource(&uploadheapProperties, D3D12_HEAP_FLAG_NONE, - &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, IID_PPV_ARGS(&textureUploadHeap))); - - // Max mipmap levels is 10. - D3D12_SUBRESOURCE_DATA textureData[11]; - - for (int i = 0; i < num2DSubresources; i++) - { - textureData[i].pData = texture[i]; - textureData[i].RowPitch = TextureWidth * 4; - textureData[i].SlicePitch = textureData[i].RowPitch * TextureHeight; - - // Width and height of cubemap are the same. - if (arraySize == 6) - { - continue; - } - - TextureWidth >>= 1; - TextureHeight >>= 1; - if (TextureHeight == 0) - { - TextureHeight = 1; - } - } - - UpdateSubresources(mCommandList.Get(), m_texture.Get(), textureUploadHeap.Get(), 0, 0, - num2DSubresources, &textureData[0]); - - stateTransition(m_texture, D3D12_RESOURCE_STATE_COPY_DEST, - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); -} - -void ContextD3D12::createGraphicsPipelineState( - const std::vector &mInputElementDescs, - const ComPtr &rootSignature, - const ComPtr &mVertexShader, - const ComPtr &mPixelShader, - ComPtr &mPipelineState, - bool enableBlend) const -{ - // Describe and create the graphics mPipeline state object (PSO). - D3D12_DEPTH_STENCILOP_DESC stencilDesc = {}; - stencilDesc.StencilFailOp = D3D12_STENCIL_OP_KEEP; - stencilDesc.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP; - stencilDesc.StencilPassOp = D3D12_STENCIL_OP_KEEP; - stencilDesc.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS; - - D3D12_RENDER_TARGET_BLEND_DESC renderTargetBlendDesc = {}; - renderTargetBlendDesc.BlendEnable = enableBlend; - renderTargetBlendDesc.LogicOpEnable = false; - renderTargetBlendDesc.SrcBlend = D3D12_BLEND_SRC_ALPHA; - renderTargetBlendDesc.DestBlend = D3D12_BLEND_INV_SRC_ALPHA; - renderTargetBlendDesc.BlendOp = D3D12_BLEND_OP_ADD; - renderTargetBlendDesc.SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA; - renderTargetBlendDesc.DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; - renderTargetBlendDesc.BlendOpAlpha = D3D12_BLEND_OP_ADD; - renderTargetBlendDesc.LogicOp = D3D12_LOGIC_OP_NOOP; - renderTargetBlendDesc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; - - D3D12_BLEND_DESC blendDesc = {}; - blendDesc.AlphaToCoverageEnable = false; - blendDesc.IndependentBlendEnable = false; - blendDesc.RenderTarget[0] = renderTargetBlendDesc; - - D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; - psoDesc.InputLayout = {mInputElementDescs.data(), - static_cast(mInputElementDescs.size())}; - psoDesc.pRootSignature = rootSignature.Get(); - psoDesc.VS = CD3DX12_SHADER_BYTECODE(mVertexShader.Get()); - psoDesc.PS = CD3DX12_SHADER_BYTECODE(mPixelShader.Get()); - psoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; - psoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK; - psoDesc.RasterizerState.FrontCounterClockwise = TRUE; // oppose to opengl - psoDesc.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; - psoDesc.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; - psoDesc.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; - psoDesc.RasterizerState.DepthClipEnable = TRUE; - psoDesc.RasterizerState.MultisampleEnable = mEnableMSAA; - psoDesc.RasterizerState.AntialiasedLineEnable = FALSE; - psoDesc.RasterizerState.ForcedSampleCount = 0; - psoDesc.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; - psoDesc.BlendState = blendDesc; - psoDesc.DepthStencilState.DepthEnable = true; - psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS; - psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; - psoDesc.DepthStencilState.BackFace = stencilDesc; - psoDesc.DepthStencilState.FrontFace = stencilDesc; - psoDesc.DepthStencilState.StencilEnable = true; - psoDesc.DepthStencilState.StencilReadMask = 0xff; - psoDesc.DepthStencilState.StencilWriteMask = 0xff; - psoDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; - psoDesc.SampleMask = UINT_MAX; - psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - psoDesc.NumRenderTargets = 1u; - psoDesc.RTVFormats[0] = mPreferredSwapChainFormat; - psoDesc.SampleDesc.Count = mEnableMSAA ? 4u : 1u; - psoDesc.SampleDesc.Quality = 0; - - ThrowIfFailed(mDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPipelineState))); -} - -void ContextD3D12::buildSrvDescriptor(const ComPtr &resource, - const D3D12_SHADER_RESOURCE_VIEW_DESC &mSrvDesc, - D3D12_GPU_DESCRIPTOR_HANDLE *hGpuDescriptor) -{ - mDevice->CreateShaderResourceView(resource.Get(), &mSrvDesc, cbvsrvCPUHandle); - cbvsrvCPUHandle.Offset(mCbvmSrvDescriptorSize); - - *hGpuDescriptor = CD3DX12_GPU_DESCRIPTOR_HANDLE(cbvsrvGPUHandle); - cbvsrvGPUHandle.Offset(mCbvmSrvDescriptorSize); -} - -void ContextD3D12::buildCbvDescriptor(const D3D12_CONSTANT_BUFFER_VIEW_DESC &cbvDesc, - D3D12_GPU_DESCRIPTOR_HANDLE *hGpuDescriptor) -{ - mDevice->CreateConstantBufferView(&cbvDesc, cbvsrvCPUHandle); - cbvsrvCPUHandle.Offset(mCbvmSrvDescriptorSize); - - *hGpuDescriptor = CD3DX12_GPU_DESCRIPTOR_HANDLE(cbvsrvGPUHandle); - cbvsrvGPUHandle.Offset(mCbvmSrvDescriptorSize); -} - -UINT ContextD3D12::CalcConstantBufferByteSize(UINT byteSize) -{ - // Constant buffers must be a multiple of the minimum hardware - // allocation size (usually 256 bytes). So round up to nearest - // multiple of 256. We do this by adding 255 and then masking off - // the lower 2 bytes which store all bits < 256. - // Example: Suppose byteSize = 300. - // (300 + 255) & ~255 - // 555 & ~255 - // 0x022B & ~0x00ff - // 0x022B & 0xff00 - // 0x0200 - // 512 - return (byteSize + 255) & ~255; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "ContextD3D12.h" + +#include +#include + +#define GLFW_EXPOSE_NATIVE_WIN32 +#include + +#include "BufferD3D12.h" +#include "FishModelD3D12.h" +#include "FishModelInstancedDrawD3D12.h" +#include "GenericModelD3D12.h" +#include "InnerModelD3D12.h" +#include "OutsideModelD3D12.h" +#include "ProgramD3D12.h" +#include "SeaweedModelD3D12.h" +#include "TextureD3D12.h" + +#include "imgui.h" +#include "imgui_impl_dx12.h" +#include "imgui_impl_glfw.h" + +const CD3DX12_HEAP_PROPERTIES defaultheapProperties = + CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); +const CD3DX12_HEAP_PROPERTIES uploadheapProperties = + CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD); + +inline void ThrowIfFailed(HRESULT hr) +{ + if (FAILED(hr)) + { + printf("D3D12 backend failed: file \"%s\", line %d\n", __FILE__, __LINE__); + } +} + +ContextD3D12::ContextD3D12(BACKENDTYPE backendType) + : lightWorldPositionView({}), + mWindow(nullptr), + mDevice(nullptr), + mCommandQueue(nullptr), + mSwapChain(nullptr), + mPreferredSwapChainFormat(DXGI_FORMAT_R8G8B8A8_UNORM), + mCompileFlags(0), + m_frameIndex(0), + mRtvHeap(nullptr), + mDsvHeap(nullptr), + mCbvsrvHeap(nullptr), + mRtvDescriptorSize(0), + mCbvmSrvDescriptorSize(0), + mFenceValue(0), + mRootSignature({}), + mViewport(0.0f, 0.0f, 0.0f, 0.0f), + mScissorRect(0.0f, 0.0f, 0.0f, 0.0f), + mLightView({}), + mFogView({}), + mSceneRenderTargetView({}), + mEnableMSAA(false) +{ + for (UINT n = 0; n < mFrameCount; n++) + { + mBufferSerias[n] = 0; + } + + mResourceHelper = new ResourceHelper("d3d12", ""); + initAvailableToggleBitset(backendType); +} + +ContextD3D12::~ContextD3D12() +{ + delete mResourceHelper; + destoryImgUI(); +} + +bool ContextD3D12::initialize( + BACKENDTYPE backend, + const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) +{ + mEnableMSAA = toggleBitset.test(static_cast(TOGGLE::ENABLEMSAAx4)); + + // initialise GLFW + if (!glfwInit()) + { + std::cout << "Failed to initialise GLFW" << std::endl; + return false; + } + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + // set full screen + // glfwWindowHint(GLFW_DECORATED, GL_FALSE); + + GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); + const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); + mClientWidth = mode->width; + mClientHeight = mode->height; + + if (toggleBitset.test(static_cast(TOGGLE::ENABLEFULLSCREENMODE))) + { + mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", pMonitor, nullptr); + } + else + { + mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", nullptr, nullptr); + } + + if (mWindow == nullptr) + { + std::cout << "Failed to open GLFW window." << std::endl; + glfwTerminate(); + return false; + } + + HWND hwnd = glfwGetWin32Window(mWindow); + + // Get the resolution of screen + glfwGetFramebufferSize(mWindow, &mClientWidth, &mClientHeight); + + UINT dxgiFactoryFlags = 0; +#if defined(_DEBUG) + // Enable the debug layer (requires the Graphics Tools "optional feature"). + // NOTE: Enabling the debug layer after mDevice creation will invalidate the active mDevice. + { + ComPtr debugController; + if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) + { + debugController->EnableDebugLayer(); + + // Enable additional debug layers. + dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; + } + + mCompileFlags = + D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_ENABLE_STRICTNESS; + } +#endif + + ComPtr mFactory; + ThrowIfFailed(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&mFactory))); + + ComPtr hardwareAdapter; + ThrowIfFailed(GetHardwareAdapter(mFactory.Get(), &hardwareAdapter, toggleBitset)); + + ThrowIfFailed( + D3D12CreateDevice(hardwareAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&mDevice))); + // Describe and create the command queue. + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + + ThrowIfFailed(mDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue))); + + // Describe and create the swap chain. + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; + swapChainDesc.BufferCount = mFrameCount; + swapChainDesc.Width = mClientWidth; + swapChainDesc.Height = mClientHeight; + swapChainDesc.Format = mPreferredSwapChainFormat; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapChainDesc.SampleDesc.Count = 1; + + mViewport.Width = static_cast(mClientWidth); + mViewport.Height = static_cast(mClientHeight); + mScissorRect.right = static_cast(mClientWidth); + mScissorRect.bottom = static_cast(mClientHeight); + + ComPtr swapChain; + ThrowIfFailed(mFactory->CreateSwapChainForHwnd( + mCommandQueue.Get(), // Swap chain needs the queue so that it can force a flush on it. + hwnd, &swapChainDesc, nullptr, nullptr, &swapChain)); + + // This sample does not support fullscreen transitions. + ThrowIfFailed(mFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER)); + + ThrowIfFailed(swapChain.As(&mSwapChain)); + + m_frameIndex = mSwapChain->GetCurrentBackBufferIndex(); + + // Describe and create a render target view (RTV) descriptor heap. + D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {}; + rtvHeapDesc.NumDescriptors = mEnableMSAA ? mFrameCount + 1 : mFrameCount; + rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + ThrowIfFailed(mDevice->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&mRtvHeap))); + + mRtvDescriptorSize = mDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + + CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle; + // Create frame resources. + { + rtvHandle = mRtvHeap->GetCPUDescriptorHandleForHeapStart(); + + // Create a RTV for each frame. + for (UINT n = 0; n < mFrameCount; n++) + { + ThrowIfFailed(mSwapChain->GetBuffer(n, IID_PPV_ARGS(&mRenderTargets[n]))); + mDevice->CreateRenderTargetView(mRenderTargets[n].Get(), nullptr, rtvHandle); + rtvHandle.Offset(1, mRtvDescriptorSize); + } + } + + // Describe and create a depth stencil view (DSV) descriptor heap. + D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {}; + dsvHeapDesc.NumDescriptors = 1; + dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; + dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + ThrowIfFailed(mDevice->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&mDsvHeap))); + + // Init cbvuav descriptor heap + // Create a shader resource view (SRV) and constant + // buffer view (CBV) descriptor heap. + D3D12_DESCRIPTOR_HEAP_DESC cbvSrvHeapDesc = {}; + cbvSrvHeapDesc.NumDescriptors = cbvsrvCount; + cbvSrvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + cbvSrvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + ThrowIfFailed(mDevice->CreateDescriptorHeap(&cbvSrvHeapDesc, IID_PPV_ARGS(&mCbvsrvHeap))); + + mCbvmSrvDescriptorSize = + mDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + cbvsrvCPUHandle = mCbvsrvHeap->GetCPUDescriptorHandleForHeapStart(); + cbvsrvGPUHandle = mCbvsrvHeap->GetGPUDescriptorHandleForHeapStart(); + + // Init 3 command allocators for 3 back buffers + for (UINT n = 0; n < mFrameCount; n++) + { + ThrowIfFailed(mDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, + IID_PPV_ARGS(&mCommandAllocators[n]))); + } + + createCommandList(nullptr, mCommandList); + + // Check highest version of root signature. + mRootSignature.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1; + + if (FAILED(mDevice->CheckFeatureSupport(D3D12_FEATURE_ROOT_SIGNATURE, &mRootSignature, + sizeof(mRootSignature)))) + { + mRootSignature.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0; + } + + if (mEnableMSAA) + { + D3D12_RESOURCE_DESC textureDesc = {}; + textureDesc.MipLevels = 1; + textureDesc.Format = mPreferredSwapChainFormat; + textureDesc.Width = mClientWidth; + textureDesc.Height = mClientHeight; + textureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + textureDesc.DepthOrArraySize = 1; + textureDesc.SampleDesc.Count = 4u; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + + ThrowIfFailed(mDevice->CreateCommittedResource( + &defaultheapProperties, D3D12_HEAP_FLAG_NONE, &textureDesc, + D3D12_RESOURCE_STATE_RENDER_TARGET, nullptr, IID_PPV_ARGS(&mSceneRenderTargetTexture))); + + mSceneRenderTargetView.Format = mPreferredSwapChainFormat; + mSceneRenderTargetView.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS; + mSceneRenderTargetView.Texture2D.MipSlice = 1; + + mDevice->CreateRenderTargetView(mSceneRenderTargetTexture.Get(), &mSceneRenderTargetView, + rtvHandle); + } + createDepthStencilView(); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + + // Setup Platform/Renderer bindings + // We use glfw for d3d12 backend as well, but imgui only expose glfw to OpenGL and Vulkan. + // However, the glfw api is totoally independent of Graphics API, so we could just ingnore the + // name of the function. + ImGui_ImplGlfw_InitForOpenGL(mWindow, true); + ImGui_ImplDX12_Init(mDevice.Get(), mFrameCount, mPreferredSwapChainFormat, cbvsrvCPUHandle, + cbvsrvGPUHandle); + cbvsrvCPUHandle.Offset(mCbvmSrvDescriptorSize); + cbvsrvGPUHandle.Offset(mCbvmSrvDescriptorSize); + + return true; +} + +// Helper function for acquiring the first available hardware adapter that supports Direct3D 12. +// If no such adapter can be found, *ppAdapter will be set to nullptr. +bool ContextD3D12::GetHardwareAdapter( + IDXGIFactory2 *pFactory, + IDXGIAdapter1 **ppAdapter, + const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) +{ + ComPtr adapter; + *ppAdapter = nullptr; + + bool enableIntegratedGpu = toggleBitset.test(static_cast(TOGGLE::INTEGRATEDGPU)); + bool enableDiscreteGpu = toggleBitset.test(static_cast(TOGGLE::DISCRETEGPU)); + bool useDefaultGpu = (enableDiscreteGpu | enableIntegratedGpu) == false ? true : false; + + for (UINT adapterIndex = 0; + DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex) + { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + + if (useDefaultGpu || + (enableDiscreteGpu && (desc.VendorId == 0x10DE || desc.VendorId == 0x1002)) || + (enableIntegratedGpu && desc.VendorId == 0x8086)) + { + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + // Don't select the Basic Render Driver adapter. + continue; + } + + if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, + _uuidof(ID3D12Device), nullptr))) + { + std::wstring str = desc.Description; + mRenderer = std::string(str.begin(), str.end()); + std::cout << mRenderer << std::endl; + break; + } + } + } + + *ppAdapter = adapter.Detach(); + if (ppAdapter == nullptr) + { + std::cerr << "Failed to create adapter." << std::endl; + return false; + } + return true; +} + +void ContextD3D12::setWindowTitle(const std::string &text) +{ + glfwSetWindowTitle(mWindow, text.c_str()); +} + +bool ContextD3D12::ShouldQuit() +{ + return glfwWindowShouldClose(mWindow); +} + +void ContextD3D12::KeyBoardQuit() +{ + if (glfwGetKey(mWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(mWindow, GL_TRUE); +} + +void ContextD3D12::stateTransition(ComPtr &resource, + D3D12_RESOURCE_STATES preState, + D3D12_RESOURCE_STATES transferState) const +{ + CD3DX12_RESOURCE_BARRIER barrier = + CD3DX12_RESOURCE_BARRIER::Transition(resource.Get(), preState, transferState); + mCommandList->ResourceBarrier(1, &barrier); +} + +void ContextD3D12::initAvailableToggleBitset(BACKENDTYPE backendType) +{ + mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEMSAAx4)); + mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)); + mAvailableToggleBitset.set(static_cast(TOGGLE::DISCRETEGPU)); + mAvailableToggleBitset.set(static_cast(TOGGLE::INTEGRATEDGPU)); + mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEFULLSCREENMODE)); +} + +void ContextD3D12::DoFlush() +{ + // Resolve MSAA texture to non MSAA texture, and then present. + if (mEnableMSAA) + { + stateTransition(mSceneRenderTargetTexture, D3D12_RESOURCE_STATE_RENDER_TARGET, + D3D12_RESOURCE_STATE_RESOLVE_SOURCE); + stateTransition(mRenderTargets[m_frameIndex], D3D12_RESOURCE_STATE_COMMON, + D3D12_RESOURCE_STATE_RESOLVE_DEST); + + mCommandList->ResolveSubresource(mRenderTargets[m_frameIndex].Get(), 0, + mSceneRenderTargetTexture.Get(), 0, + mPreferredSwapChainFormat); + + stateTransition(mSceneRenderTargetTexture, D3D12_RESOURCE_STATE_RESOLVE_SOURCE, + D3D12_RESOURCE_STATE_RENDER_TARGET); + stateTransition(mRenderTargets[m_frameIndex], D3D12_RESOURCE_STATE_RESOLVE_DEST, + D3D12_RESOURCE_STATE_COMMON); + } + else + { + stateTransition(mRenderTargets[m_frameIndex], D3D12_RESOURCE_STATE_RENDER_TARGET, + D3D12_RESOURCE_STATE_COMMON); + } + + ThrowIfFailed(mCommandList->Close()); + + // Execute the command list. + ID3D12CommandList *ppCommandLists[] = {mCommandList.Get()}; + mCommandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); + + // Present the frame. + ThrowIfFailed(mSwapChain->Present(1, 0)); + + WaitForPreviousFrame(); + + glfwPollEvents(); +} + +void ContextD3D12::FlushInit() +{ + // Close the command list and execute it to begin the initial GPU setup. + ThrowIfFailed(mCommandList->Close()); + ID3D12CommandList *ppCommandLists[] = {mCommandList.Get()}; + mCommandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); + + // Create synchronization objects and wait until assets have been uploaded to the GPU. + { + ThrowIfFailed( + mDevice->CreateFence(mFenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence))); + + // Create an event handle to use for frame synchronization. + mFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + if (mFenceEvent == nullptr) + { + ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); + } + + ThrowIfFailed(mSwapChain->Present(1, 0)); + m_frameIndex = mSwapChain->GetCurrentBackBufferIndex(); + + WaitForPreviousFrame(); + } +} + +void ContextD3D12::Terminate() +{ + UINT lastSerias = 0; + if (m_frameIndex == 0) + { + lastSerias = mBufferSerias[2]; + } + else + { + lastSerias = mBufferSerias[m_frameIndex - 1]; + } + + if (mFence->GetCompletedValue() < lastSerias) + { + ThrowIfFailed(mFence->SetEventOnCompletion(lastSerias, mFenceEvent)); + WaitForSingleObject(mFenceEvent, INFINITE); + } + + glfwTerminate(); +} + +void ContextD3D12::showWindow() +{ + glfwShowWindow(mWindow); +} + +void ContextD3D12::showFPS(const FPSTimer &fpsTimer) +{ + // Start the Dear ImGui frame + ImGui_ImplDX12_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + { + ImGui::Begin("Aquarium Native"); + + std::ostringstream rendererStream; + std::string backend = mResourceHelper->getBackendName(); + for (auto &c : backend) + c = toupper(c); + rendererStream << mRenderer << " " << backend << " " << mResourceHelper->getShaderVersion(); + std::string renderer = rendererStream.str(); + ImGui::Text(renderer.c_str()); + + std::ostringstream resolutionStream; + resolutionStream << "Resolution " << mClientWidth << "x" << mClientHeight; + std::string resolution = resolutionStream.str(); + ImGui::Text(resolution.c_str()); + + ImGui::PlotLines("[0,100 FPS]", fpsTimer.getHistoryFps(), NUM_HISTORY_DATA, 0, NULL, 0.0f, + 100.0f, ImVec2(0, 40)); + + ImGui::PlotHistogram("[0,100 ms/frame]", fpsTimer.getHistoryFrameTime(), NUM_HISTORY_DATA, + 0, NULL, 0.0f, 100.0f, ImVec2(0, 40)); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", + 1000.0f / fpsTimer.getAverageFPS(), fpsTimer.getAverageFPS()); + ImGui::End(); + } + + ImGui::Render(); + ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), mCommandList.Get()); +} + +void ContextD3D12::destoryImgUI() +{ + ImGui_ImplDX12_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); +} + +void ContextD3D12::preFrame() +{ + // Reuse the memory associated with command recording. + // We can only reset when the associated command lists have finished execution on the GPU. + ThrowIfFailed(mCommandAllocators[m_frameIndex]->Reset()); + + // A command list can be reset after it has been added to the command queue via + // ExecuteCommandList. + // Reusing the command list reuses memory. + ThrowIfFailed(mCommandList->Reset(mCommandAllocators[m_frameIndex].Get(), nullptr)); + + // Set descriptor heaps related to command list. + ID3D12DescriptorHeap *mDescriptorHeaps[] = {mCbvsrvHeap.Get()}; + + mCommandList->SetDescriptorHeaps(_countof(mDescriptorHeaps), mDescriptorHeaps); + mCommandList->RSSetViewports(1, &mViewport); + mCommandList->RSSetScissorRects(1, &mScissorRect); + + CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle; + CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle; + if (mEnableMSAA) + { + rtvHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(mRtvHeap->GetCPUDescriptorHandleForHeapStart(), + mFrameCount, mRtvDescriptorSize); + } + else + { + rtvHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(mRtvHeap->GetCPUDescriptorHandleForHeapStart(), + m_frameIndex, mRtvDescriptorSize); + + stateTransition(mRenderTargets[m_frameIndex], D3D12_RESOURCE_STATE_COMMON, + D3D12_RESOURCE_STATE_RENDER_TARGET); + } + + dsvHandle = mDsvHeap->GetCPUDescriptorHandleForHeapStart(); + + mCommandList->ClearDepthStencilView(mDsvHeap->GetCPUDescriptorHandleForHeapStart(), + D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0, + 0, nullptr); + + mCommandList->OMSetRenderTargets(1, &rtvHandle, true, &dsvHandle); +} + +Model *ContextD3D12::createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) +{ + Model *model; + switch (type) + { + case MODELGROUP::FISH: + model = new FishModelD3D12(this, aquarium, type, name, blend); + break; + case MODELGROUP::FISHINSTANCEDDRAW: + model = new FishModelInstancedDrawD3D12(this, aquarium, type, name, blend); + break; + case MODELGROUP::GENERIC: + model = new GenericModelD3D12(this, aquarium, type, name, blend); + break; + case MODELGROUP::INNER: + model = new InnerModelD3D12(this, aquarium, type, name, blend); + break; + case MODELGROUP::SEAWEED: + model = new SeaweedModelD3D12(this, aquarium, type, name, blend); + break; + case MODELGROUP::OUTSIDE: + model = new OutsideModelD3D12(this, aquarium, type, name, blend); + break; + default: + model = nullptr; + std::cerr << "can not create model type" << std::endl; + } + + return model; +} + +Buffer *ContextD3D12::createBuffer(int numComponents, std::vector *buf, bool isIndex) +{ + Buffer *buffer = + new BufferD3D12(this, static_cast(buf->size()), numComponents, *buf, isIndex); + return buffer; +} + +Buffer *ContextD3D12::createBuffer(int numComponents, + std::vector *buf, + bool isIndex) +{ + Buffer *buffer = + new BufferD3D12(this, static_cast(buf->size()), numComponents, *buf, isIndex); + return buffer; +} + +Program *ContextD3D12::createProgram(const std::string &mVId, const std::string &mFId) +{ + ProgramD3D12 *program = new ProgramD3D12(this, mVId, mFId); + program->loadProgram(); + + return program; +} + +Texture *ContextD3D12::createTexture(const std::string &name, const std::string &url) +{ + Texture *texture = new TextureD3D12(this, name, url); + texture->loadTexture(); + return texture; +} + +Texture *ContextD3D12::createTexture(const std::string &name, const std::vector &urls) +{ + Texture *texture = new TextureD3D12(this, name, urls); + texture->loadTexture(); + return texture; +} + +void ContextD3D12::initGeneralResources(Aquarium *aquarium) +{ + // create common constant buffer, desc and view. + mLightBuffer = + createDefaultBuffer(&aquarium->lightUniforms, + CalcConstantBufferByteSize(sizeof(LightUniforms)), mLightUploadBuffer); + mLightView.BufferLocation = mLightBuffer->GetGPUVirtualAddress(); + mLightView.SizeInBytes = CalcConstantBufferByteSize(sizeof(LightUniforms)); + buildCbvDescriptor(mLightView, &lightGPUHandle); + + mFogBuffer = createDefaultBuffer( + &aquarium->fogUniforms, CalcConstantBufferByteSize(sizeof(FogUniforms)), mFogUploadBuffer); + mFogView.BufferLocation = mFogBuffer->GetGPUVirtualAddress(); + mFogView.SizeInBytes = CalcConstantBufferByteSize( + sizeof(FogUniforms)); // CB size is required to be 256-byte aligned. + buildCbvDescriptor(mFogView, &fogGPUHandle); + + TextureD3D12 *skybox = static_cast(aquarium->getSkybox()); + skybox->createSrvDescriptor(); + + rangeGeneral[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0, 0, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rangeGeneral[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 0, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rootParameterGeneral.InitAsDescriptorTable(2, rangeGeneral, D3D12_SHADER_VISIBILITY_PIXEL); + + mLightWorldPositionBuffer = + createUploadBuffer(&aquarium->lightWorldPositionUniform, + CalcConstantBufferByteSize(sizeof(LightWorldPositionUniform))); + lightWorldPositionView.BufferLocation = mLightWorldPositionBuffer->GetGPUVirtualAddress(); + lightWorldPositionView.SizeInBytes = + CalcConstantBufferByteSize(sizeof(LightWorldPositionUniform)); + + rootParameterWorld.InitAsConstantBufferView(0, 1, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, + D3D12_SHADER_VISIBILITY_VERTEX); + + CD3DX12_STATIC_SAMPLER_DESC sampler2D(0u, // shaderRegister + D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT, // filter + D3D12_TEXTURE_ADDRESS_MODE_MIRROR, // addressU + D3D12_TEXTURE_ADDRESS_MODE_MIRROR, // addressV + D3D12_TEXTURE_ADDRESS_MODE_MIRROR, 0.0f, 0u, + D3D12_COMPARISON_FUNC_ALWAYS, + D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK, 0.0f, + D3D12_FLOAT32_MAX, D3D12_SHADER_VISIBILITY_PIXEL, 0u); + + CD3DX12_STATIC_SAMPLER_DESC samplerCube(1u, // shaderRegister + D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT, // filter + D3D12_TEXTURE_ADDRESS_MODE_CLAMP, // addressU + D3D12_TEXTURE_ADDRESS_MODE_CLAMP, // addressV + D3D12_TEXTURE_ADDRESS_MODE_CLAMP, 0.0f, 0u, + D3D12_COMPARISON_FUNC_NEVER, + D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK, 0.0f, + D3D12_FLOAT32_MAX, D3D12_SHADER_VISIBILITY_PIXEL, 0u); + staticSamplers.emplace_back(std::move(sampler2D)); + staticSamplers.emplace_back(std::move(samplerCube)); +} + +void ContextD3D12::updateWorldlUniforms(Aquarium *aquarium) +{ + CD3DX12_RANGE readRange(0, 0); + UINT8 *m_pCbvDataBegin; + mLightWorldPositionBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); + memcpy(m_pCbvDataBegin, &aquarium->lightWorldPositionUniform, + sizeof(LightWorldPositionUniform)); +} + +ComPtr ContextD3D12::createShaderModule(const std::string &type, + const std::string &shaderStr) +{ + ComPtr shader; + ComPtr errors; + HRESULT hr; + + if (type == "VS") + { + hr = (D3DCompile(shaderStr.c_str(), shaderStr.length(), nullptr, nullptr, nullptr, "main", + "vs_5_1", mCompileFlags, 0, &shader, &errors)); + } + else // "FS" + { + hr = (D3DCompile(shaderStr.c_str(), shaderStr.length(), nullptr, nullptr, nullptr, "main", + "ps_5_1", mCompileFlags, 0, &shader, &errors)); + } + + if (FAILED(hr)) + { + if (nullptr != errors) + { + std::cerr << ((char *)errors->GetBufferPointer()); + errors->Release(); + } + } + + return shader; +} + +void ContextD3D12::createCommittedResource(const D3D12_HEAP_PROPERTIES &properties, + const D3D12_RESOURCE_DESC &desc, + D3D12_RESOURCE_STATES state, + ComPtr &resource) +{ + if (FAILED(mDevice->CreateCommittedResource(&properties, D3D12_HEAP_FLAG_NONE, &desc, state, + nullptr, IID_PPV_ARGS(&resource)))) + { + std::cout << "failed to create Resource" << std::endl; + } +} + +void ContextD3D12::updateSubresources(ID3D12GraphicsCommandList *pCmdList, + ID3D12Resource *pDestinationResource, + ID3D12Resource *pIntermediate, + UINT64 IntermediateOffset, + UINT FirstSubresource, + UINT NumSubresources, + D3D12_SUBRESOURCE_DATA *pSrcData) +{ + UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, IntermediateOffset, + FirstSubresource, NumSubresources, pSrcData); +} + +void ContextD3D12::executeCommandLists(UINT NumCommandLists, + ID3D12CommandList *const *ppCommandLists) +{ + mCommandQueue->ExecuteCommandLists(NumCommandLists, ppCommandLists); +} + +void ContextD3D12::WaitForPreviousFrame() +{ + mFenceValue++; + // Signal and increment the fence value. + const UINT64 fence = mFenceValue; + ThrowIfFailed(mCommandQueue->Signal(mFence.Get(), fence)); + mBufferSerias[m_frameIndex] = mFenceValue; + + // Aquarium uses 3 back buffers for better performance. + // Wait until the previous before previous frame is finished. + int prepreIndex = (m_frameIndex + 1) % 3; + UINT prepreSerias = mBufferSerias[prepreIndex]; + if (mFence->GetCompletedValue() < prepreSerias) + { + ThrowIfFailed(mFence->SetEventOnCompletion(fence, mFenceEvent)); + WaitForSingleObject(mFenceEvent, INFINITE); + } + + // Get frame index for the next frame + m_frameIndex = mSwapChain->GetCurrentBackBufferIndex(); +} + +void ContextD3D12::createDepthStencilView() +{ + D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = {}; + depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + depthStencilViewDesc.ViewDimension = + mEnableMSAA ? D3D12_DSV_DIMENSION_TEXTURE2DMS : D3D12_DSV_DIMENSION_TEXTURE2D; + depthStencilViewDesc.Flags = D3D12_DSV_FLAG_NONE; + + D3D12_CLEAR_VALUE depthOptimizedClearValue = {}; + depthOptimizedClearValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + depthOptimizedClearValue.DepthStencil.Depth = 1.0f; + depthOptimizedClearValue.DepthStencil.Stencil = 0; + + D3D12_RESOURCE_DESC depthStencilDesc; + depthStencilDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + depthStencilDesc.Alignment = 0; + depthStencilDesc.Width = mClientWidth; + depthStencilDesc.Height = mClientHeight; + depthStencilDesc.DepthOrArraySize = 1; + depthStencilDesc.MipLevels = 1; + depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + depthStencilDesc.SampleDesc.Count = mEnableMSAA ? 4 : 1; + depthStencilDesc.SampleDesc.Quality = 0; + depthStencilDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + depthStencilDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + + ThrowIfFailed(mDevice->CreateCommittedResource( + &defaultheapProperties, D3D12_HEAP_FLAG_NONE, &depthStencilDesc, + D3D12_RESOURCE_STATE_DEPTH_WRITE, &depthOptimizedClearValue, IID_PPV_ARGS(&mDepthStencil))); + + mDevice->CreateDepthStencilView(mDepthStencil.Get(), &depthStencilViewDesc, + mDsvHeap->GetCPUDescriptorHandleForHeapStart()); +} + +void ContextD3D12::createCommandList(ID3D12PipelineState *pInitialState, + ComPtr &commandList) +{ + ThrowIfFailed(mDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, + mCommandAllocators[0].Get(), pInitialState, + IID_PPV_ARGS(&commandList))); +} + +ComPtr ContextD3D12::createDefaultBuffer(const void *initData, + UINT64 byteSize, + ComPtr &uploadBuffer) const +{ + ComPtr defaultBuffer; + + CD3DX12_RESOURCE_DESC resourceDescriptor = CD3DX12_RESOURCE_DESC::Buffer(byteSize); + + // Create the actual default buffer resource. + ThrowIfFailed(mDevice->CreateCommittedResource( + &defaultheapProperties, D3D12_HEAP_FLAG_NONE, &resourceDescriptor, + D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(defaultBuffer.GetAddressOf()))); + + // In order to copy CPU memory data into our default buffer, we need to create + // an intermediate upload heap. + ThrowIfFailed(mDevice->CreateCommittedResource( + &uploadheapProperties, D3D12_HEAP_FLAG_NONE, &resourceDescriptor, + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(uploadBuffer.GetAddressOf()))); + + // Describe the data we want to copy into the default buffer. + D3D12_SUBRESOURCE_DATA subResourceData = {}; + subResourceData.pData = initData; + subResourceData.RowPitch = byteSize; + subResourceData.SlicePitch = subResourceData.RowPitch; + + // Schedule to copy the data to the default buffer resource. + stateTransition(defaultBuffer, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST); + + UpdateSubresources<1>(mCommandList.Get(), defaultBuffer.Get(), uploadBuffer.Get(), 0, 0, 1, + &subResourceData); + + stateTransition(defaultBuffer, D3D12_RESOURCE_STATE_COPY_DEST, + D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); + + return defaultBuffer; +} + +ComPtr ContextD3D12::createUploadBuffer(const void *initData, UINT64 byteSize) const +{ + // create an uploadBuffer for dynamic data. + ComPtr uploadBuffer; + CD3DX12_RESOURCE_DESC resourceDesc = CD3DX12_RESOURCE_DESC::Buffer(byteSize); + mDevice->CreateCommittedResource(&uploadheapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, + IID_PPV_ARGS(uploadBuffer.GetAddressOf())); + + // Copy the triangle data to the vertex buffer. + UINT8 *pVertexDataBegin; + CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU. + uploadBuffer->Map(0, &readRange, reinterpret_cast(&pVertexDataBegin)); + memcpy(pVertexDataBegin, initData, byteSize); + uploadBuffer->Unmap(0, nullptr); + return uploadBuffer; +} + +void ContextD3D12::createRootSignature( + const D3D12_VERSIONED_ROOT_SIGNATURE_DESC &pRootSignatureDesc, + ComPtr &rootSignature) const +{ + ComPtr signature = nullptr; + ComPtr error = nullptr; + ThrowIfFailed( + D3DX12SerializeVersionedRootSignature(&pRootSignatureDesc, mRootSignature.HighestVersion, + signature.GetAddressOf(), error.GetAddressOf())); + if (error != nullptr) + { + ::OutputDebugStringA((char *)error->GetBufferPointer()); + } + ThrowIfFailed(mDevice->CreateRootSignature(0, signature->GetBufferPointer(), + signature->GetBufferSize(), + IID_PPV_ARGS(&rootSignature))); +} + +void ContextD3D12::createTexture(const D3D12_RESOURCE_DESC &textureDesc, + const std::vector &texture, + ComPtr &m_texture, + ComPtr &textureUploadHeap, + int TextureWidth, + int TextureHeight, + int TexturePixelSize, + int mipLevels, + int arraySize) +{ + ThrowIfFailed(mDevice->CreateCommittedResource(&defaultheapProperties, D3D12_HEAP_FLAG_NONE, + &textureDesc, D3D12_RESOURCE_STATE_COPY_DEST, + nullptr, IID_PPV_ARGS(&m_texture))); + + int num2DSubresources = mipLevels * arraySize; + const UINT64 uploadBufferSize = + GetRequiredIntermediateSize(m_texture.Get(), 0, num2DSubresources); + + CD3DX12_RESOURCE_DESC resourceDesc = CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize); + // Create the GPU upload buffer. + ThrowIfFailed(mDevice->CreateCommittedResource(&uploadheapProperties, D3D12_HEAP_FLAG_NONE, + &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, IID_PPV_ARGS(&textureUploadHeap))); + + // Max mipmap levels is 10. + D3D12_SUBRESOURCE_DATA textureData[11]; + + for (int i = 0; i < num2DSubresources; i++) + { + textureData[i].pData = texture[i]; + textureData[i].RowPitch = TextureWidth * 4; + textureData[i].SlicePitch = textureData[i].RowPitch * TextureHeight; + + // Width and height of cubemap are the same. + if (arraySize == 6) + { + continue; + } + + TextureWidth >>= 1; + TextureHeight >>= 1; + if (TextureHeight == 0) + { + TextureHeight = 1; + } + } + + UpdateSubresources(mCommandList.Get(), m_texture.Get(), textureUploadHeap.Get(), 0, 0, + num2DSubresources, &textureData[0]); + + stateTransition(m_texture, D3D12_RESOURCE_STATE_COPY_DEST, + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); +} + +void ContextD3D12::createGraphicsPipelineState( + const std::vector &mInputElementDescs, + const ComPtr &rootSignature, + const ComPtr &mVertexShader, + const ComPtr &mPixelShader, + ComPtr &mPipelineState, + bool enableBlend) const +{ + // Describe and create the graphics mPipeline state object (PSO). + D3D12_DEPTH_STENCILOP_DESC stencilDesc = {}; + stencilDesc.StencilFailOp = D3D12_STENCIL_OP_KEEP; + stencilDesc.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP; + stencilDesc.StencilPassOp = D3D12_STENCIL_OP_KEEP; + stencilDesc.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS; + + D3D12_RENDER_TARGET_BLEND_DESC renderTargetBlendDesc = {}; + renderTargetBlendDesc.BlendEnable = enableBlend; + renderTargetBlendDesc.LogicOpEnable = false; + renderTargetBlendDesc.SrcBlend = D3D12_BLEND_SRC_ALPHA; + renderTargetBlendDesc.DestBlend = D3D12_BLEND_INV_SRC_ALPHA; + renderTargetBlendDesc.BlendOp = D3D12_BLEND_OP_ADD; + renderTargetBlendDesc.SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA; + renderTargetBlendDesc.DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; + renderTargetBlendDesc.BlendOpAlpha = D3D12_BLEND_OP_ADD; + renderTargetBlendDesc.LogicOp = D3D12_LOGIC_OP_NOOP; + renderTargetBlendDesc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + + D3D12_BLEND_DESC blendDesc = {}; + blendDesc.AlphaToCoverageEnable = false; + blendDesc.IndependentBlendEnable = false; + blendDesc.RenderTarget[0] = renderTargetBlendDesc; + + D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; + psoDesc.InputLayout = {mInputElementDescs.data(), + static_cast(mInputElementDescs.size())}; + psoDesc.pRootSignature = rootSignature.Get(); + psoDesc.VS = CD3DX12_SHADER_BYTECODE(mVertexShader.Get()); + psoDesc.PS = CD3DX12_SHADER_BYTECODE(mPixelShader.Get()); + psoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + psoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK; + psoDesc.RasterizerState.FrontCounterClockwise = TRUE; // oppose to opengl + psoDesc.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + psoDesc.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + psoDesc.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + psoDesc.RasterizerState.DepthClipEnable = TRUE; + psoDesc.RasterizerState.MultisampleEnable = mEnableMSAA; + psoDesc.RasterizerState.AntialiasedLineEnable = FALSE; + psoDesc.RasterizerState.ForcedSampleCount = 0; + psoDesc.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + psoDesc.BlendState = blendDesc; + psoDesc.DepthStencilState.DepthEnable = true; + psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS; + psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + psoDesc.DepthStencilState.BackFace = stencilDesc; + psoDesc.DepthStencilState.FrontFace = stencilDesc; + psoDesc.DepthStencilState.StencilEnable = true; + psoDesc.DepthStencilState.StencilReadMask = 0xff; + psoDesc.DepthStencilState.StencilWriteMask = 0xff; + psoDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; + psoDesc.SampleMask = UINT_MAX; + psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + psoDesc.NumRenderTargets = 1u; + psoDesc.RTVFormats[0] = mPreferredSwapChainFormat; + psoDesc.SampleDesc.Count = mEnableMSAA ? 4u : 1u; + psoDesc.SampleDesc.Quality = 0; + + ThrowIfFailed(mDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPipelineState))); +} + +void ContextD3D12::buildSrvDescriptor(const ComPtr &resource, + const D3D12_SHADER_RESOURCE_VIEW_DESC &mSrvDesc, + D3D12_GPU_DESCRIPTOR_HANDLE *hGpuDescriptor) +{ + mDevice->CreateShaderResourceView(resource.Get(), &mSrvDesc, cbvsrvCPUHandle); + cbvsrvCPUHandle.Offset(mCbvmSrvDescriptorSize); + + *hGpuDescriptor = CD3DX12_GPU_DESCRIPTOR_HANDLE(cbvsrvGPUHandle); + cbvsrvGPUHandle.Offset(mCbvmSrvDescriptorSize); +} + +void ContextD3D12::buildCbvDescriptor(const D3D12_CONSTANT_BUFFER_VIEW_DESC &cbvDesc, + D3D12_GPU_DESCRIPTOR_HANDLE *hGpuDescriptor) +{ + mDevice->CreateConstantBufferView(&cbvDesc, cbvsrvCPUHandle); + cbvsrvCPUHandle.Offset(mCbvmSrvDescriptorSize); + + *hGpuDescriptor = CD3DX12_GPU_DESCRIPTOR_HANDLE(cbvsrvGPUHandle); + cbvsrvGPUHandle.Offset(mCbvmSrvDescriptorSize); +} + +UINT ContextD3D12::CalcConstantBufferByteSize(UINT byteSize) +{ + // Constant buffers must be a multiple of the minimum hardware + // allocation size (usually 256 bytes). So round up to nearest + // multiple of 256. We do this by adding 255 and then masking off + // the lower 2 bytes which store all bits < 256. + // Example: Suppose byteSize = 300. + // (300 + 255) & ~255 + // 555 & ~255 + // 0x022B & ~0x00ff + // 0x022B & 0xff00 + // 0x0200 + // 512 + return (byteSize + 255) & ~255; +} diff --git a/src/aquarium-optimized/d3d12/ContextD3D12.h b/src/aquarium-optimized/d3d12/ContextD3D12.h index ee3daf6..120127e 100644 --- a/src/aquarium-optimized/d3d12/ContextD3D12.h +++ b/src/aquarium-optimized/d3d12/ContextD3D12.h @@ -1,175 +1,175 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// ContextD3D12.h : Defines the accessing to graphics API of D3D12. - -#pragma once -#ifndef CONTEXTD3D12_H -#define CONTEXTD3D12_H - -#include "../Context.h" - -#include "GLFW/glfw3.h" - -#include "stdafx.h" -using Microsoft::WRL::ComPtr; - -enum BACKENDTYPE : short; - -constexpr int cbvsrvCount = 87; - -class ContextD3D12 : public Context -{ - public: - ContextD3D12(BACKENDTYPE backendType); - ~ContextD3D12(); - bool initialize( - BACKENDTYPE backend, - const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) override; - void setWindowTitle(const std::string &text) override; - bool ShouldQuit() override; - void KeyBoardQuit() override; - void DoFlush() override; - void Terminate() override; - void showWindow() override; - void showFPS(const FPSTimer &fpsTimer) override; - void destoryImgUI() override; - - void FlushInit() override; - void preFrame() override; - - Model *createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) override; - Buffer *createBuffer(int numComponents, std::vector *buffer, bool isIndex) override; - Buffer *createBuffer(int numComponents, - std::vector *buffer, - bool isIndex) override; - - Program *createProgram(const std::string &mVId, const std::string &mFId) override; - - Texture *createTexture(const std::string &name, const std::string &url) override; - Texture *createTexture(const std::string &name, const std::vector &urls) override; - - void initGeneralResources(Aquarium *aquarium) override; - void updateWorldlUniforms(Aquarium *aquarium) override; - - ComPtr createShaderModule(const std::string &type, const std::string &shader); - void createCommittedResource(const D3D12_HEAP_PROPERTIES &properties, - const D3D12_RESOURCE_DESC &desc, - D3D12_RESOURCE_STATES state, - ComPtr &resource); - void updateSubresources(ID3D12GraphicsCommandList *pCmdList, - ID3D12Resource *pDestinationResource, - ID3D12Resource *pIntermediate, - UINT64 IntermediateOffset, - UINT FirstSubresource, - UINT NumSubresources, - D3D12_SUBRESOURCE_DATA *pSrcData); - void executeCommandLists(UINT NumCommandLists, ID3D12CommandList *const *ppCommandLists); - - void createCommandList(ID3D12PipelineState *pInitialState, - ComPtr &commandList); - - ComPtr createDefaultBuffer(const void *initData, - UINT64 byteSize, - ComPtr &uploadBuffer) const; - ComPtr createUploadBuffer(const void *initData, UINT64 byteSize) const; - void createRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC &pRootSignatureDesc, - ComPtr &rootSignature) const; - void createGraphicsPipelineState( - const std::vector &mInputElementDescs, - const ComPtr &rootSignature, - const ComPtr &mVertexShader, - const ComPtr &mPixelShader, - ComPtr &mPipelineState, - bool enableBlend) const; - void buildSrvDescriptor(const ComPtr &resource, - const D3D12_SHADER_RESOURCE_VIEW_DESC &mSrvDesc, - D3D12_GPU_DESCRIPTOR_HANDLE *hGpuDescriptor); - void buildCbvDescriptor(const D3D12_CONSTANT_BUFFER_VIEW_DESC &cbvDesc, - D3D12_GPU_DESCRIPTOR_HANDLE *hGpuDescriptor); - UINT CalcConstantBufferByteSize(UINT byteSize); - void createTexture(const D3D12_RESOURCE_DESC &textureDesc, - const std::vector &texture, - ComPtr &m_texture, - ComPtr &textureUploadHeap, - int TextureWidth, - int TextureHeight, - int TexturePixelSize, - int mipLevels, - int arraySize); - - Microsoft::WRL::ComPtr mCommandList; - - CD3DX12_DESCRIPTOR_RANGE1 rangeGeneral[2]; - CD3DX12_ROOT_PARAMETER1 rootParameterGeneral; - CD3DX12_ROOT_PARAMETER1 rootParameterWorld; - D3D12_GPU_DESCRIPTOR_HANDLE fogGPUHandle; - D3D12_GPU_DESCRIPTOR_HANDLE lightGPUHandle; - D3D12_CONSTANT_BUFFER_VIEW_DESC lightWorldPositionView; - CD3DX12_CPU_DESCRIPTOR_HANDLE cbvsrvCPUHandle; - CD3DX12_GPU_DESCRIPTOR_HANDLE cbvsrvGPUHandle; - - std::vector staticSamplers; - - private: - bool GetHardwareAdapter( - IDXGIFactory2 *pFactory, - IDXGIAdapter1 **ppAdapter, - const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset); - void WaitForPreviousFrame(); - void createDepthStencilView(); - void stateTransition(ComPtr &resource, - D3D12_RESOURCE_STATES preState, - D3D12_RESOURCE_STATES transferState) const; - void initAvailableToggleBitset(BACKENDTYPE backendType) override; - - GLFWwindow *mWindow; - ComPtr mDevice; - ComPtr mCommandQueue; - ComPtr mSwapChain; - DXGI_FORMAT mPreferredSwapChainFormat; - UINT mCompileFlags; - - static const UINT mFrameCount = 3; - UINT m_frameIndex; - UINT mBufferSerias[mFrameCount]; - ComPtr mCommandAllocators[mFrameCount]; - - ComPtr mRtvHeap; - ComPtr mDsvHeap; - ComPtr mCbvsrvHeap; - UINT mRtvDescriptorSize; - UINT mCbvmSrvDescriptorSize; - ComPtr mRenderTargets[mFrameCount]; - ComPtr mDepthStencil; - - ComPtr mFence; - UINT64 mFenceValue; - HANDLE mFenceEvent; - - D3D12_FEATURE_DATA_ROOT_SIGNATURE mRootSignature; - - CD3DX12_VIEWPORT mViewport; - CD3DX12_RECT mScissorRect; - - // General Resources - ComPtr mLightWorldPositionBuffer; - - D3D12_CONSTANT_BUFFER_VIEW_DESC mLightView; - ComPtr mLightBuffer; - ComPtr mLightUploadBuffer; - - D3D12_CONSTANT_BUFFER_VIEW_DESC mFogView; - ComPtr mFogBuffer; - ComPtr mFogUploadBuffer; - - ComPtr mSceneRenderTargetTexture; - D3D12_RENDER_TARGET_VIEW_DESC mSceneRenderTargetView; - - bool mEnableMSAA; - std::string mRenderer; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ContextD3D12.h : Defines the accessing to graphics API of D3D12. + +#pragma once +#ifndef CONTEXTD3D12_H +#define CONTEXTD3D12_H + +#include "../Context.h" + +#include "GLFW/glfw3.h" + +#include "stdafx.h" +using Microsoft::WRL::ComPtr; + +enum BACKENDTYPE : short; + +constexpr int cbvsrvCount = 87; + +class ContextD3D12 : public Context +{ + public: + ContextD3D12(BACKENDTYPE backendType); + ~ContextD3D12(); + bool initialize( + BACKENDTYPE backend, + const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) override; + void setWindowTitle(const std::string &text) override; + bool ShouldQuit() override; + void KeyBoardQuit() override; + void DoFlush() override; + void Terminate() override; + void showWindow() override; + void showFPS(const FPSTimer &fpsTimer) override; + void destoryImgUI() override; + + void FlushInit() override; + void preFrame() override; + + Model *createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) override; + Buffer *createBuffer(int numComponents, std::vector *buffer, bool isIndex) override; + Buffer *createBuffer(int numComponents, + std::vector *buffer, + bool isIndex) override; + + Program *createProgram(const std::string &mVId, const std::string &mFId) override; + + Texture *createTexture(const std::string &name, const std::string &url) override; + Texture *createTexture(const std::string &name, const std::vector &urls) override; + + void initGeneralResources(Aquarium *aquarium) override; + void updateWorldlUniforms(Aquarium *aquarium) override; + + ComPtr createShaderModule(const std::string &type, const std::string &shader); + void createCommittedResource(const D3D12_HEAP_PROPERTIES &properties, + const D3D12_RESOURCE_DESC &desc, + D3D12_RESOURCE_STATES state, + ComPtr &resource); + void updateSubresources(ID3D12GraphicsCommandList *pCmdList, + ID3D12Resource *pDestinationResource, + ID3D12Resource *pIntermediate, + UINT64 IntermediateOffset, + UINT FirstSubresource, + UINT NumSubresources, + D3D12_SUBRESOURCE_DATA *pSrcData); + void executeCommandLists(UINT NumCommandLists, ID3D12CommandList *const *ppCommandLists); + + void createCommandList(ID3D12PipelineState *pInitialState, + ComPtr &commandList); + + ComPtr createDefaultBuffer(const void *initData, + UINT64 byteSize, + ComPtr &uploadBuffer) const; + ComPtr createUploadBuffer(const void *initData, UINT64 byteSize) const; + void createRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC &pRootSignatureDesc, + ComPtr &rootSignature) const; + void createGraphicsPipelineState( + const std::vector &mInputElementDescs, + const ComPtr &rootSignature, + const ComPtr &mVertexShader, + const ComPtr &mPixelShader, + ComPtr &mPipelineState, + bool enableBlend) const; + void buildSrvDescriptor(const ComPtr &resource, + const D3D12_SHADER_RESOURCE_VIEW_DESC &mSrvDesc, + D3D12_GPU_DESCRIPTOR_HANDLE *hGpuDescriptor); + void buildCbvDescriptor(const D3D12_CONSTANT_BUFFER_VIEW_DESC &cbvDesc, + D3D12_GPU_DESCRIPTOR_HANDLE *hGpuDescriptor); + UINT CalcConstantBufferByteSize(UINT byteSize); + void createTexture(const D3D12_RESOURCE_DESC &textureDesc, + const std::vector &texture, + ComPtr &m_texture, + ComPtr &textureUploadHeap, + int TextureWidth, + int TextureHeight, + int TexturePixelSize, + int mipLevels, + int arraySize); + + Microsoft::WRL::ComPtr mCommandList; + + CD3DX12_DESCRIPTOR_RANGE1 rangeGeneral[2]; + CD3DX12_ROOT_PARAMETER1 rootParameterGeneral; + CD3DX12_ROOT_PARAMETER1 rootParameterWorld; + D3D12_GPU_DESCRIPTOR_HANDLE fogGPUHandle; + D3D12_GPU_DESCRIPTOR_HANDLE lightGPUHandle; + D3D12_CONSTANT_BUFFER_VIEW_DESC lightWorldPositionView; + CD3DX12_CPU_DESCRIPTOR_HANDLE cbvsrvCPUHandle; + CD3DX12_GPU_DESCRIPTOR_HANDLE cbvsrvGPUHandle; + + std::vector staticSamplers; + + private: + bool GetHardwareAdapter( + IDXGIFactory2 *pFactory, + IDXGIAdapter1 **ppAdapter, + const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset); + void WaitForPreviousFrame(); + void createDepthStencilView(); + void stateTransition(ComPtr &resource, + D3D12_RESOURCE_STATES preState, + D3D12_RESOURCE_STATES transferState) const; + void initAvailableToggleBitset(BACKENDTYPE backendType) override; + + GLFWwindow *mWindow; + ComPtr mDevice; + ComPtr mCommandQueue; + ComPtr mSwapChain; + DXGI_FORMAT mPreferredSwapChainFormat; + UINT mCompileFlags; + + static const UINT mFrameCount = 3; + UINT m_frameIndex; + UINT mBufferSerias[mFrameCount]; + ComPtr mCommandAllocators[mFrameCount]; + + ComPtr mRtvHeap; + ComPtr mDsvHeap; + ComPtr mCbvsrvHeap; + UINT mRtvDescriptorSize; + UINT mCbvmSrvDescriptorSize; + ComPtr mRenderTargets[mFrameCount]; + ComPtr mDepthStencil; + + ComPtr mFence; + UINT64 mFenceValue; + HANDLE mFenceEvent; + + D3D12_FEATURE_DATA_ROOT_SIGNATURE mRootSignature; + + CD3DX12_VIEWPORT mViewport; + CD3DX12_RECT mScissorRect; + + // General Resources + ComPtr mLightWorldPositionBuffer; + + D3D12_CONSTANT_BUFFER_VIEW_DESC mLightView; + ComPtr mLightBuffer; + ComPtr mLightUploadBuffer; + + D3D12_CONSTANT_BUFFER_VIEW_DESC mFogView; + ComPtr mFogBuffer; + ComPtr mFogUploadBuffer; + + ComPtr mSceneRenderTargetTexture; + D3D12_RENDER_TARGET_VIEW_DESC mSceneRenderTargetView; + + bool mEnableMSAA; + std::string mRenderer; +}; + +#endif diff --git a/src/aquarium-optimized/d3d12/FishModelD3D12.cpp b/src/aquarium-optimized/d3d12/FishModelD3D12.cpp index 730c6ea..99b747c 100644 --- a/src/aquarium-optimized/d3d12/FishModelD3D12.cpp +++ b/src/aquarium-optimized/d3d12/FishModelD3D12.cpp @@ -1,201 +1,201 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FishModelD3D12.cpp: Implements fish model of D3D12. - -#include "BufferD3D12.h" -#include "FishModelD3D12.h" - -FishModelD3D12::FishModelD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : FishModel(type, name, blend), instance(0) -{ - mContextD3D12 = static_cast(context); - - const Fish &fishInfo = fishTable[name - MODELNAME::MODELSMALLFISHA]; - mFishVertexUniforms.fishLength = fishInfo.fishLength; - mFishVertexUniforms.fishBendAmount = fishInfo.fishBendAmount; - mFishVertexUniforms.fishWaveLength = fishInfo.fishWaveLength; - - mLightFactorUniforms.shininess = 5.0f; - mLightFactorUniforms.specularFactor = 0.3f; - - instance = aquarium->fishCount[fishInfo.modelName - MODELNAME::MODELSMALLFISHA]; - mFishPers = new FishPer[instance]; -} - -FishModelD3D12::~FishModelD3D12() -{ - delete mFishPers; -} - -void FishModelD3D12::init() -{ - if (instance == 0) - return; - - mProgramD3D12 = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mTangentBuffer = static_cast(bufferMap["tangent"]); - mBiNormalBuffer = static_cast(bufferMap["binormal"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; - mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; - mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; - mVertexBufferView[3] = mTangentBuffer->mVertexBufferView; - mVertexBufferView[4] = mBiNormalBuffer->mVertexBufferView; - - mFishPersBuffer = mContextD3D12->createUploadBuffer( - mFishPers, mContextD3D12->CalcConstantBufferByteSize(sizeof(FishPer) * instance)); - mFishPersBufferView.BufferLocation = mFishPersBuffer->GetGPUVirtualAddress(); - mFishPersBufferView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize(sizeof(FishPer)); - - mInputElementDescs = { - {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, - 0}, - {"TEXCOORD", 3, DXGI_FORMAT_R32G32B32_FLOAT, 3, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 4, DXGI_FORMAT_R32G32B32_FLOAT, 4, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - }; - - // create constant buffer, desc. - mFishVertexBuffer = mContextD3D12->createDefaultBuffer( - &mFishVertexUniforms, mContextD3D12->CalcConstantBufferByteSize(sizeof(FishVertexUniforms)), - mFishVertexUploadBuffer); - mFishVertexView.BufferLocation = mFishVertexBuffer->GetGPUVirtualAddress(); - mFishVertexView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( - sizeof(mFishVertexUniforms)); // CB size is required to be 256-byte aligned. - mContextD3D12->buildCbvDescriptor(mFishVertexView, &mFishVertexGPUHandle); - mLightFactorBuffer = mContextD3D12->createDefaultBuffer( - &mLightFactorUniforms, - mContextD3D12->CalcConstantBufferByteSize(sizeof(LightFactorUniforms)), - mLightFactorUploadBuffer); - mLightFactorView.BufferLocation = mLightFactorBuffer->GetGPUVirtualAddress(); - mLightFactorView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( - sizeof(LightFactorUniforms)); // CB size is required to be 256-byte aligned. - mContextD3D12->buildCbvDescriptor(mLightFactorView, &mLightFactorGPUHandle); - - // Create root signature to bind resources. - // Bind textures, samplers and immutable constant buffers in a descriptor table. - // Bind frequently updated constant buffers by root descriptors. - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; - CD3DX12_ROOT_PARAMETER1 rootParameters[5]; - CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; - rootParameters[0] = mContextD3D12->rootParameterGeneral; - rootParameters[1] = mContextD3D12->rootParameterWorld; - - if (mSkyboxTexture && mReflectionTexture) - { - mDiffuseTexture->createSrvDescriptor(); - mNormalTexture->createSrvDescriptor(); - mReflectionTexture->createSrvDescriptor(); - - ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 3, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_ALL); - rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - } - else - { - mDiffuseTexture->createSrvDescriptor(); - mNormalTexture->createSrvDescriptor(); - - ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_ALL); - rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - } - - rootParameters[4].InitAsConstantBufferView(0, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, - D3D12_SHADER_VISIBILITY_VERTEX); - - rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, - mContextD3D12->staticSamplers.data(), - D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); - - mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); - - mContextD3D12->createGraphicsPipelineState( - mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), - mProgramD3D12->getFSModule(), mPipelineState, mBlend); -} - -void FishModelD3D12::prepareForDraw() const {} - -void FishModelD3D12::draw() -{ - if (instance == 0) - return; - - CD3DX12_RANGE readRange(0, 0); - UINT8 *m_pCbvDataBegin; - mFishPersBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); - memcpy(m_pCbvDataBegin, mFishPers, sizeof(FishPer) * instance); - - auto &commandList = mContextD3D12->mCommandList; - - commandList->SetPipelineState(mPipelineState.Get()); - commandList->SetGraphicsRootSignature(mRootSignature.Get()); - - commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); - commandList->SetGraphicsRootConstantBufferView( - 1, mContextD3D12->lightWorldPositionView.BufferLocation); - commandList->SetGraphicsRootDescriptorTable(2, mFishVertexGPUHandle); - commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); - - commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - commandList->IASetVertexBuffers(0, 5, mVertexBufferView); - commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); - - for (int i = 0; i < instance; i++) - { - commandList->SetGraphicsRootConstantBufferView( - 4, mFishPersBufferView.BufferLocation + i * mFishPersBufferView.SizeInBytes); - commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); - } -} - -void FishModelD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) {} - -void FishModelD3D12::updateFishPerUniforms(float x, - float y, - float z, - float nextX, - float nextY, - float nextZ, - float scale, - float time, - int index) -{ - mFishPers[index].worldPosition[0] = x; - mFishPers[index].worldPosition[1] = y; - mFishPers[index].worldPosition[2] = z; - mFishPers[index].nextPosition[0] = nextX; - mFishPers[index].nextPosition[1] = nextY; - mFishPers[index].nextPosition[2] = nextZ; - mFishPers[index].scale = scale; - mFishPers[index].time = time; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FishModelD3D12.cpp: Implements fish model of D3D12. + +#include "FishModelD3D12.h" +#include "BufferD3D12.h" + +FishModelD3D12::FishModelD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : FishModel(type, name, blend), instance(0) +{ + mContextD3D12 = static_cast(context); + + const Fish &fishInfo = fishTable[name - MODELNAME::MODELSMALLFISHA]; + mFishVertexUniforms.fishLength = fishInfo.fishLength; + mFishVertexUniforms.fishBendAmount = fishInfo.fishBendAmount; + mFishVertexUniforms.fishWaveLength = fishInfo.fishWaveLength; + + mLightFactorUniforms.shininess = 5.0f; + mLightFactorUniforms.specularFactor = 0.3f; + + instance = aquarium->fishCount[fishInfo.modelName - MODELNAME::MODELSMALLFISHA]; + mFishPers = new FishPer[instance]; +} + +FishModelD3D12::~FishModelD3D12() +{ + delete mFishPers; +} + +void FishModelD3D12::init() +{ + if (instance == 0) + return; + + mProgramD3D12 = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mTangentBuffer = static_cast(bufferMap["tangent"]); + mBiNormalBuffer = static_cast(bufferMap["binormal"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; + mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; + mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; + mVertexBufferView[3] = mTangentBuffer->mVertexBufferView; + mVertexBufferView[4] = mBiNormalBuffer->mVertexBufferView; + + mFishPersBuffer = mContextD3D12->createUploadBuffer( + mFishPers, mContextD3D12->CalcConstantBufferByteSize(sizeof(FishPer) * instance)); + mFishPersBufferView.BufferLocation = mFishPersBuffer->GetGPUVirtualAddress(); + mFishPersBufferView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize(sizeof(FishPer)); + + mInputElementDescs = { + {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, + 0}, + {"TEXCOORD", 3, DXGI_FORMAT_R32G32B32_FLOAT, 3, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 4, DXGI_FORMAT_R32G32B32_FLOAT, 4, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + }; + + // create constant buffer, desc. + mFishVertexBuffer = mContextD3D12->createDefaultBuffer( + &mFishVertexUniforms, mContextD3D12->CalcConstantBufferByteSize(sizeof(FishVertexUniforms)), + mFishVertexUploadBuffer); + mFishVertexView.BufferLocation = mFishVertexBuffer->GetGPUVirtualAddress(); + mFishVertexView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( + sizeof(mFishVertexUniforms)); // CB size is required to be 256-byte aligned. + mContextD3D12->buildCbvDescriptor(mFishVertexView, &mFishVertexGPUHandle); + mLightFactorBuffer = mContextD3D12->createDefaultBuffer( + &mLightFactorUniforms, + mContextD3D12->CalcConstantBufferByteSize(sizeof(LightFactorUniforms)), + mLightFactorUploadBuffer); + mLightFactorView.BufferLocation = mLightFactorBuffer->GetGPUVirtualAddress(); + mLightFactorView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( + sizeof(LightFactorUniforms)); // CB size is required to be 256-byte aligned. + mContextD3D12->buildCbvDescriptor(mLightFactorView, &mLightFactorGPUHandle); + + // Create root signature to bind resources. + // Bind textures, samplers and immutable constant buffers in a descriptor table. + // Bind frequently updated constant buffers by root descriptors. + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; + CD3DX12_ROOT_PARAMETER1 rootParameters[5]; + CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; + rootParameters[0] = mContextD3D12->rootParameterGeneral; + rootParameters[1] = mContextD3D12->rootParameterWorld; + + if (mSkyboxTexture && mReflectionTexture) + { + mDiffuseTexture->createSrvDescriptor(); + mNormalTexture->createSrvDescriptor(); + mReflectionTexture->createSrvDescriptor(); + + ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 3, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_ALL); + rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); + } + else + { + mDiffuseTexture->createSrvDescriptor(); + mNormalTexture->createSrvDescriptor(); + + ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_ALL); + rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); + } + + rootParameters[4].InitAsConstantBufferView(0, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, + D3D12_SHADER_VISIBILITY_VERTEX); + + rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, + mContextD3D12->staticSamplers.data(), + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + + mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); + + mContextD3D12->createGraphicsPipelineState( + mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), + mProgramD3D12->getFSModule(), mPipelineState, mBlend); +} + +void FishModelD3D12::prepareForDraw() const {} + +void FishModelD3D12::draw() +{ + if (instance == 0) + return; + + CD3DX12_RANGE readRange(0, 0); + UINT8 *m_pCbvDataBegin; + mFishPersBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); + memcpy(m_pCbvDataBegin, mFishPers, sizeof(FishPer) * instance); + + auto &commandList = mContextD3D12->mCommandList; + + commandList->SetPipelineState(mPipelineState.Get()); + commandList->SetGraphicsRootSignature(mRootSignature.Get()); + + commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); + commandList->SetGraphicsRootConstantBufferView( + 1, mContextD3D12->lightWorldPositionView.BufferLocation); + commandList->SetGraphicsRootDescriptorTable(2, mFishVertexGPUHandle); + commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); + + commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + commandList->IASetVertexBuffers(0, 5, mVertexBufferView); + commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); + + for (int i = 0; i < instance; i++) + { + commandList->SetGraphicsRootConstantBufferView( + 4, mFishPersBufferView.BufferLocation + i * mFishPersBufferView.SizeInBytes); + commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); + } +} + +void FishModelD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) {} + +void FishModelD3D12::updateFishPerUniforms(float x, + float y, + float z, + float nextX, + float nextY, + float nextZ, + float scale, + float time, + int index) +{ + mFishPers[index].worldPosition[0] = x; + mFishPers[index].worldPosition[1] = y; + mFishPers[index].worldPosition[2] = z; + mFishPers[index].nextPosition[0] = nextX; + mFishPers[index].nextPosition[1] = nextY; + mFishPers[index].nextPosition[2] = nextZ; + mFishPers[index].scale = scale; + mFishPers[index].time = time; +} diff --git a/src/aquarium-optimized/d3d12/FishModelD3D12.h b/src/aquarium-optimized/d3d12/FishModelD3D12.h index 66c436e..84d6313 100644 --- a/src/aquarium-optimized/d3d12/FishModelD3D12.h +++ b/src/aquarium-optimized/d3d12/FishModelD3D12.h @@ -1,110 +1,110 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FishModelD3D12.h: Defnes fish model of D3D12 - -#pragma once -#ifndef FISHMODELD3D12_H -#define FISHMODELD3D12_H 1 - -#include - -#include "BufferD3D12.h" -#include "ContextD3D12.h" -#include "ProgramD3D12.h" -#include "TextureD3D12.h" - -#include "../FishModel.h" - -class FishModelD3D12 : public FishModel -{ - public: - FishModelD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - ~FishModelD3D12(); - - void init() override; - void prepareForDraw() const override; - void draw() override; - - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - void updateFishPerUniforms(float x, - float y, - float z, - float nextX, - float nextY, - float nextZ, - float scale, - float time, - int index) override; - - struct FishVertexUniforms - { - float fishLength; - float fishWaveLength; - float fishBendAmount; - } mFishVertexUniforms; - - struct LightFactorUniforms - { - float shininess; - float specularFactor; - } mLightFactorUniforms; - - struct FishPer - { - float worldPosition[3]; - float scale; - float nextPosition[3]; - float time; - float padding[56]; // TODO(yizhou): the padding is to align with 256 byte offset. - }; - FishPer *mFishPers; - - TextureD3D12 *mDiffuseTexture; - TextureD3D12 *mNormalTexture; - TextureD3D12 *mReflectionTexture; - TextureD3D12 *mSkyboxTexture; - - BufferD3D12 *mPositionBuffer; - BufferD3D12 *mNormalBuffer; - BufferD3D12 *mTexCoordBuffer; - BufferD3D12 *mTangentBuffer; - BufferD3D12 *mBiNormalBuffer; - - BufferD3D12 *mIndicesBuffer; - - private: - D3D12_CONSTANT_BUFFER_VIEW_DESC mFishPersBufferView; - ComPtr mFishPersBuffer; - - D3D12_CONSTANT_BUFFER_VIEW_DESC mLightFactorView; - D3D12_GPU_DESCRIPTOR_HANDLE mLightFactorGPUHandle; - ComPtr mLightFactorBuffer; - ComPtr mLightFactorUploadBuffer; - - D3D12_CONSTANT_BUFFER_VIEW_DESC mFishVertexView; - D3D12_GPU_DESCRIPTOR_HANDLE mFishVertexGPUHandle; - ComPtr mFishVertexBuffer; - ComPtr mFishVertexUploadBuffer; - - std::vector mInputElementDescs; - - D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[5]; - - ComPtr mRootSignature; - - ComPtr mPipelineState; - - int instance; - - ProgramD3D12 *mProgramD3D12; - ContextD3D12 *mContextD3D12; -}; - -#endif \ No newline at end of file +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FishModelD3D12.h: Defnes fish model of D3D12 + +#pragma once +#ifndef FISHMODELD3D12_H +#define FISHMODELD3D12_H 1 + +#include + +#include "BufferD3D12.h" +#include "ContextD3D12.h" +#include "ProgramD3D12.h" +#include "TextureD3D12.h" + +#include "../FishModel.h" + +class FishModelD3D12 : public FishModel +{ + public: + FishModelD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + ~FishModelD3D12(); + + void init() override; + void prepareForDraw() const override; + void draw() override; + + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + void updateFishPerUniforms(float x, + float y, + float z, + float nextX, + float nextY, + float nextZ, + float scale, + float time, + int index) override; + + struct FishVertexUniforms + { + float fishLength; + float fishWaveLength; + float fishBendAmount; + } mFishVertexUniforms; + + struct LightFactorUniforms + { + float shininess; + float specularFactor; + } mLightFactorUniforms; + + struct FishPer + { + float worldPosition[3]; + float scale; + float nextPosition[3]; + float time; + float padding[56]; // TODO(yizhou): the padding is to align with 256 byte offset. + }; + FishPer *mFishPers; + + TextureD3D12 *mDiffuseTexture; + TextureD3D12 *mNormalTexture; + TextureD3D12 *mReflectionTexture; + TextureD3D12 *mSkyboxTexture; + + BufferD3D12 *mPositionBuffer; + BufferD3D12 *mNormalBuffer; + BufferD3D12 *mTexCoordBuffer; + BufferD3D12 *mTangentBuffer; + BufferD3D12 *mBiNormalBuffer; + + BufferD3D12 *mIndicesBuffer; + + private: + D3D12_CONSTANT_BUFFER_VIEW_DESC mFishPersBufferView; + ComPtr mFishPersBuffer; + + D3D12_CONSTANT_BUFFER_VIEW_DESC mLightFactorView; + D3D12_GPU_DESCRIPTOR_HANDLE mLightFactorGPUHandle; + ComPtr mLightFactorBuffer; + ComPtr mLightFactorUploadBuffer; + + D3D12_CONSTANT_BUFFER_VIEW_DESC mFishVertexView; + D3D12_GPU_DESCRIPTOR_HANDLE mFishVertexGPUHandle; + ComPtr mFishVertexBuffer; + ComPtr mFishVertexUploadBuffer; + + std::vector mInputElementDescs; + + D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[5]; + + ComPtr mRootSignature; + + ComPtr mPipelineState; + + int instance; + + ProgramD3D12 *mProgramD3D12; + ContextD3D12 *mContextD3D12; +}; + +#endif diff --git a/src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.cpp b/src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.cpp index 4c1869c..9602b85 100644 --- a/src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.cpp +++ b/src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.cpp @@ -1,205 +1,205 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FishModelD3D12.cpp: Implements fish model of D3D12. - -#include "BufferD3D12.h" -#include "FishModelInstancedDrawD3D12.h" - -FishModelInstancedDrawD3D12::FishModelInstancedDrawD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : FishModel(type, name, blend), instance(0) -{ - mContextD3D12 = static_cast(context); - - const Fish &fishInfo = fishTable[name - MODELNAME::MODELSMALLFISHAINSTANCEDDRAWS]; - mFishVertexUniforms.fishLength = fishInfo.fishLength; - mFishVertexUniforms.fishBendAmount = fishInfo.fishBendAmount; - mFishVertexUniforms.fishWaveLength = fishInfo.fishWaveLength; - - mLightFactorUniforms.shininess = 5.0f; - mLightFactorUniforms.specularFactor = 0.3f; - - instance = aquarium->fishCount[fishInfo.modelName - MODELNAME::MODELSMALLFISHA]; - mFishPers = new FishPer[instance]; -} - -FishModelInstancedDrawD3D12::~FishModelInstancedDrawD3D12() -{ - delete mFishPers; -} - -void FishModelInstancedDrawD3D12::init() -{ - if (instance == 0) - return; - - mProgramD3D12 = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mTangentBuffer = static_cast(bufferMap["tangent"]); - mBiNormalBuffer = static_cast(bufferMap["binormal"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; - mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; - mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; - mVertexBufferView[3] = mTangentBuffer->mVertexBufferView; - mVertexBufferView[4] = mBiNormalBuffer->mVertexBufferView; - - mFishPersBuffer = mContextD3D12->createUploadBuffer( - mFishPers, mContextD3D12->CalcConstantBufferByteSize(sizeof(FishPer) * instance)); - mFishPersBufferView.BufferLocation = mFishPersBuffer->GetGPUVirtualAddress(); - mFishPersBufferView.SizeInBytes = - mContextD3D12->CalcConstantBufferByteSize(sizeof(FishPer) * instance); - mFishPersBufferView.StrideInBytes = sizeof(FishPer); - - mVertexBufferView[5] = mFishPersBufferView; - - mInputElementDescs = { - {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, - 0}, - {"TEXCOORD", 3, DXGI_FORMAT_R32G32B32_FLOAT, 3, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 4, DXGI_FORMAT_R32G32B32_FLOAT, 4, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 5, DXGI_FORMAT_R32G32B32_FLOAT, 5, 0, - D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1}, - {"TEXCOORD", 6, DXGI_FORMAT_R32_FLOAT, 5, 3 * sizeof(float), - D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1}, - {"TEXCOORD", 7, DXGI_FORMAT_R32G32B32_FLOAT, 5, 4 * sizeof(float), - D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1}, - {"TEXCOORD", 8, DXGI_FORMAT_R32_FLOAT, 5, 5 * sizeof(float), - D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1}, - }; - - // create constant buffer, desc. - mFishVertexBuffer = mContextD3D12->createDefaultBuffer( - &mFishVertexUniforms, mContextD3D12->CalcConstantBufferByteSize(sizeof(FishVertexUniforms)), - mFishVertexUploadBuffer); - mFishVertexView.BufferLocation = mFishVertexBuffer->GetGPUVirtualAddress(); - mFishVertexView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( - sizeof(mFishVertexUniforms)); // CB size is required to be 256-byte aligned. - mContextD3D12->buildCbvDescriptor(mFishVertexView, &mFishVertexGPUHandle); - mLightFactorBuffer = mContextD3D12->createDefaultBuffer( - &mLightFactorUniforms, - mContextD3D12->CalcConstantBufferByteSize(sizeof(LightFactorUniforms)), - mLightFactorUploadBuffer); - mLightFactorView.BufferLocation = mLightFactorBuffer->GetGPUVirtualAddress(); - mLightFactorView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( - sizeof(LightFactorUniforms)); // CB size is required to be 256-byte aligned. - mContextD3D12->buildCbvDescriptor(mLightFactorView, &mLightFactorGPUHandle); - - // Create root signature to bind resources. - // Bind textures, samplers and immutable constant buffers in a descriptor table. - // Bind frequently updated constant buffers by root descriptors. - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; - CD3DX12_ROOT_PARAMETER1 rootParameters[4]; - CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; - rootParameters[0] = mContextD3D12->rootParameterGeneral; - rootParameters[1] = mContextD3D12->rootParameterWorld; - - if (mSkyboxTexture && mReflectionTexture) - { - mDiffuseTexture->createSrvDescriptor(); - mNormalTexture->createSrvDescriptor(); - mReflectionTexture->createSrvDescriptor(); - - ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 3, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_ALL); - rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - } - else - { - mDiffuseTexture->createSrvDescriptor(); - mNormalTexture->createSrvDescriptor(); - - ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_ALL); - rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - } - - rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, - mContextD3D12->staticSamplers.data(), - D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); - - mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); - - mContextD3D12->createGraphicsPipelineState( - mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), - mProgramD3D12->getFSModule(), mPipelineState, mBlend); -} - -void FishModelInstancedDrawD3D12::prepareForDraw() const {} - -void FishModelInstancedDrawD3D12::draw() -{ - if (instance == 0) - return; - - CD3DX12_RANGE readRange(0, 0); - UINT8 *m_pCbvDataBegin; - mFishPersBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); - memcpy(m_pCbvDataBegin, mFishPers, sizeof(FishPer) * instance); - - auto &commandList = mContextD3D12->mCommandList; - - commandList->SetPipelineState(mPipelineState.Get()); - commandList->SetGraphicsRootSignature(mRootSignature.Get()); - - commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); - commandList->SetGraphicsRootConstantBufferView( - 1, mContextD3D12->lightWorldPositionView.BufferLocation); - commandList->SetGraphicsRootDescriptorTable(2, mFishVertexGPUHandle); - commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); - - commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - commandList->IASetVertexBuffers(0, 6, mVertexBufferView); - commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); - - commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), instance, 0, 0, 0); -} - -void FishModelInstancedDrawD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) {} - -void FishModelInstancedDrawD3D12::updateFishPerUniforms(float x, - float y, - float z, - float nextX, - float nextY, - float nextZ, - float scale, - float time, - int index) -{ - mFishPers[index].worldPosition[0] = x; - mFishPers[index].worldPosition[1] = y; - mFishPers[index].worldPosition[2] = z; - mFishPers[index].nextPosition[0] = nextX; - mFishPers[index].nextPosition[1] = nextY; - mFishPers[index].nextPosition[2] = nextZ; - mFishPers[index].scale = scale; - mFishPers[index].time = time; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FishModelD3D12.cpp: Implements fish model of D3D12. + +#include "FishModelInstancedDrawD3D12.h" +#include "BufferD3D12.h" + +FishModelInstancedDrawD3D12::FishModelInstancedDrawD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : FishModel(type, name, blend), instance(0) +{ + mContextD3D12 = static_cast(context); + + const Fish &fishInfo = fishTable[name - MODELNAME::MODELSMALLFISHAINSTANCEDDRAWS]; + mFishVertexUniforms.fishLength = fishInfo.fishLength; + mFishVertexUniforms.fishBendAmount = fishInfo.fishBendAmount; + mFishVertexUniforms.fishWaveLength = fishInfo.fishWaveLength; + + mLightFactorUniforms.shininess = 5.0f; + mLightFactorUniforms.specularFactor = 0.3f; + + instance = aquarium->fishCount[fishInfo.modelName - MODELNAME::MODELSMALLFISHA]; + mFishPers = new FishPer[instance]; +} + +FishModelInstancedDrawD3D12::~FishModelInstancedDrawD3D12() +{ + delete mFishPers; +} + +void FishModelInstancedDrawD3D12::init() +{ + if (instance == 0) + return; + + mProgramD3D12 = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mTangentBuffer = static_cast(bufferMap["tangent"]); + mBiNormalBuffer = static_cast(bufferMap["binormal"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; + mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; + mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; + mVertexBufferView[3] = mTangentBuffer->mVertexBufferView; + mVertexBufferView[4] = mBiNormalBuffer->mVertexBufferView; + + mFishPersBuffer = mContextD3D12->createUploadBuffer( + mFishPers, mContextD3D12->CalcConstantBufferByteSize(sizeof(FishPer) * instance)); + mFishPersBufferView.BufferLocation = mFishPersBuffer->GetGPUVirtualAddress(); + mFishPersBufferView.SizeInBytes = + mContextD3D12->CalcConstantBufferByteSize(sizeof(FishPer) * instance); + mFishPersBufferView.StrideInBytes = sizeof(FishPer); + + mVertexBufferView[5] = mFishPersBufferView; + + mInputElementDescs = { + {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, + 0}, + {"TEXCOORD", 3, DXGI_FORMAT_R32G32B32_FLOAT, 3, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 4, DXGI_FORMAT_R32G32B32_FLOAT, 4, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 5, DXGI_FORMAT_R32G32B32_FLOAT, 5, 0, + D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1}, + {"TEXCOORD", 6, DXGI_FORMAT_R32_FLOAT, 5, 3 * sizeof(float), + D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1}, + {"TEXCOORD", 7, DXGI_FORMAT_R32G32B32_FLOAT, 5, 4 * sizeof(float), + D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1}, + {"TEXCOORD", 8, DXGI_FORMAT_R32_FLOAT, 5, 5 * sizeof(float), + D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1}, + }; + + // create constant buffer, desc. + mFishVertexBuffer = mContextD3D12->createDefaultBuffer( + &mFishVertexUniforms, mContextD3D12->CalcConstantBufferByteSize(sizeof(FishVertexUniforms)), + mFishVertexUploadBuffer); + mFishVertexView.BufferLocation = mFishVertexBuffer->GetGPUVirtualAddress(); + mFishVertexView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( + sizeof(mFishVertexUniforms)); // CB size is required to be 256-byte aligned. + mContextD3D12->buildCbvDescriptor(mFishVertexView, &mFishVertexGPUHandle); + mLightFactorBuffer = mContextD3D12->createDefaultBuffer( + &mLightFactorUniforms, + mContextD3D12->CalcConstantBufferByteSize(sizeof(LightFactorUniforms)), + mLightFactorUploadBuffer); + mLightFactorView.BufferLocation = mLightFactorBuffer->GetGPUVirtualAddress(); + mLightFactorView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( + sizeof(LightFactorUniforms)); // CB size is required to be 256-byte aligned. + mContextD3D12->buildCbvDescriptor(mLightFactorView, &mLightFactorGPUHandle); + + // Create root signature to bind resources. + // Bind textures, samplers and immutable constant buffers in a descriptor table. + // Bind frequently updated constant buffers by root descriptors. + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; + CD3DX12_ROOT_PARAMETER1 rootParameters[4]; + CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; + rootParameters[0] = mContextD3D12->rootParameterGeneral; + rootParameters[1] = mContextD3D12->rootParameterWorld; + + if (mSkyboxTexture && mReflectionTexture) + { + mDiffuseTexture->createSrvDescriptor(); + mNormalTexture->createSrvDescriptor(); + mReflectionTexture->createSrvDescriptor(); + + ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 3, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_ALL); + rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); + } + else + { + mDiffuseTexture->createSrvDescriptor(); + mNormalTexture->createSrvDescriptor(); + + ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_ALL); + rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); + } + + rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, + mContextD3D12->staticSamplers.data(), + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + + mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); + + mContextD3D12->createGraphicsPipelineState( + mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), + mProgramD3D12->getFSModule(), mPipelineState, mBlend); +} + +void FishModelInstancedDrawD3D12::prepareForDraw() const {} + +void FishModelInstancedDrawD3D12::draw() +{ + if (instance == 0) + return; + + CD3DX12_RANGE readRange(0, 0); + UINT8 *m_pCbvDataBegin; + mFishPersBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); + memcpy(m_pCbvDataBegin, mFishPers, sizeof(FishPer) * instance); + + auto &commandList = mContextD3D12->mCommandList; + + commandList->SetPipelineState(mPipelineState.Get()); + commandList->SetGraphicsRootSignature(mRootSignature.Get()); + + commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); + commandList->SetGraphicsRootConstantBufferView( + 1, mContextD3D12->lightWorldPositionView.BufferLocation); + commandList->SetGraphicsRootDescriptorTable(2, mFishVertexGPUHandle); + commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); + + commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + commandList->IASetVertexBuffers(0, 6, mVertexBufferView); + commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); + + commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), instance, 0, 0, 0); +} + +void FishModelInstancedDrawD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) {} + +void FishModelInstancedDrawD3D12::updateFishPerUniforms(float x, + float y, + float z, + float nextX, + float nextY, + float nextZ, + float scale, + float time, + int index) +{ + mFishPers[index].worldPosition[0] = x; + mFishPers[index].worldPosition[1] = y; + mFishPers[index].worldPosition[2] = z; + mFishPers[index].nextPosition[0] = nextX; + mFishPers[index].nextPosition[1] = nextY; + mFishPers[index].nextPosition[2] = nextZ; + mFishPers[index].scale = scale; + mFishPers[index].time = time; +} diff --git a/src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.h b/src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.h index 4991bda..cc6f83f 100644 --- a/src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.h +++ b/src/aquarium-optimized/d3d12/FishModelInstancedDrawD3D12.h @@ -1,107 +1,107 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FishModelD3D12InstancedDraw.h: Defnes fish model of D3D12 - -#pragma once -#ifndef FISHMODELD3D12INSTANCEDDRAW_H -#define FISHMODELD3D12INSTANCEDDRAW_H 1 - -#include - -#include "BufferD3D12.h" -#include "ContextD3D12.h" -#include "ProgramD3D12.h" -#include "TextureD3D12.h" - -#include "../FishModel.h" - -class FishModelInstancedDrawD3D12 : public FishModel -{ - public: - FishModelInstancedDrawD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - ~FishModelInstancedDrawD3D12(); - - void init() override; - void prepareForDraw() const override; - void draw() override; - - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - void updateFishPerUniforms(float x, - float y, - float z, - float nextX, - float nextY, - float nextZ, - float scale, - float time, - int index) override; - - struct FishVertexUniforms - { - float fishLength; - float fishWaveLength; - float fishBendAmount; - } mFishVertexUniforms; - - struct LightFactorUniforms - { - float shininess; - float specularFactor; - } mLightFactorUniforms; - - struct FishPer - { - float worldPosition[3]; - float scale; - float nextPosition[3]; - float time; - }; - FishPer *mFishPers; - - TextureD3D12 *mDiffuseTexture; - TextureD3D12 *mNormalTexture; - TextureD3D12 *mReflectionTexture; - TextureD3D12 *mSkyboxTexture; - - BufferD3D12 *mPositionBuffer; - BufferD3D12 *mNormalBuffer; - BufferD3D12 *mTexCoordBuffer; - BufferD3D12 *mTangentBuffer; - BufferD3D12 *mBiNormalBuffer; - - BufferD3D12 *mIndicesBuffer; - - private: - D3D12_VERTEX_BUFFER_VIEW mFishPersBufferView; - ComPtr mFishPersBuffer; - - D3D12_CONSTANT_BUFFER_VIEW_DESC mLightFactorView; - D3D12_GPU_DESCRIPTOR_HANDLE mLightFactorGPUHandle; - ComPtr mLightFactorBuffer; - ComPtr mLightFactorUploadBuffer; - - D3D12_CONSTANT_BUFFER_VIEW_DESC mFishVertexView; - D3D12_GPU_DESCRIPTOR_HANDLE mFishVertexGPUHandle; - ComPtr mFishVertexBuffer; - ComPtr mFishVertexUploadBuffer; - - std::vector mInputElementDescs; - D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[6]; - - ComPtr mRootSignature; - ComPtr mPipelineState; - - int instance; - - ProgramD3D12 *mProgramD3D12; - ContextD3D12 *mContextD3D12; -}; - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FishModelD3D12InstancedDraw.h: Defnes fish model of D3D12 + +#pragma once +#ifndef FISHMODELD3D12INSTANCEDDRAW_H +#define FISHMODELD3D12INSTANCEDDRAW_H 1 + +#include + +#include "BufferD3D12.h" +#include "ContextD3D12.h" +#include "ProgramD3D12.h" +#include "TextureD3D12.h" + +#include "../FishModel.h" + +class FishModelInstancedDrawD3D12 : public FishModel +{ + public: + FishModelInstancedDrawD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + ~FishModelInstancedDrawD3D12(); + + void init() override; + void prepareForDraw() const override; + void draw() override; + + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + void updateFishPerUniforms(float x, + float y, + float z, + float nextX, + float nextY, + float nextZ, + float scale, + float time, + int index) override; + + struct FishVertexUniforms + { + float fishLength; + float fishWaveLength; + float fishBendAmount; + } mFishVertexUniforms; + + struct LightFactorUniforms + { + float shininess; + float specularFactor; + } mLightFactorUniforms; + + struct FishPer + { + float worldPosition[3]; + float scale; + float nextPosition[3]; + float time; + }; + FishPer *mFishPers; + + TextureD3D12 *mDiffuseTexture; + TextureD3D12 *mNormalTexture; + TextureD3D12 *mReflectionTexture; + TextureD3D12 *mSkyboxTexture; + + BufferD3D12 *mPositionBuffer; + BufferD3D12 *mNormalBuffer; + BufferD3D12 *mTexCoordBuffer; + BufferD3D12 *mTangentBuffer; + BufferD3D12 *mBiNormalBuffer; + + BufferD3D12 *mIndicesBuffer; + + private: + D3D12_VERTEX_BUFFER_VIEW mFishPersBufferView; + ComPtr mFishPersBuffer; + + D3D12_CONSTANT_BUFFER_VIEW_DESC mLightFactorView; + D3D12_GPU_DESCRIPTOR_HANDLE mLightFactorGPUHandle; + ComPtr mLightFactorBuffer; + ComPtr mLightFactorUploadBuffer; + + D3D12_CONSTANT_BUFFER_VIEW_DESC mFishVertexView; + D3D12_GPU_DESCRIPTOR_HANDLE mFishVertexGPUHandle; + ComPtr mFishVertexBuffer; + ComPtr mFishVertexUploadBuffer; + + std::vector mInputElementDescs; + D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[6]; + + ComPtr mRootSignature; + ComPtr mPipelineState; + + int instance; + + ProgramD3D12 *mProgramD3D12; + ContextD3D12 *mContextD3D12; +}; + #endif \ No newline at end of file diff --git a/src/aquarium-optimized/d3d12/GenericModelD3D12.cpp b/src/aquarium-optimized/d3d12/GenericModelD3D12.cpp index 8b016a2..4cde995 100644 --- a/src/aquarium-optimized/d3d12/GenericModelD3D12.cpp +++ b/src/aquarium-optimized/d3d12/GenericModelD3D12.cpp @@ -1,194 +1,195 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -#include "GenericModelD3D12.h" - -GenericModelD3D12::GenericModelD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : Model(type, name, blend), mInstance(0) -{ - mContextD3D12 = static_cast(context); - - mLightFactorUniforms.shininess = 50.0f; - mLightFactorUniforms.specularFactor = 1.0f; -} - -void GenericModelD3D12::init() -{ - mProgramD3D12 = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mTangentBuffer = static_cast(bufferMap["tangent"]); - mBiNormalBuffer = static_cast(bufferMap["binormal"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; - mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; - mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; - mVertexBufferView[3] = mTangentBuffer->mVertexBufferView; - mVertexBufferView[4] = mBiNormalBuffer->mVertexBufferView; - - // create input layout - // Generic models use reflection, normal or diffuse shaders, of which groupLayouts are - // different in texture binding. MODELGLOBEBASE use diffuse shader though it contains - // normal and reflection textures. - if (mNormalTexture && mName != MODELNAME::MODELGLOBEBASE) - { - mInputElementDescs = { - {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 3, DXGI_FORMAT_R32G32B32_FLOAT, 3, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 4, DXGI_FORMAT_R32G32B32_FLOAT, 4, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - }; - } - else - { - mInputElementDescs = { - {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - }; - } - - // create constant buffer, desc. - mLightFactorBuffer = mContextD3D12->createDefaultBuffer( - &mLightFactorUniforms, - mContextD3D12->CalcConstantBufferByteSize(sizeof(LightFactorUniforms)), - mLightFactorUploadBuffer); - mLightFactorView.BufferLocation = mLightFactorBuffer->GetGPUVirtualAddress(); - mLightFactorView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( - sizeof(LightFactorUniforms)); // CB size is required to be 256-byte aligned. - mContextD3D12->buildCbvDescriptor(mLightFactorView, &mLightFactorGPUHandle); - mWorldBuffer = mContextD3D12->createUploadBuffer( - &mWorldUniformPer, mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniformPer))); - mWorldBufferView.BufferLocation = mWorldBuffer->GetGPUVirtualAddress(); - mWorldBufferView.SizeInBytes = - mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniformPer)); - - // Create root signature to bind resources. - // Bind textures, samplers and immutable constant buffers in a descriptor table. - // Bind frequently updated constant buffers by root descriptors. - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; - CD3DX12_ROOT_PARAMETER1 rootParameters[5]; - CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; - rootParameters[0] = mContextD3D12->rootParameterGeneral; - rootParameters[1] = mContextD3D12->rootParameterWorld; - - if (mSkyboxTexture && mReflectionTexture && mName != MODELNAME::MODELGLOBEBASE) - { - mDiffuseTexture->createSrvDescriptor(); - mNormalTexture->createSrvDescriptor(); - mReflectionTexture->createSrvDescriptor(); - - ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 3, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); - rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - } - else if (mNormalTexture && mName != MODELNAME::MODELGLOBEBASE) - { - mDiffuseTexture->createSrvDescriptor(); - mNormalTexture->createSrvDescriptor(); - - ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); - rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - } - else - { - mDiffuseTexture->createSrvDescriptor(); - - ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); - rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - } - - rootParameters[4].InitAsConstantBufferView(0, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, - D3D12_SHADER_VISIBILITY_VERTEX); - - rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, - mContextD3D12->staticSamplers.data(), - D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); - - mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); - - mContextD3D12->createGraphicsPipelineState( - mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), - mProgramD3D12->getFSModule(), mPipelineState, mBlend); -} - -// Update constant buffer per frame -void GenericModelD3D12::prepareForDraw() const -{ - CD3DX12_RANGE readRange(0, 0); - UINT8 *m_pCbvDataBegin; - mWorldBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); - memcpy(m_pCbvDataBegin, &mWorldUniformPer, sizeof(WorldUniformPer)); -} - -void GenericModelD3D12::draw() -{ - auto &commandList = mContextD3D12->mCommandList; - - commandList->SetPipelineState(mPipelineState.Get()); - commandList->SetGraphicsRootSignature(mRootSignature.Get()); - - commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); - commandList->SetGraphicsRootConstantBufferView( - 1, mContextD3D12->lightWorldPositionView.BufferLocation); - commandList->SetGraphicsRootDescriptorTable(2, mLightFactorGPUHandle); - commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); - commandList->SetGraphicsRootConstantBufferView(4, mWorldBufferView.BufferLocation); - - commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - // diffuseShader doesn't have to input tangent buffer or binormal buffer. - if (mTangentBuffer && mBiNormalBuffer && mName != MODELNAME::MODELGLOBEBASE) - { - commandList->IASetVertexBuffers(0, 5, mVertexBufferView); - } else - { - commandList->IASetVertexBuffers(0, 3, mVertexBufferView); - } - commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); - - commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), mInstance, 0, 0, 0); - - mInstance = 0; -} - -void GenericModelD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) -{ - mWorldUniformPer.WorldUniforms[mInstance] = worldUniforms; - - mInstance++; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +#include "GenericModelD3D12.h" + +GenericModelD3D12::GenericModelD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : Model(type, name, blend), mInstance(0) +{ + mContextD3D12 = static_cast(context); + + mLightFactorUniforms.shininess = 50.0f; + mLightFactorUniforms.specularFactor = 1.0f; +} + +void GenericModelD3D12::init() +{ + mProgramD3D12 = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mTangentBuffer = static_cast(bufferMap["tangent"]); + mBiNormalBuffer = static_cast(bufferMap["binormal"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; + mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; + mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; + mVertexBufferView[3] = mTangentBuffer->mVertexBufferView; + mVertexBufferView[4] = mBiNormalBuffer->mVertexBufferView; + + // create input layout + // Generic models use reflection, normal or diffuse shaders, of which groupLayouts are + // different in texture binding. MODELGLOBEBASE use diffuse shader though it contains + // normal and reflection textures. + if (mNormalTexture && mName != MODELNAME::MODELGLOBEBASE) + { + mInputElementDescs = { + {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 3, DXGI_FORMAT_R32G32B32_FLOAT, 3, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 4, DXGI_FORMAT_R32G32B32_FLOAT, 4, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + }; + } + else + { + mInputElementDescs = { + {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + }; + } + + // create constant buffer, desc. + mLightFactorBuffer = mContextD3D12->createDefaultBuffer( + &mLightFactorUniforms, + mContextD3D12->CalcConstantBufferByteSize(sizeof(LightFactorUniforms)), + mLightFactorUploadBuffer); + mLightFactorView.BufferLocation = mLightFactorBuffer->GetGPUVirtualAddress(); + mLightFactorView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( + sizeof(LightFactorUniforms)); // CB size is required to be 256-byte aligned. + mContextD3D12->buildCbvDescriptor(mLightFactorView, &mLightFactorGPUHandle); + mWorldBuffer = mContextD3D12->createUploadBuffer( + &mWorldUniformPer, mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniformPer))); + mWorldBufferView.BufferLocation = mWorldBuffer->GetGPUVirtualAddress(); + mWorldBufferView.SizeInBytes = + mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniformPer)); + + // Create root signature to bind resources. + // Bind textures, samplers and immutable constant buffers in a descriptor table. + // Bind frequently updated constant buffers by root descriptors. + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; + CD3DX12_ROOT_PARAMETER1 rootParameters[5]; + CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; + rootParameters[0] = mContextD3D12->rootParameterGeneral; + rootParameters[1] = mContextD3D12->rootParameterWorld; + + if (mSkyboxTexture && mReflectionTexture && mName != MODELNAME::MODELGLOBEBASE) + { + mDiffuseTexture->createSrvDescriptor(); + mNormalTexture->createSrvDescriptor(); + mReflectionTexture->createSrvDescriptor(); + + ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 3, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); + rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); + } + else if (mNormalTexture && mName != MODELNAME::MODELGLOBEBASE) + { + mDiffuseTexture->createSrvDescriptor(); + mNormalTexture->createSrvDescriptor(); + + ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); + rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); + } + else + { + mDiffuseTexture->createSrvDescriptor(); + + ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); + rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); + } + + rootParameters[4].InitAsConstantBufferView(0, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, + D3D12_SHADER_VISIBILITY_VERTEX); + + rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, + mContextD3D12->staticSamplers.data(), + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + + mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); + + mContextD3D12->createGraphicsPipelineState( + mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), + mProgramD3D12->getFSModule(), mPipelineState, mBlend); +} + +// Update constant buffer per frame +void GenericModelD3D12::prepareForDraw() const +{ + CD3DX12_RANGE readRange(0, 0); + UINT8 *m_pCbvDataBegin; + mWorldBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); + memcpy(m_pCbvDataBegin, &mWorldUniformPer, sizeof(WorldUniformPer)); +} + +void GenericModelD3D12::draw() +{ + auto &commandList = mContextD3D12->mCommandList; + + commandList->SetPipelineState(mPipelineState.Get()); + commandList->SetGraphicsRootSignature(mRootSignature.Get()); + + commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); + commandList->SetGraphicsRootConstantBufferView( + 1, mContextD3D12->lightWorldPositionView.BufferLocation); + commandList->SetGraphicsRootDescriptorTable(2, mLightFactorGPUHandle); + commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); + commandList->SetGraphicsRootConstantBufferView(4, mWorldBufferView.BufferLocation); + + commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + // diffuseShader doesn't have to input tangent buffer or binormal buffer. + if (mTangentBuffer && mBiNormalBuffer && mName != MODELNAME::MODELGLOBEBASE) + { + commandList->IASetVertexBuffers(0, 5, mVertexBufferView); + } + else + { + commandList->IASetVertexBuffers(0, 3, mVertexBufferView); + } + commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); + + commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), mInstance, 0, 0, 0); + + mInstance = 0; +} + +void GenericModelD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) +{ + mWorldUniformPer.WorldUniforms[mInstance] = worldUniforms; + + mInstance++; +} diff --git a/src/aquarium-optimized/d3d12/GenericModelD3D12.h b/src/aquarium-optimized/d3d12/GenericModelD3D12.h index 8c787d9..6576b93 100644 --- a/src/aquarium-optimized/d3d12/GenericModelD3D12.h +++ b/src/aquarium-optimized/d3d12/GenericModelD3D12.h @@ -1,83 +1,83 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// GenericModelD3D12.h: Defnes generic model of D3D12 - -#pragma once -#ifndef GENERICMODELD3D12_H -#define GENERICMODELD3D12_H 1 - -#include -#include - -#include "BufferD3D12.h" -#include "ContextD3D12.h" -#include "ProgramD3D12.h" -#include "TextureD3D12.h" - -#include "../Model.h" - -class GenericModelD3D12 : public Model -{ - public: - GenericModelD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - - void init() override; - void prepareForDraw() const override; - void draw() override; - - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - - TextureD3D12 *mDiffuseTexture; - TextureD3D12 *mNormalTexture; - TextureD3D12 *mReflectionTexture; - TextureD3D12 *mSkyboxTexture; - - BufferD3D12 *mPositionBuffer; - BufferD3D12 *mNormalBuffer; - BufferD3D12 *mTexCoordBuffer; - BufferD3D12 *mTangentBuffer; - BufferD3D12 *mBiNormalBuffer; - - BufferD3D12 *mIndicesBuffer; - - struct LightFactorUniforms - { - float shininess; - float specularFactor; - } mLightFactorUniforms; - - struct WorldUniformPer - { - WorldUniforms WorldUniforms[20]; - }; - WorldUniformPer mWorldUniformPer; - - private: - D3D12_CONSTANT_BUFFER_VIEW_DESC mWorldBufferView; - ComPtr mWorldBuffer; - - D3D12_CONSTANT_BUFFER_VIEW_DESC mLightFactorView; - D3D12_GPU_DESCRIPTOR_HANDLE mLightFactorGPUHandle; - ComPtr mLightFactorBuffer; - ComPtr mLightFactorUploadBuffer; - - std::vector mInputElementDescs; - D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[5]; - - ComPtr mRootSignature; - ComPtr mPipelineState; - - ContextD3D12 *mContextD3D12; - ProgramD3D12 *mProgramD3D12; - - int mInstance; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// GenericModelD3D12.h: Defnes generic model of D3D12 + +#pragma once +#ifndef GENERICMODELD3D12_H +#define GENERICMODELD3D12_H 1 + +#include +#include + +#include "BufferD3D12.h" +#include "ContextD3D12.h" +#include "ProgramD3D12.h" +#include "TextureD3D12.h" + +#include "../Model.h" + +class GenericModelD3D12 : public Model +{ + public: + GenericModelD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + + void init() override; + void prepareForDraw() const override; + void draw() override; + + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + + TextureD3D12 *mDiffuseTexture; + TextureD3D12 *mNormalTexture; + TextureD3D12 *mReflectionTexture; + TextureD3D12 *mSkyboxTexture; + + BufferD3D12 *mPositionBuffer; + BufferD3D12 *mNormalBuffer; + BufferD3D12 *mTexCoordBuffer; + BufferD3D12 *mTangentBuffer; + BufferD3D12 *mBiNormalBuffer; + + BufferD3D12 *mIndicesBuffer; + + struct LightFactorUniforms + { + float shininess; + float specularFactor; + } mLightFactorUniforms; + + struct WorldUniformPer + { + WorldUniforms WorldUniforms[20]; + }; + WorldUniformPer mWorldUniformPer; + + private: + D3D12_CONSTANT_BUFFER_VIEW_DESC mWorldBufferView; + ComPtr mWorldBuffer; + + D3D12_CONSTANT_BUFFER_VIEW_DESC mLightFactorView; + D3D12_GPU_DESCRIPTOR_HANDLE mLightFactorGPUHandle; + ComPtr mLightFactorBuffer; + ComPtr mLightFactorUploadBuffer; + + std::vector mInputElementDescs; + D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[5]; + + ComPtr mRootSignature; + ComPtr mPipelineState; + + ContextD3D12 *mContextD3D12; + ProgramD3D12 *mProgramD3D12; + + int mInstance; +}; + +#endif diff --git a/src/aquarium-optimized/d3d12/InnerModelD3D12.cpp b/src/aquarium-optimized/d3d12/InnerModelD3D12.cpp index e1d6e40..b989dce 100644 --- a/src/aquarium-optimized/d3d12/InnerModelD3D12.cpp +++ b/src/aquarium-optimized/d3d12/InnerModelD3D12.cpp @@ -1,136 +1,136 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// InnerModelD3D12.cpp: Implements inner model of D3D12. - -#include "InnerModelD3D12.h" - -InnerModelD3D12::InnerModelD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : Model(type, name, blend) -{ - mContextD3D12 = static_cast(context); - - mInnerUniforms.eta = 1.0f; - mInnerUniforms.tankColorFudge = 0.796f; - mInnerUniforms.refractionFudge = 3.0f; -} - -void InnerModelD3D12::init() -{ - mProgramD3D12 = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mTangentBuffer = static_cast(bufferMap["tangent"]); - mBiNormalBuffer = static_cast(bufferMap["binormal"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; - mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; - mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; - mVertexBufferView[3] = mTangentBuffer->mVertexBufferView; - mVertexBufferView[4] = mBiNormalBuffer->mVertexBufferView; - - mInputElementDescs = {{"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 3, DXGI_FORMAT_R32G32B32_FLOAT, 3, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 4, DXGI_FORMAT_R32G32B32_FLOAT, 4, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}}; - - // create constant buffer, desc. - mInnerBuffer = mContextD3D12->createDefaultBuffer( - &mInnerUniforms, mContextD3D12->CalcConstantBufferByteSize(sizeof(InnerUniforms)), - mInnerUploadBuffer); - mInnerView.BufferLocation = mInnerBuffer->GetGPUVirtualAddress(); - mInnerView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( - sizeof(InnerUniforms)); // CB size is required to be 256-byte aligned. - mContextD3D12->buildCbvDescriptor(mInnerView, &mInnerGPUHandle); - mWorldBuffer = mContextD3D12->createUploadBuffer( - &mWorldUniformPer, mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniforms))); - mWorldBufferView.BufferLocation = mWorldBuffer->GetGPUVirtualAddress(); - mWorldBufferView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniforms)); - - // Create root signature to bind resources. - // Bind textures, samplers and immutable constant buffers in a descriptor table. - // Bind frequently updated constant buffers by root descriptors. - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; - CD3DX12_ROOT_PARAMETER1 rootParameters[5]; - CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; - rootParameters[0] = mContextD3D12->rootParameterGeneral; - rootParameters[1] = mContextD3D12->rootParameterWorld; - - mDiffuseTexture->createSrvDescriptor(); - mNormalTexture->createSrvDescriptor(); - mReflectionTexture->createSrvDescriptor(); - - ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 3, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); - rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - - rootParameters[4].InitAsConstantBufferView(0, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, - D3D12_SHADER_VISIBILITY_VERTEX); - - rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, - mContextD3D12->staticSamplers.data(), - D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); - - mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); - - mContextD3D12->createGraphicsPipelineState( - mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), - mProgramD3D12->getFSModule(), mPipelineState, mBlend); -} - -void InnerModelD3D12::prepareForDraw() const {} - -void InnerModelD3D12::draw() -{ - auto &commandList = mContextD3D12->mCommandList; - - commandList->SetPipelineState(mPipelineState.Get()); - commandList->SetGraphicsRootSignature(mRootSignature.Get()); - - commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); - commandList->SetGraphicsRootConstantBufferView( - 1, mContextD3D12->lightWorldPositionView.BufferLocation); - commandList->SetGraphicsRootDescriptorTable(2, mInnerGPUHandle); - commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); - commandList->SetGraphicsRootConstantBufferView(4, mWorldBufferView.BufferLocation); - - commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - commandList->IASetVertexBuffers(0, 5, mVertexBufferView); - - commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); - - commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); -} - -void InnerModelD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) -{ - memcpy(&mWorldUniformPer, &worldUniforms, sizeof(WorldUniforms)); - - CD3DX12_RANGE readRange(0, 0); - UINT8 *m_pCbvDataBegin; - mWorldBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); - memcpy(m_pCbvDataBegin, &mWorldUniformPer, sizeof(WorldUniforms)); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// InnerModelD3D12.cpp: Implements inner model of D3D12. + +#include "InnerModelD3D12.h" + +InnerModelD3D12::InnerModelD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : Model(type, name, blend) +{ + mContextD3D12 = static_cast(context); + + mInnerUniforms.eta = 1.0f; + mInnerUniforms.tankColorFudge = 0.796f; + mInnerUniforms.refractionFudge = 3.0f; +} + +void InnerModelD3D12::init() +{ + mProgramD3D12 = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mTangentBuffer = static_cast(bufferMap["tangent"]); + mBiNormalBuffer = static_cast(bufferMap["binormal"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; + mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; + mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; + mVertexBufferView[3] = mTangentBuffer->mVertexBufferView; + mVertexBufferView[4] = mBiNormalBuffer->mVertexBufferView; + + mInputElementDescs = {{"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 3, DXGI_FORMAT_R32G32B32_FLOAT, 3, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 4, DXGI_FORMAT_R32G32B32_FLOAT, 4, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}}; + + // create constant buffer, desc. + mInnerBuffer = mContextD3D12->createDefaultBuffer( + &mInnerUniforms, mContextD3D12->CalcConstantBufferByteSize(sizeof(InnerUniforms)), + mInnerUploadBuffer); + mInnerView.BufferLocation = mInnerBuffer->GetGPUVirtualAddress(); + mInnerView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( + sizeof(InnerUniforms)); // CB size is required to be 256-byte aligned. + mContextD3D12->buildCbvDescriptor(mInnerView, &mInnerGPUHandle); + mWorldBuffer = mContextD3D12->createUploadBuffer( + &mWorldUniformPer, mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniforms))); + mWorldBufferView.BufferLocation = mWorldBuffer->GetGPUVirtualAddress(); + mWorldBufferView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniforms)); + + // Create root signature to bind resources. + // Bind textures, samplers and immutable constant buffers in a descriptor table. + // Bind frequently updated constant buffers by root descriptors. + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; + CD3DX12_ROOT_PARAMETER1 rootParameters[5]; + CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; + rootParameters[0] = mContextD3D12->rootParameterGeneral; + rootParameters[1] = mContextD3D12->rootParameterWorld; + + mDiffuseTexture->createSrvDescriptor(); + mNormalTexture->createSrvDescriptor(); + mReflectionTexture->createSrvDescriptor(); + + ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 3, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); + rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); + + rootParameters[4].InitAsConstantBufferView(0, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, + D3D12_SHADER_VISIBILITY_VERTEX); + + rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, + mContextD3D12->staticSamplers.data(), + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + + mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); + + mContextD3D12->createGraphicsPipelineState( + mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), + mProgramD3D12->getFSModule(), mPipelineState, mBlend); +} + +void InnerModelD3D12::prepareForDraw() const {} + +void InnerModelD3D12::draw() +{ + auto &commandList = mContextD3D12->mCommandList; + + commandList->SetPipelineState(mPipelineState.Get()); + commandList->SetGraphicsRootSignature(mRootSignature.Get()); + + commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); + commandList->SetGraphicsRootConstantBufferView( + 1, mContextD3D12->lightWorldPositionView.BufferLocation); + commandList->SetGraphicsRootDescriptorTable(2, mInnerGPUHandle); + commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); + commandList->SetGraphicsRootConstantBufferView(4, mWorldBufferView.BufferLocation); + + commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + commandList->IASetVertexBuffers(0, 5, mVertexBufferView); + + commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); + + commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); +} + +void InnerModelD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) +{ + memcpy(&mWorldUniformPer, &worldUniforms, sizeof(WorldUniforms)); + + CD3DX12_RANGE readRange(0, 0); + UINT8 *m_pCbvDataBegin; + mWorldBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); + memcpy(m_pCbvDataBegin, &mWorldUniformPer, sizeof(WorldUniforms)); +} diff --git a/src/aquarium-optimized/d3d12/InnerModelD3D12.h b/src/aquarium-optimized/d3d12/InnerModelD3D12.h index 653846d..b4910b7 100644 --- a/src/aquarium-optimized/d3d12/InnerModelD3D12.h +++ b/src/aquarium-optimized/d3d12/InnerModelD3D12.h @@ -1,76 +1,76 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// InnerModelD3D12.h: Defines inner model of D3D12. - -#pragma once -#ifndef INNERMODELD3D12_H -#define INNERMODELD3D12_H 1 - -#include "BufferD3D12.h" -#include "ContextD3D12.h" -#include "ProgramD3D12.h" -#include "TextureD3D12.h" - -#include "../Model.h" - -class InnerModelD3D12 : public Model -{ - public: - InnerModelD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - - void init() override; - void prepareForDraw() const override; - void draw() override; - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - - struct InnerUniforms - { - float eta; - float tankColorFudge; - float refractionFudge; - float padding; - } mInnerUniforms; - - WorldUniforms mWorldUniformPer; - - TextureD3D12 *mDiffuseTexture; - TextureD3D12 *mNormalTexture; - TextureD3D12 *mReflectionTexture; - TextureD3D12 *mSkyboxTexture; - - BufferD3D12 *mPositionBuffer; - BufferD3D12 *mNormalBuffer; - BufferD3D12 *mTexCoordBuffer; - BufferD3D12 *mTangentBuffer; - BufferD3D12 *mBiNormalBuffer; - - BufferD3D12 *mIndicesBuffer; - - private: - D3D12_CONSTANT_BUFFER_VIEW_DESC mWorldBufferView; - ComPtr mWorldBuffer; - - D3D12_CONSTANT_BUFFER_VIEW_DESC mInnerView; - D3D12_GPU_DESCRIPTOR_HANDLE mInnerGPUHandle; - ComPtr mInnerBuffer; - ComPtr mInnerUploadBuffer; - - std::vector mInputElementDescs; - D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[5]; - - ComPtr mRootSignature; - ComPtr mPipelineState; - - ContextD3D12 *mContextD3D12; - ProgramD3D12 *mProgramD3D12; -}; - -#endif // !INNERMODELD3D12_H -#pragma once +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// InnerModelD3D12.h: Defines inner model of D3D12. + +#pragma once +#ifndef INNERMODELD3D12_H +#define INNERMODELD3D12_H 1 + +#include "BufferD3D12.h" +#include "ContextD3D12.h" +#include "ProgramD3D12.h" +#include "TextureD3D12.h" + +#include "../Model.h" + +class InnerModelD3D12 : public Model +{ + public: + InnerModelD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + + void init() override; + void prepareForDraw() const override; + void draw() override; + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + + struct InnerUniforms + { + float eta; + float tankColorFudge; + float refractionFudge; + float padding; + } mInnerUniforms; + + WorldUniforms mWorldUniformPer; + + TextureD3D12 *mDiffuseTexture; + TextureD3D12 *mNormalTexture; + TextureD3D12 *mReflectionTexture; + TextureD3D12 *mSkyboxTexture; + + BufferD3D12 *mPositionBuffer; + BufferD3D12 *mNormalBuffer; + BufferD3D12 *mTexCoordBuffer; + BufferD3D12 *mTangentBuffer; + BufferD3D12 *mBiNormalBuffer; + + BufferD3D12 *mIndicesBuffer; + + private: + D3D12_CONSTANT_BUFFER_VIEW_DESC mWorldBufferView; + ComPtr mWorldBuffer; + + D3D12_CONSTANT_BUFFER_VIEW_DESC mInnerView; + D3D12_GPU_DESCRIPTOR_HANDLE mInnerGPUHandle; + ComPtr mInnerBuffer; + ComPtr mInnerUploadBuffer; + + std::vector mInputElementDescs; + D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[5]; + + ComPtr mRootSignature; + ComPtr mPipelineState; + + ContextD3D12 *mContextD3D12; + ProgramD3D12 *mProgramD3D12; +}; + +#endif // !INNERMODELD3D12_H +#pragma once diff --git a/src/aquarium-optimized/d3d12/OutsideModelD3D12.cpp b/src/aquarium-optimized/d3d12/OutsideModelD3D12.cpp index 60e06ac..acef073 100644 --- a/src/aquarium-optimized/d3d12/OutsideModelD3D12.cpp +++ b/src/aquarium-optimized/d3d12/OutsideModelD3D12.cpp @@ -1,128 +1,128 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -#include "OutsideModelD3D12.h" - -OutsideModelD3D12::OutsideModelD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : Model(type, name, blend) -{ - mContextD3D12 = static_cast(context); - - mLightFactorUniforms.shininess = 50.0f; - mLightFactorUniforms.specularFactor = 0.0f; -} - -void OutsideModelD3D12::init() -{ - mProgramD3D12 = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mTangentBuffer = static_cast(bufferMap["tangent"]); - mBiNormalBuffer = static_cast(bufferMap["binormal"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; - mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; - mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; - - mInputElementDescs = { - {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, - 0}, - }; - - // create constant buffer, desc. - mLightFactorBuffer = mContextD3D12->createDefaultBuffer( - &mLightFactorUniforms, - mContextD3D12->CalcConstantBufferByteSize(sizeof(LightFactorUniforms)), - mLightFactorUploadBuffer); - mLightFactorView.BufferLocation = mLightFactorBuffer->GetGPUVirtualAddress(); - mLightFactorView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( - sizeof(LightFactorUniforms)); // CB size is required to be 256-byte aligned. - mContextD3D12->buildCbvDescriptor(mLightFactorView, &mLightFactorGPUHandle); - mWorldBuffer = mContextD3D12->createUploadBuffer( - &mWorldUniformPer, mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniforms))); - mWorldBufferView.BufferLocation = mWorldBuffer->GetGPUVirtualAddress(); - mWorldBufferView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniforms)); - - // Create root signature to bind resources. - // Bind textures, samplers and immutable constant buffers in a descriptor table. - // Bind frequently updated constant buffers by root descriptors. - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; - CD3DX12_ROOT_PARAMETER1 rootParameters[5]; - CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; - rootParameters[0] = mContextD3D12->rootParameterGeneral; - rootParameters[1] = mContextD3D12->rootParameterWorld; - - mDiffuseTexture->createSrvDescriptor(); - - ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); - rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - - rootParameters[4].InitAsConstantBufferView(0, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, - D3D12_SHADER_VISIBILITY_VERTEX); - - rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, - mContextD3D12->staticSamplers.data(), - D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); - - mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); - - mContextD3D12->createGraphicsPipelineState( - mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), - mProgramD3D12->getFSModule(), mPipelineState, mBlend); -} - -void OutsideModelD3D12::prepareForDraw() const {} - -void OutsideModelD3D12::draw() -{ - auto &commandList = mContextD3D12->mCommandList; - - commandList->SetPipelineState(mPipelineState.Get()); - commandList->SetGraphicsRootSignature(mRootSignature.Get()); - - commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); - commandList->SetGraphicsRootConstantBufferView( - 1, mContextD3D12->lightWorldPositionView.BufferLocation); - commandList->SetGraphicsRootDescriptorTable(2, mLightFactorGPUHandle); - commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); - commandList->SetGraphicsRootConstantBufferView(4, mWorldBufferView.BufferLocation); - - commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - commandList->IASetVertexBuffers(0, 3, mVertexBufferView); - - commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); - - commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); -} - -void OutsideModelD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) -{ - memcpy(&mWorldUniformPer, &worldUniforms, sizeof(WorldUniforms)); - - CD3DX12_RANGE readRange(0, 0); - UINT8 *m_pCbvDataBegin; - mWorldBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); - memcpy(m_pCbvDataBegin, &mWorldUniformPer, sizeof(WorldUniforms)); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +#include "OutsideModelD3D12.h" + +OutsideModelD3D12::OutsideModelD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : Model(type, name, blend) +{ + mContextD3D12 = static_cast(context); + + mLightFactorUniforms.shininess = 50.0f; + mLightFactorUniforms.specularFactor = 0.0f; +} + +void OutsideModelD3D12::init() +{ + mProgramD3D12 = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mTangentBuffer = static_cast(bufferMap["tangent"]); + mBiNormalBuffer = static_cast(bufferMap["binormal"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; + mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; + mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; + + mInputElementDescs = { + {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, + 0}, + }; + + // create constant buffer, desc. + mLightFactorBuffer = mContextD3D12->createDefaultBuffer( + &mLightFactorUniforms, + mContextD3D12->CalcConstantBufferByteSize(sizeof(LightFactorUniforms)), + mLightFactorUploadBuffer); + mLightFactorView.BufferLocation = mLightFactorBuffer->GetGPUVirtualAddress(); + mLightFactorView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( + sizeof(LightFactorUniforms)); // CB size is required to be 256-byte aligned. + mContextD3D12->buildCbvDescriptor(mLightFactorView, &mLightFactorGPUHandle); + mWorldBuffer = mContextD3D12->createUploadBuffer( + &mWorldUniformPer, mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniforms))); + mWorldBufferView.BufferLocation = mWorldBuffer->GetGPUVirtualAddress(); + mWorldBufferView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniforms)); + + // Create root signature to bind resources. + // Bind textures, samplers and immutable constant buffers in a descriptor table. + // Bind frequently updated constant buffers by root descriptors. + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; + CD3DX12_ROOT_PARAMETER1 rootParameters[5]; + CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; + rootParameters[0] = mContextD3D12->rootParameterGeneral; + rootParameters[1] = mContextD3D12->rootParameterWorld; + + mDiffuseTexture->createSrvDescriptor(); + + ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); + rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); + + rootParameters[4].InitAsConstantBufferView(0, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, + D3D12_SHADER_VISIBILITY_VERTEX); + + rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, + mContextD3D12->staticSamplers.data(), + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + + mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); + + mContextD3D12->createGraphicsPipelineState( + mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), + mProgramD3D12->getFSModule(), mPipelineState, mBlend); +} + +void OutsideModelD3D12::prepareForDraw() const {} + +void OutsideModelD3D12::draw() +{ + auto &commandList = mContextD3D12->mCommandList; + + commandList->SetPipelineState(mPipelineState.Get()); + commandList->SetGraphicsRootSignature(mRootSignature.Get()); + + commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); + commandList->SetGraphicsRootConstantBufferView( + 1, mContextD3D12->lightWorldPositionView.BufferLocation); + commandList->SetGraphicsRootDescriptorTable(2, mLightFactorGPUHandle); + commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); + commandList->SetGraphicsRootConstantBufferView(4, mWorldBufferView.BufferLocation); + + commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + commandList->IASetVertexBuffers(0, 3, mVertexBufferView); + + commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); + + commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); +} + +void OutsideModelD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) +{ + memcpy(&mWorldUniformPer, &worldUniforms, sizeof(WorldUniforms)); + + CD3DX12_RANGE readRange(0, 0); + UINT8 *m_pCbvDataBegin; + mWorldBuffer->Map(0, &readRange, reinterpret_cast(&m_pCbvDataBegin)); + memcpy(m_pCbvDataBegin, &mWorldUniformPer, sizeof(WorldUniforms)); +} diff --git a/src/aquarium-optimized/d3d12/OutsideModelD3D12.h b/src/aquarium-optimized/d3d12/OutsideModelD3D12.h index 1b5e2ab..1cf09d9 100644 --- a/src/aquarium-optimized/d3d12/OutsideModelD3D12.h +++ b/src/aquarium-optimized/d3d12/OutsideModelD3D12.h @@ -1,76 +1,76 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// OutsideModelD3D12.h: Defnes outside model of D3D12 - -#pragma once -#ifndef OUTSIDEMODELD3D12_H -#define OUTSIDEMODELD3D12_H 1 - -#include - -#include "BufferD3D12.h" -#include "ContextD3D12.h" -#include "ProgramD3D12.h" -#include "TextureD3D12.h" - -#include "../Model.h" - -class OutsideModelD3D12 : public Model -{ - public: - OutsideModelD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - - void init() override; - void prepareForDraw() const override; - void draw() override; - - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - - TextureD3D12 *mDiffuseTexture; - TextureD3D12 *mNormalTexture; - TextureD3D12 *mReflectionTexture; - TextureD3D12 *mSkyboxTexture; - - BufferD3D12 *mPositionBuffer; - BufferD3D12 *mNormalBuffer; - BufferD3D12 *mTexCoordBuffer; - BufferD3D12 *mTangentBuffer; - BufferD3D12 *mBiNormalBuffer; - - BufferD3D12 *mIndicesBuffer; - - struct LightFactorUniforms - { - float shininess; - float specularFactor; - } mLightFactorUniforms; - - WorldUniforms mWorldUniformPer; - - private: - D3D12_CONSTANT_BUFFER_VIEW_DESC mWorldBufferView; - ComPtr mWorldBuffer; - - D3D12_CONSTANT_BUFFER_VIEW_DESC mLightFactorView; - D3D12_GPU_DESCRIPTOR_HANDLE mLightFactorGPUHandle; - ComPtr mLightFactorBuffer; - ComPtr mLightFactorUploadBuffer; - - std::vector mInputElementDescs; - D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[3]; - - ComPtr mRootSignature; - ComPtr mPipelineState; - - ContextD3D12 *mContextD3D12; - ProgramD3D12 *mProgramD3D12; -}; - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// OutsideModelD3D12.h: Defnes outside model of D3D12 + +#pragma once +#ifndef OUTSIDEMODELD3D12_H +#define OUTSIDEMODELD3D12_H 1 + +#include + +#include "BufferD3D12.h" +#include "ContextD3D12.h" +#include "ProgramD3D12.h" +#include "TextureD3D12.h" + +#include "../Model.h" + +class OutsideModelD3D12 : public Model +{ + public: + OutsideModelD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + + void init() override; + void prepareForDraw() const override; + void draw() override; + + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + + TextureD3D12 *mDiffuseTexture; + TextureD3D12 *mNormalTexture; + TextureD3D12 *mReflectionTexture; + TextureD3D12 *mSkyboxTexture; + + BufferD3D12 *mPositionBuffer; + BufferD3D12 *mNormalBuffer; + BufferD3D12 *mTexCoordBuffer; + BufferD3D12 *mTangentBuffer; + BufferD3D12 *mBiNormalBuffer; + + BufferD3D12 *mIndicesBuffer; + + struct LightFactorUniforms + { + float shininess; + float specularFactor; + } mLightFactorUniforms; + + WorldUniforms mWorldUniformPer; + + private: + D3D12_CONSTANT_BUFFER_VIEW_DESC mWorldBufferView; + ComPtr mWorldBuffer; + + D3D12_CONSTANT_BUFFER_VIEW_DESC mLightFactorView; + D3D12_GPU_DESCRIPTOR_HANDLE mLightFactorGPUHandle; + ComPtr mLightFactorBuffer; + ComPtr mLightFactorUploadBuffer; + + std::vector mInputElementDescs; + D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[3]; + + ComPtr mRootSignature; + ComPtr mPipelineState; + + ContextD3D12 *mContextD3D12; + ProgramD3D12 *mProgramD3D12; +}; + #endif \ No newline at end of file diff --git a/src/aquarium-optimized/d3d12/ProgramD3D12.cpp b/src/aquarium-optimized/d3d12/ProgramD3D12.cpp index c2f7d1c..244aeca 100644 --- a/src/aquarium-optimized/d3d12/ProgramD3D12.cpp +++ b/src/aquarium-optimized/d3d12/ProgramD3D12.cpp @@ -1,34 +1,34 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -#include -#include - -#include "ContextD3D12.h" -#include "ProgramD3D12.h" - -ProgramD3D12::ProgramD3D12(ContextD3D12 *context, const std::string &mVId, const std::string &mFId) - : Program(mVId, mFId), mVertexShader(nullptr), mPixelShader(nullptr), context(context) -{ -} - -ProgramD3D12::~ProgramD3D12() {} - -void ProgramD3D12::loadProgram() -{ - std::ifstream VertexShaderStream(mVId, std::ios::in); - std::string VertexShaderCode((std::istreambuf_iterator(VertexShaderStream)), - std::istreambuf_iterator()); - VertexShaderStream.close(); - - // Read the Fragment Shader code from the file - std::ifstream FragmentShaderStream(mFId, std::ios::in); - std::string FragmentShaderCode((std::istreambuf_iterator(FragmentShaderStream)), - std::istreambuf_iterator()); - FragmentShaderStream.close(); - - mVertexShader = context->createShaderModule("VS", VertexShaderCode); - mPixelShader = context->createShaderModule("PS", FragmentShaderCode); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +#include +#include + +#include "ContextD3D12.h" +#include "ProgramD3D12.h" + +ProgramD3D12::ProgramD3D12(ContextD3D12 *context, const std::string &mVId, const std::string &mFId) + : Program(mVId, mFId), mVertexShader(nullptr), mPixelShader(nullptr), context(context) +{ +} + +ProgramD3D12::~ProgramD3D12() {} + +void ProgramD3D12::loadProgram() +{ + std::ifstream VertexShaderStream(mVId, std::ios::in); + std::string VertexShaderCode((std::istreambuf_iterator(VertexShaderStream)), + std::istreambuf_iterator()); + VertexShaderStream.close(); + + // Read the Fragment Shader code from the file + std::ifstream FragmentShaderStream(mFId, std::ios::in); + std::string FragmentShaderCode((std::istreambuf_iterator(FragmentShaderStream)), + std::istreambuf_iterator()); + FragmentShaderStream.close(); + + mVertexShader = context->createShaderModule("VS", VertexShaderCode); + mPixelShader = context->createShaderModule("PS", FragmentShaderCode); +} diff --git a/src/aquarium-optimized/d3d12/ProgramD3D12.h b/src/aquarium-optimized/d3d12/ProgramD3D12.h index 4f7505d..a86b9c0 100644 --- a/src/aquarium-optimized/d3d12/ProgramD3D12.h +++ b/src/aquarium-optimized/d3d12/ProgramD3D12.h @@ -1,44 +1,43 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// ProgramD3D.h: Defines Program wrapper of D3D. -// Load shaders from folder shaders/d3d12. - -#pragma once -#ifndef PROGRAMD3D12_H -#define PROGRAMD3D12_H 1 - -#include -#include - -#include "stdafx.h" - -#include "../Aquarium.h" -#include "../Program.h" - -using Microsoft::WRL::ComPtr; - -class ContextD3D12; - -class ProgramD3D12 : public Program -{ - public: - ProgramD3D12() {} - ProgramD3D12(ContextD3D12 *context, const std::string &mVId, const std::string &mFId); - ~ProgramD3D12() override; - - void loadProgram(); - ComPtr getVSModule() { return mVertexShader; } - ComPtr getFSModule() { return mPixelShader; } - - private: - ComPtr mVertexShader; - ComPtr mPixelShader; - - ContextD3D12 *context; -}; - -#endif - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramD3D.h: Defines Program wrapper of D3D. +// Load shaders from folder shaders/d3d12. + +#pragma once +#ifndef PROGRAMD3D12_H +#define PROGRAMD3D12_H 1 + +#include +#include + +#include "stdafx.h" + +#include "../Aquarium.h" +#include "../Program.h" + +using Microsoft::WRL::ComPtr; + +class ContextD3D12; + +class ProgramD3D12 : public Program +{ + public: + ProgramD3D12() {} + ProgramD3D12(ContextD3D12 *context, const std::string &mVId, const std::string &mFId); + ~ProgramD3D12() override; + + void loadProgram(); + ComPtr getVSModule() { return mVertexShader; } + ComPtr getFSModule() { return mPixelShader; } + + private: + ComPtr mVertexShader; + ComPtr mPixelShader; + + ContextD3D12 *context; +}; + +#endif diff --git a/src/aquarium-optimized/d3d12/SeaweedModelD3D12.cpp b/src/aquarium-optimized/d3d12/SeaweedModelD3D12.cpp index 9977dfb..ec0dff8 100644 --- a/src/aquarium-optimized/d3d12/SeaweedModelD3D12.cpp +++ b/src/aquarium-optimized/d3d12/SeaweedModelD3D12.cpp @@ -1,151 +1,151 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// SeaweenModelD3D12: Implements seaweed model of D3D12. - -#include "SeaweedModelD3D12.h" - -SeaweedModelD3D12::SeaweedModelD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : SeaweedModel(type, name, blend), instance(0) -{ - mContextD3D12 = static_cast(context); - mAquarium = aquarium; - - mLightFactorUniforms.shininess = 50.0f; - mLightFactorUniforms.specularFactor = 1.0f; -} - -void SeaweedModelD3D12::init() -{ - mProgramD3D12 = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; - mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; - mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; - - // create input layout - mInputElementDescs = { - {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, - 0}, - }; - - // create constant buffer, desc. - mLightFactorBuffer = mContextD3D12->createDefaultBuffer( - &mLightFactorUniforms, - mContextD3D12->CalcConstantBufferByteSize(sizeof(LightFactorUniforms)), - mLightFactorUploadBuffer); - mLightFactorView.BufferLocation = mLightFactorBuffer->GetGPUVirtualAddress(); - mLightFactorView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( - sizeof(LightFactorUniforms)); // CB size is required to be 256-byte aligned. - mContextD3D12->buildCbvDescriptor(mLightFactorView, &mLightFactorGPUHandle); - mWorldBuffer = mContextD3D12->createUploadBuffer( - &mWorldUniformPer, mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniformPer))); - mWorldBufferView.BufferLocation = mWorldBuffer->GetGPUVirtualAddress(); - mWorldBufferView.SizeInBytes = - mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniformPer)); - mSeaweedBuffer = mContextD3D12->createUploadBuffer( - &mSeaweedPer, mContextD3D12->CalcConstantBufferByteSize(sizeof(SeaweedPer))); - mSeaweedBufferView.BufferLocation = mSeaweedBuffer->GetGPUVirtualAddress(); - mSeaweedBufferView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize(sizeof(SeaweedPer)); - - // Create root signature to bind resources. - // Bind textures, samplers and immutable constant buffers in a descriptor table. - // Bind frequently updated constant buffers by root descriptors. - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; - CD3DX12_ROOT_PARAMETER1 rootParameters[6]; - CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; - rootParameters[0] = mContextD3D12->rootParameterGeneral; - rootParameters[1] = mContextD3D12->rootParameterWorld; - - mDiffuseTexture->createSrvDescriptor(); - - ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); - rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); - rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - - rootParameters[4].InitAsConstantBufferView(0, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, - D3D12_SHADER_VISIBILITY_VERTEX); - rootParameters[5].InitAsConstantBufferView(1, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, - D3D12_SHADER_VISIBILITY_VERTEX); - - rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, - mContextD3D12->staticSamplers.data(), - D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); - - mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); - - mContextD3D12->createGraphicsPipelineState( - mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), - mProgramD3D12->getFSModule(), mPipelineState, mBlend); -} - -void SeaweedModelD3D12::prepareForDraw() const -{ - CD3DX12_RANGE readRangeView(0, 0); - UINT8 *m_pCbvDataBeginView; - mWorldBuffer->Map(0, &readRangeView, reinterpret_cast(&m_pCbvDataBeginView)); - memcpy(m_pCbvDataBeginView, &mWorldUniformPer, sizeof(WorldUniformPer)); - - CD3DX12_RANGE readRangeSeaweed(0, 0); - UINT8 *m_pCbvDataBeginSeaweed; - mSeaweedBuffer->Map(0, &readRangeSeaweed, reinterpret_cast(&m_pCbvDataBeginSeaweed)); - memcpy(m_pCbvDataBeginSeaweed, &mSeaweedPer, sizeof(SeaweedPer)); -} - -void SeaweedModelD3D12::draw() -{ - auto &commandList = mContextD3D12->mCommandList; - - commandList->SetPipelineState(mPipelineState.Get()); - commandList->SetGraphicsRootSignature(mRootSignature.Get()); - - commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); - commandList->SetGraphicsRootConstantBufferView( - 1, mContextD3D12->lightWorldPositionView.BufferLocation); - commandList->SetGraphicsRootDescriptorTable(2, mLightFactorGPUHandle); - commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); - commandList->SetGraphicsRootConstantBufferView(4, mWorldBufferView.BufferLocation); - commandList->SetGraphicsRootConstantBufferView(5, mSeaweedBufferView.BufferLocation); - - commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - commandList->IASetVertexBuffers(0, 3, mVertexBufferView); - - commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); - - commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), instance, 0, 0, 0); - - instance = 0; -} - -void SeaweedModelD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) -{ - mWorldUniformPer.worldUniforms[instance] = worldUniforms; - mSeaweedPer.seaweed[instance].time = mAquarium->g.mclock + instance; - - instance++; -} - -void SeaweedModelD3D12::updateSeaweedModelTime(float time) {} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SeaweenModelD3D12: Implements seaweed model of D3D12. + +#include "SeaweedModelD3D12.h" + +SeaweedModelD3D12::SeaweedModelD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : SeaweedModel(type, name, blend), instance(0) +{ + mContextD3D12 = static_cast(context); + mAquarium = aquarium; + + mLightFactorUniforms.shininess = 50.0f; + mLightFactorUniforms.specularFactor = 1.0f; +} + +void SeaweedModelD3D12::init() +{ + mProgramD3D12 = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + mVertexBufferView[0] = mPositionBuffer->mVertexBufferView; + mVertexBufferView[1] = mNormalBuffer->mVertexBufferView; + mVertexBufferView[2] = mTexCoordBuffer->mVertexBufferView; + + // create input layout + mInputElementDescs = { + {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 2, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, + 0}, + }; + + // create constant buffer, desc. + mLightFactorBuffer = mContextD3D12->createDefaultBuffer( + &mLightFactorUniforms, + mContextD3D12->CalcConstantBufferByteSize(sizeof(LightFactorUniforms)), + mLightFactorUploadBuffer); + mLightFactorView.BufferLocation = mLightFactorBuffer->GetGPUVirtualAddress(); + mLightFactorView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize( + sizeof(LightFactorUniforms)); // CB size is required to be 256-byte aligned. + mContextD3D12->buildCbvDescriptor(mLightFactorView, &mLightFactorGPUHandle); + mWorldBuffer = mContextD3D12->createUploadBuffer( + &mWorldUniformPer, mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniformPer))); + mWorldBufferView.BufferLocation = mWorldBuffer->GetGPUVirtualAddress(); + mWorldBufferView.SizeInBytes = + mContextD3D12->CalcConstantBufferByteSize(sizeof(WorldUniformPer)); + mSeaweedBuffer = mContextD3D12->createUploadBuffer( + &mSeaweedPer, mContextD3D12->CalcConstantBufferByteSize(sizeof(SeaweedPer))); + mSeaweedBufferView.BufferLocation = mSeaweedBuffer->GetGPUVirtualAddress(); + mSeaweedBufferView.SizeInBytes = mContextD3D12->CalcConstantBufferByteSize(sizeof(SeaweedPer)); + + // Create root signature to bind resources. + // Bind textures, samplers and immutable constant buffers in a descriptor table. + // Bind frequently updated constant buffers by root descriptors. + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; + CD3DX12_ROOT_PARAMETER1 rootParameters[6]; + CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; + rootParameters[0] = mContextD3D12->rootParameterGeneral; + rootParameters[1] = mContextD3D12->rootParameterWorld; + + mDiffuseTexture->createSrvDescriptor(); + + ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); + rootParameters[2].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); + rootParameters[3].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); + + rootParameters[4].InitAsConstantBufferView(0, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, + D3D12_SHADER_VISIBILITY_VERTEX); + rootParameters[5].InitAsConstantBufferView(1, 3, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, + D3D12_SHADER_VISIBILITY_VERTEX); + + rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 2u, + mContextD3D12->staticSamplers.data(), + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + + mContextD3D12->createRootSignature(rootSignatureDesc, mRootSignature); + + mContextD3D12->createGraphicsPipelineState( + mInputElementDescs, mRootSignature, mProgramD3D12->getVSModule(), + mProgramD3D12->getFSModule(), mPipelineState, mBlend); +} + +void SeaweedModelD3D12::prepareForDraw() const +{ + CD3DX12_RANGE readRangeView(0, 0); + UINT8 *m_pCbvDataBeginView; + mWorldBuffer->Map(0, &readRangeView, reinterpret_cast(&m_pCbvDataBeginView)); + memcpy(m_pCbvDataBeginView, &mWorldUniformPer, sizeof(WorldUniformPer)); + + CD3DX12_RANGE readRangeSeaweed(0, 0); + UINT8 *m_pCbvDataBeginSeaweed; + mSeaweedBuffer->Map(0, &readRangeSeaweed, reinterpret_cast(&m_pCbvDataBeginSeaweed)); + memcpy(m_pCbvDataBeginSeaweed, &mSeaweedPer, sizeof(SeaweedPer)); +} + +void SeaweedModelD3D12::draw() +{ + auto &commandList = mContextD3D12->mCommandList; + + commandList->SetPipelineState(mPipelineState.Get()); + commandList->SetGraphicsRootSignature(mRootSignature.Get()); + + commandList->SetGraphicsRootDescriptorTable(0, mContextD3D12->lightGPUHandle); + commandList->SetGraphicsRootConstantBufferView( + 1, mContextD3D12->lightWorldPositionView.BufferLocation); + commandList->SetGraphicsRootDescriptorTable(2, mLightFactorGPUHandle); + commandList->SetGraphicsRootDescriptorTable(3, mDiffuseTexture->getTextureGPUHandle()); + commandList->SetGraphicsRootConstantBufferView(4, mWorldBufferView.BufferLocation); + commandList->SetGraphicsRootConstantBufferView(5, mSeaweedBufferView.BufferLocation); + + commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + commandList->IASetVertexBuffers(0, 3, mVertexBufferView); + + commandList->IASetIndexBuffer(&mIndicesBuffer->mIndexBufferView); + + commandList->DrawIndexedInstanced(mIndicesBuffer->getTotalComponents(), instance, 0, 0, 0); + + instance = 0; +} + +void SeaweedModelD3D12::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) +{ + mWorldUniformPer.worldUniforms[instance] = worldUniforms; + mSeaweedPer.seaweed[instance].time = mAquarium->g.mclock + instance; + + instance++; +} + +void SeaweedModelD3D12::updateSeaweedModelTime(float time) {} diff --git a/src/aquarium-optimized/d3d12/SeaweedModelD3D12.h b/src/aquarium-optimized/d3d12/SeaweedModelD3D12.h index 5d14431..0dc29cf 100644 --- a/src/aquarium-optimized/d3d12/SeaweedModelD3D12.h +++ b/src/aquarium-optimized/d3d12/SeaweedModelD3D12.h @@ -1,92 +1,92 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// SeaweedModelD3D12.h: Defines seaweed model of D3D12. - -#pragma once -#ifndef SEAWEEDMODELD3D12_H -#define SEAWEEDMODELD3D12_H 1 - -#include "BufferD3D12.h" -#include "ContextD3D12.h" -#include "ProgramD3D12.h" -#include "TextureD3D12.h" - -#include "../SeaweedModel.h" - -class SeaweedModelD3D12 : public SeaweedModel -{ - public: - SeaweedModelD3D12(Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - - void init() override; - void prepareForDraw() const override; - void draw() override; - - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - - TextureD3D12 *mDiffuseTexture; - TextureD3D12 *mNormalTexture; - TextureD3D12 *mReflectionTexture; - TextureD3D12 *mSkyboxTexture; - - BufferD3D12 *mPositionBuffer; - BufferD3D12 *mNormalBuffer; - BufferD3D12 *mTexCoordBuffer; - - BufferD3D12 *mIndicesBuffer; - void updateSeaweedModelTime(float time) override; - - struct LightFactorUniforms - { - float shininess; - float specularFactor; - } mLightFactorUniforms; - - struct Seaweed - { - float time; - float padding[3]; - }; - struct SeaweedPer - { - Seaweed seaweed[20]; - } mSeaweedPer; - - struct WorldUniformPer - { - WorldUniforms worldUniforms[20]; - }; - WorldUniformPer mWorldUniformPer; - - private: - D3D12_CONSTANT_BUFFER_VIEW_DESC mWorldBufferView; - ComPtr mWorldBuffer; - D3D12_CONSTANT_BUFFER_VIEW_DESC mSeaweedBufferView; - ComPtr mSeaweedBuffer; - - D3D12_CONSTANT_BUFFER_VIEW_DESC mLightFactorView; - D3D12_GPU_DESCRIPTOR_HANDLE mLightFactorGPUHandle; - ComPtr mLightFactorBuffer; - ComPtr mLightFactorUploadBuffer; - - std::vector mInputElementDescs; - D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[3]; - - ComPtr mRootSignature; - ComPtr mPipelineState; - - ContextD3D12 *mContextD3D12; - ProgramD3D12 *mProgramD3D12; - Aquarium *mAquarium; - - int instance; -}; - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SeaweedModelD3D12.h: Defines seaweed model of D3D12. + +#pragma once +#ifndef SEAWEEDMODELD3D12_H +#define SEAWEEDMODELD3D12_H 1 + +#include "BufferD3D12.h" +#include "ContextD3D12.h" +#include "ProgramD3D12.h" +#include "TextureD3D12.h" + +#include "../SeaweedModel.h" + +class SeaweedModelD3D12 : public SeaweedModel +{ + public: + SeaweedModelD3D12(Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + + void init() override; + void prepareForDraw() const override; + void draw() override; + + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + + TextureD3D12 *mDiffuseTexture; + TextureD3D12 *mNormalTexture; + TextureD3D12 *mReflectionTexture; + TextureD3D12 *mSkyboxTexture; + + BufferD3D12 *mPositionBuffer; + BufferD3D12 *mNormalBuffer; + BufferD3D12 *mTexCoordBuffer; + + BufferD3D12 *mIndicesBuffer; + void updateSeaweedModelTime(float time) override; + + struct LightFactorUniforms + { + float shininess; + float specularFactor; + } mLightFactorUniforms; + + struct Seaweed + { + float time; + float padding[3]; + }; + struct SeaweedPer + { + Seaweed seaweed[20]; + } mSeaweedPer; + + struct WorldUniformPer + { + WorldUniforms worldUniforms[20]; + }; + WorldUniformPer mWorldUniformPer; + + private: + D3D12_CONSTANT_BUFFER_VIEW_DESC mWorldBufferView; + ComPtr mWorldBuffer; + D3D12_CONSTANT_BUFFER_VIEW_DESC mSeaweedBufferView; + ComPtr mSeaweedBuffer; + + D3D12_CONSTANT_BUFFER_VIEW_DESC mLightFactorView; + D3D12_GPU_DESCRIPTOR_HANDLE mLightFactorGPUHandle; + ComPtr mLightFactorBuffer; + ComPtr mLightFactorUploadBuffer; + + std::vector mInputElementDescs; + D3D12_VERTEX_BUFFER_VIEW mVertexBufferView[3]; + + ComPtr mRootSignature; + ComPtr mPipelineState; + + ContextD3D12 *mContextD3D12; + ProgramD3D12 *mProgramD3D12; + Aquarium *mAquarium; + + int instance; +}; + #endif // !SEAWEEDMODEL_H \ No newline at end of file diff --git a/src/aquarium-optimized/d3d12/TextureD3D12.cpp b/src/aquarium-optimized/d3d12/TextureD3D12.cpp index 49a5a70..7a64ce9 100644 --- a/src/aquarium-optimized/d3d12/TextureD3D12.cpp +++ b/src/aquarium-optimized/d3d12/TextureD3D12.cpp @@ -1,96 +1,96 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -#include -#include - -#include "ContextD3D12.h" -#include "TextureD3D12.h" - -TextureD3D12::~TextureD3D12() {} - -TextureD3D12::TextureD3D12(ContextD3D12 *context, const std::string &name, const std::string &url) - : Texture(name, url, true), - mTextureDimension(D3D12_RESOURCE_DIMENSION_TEXTURE2D), - mTextureViewDimension(D3D12_SRV_DIMENSION_TEXTURE2D), - mFormat(DXGI_FORMAT_R8G8B8A8_UNORM), - mSrvDesc({}), - mContext(context) -{ -} - -TextureD3D12::TextureD3D12(ContextD3D12 *context, - const std::string &name, - const std::vector &urls) - : Texture(name, urls, false), - mTextureDimension(D3D12_RESOURCE_DIMENSION_TEXTURE2D), - mTextureViewDimension(D3D12_SRV_DIMENSION_TEXTURECUBE), - mFormat(DXGI_FORMAT_R8G8B8A8_UNORM), - mSrvDesc({}), - mContext(context) -{ -} - -void TextureD3D12::loadTexture() -{ - loadImage(mUrls, &mPixelVec); - - if (mTextureViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBE) - { - D3D12_RESOURCE_DESC textureDesc = {}; - textureDesc.MipLevels = 1; - textureDesc.Format = mFormat; - textureDesc.Width = mWidth; - textureDesc.Height = mHeight; - textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE; - textureDesc.DepthOrArraySize = 6; - textureDesc.SampleDesc.Count = 1; - textureDesc.SampleDesc.Quality = 0; - textureDesc.Dimension = mTextureDimension; - - mContext->createTexture(textureDesc, mPixelVec, mTexture, mTextureUploadHeap, mWidth, - mHeight, 4u, textureDesc.MipLevels, textureDesc.DepthOrArraySize); - } - else - { - generateMipmap(mPixelVec[0], mWidth, mHeight, 0, mResizedVec, mWidth, mHeight, 0, 4, false); - - D3D12_RESOURCE_DESC textureDesc = {}; - textureDesc.MipLevels = - static_cast(std::floor(std::log2(std::max(mWidth, mHeight)))) + 1; - textureDesc.Format = mFormat; - textureDesc.Width = mWidth; - textureDesc.Height = mHeight; - textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE; - textureDesc.DepthOrArraySize = 1; - textureDesc.SampleDesc.Count = 1; - textureDesc.SampleDesc.Quality = 0; - textureDesc.Dimension = mTextureDimension; - - mContext->createTexture(textureDesc, mResizedVec, mTexture, mTextureUploadHeap, mWidth, - mHeight, 4u, textureDesc.MipLevels, textureDesc.DepthOrArraySize); - } -} - -// Allocate descriptors sequentially on deascriptor heap to bind root signature, create srv before -// binding resources. -void TextureD3D12::createSrvDescriptor() -{ - mSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - mSrvDesc.Format = mFormat; - mSrvDesc.ViewDimension = mTextureViewDimension; - if (mTextureViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBE) - { - mSrvDesc.Texture2D.MipLevels = 1; - } - else - { - - mSrvDesc.Texture2D.MipLevels = - static_cast(std::floor(std::log2(std::max(mWidth, mHeight)))) + 1; - } - - mContext->buildSrvDescriptor(mTexture.Get(), mSrvDesc, &mTextureGPUHandle); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +#include +#include + +#include "ContextD3D12.h" +#include "TextureD3D12.h" + +TextureD3D12::~TextureD3D12() {} + +TextureD3D12::TextureD3D12(ContextD3D12 *context, const std::string &name, const std::string &url) + : Texture(name, url, true), + mTextureDimension(D3D12_RESOURCE_DIMENSION_TEXTURE2D), + mTextureViewDimension(D3D12_SRV_DIMENSION_TEXTURE2D), + mFormat(DXGI_FORMAT_R8G8B8A8_UNORM), + mSrvDesc({}), + mContext(context) +{ +} + +TextureD3D12::TextureD3D12(ContextD3D12 *context, + const std::string &name, + const std::vector &urls) + : Texture(name, urls, false), + mTextureDimension(D3D12_RESOURCE_DIMENSION_TEXTURE2D), + mTextureViewDimension(D3D12_SRV_DIMENSION_TEXTURECUBE), + mFormat(DXGI_FORMAT_R8G8B8A8_UNORM), + mSrvDesc({}), + mContext(context) +{ +} + +void TextureD3D12::loadTexture() +{ + loadImage(mUrls, &mPixelVec); + + if (mTextureViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBE) + { + D3D12_RESOURCE_DESC textureDesc = {}; + textureDesc.MipLevels = 1; + textureDesc.Format = mFormat; + textureDesc.Width = mWidth; + textureDesc.Height = mHeight; + textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + textureDesc.DepthOrArraySize = 6; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Dimension = mTextureDimension; + + mContext->createTexture(textureDesc, mPixelVec, mTexture, mTextureUploadHeap, mWidth, + mHeight, 4u, textureDesc.MipLevels, textureDesc.DepthOrArraySize); + } + else + { + generateMipmap(mPixelVec[0], mWidth, mHeight, 0, mResizedVec, mWidth, mHeight, 0, 4, false); + + D3D12_RESOURCE_DESC textureDesc = {}; + textureDesc.MipLevels = + static_cast(std::floor(std::log2(std::max(mWidth, mHeight)))) + 1; + textureDesc.Format = mFormat; + textureDesc.Width = mWidth; + textureDesc.Height = mHeight; + textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + textureDesc.DepthOrArraySize = 1; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Dimension = mTextureDimension; + + mContext->createTexture(textureDesc, mResizedVec, mTexture, mTextureUploadHeap, mWidth, + mHeight, 4u, textureDesc.MipLevels, textureDesc.DepthOrArraySize); + } +} + +// Allocate descriptors sequentially on deascriptor heap to bind root signature, create srv before +// binding resources. +void TextureD3D12::createSrvDescriptor() +{ + mSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + mSrvDesc.Format = mFormat; + mSrvDesc.ViewDimension = mTextureViewDimension; + if (mTextureViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBE) + { + mSrvDesc.Texture2D.MipLevels = 1; + } + else + { + + mSrvDesc.Texture2D.MipLevels = + static_cast(std::floor(std::log2(std::max(mWidth, mHeight)))) + 1; + } + + mContext->buildSrvDescriptor(mTexture.Get(), mSrvDesc, &mTextureGPUHandle); +} diff --git a/src/aquarium-optimized/d3d12/TextureD3D12.h b/src/aquarium-optimized/d3d12/TextureD3D12.h index ec87c6b..86fd5cb 100644 --- a/src/aquarium-optimized/d3d12/TextureD3D12.h +++ b/src/aquarium-optimized/d3d12/TextureD3D12.h @@ -1,51 +1,51 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// TextureD3D12.h: Wrap textures of D3D12. - -#pragma once -#ifndef TEXTURED3D12_H -#define TEXTURED3D12_H - -#include - -#include "stdafx.h" - -#include "../Texture.h" - -using Microsoft::WRL::ComPtr; - -class ContextD3D12; - -class TextureD3D12 : public Texture -{ - public: - ~TextureD3D12() override; - TextureD3D12(ContextD3D12 *context, const std::string &name, const std::string &url); - TextureD3D12(ContextD3D12 *context, - const std::string &name, - const std::vector &urls); - - D3D12_RESOURCE_DIMENSION getTextureDimension() { return mTextureDimension; } - D3D12_SRV_DIMENSION getTextureViewDimension() { return mTextureViewDimension; } - D3D12_GPU_DESCRIPTOR_HANDLE getTextureGPUHandle() { return mTextureGPUHandle; } - void loadTexture() override; - void createSrvDescriptor(); - - private: - D3D12_RESOURCE_DIMENSION mTextureDimension; - D3D12_SRV_DIMENSION mTextureViewDimension; - DXGI_FORMAT mFormat; - ComPtr mTexture; - ComPtr mTextureUploadHeap; - D3D12_SHADER_RESOURCE_VIEW_DESC mSrvDesc; - D3D12_GPU_DESCRIPTOR_HANDLE mTextureGPUHandle; - - std::vector mPixelVec; - std::vector mResizedVec; - ContextD3D12 *mContext; -}; - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TextureD3D12.h: Wrap textures of D3D12. + +#pragma once +#ifndef TEXTURED3D12_H +#define TEXTURED3D12_H + +#include + +#include "stdafx.h" + +#include "../Texture.h" + +using Microsoft::WRL::ComPtr; + +class ContextD3D12; + +class TextureD3D12 : public Texture +{ + public: + ~TextureD3D12() override; + TextureD3D12(ContextD3D12 *context, const std::string &name, const std::string &url); + TextureD3D12(ContextD3D12 *context, + const std::string &name, + const std::vector &urls); + + D3D12_RESOURCE_DIMENSION getTextureDimension() { return mTextureDimension; } + D3D12_SRV_DIMENSION getTextureViewDimension() { return mTextureViewDimension; } + D3D12_GPU_DESCRIPTOR_HANDLE getTextureGPUHandle() { return mTextureGPUHandle; } + void loadTexture() override; + void createSrvDescriptor(); + + private: + D3D12_RESOURCE_DIMENSION mTextureDimension; + D3D12_SRV_DIMENSION mTextureViewDimension; + DXGI_FORMAT mFormat; + ComPtr mTexture; + ComPtr mTextureUploadHeap; + D3D12_SHADER_RESOURCE_VIEW_DESC mSrvDesc; + D3D12_GPU_DESCRIPTOR_HANDLE mTextureGPUHandle; + + std::vector mPixelVec; + std::vector mResizedVec; + ContextD3D12 *mContext; +}; + #endif // !TEXTURED3D12_H \ No newline at end of file diff --git a/src/aquarium-optimized/d3d12/imgui_impl_dx12.cpp b/src/aquarium-optimized/d3d12/imgui_impl_dx12.cpp index a998fe6..3b813f4 100644 --- a/src/aquarium-optimized/d3d12/imgui_impl_dx12.cpp +++ b/src/aquarium-optimized/d3d12/imgui_impl_dx12.cpp @@ -1,731 +1,731 @@ -// dear imgui: Renderer for DirectX12 -// This needs to be used along with a Platform Binding (e.g. Win32) - -// Implemented features: -// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the -// FAQ about ImTextureID in imgui.cpp. [X] Renderer: Support for large meshes (64k+ vertices) with -// 16-bits indices. -// Issues: -// [ ] 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*)). See -// github.com/ocornut/imgui/pull/301 - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example -// of using this. If you are new to dear imgui, read examples/README.txt and read the documentation -// at the top of imgui.cpp. https://github.com/ocornut/imgui - -// CHANGELOG -// (minor and older changes stripped away, please see git history for details) -// 2019-05-29: DirectX12: Added support for large mesh (64K+ vertices), enable -// ImGuiBackendFlags_RendererHasVtxOffset flag. 2019-04-30: DirectX12: Added support for special -// ImDrawCallback_ResetRenderState callback to reset render state. 2019-03-29: Misc: Various minor -// tidying up. 2018-12-03: Misc: Added #pragma comment statement to automatically link with -// d3dcompiler.lib when using D3DCompile(). 2018-11-30: Misc: Setting up io.BackendRendererName so -// it can be displayed in the About Window. 2018-06-12: DirectX12: Moved the -// ID3D12GraphicsCommandList* parameter from NewFrame() to RenderDrawData(). 2018-06-08: Misc: -// Extracted imgui_impl_dx12.cpp/.h away from the old combined DX12+Win32 example. 2018-06-08: -// DirectX12: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and -// clipping rectangle (to ease support for future multi-viewport). 2018-02-22: Merged into master -// with all Win32 code synchronized to other examples. - -#include "imgui_impl_dx12.h" -#include "imgui.h" - -// DirectX -#include -#include -#include -#ifdef _MSC_VER -#pragma comment( \ - lib, \ - "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below. -#endif - -// DirectX data -static ID3D12Device *g_pd3dDevice = NULL; -static ID3D10Blob *g_pVertexShaderBlob = NULL; -static ID3D10Blob *g_pPixelShaderBlob = NULL; -static ID3D12RootSignature *g_pRootSignature = NULL; -static ID3D12PipelineState *g_pPipelineState = NULL; -static DXGI_FORMAT g_RTVFormat = DXGI_FORMAT_UNKNOWN; -static ID3D12Resource *g_pFontTextureResource = NULL; -static D3D12_CPU_DESCRIPTOR_HANDLE g_hFontSrvCpuDescHandle = {}; -static D3D12_GPU_DESCRIPTOR_HANDLE g_hFontSrvGpuDescHandle = {}; - -struct FrameResources -{ - ID3D12Resource *IndexBuffer; - ID3D12Resource *VertexBuffer; - int IndexBufferSize; - int VertexBufferSize; -}; -static FrameResources *g_pFrameResources = NULL; -static UINT g_numFramesInFlight = 0; -static UINT g_frameIndex = UINT_MAX; - -struct VERTEX_CONSTANT_BUFFER -{ - float mvp[4][4]; -}; - -static void ImGui_ImplDX12_SetupRenderState(ImDrawData *draw_data, - ID3D12GraphicsCommandList *ctx, - FrameResources *fr) -{ - // Setup orthographic projection matrix into our constant buffer - // Our visible imgui space lies from draw_data->DisplayPos (top left) to - // draw_data->DisplayPos+data_data->DisplaySize (bottom right). - VERTEX_CONSTANT_BUFFER vertex_constant_buffer; - { - float L = draw_data->DisplayPos.x; - float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; - float T = draw_data->DisplayPos.y; - float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; - float mvp[4][4] = { - {2.0f / (R - L), 0.0f, 0.0f, 0.0f}, - {0.0f, 2.0f / (T - B), 0.0f, 0.0f}, - {0.0f, 0.0f, 0.5f, 0.0f}, - {(R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f}, - }; - memcpy(&vertex_constant_buffer.mvp, mvp, sizeof(mvp)); - } - - // Setup viewport - D3D12_VIEWPORT vp; - memset(&vp, 0, sizeof(D3D12_VIEWPORT)); - vp.Width = draw_data->DisplaySize.x; - vp.Height = draw_data->DisplaySize.y; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - vp.TopLeftX = vp.TopLeftY = 0.0f; - ctx->RSSetViewports(1, &vp); - - // Bind shader and vertex buffers - unsigned int stride = sizeof(ImDrawVert); - unsigned int offset = 0; - D3D12_VERTEX_BUFFER_VIEW vbv; - memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW)); - vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset; - vbv.SizeInBytes = fr->VertexBufferSize * stride; - vbv.StrideInBytes = stride; - ctx->IASetVertexBuffers(0, 1, &vbv); - D3D12_INDEX_BUFFER_VIEW ibv; - memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW)); - ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress(); - ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx); - ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; - ctx->IASetIndexBuffer(&ibv); - ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ctx->SetPipelineState(g_pPipelineState); - ctx->SetGraphicsRootSignature(g_pRootSignature); - ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0); - - // Setup blend factor - const float blend_factor[4] = {0.f, 0.f, 0.f, 0.f}; - ctx->OMSetBlendFactor(blend_factor); -} - -// Render function -// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call -// this directly from your main loop) -void ImGui_ImplDX12_RenderDrawData(ImDrawData *draw_data, ID3D12GraphicsCommandList *ctx) -{ - // Avoid rendering when minimized - if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) - return; - - // FIXME: I'm assuming that this only gets called once per frame! - // If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator. - g_frameIndex = g_frameIndex + 1; - FrameResources *fr = &g_pFrameResources[g_frameIndex % g_numFramesInFlight]; - - // Create and grow vertex/index buffers if needed - if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount) - { - if (fr->VertexBuffer != NULL) - { - fr->VertexBuffer->Release(); - fr->VertexBuffer = NULL; - } - fr->VertexBufferSize = draw_data->TotalVtxCount + 5000; - D3D12_HEAP_PROPERTIES props; - memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); - props.Type = D3D12_HEAP_TYPE_UPLOAD; - props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - D3D12_RESOURCE_DESC desc; - memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC)); - desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - desc.Width = fr->VertexBufferSize * sizeof(ImDrawVert); - desc.Height = 1; - desc.DepthOrArraySize = 1; - desc.MipLevels = 1; - desc.Format = DXGI_FORMAT_UNKNOWN; - desc.SampleDesc.Count = 1; - desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - desc.Flags = D3D12_RESOURCE_FLAG_NONE; - if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, - D3D12_RESOURCE_STATE_GENERIC_READ, NULL, - IID_PPV_ARGS(&fr->VertexBuffer)) < 0) - return; - } - if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount) - { - if (fr->IndexBuffer != NULL) - { - fr->IndexBuffer->Release(); - fr->IndexBuffer = NULL; - } - fr->IndexBufferSize = draw_data->TotalIdxCount + 10000; - D3D12_HEAP_PROPERTIES props; - memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); - props.Type = D3D12_HEAP_TYPE_UPLOAD; - props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - D3D12_RESOURCE_DESC desc; - memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC)); - desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - desc.Width = fr->IndexBufferSize * sizeof(ImDrawIdx); - desc.Height = 1; - desc.DepthOrArraySize = 1; - desc.MipLevels = 1; - desc.Format = DXGI_FORMAT_UNKNOWN; - desc.SampleDesc.Count = 1; - desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - desc.Flags = D3D12_RESOURCE_FLAG_NONE; - if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, - D3D12_RESOURCE_STATE_GENERIC_READ, NULL, - IID_PPV_ARGS(&fr->IndexBuffer)) < 0) - return; - } - - // Upload vertex/index data into a single contiguous GPU buffer - void *vtx_resource, *idx_resource; - D3D12_RANGE range; - memset(&range, 0, sizeof(D3D12_RANGE)); - if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK) - return; - if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK) - return; - ImDrawVert *vtx_dst = (ImDrawVert *)vtx_resource; - ImDrawIdx *idx_dst = (ImDrawIdx *)idx_resource; - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList *cmd_list = draw_data->CmdLists[n]; - memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); - memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); - vtx_dst += cmd_list->VtxBuffer.Size; - idx_dst += cmd_list->IdxBuffer.Size; - } - fr->VertexBuffer->Unmap(0, &range); - fr->IndexBuffer->Unmap(0, &range); - - // Setup desired DX state - ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr); - - // Render command lists - // (Because we merged all buffers into a single one, we maintain our own offset into them) - int global_vtx_offset = 0; - int global_idx_offset = 0; - ImVec2 clip_off = draw_data->DisplayPos; - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList *cmd_list = draw_data->CmdLists[n]; - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) - { - const ImDrawCmd *pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback != NULL) - { - // User callback, registered via ImDrawList::AddCallback() - // (ImDrawCallback_ResetRenderState is a special callback value used by the user to - // request the renderer to reset render state.) - if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) - ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr); - else - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - // Apply Scissor, Bind texture, Draw - const D3D12_RECT r = { - (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), - (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y)}; - ctx->SetGraphicsRootDescriptorTable( - 1, *(D3D12_GPU_DESCRIPTOR_HANDLE *)&pcmd->TextureId); - ctx->RSSetScissorRects(1, &r); - ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, - pcmd->VtxOffset + global_vtx_offset, 0); - } - } - global_idx_offset += cmd_list->IdxBuffer.Size; - global_vtx_offset += cmd_list->VtxBuffer.Size; - } -} - -static void ImGui_ImplDX12_CreateFontsTexture() -{ - // Build texture atlas - ImGuiIO &io = ImGui::GetIO(); - unsigned char *pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); - - // Upload texture to graphics system - { - D3D12_HEAP_PROPERTIES props; - memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); - props.Type = D3D12_HEAP_TYPE_DEFAULT; - props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - - D3D12_RESOURCE_DESC desc; - ZeroMemory(&desc, sizeof(desc)); - desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - desc.Alignment = 0; - desc.Width = width; - desc.Height = height; - desc.DepthOrArraySize = 1; - desc.MipLevels = 1; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - desc.Flags = D3D12_RESOURCE_FLAG_NONE; - - ID3D12Resource *pTexture = NULL; - g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, - D3D12_RESOURCE_STATE_COPY_DEST, NULL, - IID_PPV_ARGS(&pTexture)); - - UINT uploadPitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & - ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u); - UINT uploadSize = height * uploadPitch; - desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - desc.Alignment = 0; - desc.Width = uploadSize; - desc.Height = 1; - desc.DepthOrArraySize = 1; - desc.MipLevels = 1; - desc.Format = DXGI_FORMAT_UNKNOWN; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - desc.Flags = D3D12_RESOURCE_FLAG_NONE; - - props.Type = D3D12_HEAP_TYPE_UPLOAD; - props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - - ID3D12Resource *uploadBuffer = NULL; - HRESULT hr = g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, - D3D12_RESOURCE_STATE_GENERIC_READ, NULL, - IID_PPV_ARGS(&uploadBuffer)); - IM_ASSERT(SUCCEEDED(hr)); - - void *mapped = NULL; - D3D12_RANGE range = {0, uploadSize}; - hr = uploadBuffer->Map(0, &range, &mapped); - IM_ASSERT(SUCCEEDED(hr)); - for (int y = 0; y < height; y++) - memcpy((void *)((uintptr_t)mapped + y * uploadPitch), pixels + y * width * 4, - width * 4); - uploadBuffer->Unmap(0, &range); - - D3D12_TEXTURE_COPY_LOCATION srcLocation = {}; - srcLocation.pResource = uploadBuffer; - srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - srcLocation.PlacedFootprint.Footprint.Width = width; - srcLocation.PlacedFootprint.Footprint.Height = height; - srcLocation.PlacedFootprint.Footprint.Depth = 1; - srcLocation.PlacedFootprint.Footprint.RowPitch = uploadPitch; - - D3D12_TEXTURE_COPY_LOCATION dstLocation = {}; - dstLocation.pResource = pTexture; - dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dstLocation.SubresourceIndex = 0; - - D3D12_RESOURCE_BARRIER barrier = {}; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrier.Transition.pResource = pTexture; - barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; - barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; - - ID3D12Fence *fence = NULL; - hr = g_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); - IM_ASSERT(SUCCEEDED(hr)); - - HANDLE event = CreateEvent(0, 0, 0, 0); - IM_ASSERT(event != NULL); - - D3D12_COMMAND_QUEUE_DESC queueDesc = {}; - queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; - queueDesc.NodeMask = 1; - - ID3D12CommandQueue *cmdQueue = NULL; - hr = g_pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue)); - IM_ASSERT(SUCCEEDED(hr)); - - ID3D12CommandAllocator *cmdAlloc = NULL; - hr = g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, - IID_PPV_ARGS(&cmdAlloc)); - IM_ASSERT(SUCCEEDED(hr)); - - ID3D12GraphicsCommandList *cmdList = NULL; - hr = g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, NULL, - IID_PPV_ARGS(&cmdList)); - IM_ASSERT(SUCCEEDED(hr)); - - cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, NULL); - cmdList->ResourceBarrier(1, &barrier); - - hr = cmdList->Close(); - IM_ASSERT(SUCCEEDED(hr)); - - cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList *const *)&cmdList); - hr = cmdQueue->Signal(fence, 1); - IM_ASSERT(SUCCEEDED(hr)); - - fence->SetEventOnCompletion(1, event); - WaitForSingleObject(event, INFINITE); - - cmdList->Release(); - cmdAlloc->Release(); - cmdQueue->Release(); - CloseHandle(event); - fence->Release(); - uploadBuffer->Release(); - - // Create texture view - D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc; - ZeroMemory(&srvDesc, sizeof(srvDesc)); - srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = desc.MipLevels; - srvDesc.Texture2D.MostDetailedMip = 0; - srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, g_hFontSrvCpuDescHandle); - if (g_pFontTextureResource != NULL) - g_pFontTextureResource->Release(); - g_pFontTextureResource = pTexture; - } - - // Store our identifier - static_assert(sizeof(ImTextureID) >= sizeof(g_hFontSrvGpuDescHandle.ptr), - "Can't pack descriptor handle into TexID, 32-bit not supported yet."); - io.Fonts->TexID = (ImTextureID)g_hFontSrvGpuDescHandle.ptr; -} - -bool ImGui_ImplDX12_CreateDeviceObjects() -{ - if (!g_pd3dDevice) - return false; - if (g_pPipelineState) - ImGui_ImplDX12_InvalidateDeviceObjects(); - - // Create the root signature - { - D3D12_DESCRIPTOR_RANGE descRange = {}; - descRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; - descRange.NumDescriptors = 1; - descRange.BaseShaderRegister = 0; - descRange.RegisterSpace = 0; - descRange.OffsetInDescriptorsFromTableStart = 0; - - D3D12_ROOT_PARAMETER param[2] = {}; - - param[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; - param[0].Constants.ShaderRegister = 0; - param[0].Constants.RegisterSpace = 0; - param[0].Constants.Num32BitValues = 16; - param[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; - - param[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - param[1].DescriptorTable.NumDescriptorRanges = 1; - param[1].DescriptorTable.pDescriptorRanges = &descRange; - param[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; - - D3D12_STATIC_SAMPLER_DESC staticSampler = {}; - staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; - staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - staticSampler.MipLODBias = 0.f; - staticSampler.MaxAnisotropy = 0; - staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; - staticSampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK; - staticSampler.MinLOD = 0.f; - staticSampler.MaxLOD = 0.f; - staticSampler.ShaderRegister = 0; - staticSampler.RegisterSpace = 0; - staticSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; - - D3D12_ROOT_SIGNATURE_DESC desc = {}; - desc.NumParameters = _countof(param); - desc.pParameters = param; - desc.NumStaticSamplers = 1; - desc.pStaticSamplers = &staticSampler; - desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | - D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | - D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | - D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS; - - ID3DBlob *blob = NULL; - if (D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, NULL) != S_OK) - return false; - - g_pd3dDevice->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), - IID_PPV_ARGS(&g_pRootSignature)); - blob->Release(); - } - - // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a - // given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) If you would like to use this - // DX12 sample code but remove this dependency you can: - // 1) compile once, save the compiled shader blobs into a file or source code and pass them to - // CreateVertexShader()/CreatePixelShader() [preferred solution] 2) use code to detect any - // version of the DLL and grab a pointer to D3DCompile from the DLL. - // See https://github.com/ocornut/imgui/pull/638 for sources and details. - - D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc; - memset(&psoDesc, 0, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC)); - psoDesc.NodeMask = 1; - psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - psoDesc.pRootSignature = g_pRootSignature; - psoDesc.SampleMask = UINT_MAX; - psoDesc.NumRenderTargets = 1; - psoDesc.RTVFormats[0] = g_RTVFormat; - psoDesc.SampleDesc.Count = 1; - psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; - - // Create the vertex shader - { - static const char *vertexShader = - "cbuffer vertexBuffer : register(b0) \ - {\ - float4x4 ProjectionMatrix; \ - };\ - struct VS_INPUT\ - {\ - float2 pos : POSITION;\ - float4 col : COLOR0;\ - float2 uv : TEXCOORD0;\ - };\ - \ - struct PS_INPUT\ - {\ - float4 pos : SV_POSITION;\ - float4 col : COLOR0;\ - float2 uv : TEXCOORD0;\ - };\ - \ - PS_INPUT main(VS_INPUT input)\ - {\ - PS_INPUT output;\ - output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ - output.col = input.col;\ - output.uv = input.uv;\ - return output;\ - }"; - - D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, - &g_pVertexShaderBlob, NULL); - if (g_pVertexShaderBlob == - NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const - // char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! - return false; - psoDesc.VS = {g_pVertexShaderBlob->GetBufferPointer(), - g_pVertexShaderBlob->GetBufferSize()}; - - // Create the input layout - static D3D12_INPUT_ELEMENT_DESC local_layout[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, IM_OFFSETOF(ImDrawVert, pos), - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, IM_OFFSETOF(ImDrawVert, uv), - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, IM_OFFSETOF(ImDrawVert, col), - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - }; - psoDesc.InputLayout = {local_layout, 3}; - } - - // Create the pixel shader - { - static const char *pixelShader = - "struct PS_INPUT\ - {\ - float4 pos : SV_POSITION;\ - float4 col : COLOR0;\ - float2 uv : TEXCOORD0;\ - };\ - SamplerState sampler0 : register(s0);\ - Texture2D texture0 : register(t0);\ - \ - float4 main(PS_INPUT input) : SV_Target\ - {\ - float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ - return out_col; \ - }"; - - D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, - &g_pPixelShaderBlob, NULL); - if (g_pPixelShaderBlob == - NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const - // char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! - return false; - psoDesc.PS = {g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize()}; - } - - // Create the blending setup - { - D3D12_BLEND_DESC &desc = psoDesc.BlendState; - desc.AlphaToCoverageEnable = false; - desc.RenderTarget[0].BlendEnable = true; - desc.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; - desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; - desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO; - desc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; - desc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; - } - - // Create the rasterizer state - { - D3D12_RASTERIZER_DESC &desc = psoDesc.RasterizerState; - desc.FillMode = D3D12_FILL_MODE_SOLID; - desc.CullMode = D3D12_CULL_MODE_NONE; - desc.FrontCounterClockwise = FALSE; - desc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; - desc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; - desc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; - desc.DepthClipEnable = true; - desc.MultisampleEnable = FALSE; - desc.AntialiasedLineEnable = FALSE; - desc.ForcedSampleCount = 0; - desc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; - } - - // Create depth-stencil State - { - D3D12_DEPTH_STENCIL_DESC &desc = psoDesc.DepthStencilState; - desc.DepthEnable = false; - desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; - desc.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS; - desc.StencilEnable = false; - desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = - desc.FrontFace.StencilPassOp = D3D12_STENCIL_OP_KEEP; - desc.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS; - desc.BackFace = desc.FrontFace; - } - - if (g_pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&g_pPipelineState)) != - S_OK) - return false; - - ImGui_ImplDX12_CreateFontsTexture(); - - return true; -} - -void ImGui_ImplDX12_InvalidateDeviceObjects() -{ - if (!g_pd3dDevice) - return; - - ImGuiIO &io = ImGui::GetIO(); - if (g_pVertexShaderBlob) - { - g_pVertexShaderBlob->Release(); - g_pVertexShaderBlob = NULL; - } - if (g_pPixelShaderBlob) - { - g_pPixelShaderBlob->Release(); - g_pPixelShaderBlob = NULL; - } - if (g_pRootSignature) - { - g_pRootSignature->Release(); - g_pRootSignature = NULL; - } - if (g_pPipelineState) - { - g_pPipelineState->Release(); - g_pPipelineState = NULL; - } - if (g_pFontTextureResource) - { - g_pFontTextureResource->Release(); - g_pFontTextureResource = NULL; - io.Fonts->TexID = NULL; - } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. - for (UINT i = 0; i < g_numFramesInFlight; i++) - { - FrameResources *fr = &g_pFrameResources[i]; - if (fr->IndexBuffer) - { - fr->IndexBuffer->Release(); - fr->IndexBuffer = NULL; - } - if (fr->VertexBuffer) - { - fr->VertexBuffer->Release(); - fr->VertexBuffer = NULL; - } - } -} - -bool ImGui_ImplDX12_Init(ID3D12Device *device, - int num_frames_in_flight, - DXGI_FORMAT rtv_format, - D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, - D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle) -{ - // Setup back-end capabilities flags - ImGuiIO &io = ImGui::GetIO(); - io.BackendRendererName = "imgui_impl_dx12"; - io.BackendFlags |= - ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, - // allowing for large meshes. - - g_pd3dDevice = device; - g_RTVFormat = rtv_format; - g_hFontSrvCpuDescHandle = font_srv_cpu_desc_handle; - g_hFontSrvGpuDescHandle = font_srv_gpu_desc_handle; - g_pFrameResources = new FrameResources[num_frames_in_flight]; - g_numFramesInFlight = num_frames_in_flight; - g_frameIndex = UINT_MAX; - - // Create buffers with a default size (they will later be grown as needed) - for (int i = 0; i < num_frames_in_flight; i++) - { - FrameResources *fr = &g_pFrameResources[i]; - fr->IndexBuffer = NULL; - fr->VertexBuffer = NULL; - fr->IndexBufferSize = 10000; - fr->VertexBufferSize = 5000; - } - - return true; -} - -void ImGui_ImplDX12_Shutdown() -{ - ImGui_ImplDX12_InvalidateDeviceObjects(); - delete[] g_pFrameResources; - g_pFrameResources = NULL; - g_pd3dDevice = NULL; - g_hFontSrvCpuDescHandle.ptr = 0; - g_hFontSrvGpuDescHandle.ptr = 0; - g_numFramesInFlight = 0; - g_frameIndex = UINT_MAX; -} - -void ImGui_ImplDX12_NewFrame() -{ - if (!g_pPipelineState) - ImGui_ImplDX12_CreateDeviceObjects(); -} +// dear imgui: Renderer for DirectX12 +// This needs to be used along with a Platform Binding (e.g. Win32) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the +// FAQ about ImTextureID in imgui.cpp. [X] Renderer: Support for large meshes (64k+ vertices) with +// 16-bits indices. +// Issues: +// [ ] 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*)). See +// github.com/ocornut/imgui/pull/301 + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example +// of using this. If you are new to dear imgui, read examples/README.txt and read the documentation +// at the top of imgui.cpp. https://github.com/ocornut/imgui + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2019-05-29: DirectX12: Added support for large mesh (64K+ vertices), enable +// ImGuiBackendFlags_RendererHasVtxOffset flag. 2019-04-30: DirectX12: Added support for special +// ImDrawCallback_ResetRenderState callback to reset render state. 2019-03-29: Misc: Various minor +// tidying up. 2018-12-03: Misc: Added #pragma comment statement to automatically link with +// d3dcompiler.lib when using D3DCompile(). 2018-11-30: Misc: Setting up io.BackendRendererName so +// it can be displayed in the About Window. 2018-06-12: DirectX12: Moved the +// ID3D12GraphicsCommandList* parameter from NewFrame() to RenderDrawData(). 2018-06-08: Misc: +// Extracted imgui_impl_dx12.cpp/.h away from the old combined DX12+Win32 example. 2018-06-08: +// DirectX12: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and +// clipping rectangle (to ease support for future multi-viewport). 2018-02-22: Merged into master +// with all Win32 code synchronized to other examples. + +#include "imgui_impl_dx12.h" +#include "imgui.h" + +// DirectX +#include +#include +#include +#ifdef _MSC_VER +#pragma comment( \ + lib, \ + "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below. +#endif + +// DirectX data +static ID3D12Device *g_pd3dDevice = NULL; +static ID3D10Blob *g_pVertexShaderBlob = NULL; +static ID3D10Blob *g_pPixelShaderBlob = NULL; +static ID3D12RootSignature *g_pRootSignature = NULL; +static ID3D12PipelineState *g_pPipelineState = NULL; +static DXGI_FORMAT g_RTVFormat = DXGI_FORMAT_UNKNOWN; +static ID3D12Resource *g_pFontTextureResource = NULL; +static D3D12_CPU_DESCRIPTOR_HANDLE g_hFontSrvCpuDescHandle = {}; +static D3D12_GPU_DESCRIPTOR_HANDLE g_hFontSrvGpuDescHandle = {}; + +struct FrameResources +{ + ID3D12Resource *IndexBuffer; + ID3D12Resource *VertexBuffer; + int IndexBufferSize; + int VertexBufferSize; +}; +static FrameResources *g_pFrameResources = NULL; +static UINT g_numFramesInFlight = 0; +static UINT g_frameIndex = UINT_MAX; + +struct VERTEX_CONSTANT_BUFFER +{ + float mvp[4][4]; +}; + +static void ImGui_ImplDX12_SetupRenderState(ImDrawData *draw_data, + ID3D12GraphicsCommandList *ctx, + FrameResources *fr) +{ + // Setup orthographic projection matrix into our constant buffer + // Our visible imgui space lies from draw_data->DisplayPos (top left) to + // draw_data->DisplayPos+data_data->DisplaySize (bottom right). + VERTEX_CONSTANT_BUFFER vertex_constant_buffer; + { + float L = draw_data->DisplayPos.x; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; + float T = draw_data->DisplayPos.y; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; + float mvp[4][4] = { + {2.0f / (R - L), 0.0f, 0.0f, 0.0f}, + {0.0f, 2.0f / (T - B), 0.0f, 0.0f}, + {0.0f, 0.0f, 0.5f, 0.0f}, + {(R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f}, + }; + memcpy(&vertex_constant_buffer.mvp, mvp, sizeof(mvp)); + } + + // Setup viewport + D3D12_VIEWPORT vp; + memset(&vp, 0, sizeof(D3D12_VIEWPORT)); + vp.Width = draw_data->DisplaySize.x; + vp.Height = draw_data->DisplaySize.y; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + vp.TopLeftX = vp.TopLeftY = 0.0f; + ctx->RSSetViewports(1, &vp); + + // Bind shader and vertex buffers + unsigned int stride = sizeof(ImDrawVert); + unsigned int offset = 0; + D3D12_VERTEX_BUFFER_VIEW vbv; + memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW)); + vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset; + vbv.SizeInBytes = fr->VertexBufferSize * stride; + vbv.StrideInBytes = stride; + ctx->IASetVertexBuffers(0, 1, &vbv); + D3D12_INDEX_BUFFER_VIEW ibv; + memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW)); + ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress(); + ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx); + ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; + ctx->IASetIndexBuffer(&ibv); + ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ctx->SetPipelineState(g_pPipelineState); + ctx->SetGraphicsRootSignature(g_pRootSignature); + ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0); + + // Setup blend factor + const float blend_factor[4] = {0.f, 0.f, 0.f, 0.f}; + ctx->OMSetBlendFactor(blend_factor); +} + +// Render function +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call +// this directly from your main loop) +void ImGui_ImplDX12_RenderDrawData(ImDrawData *draw_data, ID3D12GraphicsCommandList *ctx) +{ + // Avoid rendering when minimized + if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) + return; + + // FIXME: I'm assuming that this only gets called once per frame! + // If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator. + g_frameIndex = g_frameIndex + 1; + FrameResources *fr = &g_pFrameResources[g_frameIndex % g_numFramesInFlight]; + + // Create and grow vertex/index buffers if needed + if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount) + { + if (fr->VertexBuffer != NULL) + { + fr->VertexBuffer->Release(); + fr->VertexBuffer = NULL; + } + fr->VertexBufferSize = draw_data->TotalVtxCount + 5000; + D3D12_HEAP_PROPERTIES props; + memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); + props.Type = D3D12_HEAP_TYPE_UPLOAD; + props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + D3D12_RESOURCE_DESC desc; + memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC)); + desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + desc.Width = fr->VertexBufferSize * sizeof(ImDrawVert); + desc.Height = 1; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.SampleDesc.Count = 1; + desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, + D3D12_RESOURCE_STATE_GENERIC_READ, NULL, + IID_PPV_ARGS(&fr->VertexBuffer)) < 0) + return; + } + if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount) + { + if (fr->IndexBuffer != NULL) + { + fr->IndexBuffer->Release(); + fr->IndexBuffer = NULL; + } + fr->IndexBufferSize = draw_data->TotalIdxCount + 10000; + D3D12_HEAP_PROPERTIES props; + memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); + props.Type = D3D12_HEAP_TYPE_UPLOAD; + props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + D3D12_RESOURCE_DESC desc; + memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC)); + desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + desc.Width = fr->IndexBufferSize * sizeof(ImDrawIdx); + desc.Height = 1; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.SampleDesc.Count = 1; + desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, + D3D12_RESOURCE_STATE_GENERIC_READ, NULL, + IID_PPV_ARGS(&fr->IndexBuffer)) < 0) + return; + } + + // Upload vertex/index data into a single contiguous GPU buffer + void *vtx_resource, *idx_resource; + D3D12_RANGE range; + memset(&range, 0, sizeof(D3D12_RANGE)); + if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK) + return; + if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK) + return; + ImDrawVert *vtx_dst = (ImDrawVert *)vtx_resource; + ImDrawIdx *idx_dst = (ImDrawIdx *)idx_resource; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList *cmd_list = draw_data->CmdLists[n]; + memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); + memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + vtx_dst += cmd_list->VtxBuffer.Size; + idx_dst += cmd_list->IdxBuffer.Size; + } + fr->VertexBuffer->Unmap(0, &range); + fr->IndexBuffer->Unmap(0, &range); + + // Setup desired DX state + ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr); + + // Render command lists + // (Because we merged all buffers into a single one, we maintain our own offset into them) + int global_vtx_offset = 0; + int global_idx_offset = 0; + ImVec2 clip_off = draw_data->DisplayPos; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList *cmd_list = draw_data->CmdLists[n]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd *pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != NULL) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to + // request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Apply Scissor, Bind texture, Draw + const D3D12_RECT r = { + (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), + (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y)}; + ctx->SetGraphicsRootDescriptorTable( + 1, *(D3D12_GPU_DESCRIPTOR_HANDLE *)&pcmd->TextureId); + ctx->RSSetScissorRects(1, &r); + ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, + pcmd->VtxOffset + global_vtx_offset, 0); + } + } + global_idx_offset += cmd_list->IdxBuffer.Size; + global_vtx_offset += cmd_list->VtxBuffer.Size; + } +} + +static void ImGui_ImplDX12_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO &io = ImGui::GetIO(); + unsigned char *pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + // Upload texture to graphics system + { + D3D12_HEAP_PROPERTIES props; + memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); + props.Type = D3D12_HEAP_TYPE_DEFAULT; + props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + D3D12_RESOURCE_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + desc.Alignment = 0; + desc.Width = width; + desc.Height = height; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + + ID3D12Resource *pTexture = NULL; + g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, + D3D12_RESOURCE_STATE_COPY_DEST, NULL, + IID_PPV_ARGS(&pTexture)); + + UINT uploadPitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & + ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u); + UINT uploadSize = height * uploadPitch; + desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + desc.Alignment = 0; + desc.Width = uploadSize; + desc.Height = 1; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + + props.Type = D3D12_HEAP_TYPE_UPLOAD; + props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + ID3D12Resource *uploadBuffer = NULL; + HRESULT hr = g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, + D3D12_RESOURCE_STATE_GENERIC_READ, NULL, + IID_PPV_ARGS(&uploadBuffer)); + IM_ASSERT(SUCCEEDED(hr)); + + void *mapped = NULL; + D3D12_RANGE range = {0, uploadSize}; + hr = uploadBuffer->Map(0, &range, &mapped); + IM_ASSERT(SUCCEEDED(hr)); + for (int y = 0; y < height; y++) + memcpy((void *)((uintptr_t)mapped + y * uploadPitch), pixels + y * width * 4, + width * 4); + uploadBuffer->Unmap(0, &range); + + D3D12_TEXTURE_COPY_LOCATION srcLocation = {}; + srcLocation.pResource = uploadBuffer; + srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srcLocation.PlacedFootprint.Footprint.Width = width; + srcLocation.PlacedFootprint.Footprint.Height = height; + srcLocation.PlacedFootprint.Footprint.Depth = 1; + srcLocation.PlacedFootprint.Footprint.RowPitch = uploadPitch; + + D3D12_TEXTURE_COPY_LOCATION dstLocation = {}; + dstLocation.pResource = pTexture; + dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstLocation.SubresourceIndex = 0; + + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = pTexture; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + + ID3D12Fence *fence = NULL; + hr = g_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); + IM_ASSERT(SUCCEEDED(hr)); + + HANDLE event = CreateEvent(0, 0, 0, 0); + IM_ASSERT(event != NULL); + + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.NodeMask = 1; + + ID3D12CommandQueue *cmdQueue = NULL; + hr = g_pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue)); + IM_ASSERT(SUCCEEDED(hr)); + + ID3D12CommandAllocator *cmdAlloc = NULL; + hr = g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, + IID_PPV_ARGS(&cmdAlloc)); + IM_ASSERT(SUCCEEDED(hr)); + + ID3D12GraphicsCommandList *cmdList = NULL; + hr = g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, NULL, + IID_PPV_ARGS(&cmdList)); + IM_ASSERT(SUCCEEDED(hr)); + + cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, NULL); + cmdList->ResourceBarrier(1, &barrier); + + hr = cmdList->Close(); + IM_ASSERT(SUCCEEDED(hr)); + + cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList *const *)&cmdList); + hr = cmdQueue->Signal(fence, 1); + IM_ASSERT(SUCCEEDED(hr)); + + fence->SetEventOnCompletion(1, event); + WaitForSingleObject(event, INFINITE); + + cmdList->Release(); + cmdAlloc->Release(); + cmdQueue->Release(); + CloseHandle(event); + fence->Release(); + uploadBuffer->Release(); + + // Create texture view + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc; + ZeroMemory(&srvDesc, sizeof(srvDesc)); + srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = desc.MipLevels; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, g_hFontSrvCpuDescHandle); + if (g_pFontTextureResource != NULL) + g_pFontTextureResource->Release(); + g_pFontTextureResource = pTexture; + } + + // Store our identifier + static_assert(sizeof(ImTextureID) >= sizeof(g_hFontSrvGpuDescHandle.ptr), + "Can't pack descriptor handle into TexID, 32-bit not supported yet."); + io.Fonts->TexID = (ImTextureID)g_hFontSrvGpuDescHandle.ptr; +} + +bool ImGui_ImplDX12_CreateDeviceObjects() +{ + if (!g_pd3dDevice) + return false; + if (g_pPipelineState) + ImGui_ImplDX12_InvalidateDeviceObjects(); + + // Create the root signature + { + D3D12_DESCRIPTOR_RANGE descRange = {}; + descRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + descRange.NumDescriptors = 1; + descRange.BaseShaderRegister = 0; + descRange.RegisterSpace = 0; + descRange.OffsetInDescriptorsFromTableStart = 0; + + D3D12_ROOT_PARAMETER param[2] = {}; + + param[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + param[0].Constants.ShaderRegister = 0; + param[0].Constants.RegisterSpace = 0; + param[0].Constants.Num32BitValues = 16; + param[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; + + param[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + param[1].DescriptorTable.NumDescriptorRanges = 1; + param[1].DescriptorTable.pDescriptorRanges = &descRange; + param[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + + D3D12_STATIC_SAMPLER_DESC staticSampler = {}; + staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; + staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + staticSampler.MipLODBias = 0.f; + staticSampler.MaxAnisotropy = 0; + staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; + staticSampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK; + staticSampler.MinLOD = 0.f; + staticSampler.MaxLOD = 0.f; + staticSampler.ShaderRegister = 0; + staticSampler.RegisterSpace = 0; + staticSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + + D3D12_ROOT_SIGNATURE_DESC desc = {}; + desc.NumParameters = _countof(param); + desc.pParameters = param; + desc.NumStaticSamplers = 1; + desc.pStaticSamplers = &staticSampler; + desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | + D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS; + + ID3DBlob *blob = NULL; + if (D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, NULL) != S_OK) + return false; + + g_pd3dDevice->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), + IID_PPV_ARGS(&g_pRootSignature)); + blob->Release(); + } + + // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a + // given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) If you would like to use this + // DX12 sample code but remove this dependency you can: + // 1) compile once, save the compiled shader blobs into a file or source code and pass them to + // CreateVertexShader()/CreatePixelShader() [preferred solution] 2) use code to detect any + // version of the DLL and grab a pointer to D3DCompile from the DLL. + // See https://github.com/ocornut/imgui/pull/638 for sources and details. + + D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc; + memset(&psoDesc, 0, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC)); + psoDesc.NodeMask = 1; + psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + psoDesc.pRootSignature = g_pRootSignature; + psoDesc.SampleMask = UINT_MAX; + psoDesc.NumRenderTargets = 1; + psoDesc.RTVFormats[0] = g_RTVFormat; + psoDesc.SampleDesc.Count = 1; + psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + + // Create the vertex shader + { + static const char *vertexShader = + "cbuffer vertexBuffer : register(b0) \ + {\ + float4x4 ProjectionMatrix; \ + };\ + struct VS_INPUT\ + {\ + float2 pos : POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + PS_INPUT main(VS_INPUT input)\ + {\ + PS_INPUT output;\ + output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ + output.col = input.col;\ + output.uv = input.uv;\ + return output;\ + }"; + + D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, + &g_pVertexShaderBlob, NULL); + if (g_pVertexShaderBlob == + NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const + // char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + return false; + psoDesc.VS = {g_pVertexShaderBlob->GetBufferPointer(), + g_pVertexShaderBlob->GetBufferSize()}; + + // Create the input layout + static D3D12_INPUT_ELEMENT_DESC local_layout[] = { + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, IM_OFFSETOF(ImDrawVert, pos), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, IM_OFFSETOF(ImDrawVert, uv), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, IM_OFFSETOF(ImDrawVert, col), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, + }; + psoDesc.InputLayout = {local_layout, 3}; + } + + // Create the pixel shader + { + static const char *pixelShader = + "struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + SamplerState sampler0 : register(s0);\ + Texture2D texture0 : register(t0);\ + \ + float4 main(PS_INPUT input) : SV_Target\ + {\ + float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ + return out_col; \ + }"; + + D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, + &g_pPixelShaderBlob, NULL); + if (g_pPixelShaderBlob == + NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const + // char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + return false; + psoDesc.PS = {g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize()}; + } + + // Create the blending setup + { + D3D12_BLEND_DESC &desc = psoDesc.BlendState; + desc.AlphaToCoverageEnable = false; + desc.RenderTarget[0].BlendEnable = true; + desc.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; + desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; + desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO; + desc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; + desc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + } + + // Create the rasterizer state + { + D3D12_RASTERIZER_DESC &desc = psoDesc.RasterizerState; + desc.FillMode = D3D12_FILL_MODE_SOLID; + desc.CullMode = D3D12_CULL_MODE_NONE; + desc.FrontCounterClockwise = FALSE; + desc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + desc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + desc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + desc.DepthClipEnable = true; + desc.MultisampleEnable = FALSE; + desc.AntialiasedLineEnable = FALSE; + desc.ForcedSampleCount = 0; + desc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + } + + // Create depth-stencil State + { + D3D12_DEPTH_STENCIL_DESC &desc = psoDesc.DepthStencilState; + desc.DepthEnable = false; + desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + desc.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS; + desc.StencilEnable = false; + desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = + desc.FrontFace.StencilPassOp = D3D12_STENCIL_OP_KEEP; + desc.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS; + desc.BackFace = desc.FrontFace; + } + + if (g_pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&g_pPipelineState)) != + S_OK) + return false; + + ImGui_ImplDX12_CreateFontsTexture(); + + return true; +} + +void ImGui_ImplDX12_InvalidateDeviceObjects() +{ + if (!g_pd3dDevice) + return; + + ImGuiIO &io = ImGui::GetIO(); + if (g_pVertexShaderBlob) + { + g_pVertexShaderBlob->Release(); + g_pVertexShaderBlob = NULL; + } + if (g_pPixelShaderBlob) + { + g_pPixelShaderBlob->Release(); + g_pPixelShaderBlob = NULL; + } + if (g_pRootSignature) + { + g_pRootSignature->Release(); + g_pRootSignature = NULL; + } + if (g_pPipelineState) + { + g_pPipelineState->Release(); + g_pPipelineState = NULL; + } + if (g_pFontTextureResource) + { + g_pFontTextureResource->Release(); + g_pFontTextureResource = NULL; + io.Fonts->TexID = NULL; + } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. + for (UINT i = 0; i < g_numFramesInFlight; i++) + { + FrameResources *fr = &g_pFrameResources[i]; + if (fr->IndexBuffer) + { + fr->IndexBuffer->Release(); + fr->IndexBuffer = NULL; + } + if (fr->VertexBuffer) + { + fr->VertexBuffer->Release(); + fr->VertexBuffer = NULL; + } + } +} + +bool ImGui_ImplDX12_Init(ID3D12Device *device, + int num_frames_in_flight, + DXGI_FORMAT rtv_format, + D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, + D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle) +{ + // Setup back-end capabilities flags + ImGuiIO &io = ImGui::GetIO(); + io.BackendRendererName = "imgui_impl_dx12"; + io.BackendFlags |= + ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, + // allowing for large meshes. + + g_pd3dDevice = device; + g_RTVFormat = rtv_format; + g_hFontSrvCpuDescHandle = font_srv_cpu_desc_handle; + g_hFontSrvGpuDescHandle = font_srv_gpu_desc_handle; + g_pFrameResources = new FrameResources[num_frames_in_flight]; + g_numFramesInFlight = num_frames_in_flight; + g_frameIndex = UINT_MAX; + + // Create buffers with a default size (they will later be grown as needed) + for (int i = 0; i < num_frames_in_flight; i++) + { + FrameResources *fr = &g_pFrameResources[i]; + fr->IndexBuffer = NULL; + fr->VertexBuffer = NULL; + fr->IndexBufferSize = 10000; + fr->VertexBufferSize = 5000; + } + + return true; +} + +void ImGui_ImplDX12_Shutdown() +{ + ImGui_ImplDX12_InvalidateDeviceObjects(); + delete[] g_pFrameResources; + g_pFrameResources = NULL; + g_pd3dDevice = NULL; + g_hFontSrvCpuDescHandle.ptr = 0; + g_hFontSrvGpuDescHandle.ptr = 0; + g_numFramesInFlight = 0; + g_frameIndex = UINT_MAX; +} + +void ImGui_ImplDX12_NewFrame() +{ + if (!g_pPipelineState) + ImGui_ImplDX12_CreateDeviceObjects(); +} diff --git a/src/aquarium-optimized/d3d12/imgui_impl_dx12.h b/src/aquarium-optimized/d3d12/imgui_impl_dx12.h index e672158..6050dbc 100644 --- a/src/aquarium-optimized/d3d12/imgui_impl_dx12.h +++ b/src/aquarium-optimized/d3d12/imgui_impl_dx12.h @@ -1,44 +1,44 @@ -// dear imgui: Renderer for DirectX12 -// This needs to be used along with a Platform Binding (e.g. Win32) - -// Implemented features: -// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the -// FAQ about ImTextureID in imgui.cpp. [X] Renderer: Support for large meshes (64k+ vertices) with -// 16-bits indices. -// Issues: -// [ ] 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*)). See -// github.com/ocornut/imgui/pull/301 - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example -// of using this. If you are new to dear imgui, read examples/README.txt and read the documentation -// at the top of imgui.cpp. https://github.com/ocornut/imgui - -#pragma once - -#include "imgui.h" - -enum DXGI_FORMAT; -struct ID3D12Device; -struct ID3D12GraphicsCommandList; -struct D3D12_CPU_DESCRIPTOR_HANDLE; -struct D3D12_GPU_DESCRIPTOR_HANDLE; - -// cmd_list is the command list that the implementation will use to render imgui draw lists. -// Before calling the render function, caller must prepare cmd_list by resetting it and setting the -// appropriate render target and descriptor heap that contains -// font_srv_cpu_desc_handle/font_srv_gpu_desc_handle. font_srv_cpu_desc_handle and -// font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font -// texture. -IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device *device, - int num_frames_in_flight, - DXGI_FORMAT rtv_format, - D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, - D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle); -IMGUI_IMPL_API void ImGui_ImplDX12_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame(); -IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData *draw_data, - ID3D12GraphicsCommandList *graphics_command_list); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects(); -IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects(); +// dear imgui: Renderer for DirectX12 +// This needs to be used along with a Platform Binding (e.g. Win32) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the +// FAQ about ImTextureID in imgui.cpp. [X] Renderer: Support for large meshes (64k+ vertices) with +// 16-bits indices. +// Issues: +// [ ] 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*)). See +// github.com/ocornut/imgui/pull/301 + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example +// of using this. If you are new to dear imgui, read examples/README.txt and read the documentation +// at the top of imgui.cpp. https://github.com/ocornut/imgui + +#pragma once + +#include "imgui.h" + +enum DXGI_FORMAT; +struct ID3D12Device; +struct ID3D12GraphicsCommandList; +struct D3D12_CPU_DESCRIPTOR_HANDLE; +struct D3D12_GPU_DESCRIPTOR_HANDLE; + +// cmd_list is the command list that the implementation will use to render imgui draw lists. +// Before calling the render function, caller must prepare cmd_list by resetting it and setting the +// appropriate render target and descriptor heap that contains +// font_srv_cpu_desc_handle/font_srv_gpu_desc_handle. font_srv_cpu_desc_handle and +// font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font +// texture. +IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device *device, + int num_frames_in_flight, + DXGI_FORMAT rtv_format, + D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, + D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle); +IMGUI_IMPL_API void ImGui_ImplDX12_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData *draw_data, + ID3D12GraphicsCommandList *graphics_command_list); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects(); +IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects(); diff --git a/src/aquarium-optimized/dawn/BufferDawn.cpp b/src/aquarium-optimized/dawn/BufferDawn.cpp index 236ee9f..53056e2 100644 --- a/src/aquarium-optimized/dawn/BufferDawn.cpp +++ b/src/aquarium-optimized/dawn/BufferDawn.cpp @@ -1,60 +1,61 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// BufferDawn.cpp: Implements the index or vertex buffers wrappers and resource bindings of dawn. - -#include "BufferDawn.h" -#include "ContextDawn.h" - -// Copy size must be a multiple of 4 bytes on dawn mac backend. -BufferDawn::BufferDawn(ContextDawn *context, - int totalCmoponents, - int numComponents, - std::vector *buffer, - bool isIndex) - : mUsageBit(isIndex ? dawn::BufferUsageBit::Index : dawn::BufferUsageBit::Vertex), - mTotoalComponents(totalCmoponents), - mStride(0), - mOffset(nullptr) -{ - mSize = numComponents * sizeof(float); - if (mTotoalComponents % 4 != 0) - { - int dummyCount = 4 - mTotoalComponents % 4; - for (int i = 0; i < dummyCount; i++) - { - buffer->push_back(0.0f); - } - } - mBuf = context->createBufferFromData(buffer->data(), sizeof(float) * static_cast(buffer->size()), mUsageBit); -} - -BufferDawn::BufferDawn(ContextDawn *context, - int totalCmoponents, - int numComponents, - std::vector *buffer, - bool isIndex) - : mUsageBit(isIndex ? dawn::BufferUsageBit::Index : dawn::BufferUsageBit::Vertex), - mTotoalComponents(totalCmoponents), - mStride(0), - mOffset(nullptr) -{ - mSize = numComponents * sizeof(unsigned short); - if (mTotoalComponents % 4 != 0) - { - int dummyCount = 4 - mTotoalComponents % 4; - for (int i = 0; i < dummyCount; i++) - { - buffer->push_back(0.0f); - } - } - mBuf = context->createBufferFromData( - buffer->data(), sizeof(unsigned short) * static_cast(buffer->size()), mUsageBit); -} - -BufferDawn::~BufferDawn() -{ - mBuf = nullptr; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// BufferDawn.cpp: Implements the index or vertex buffers wrappers and resource bindings of dawn. + +#include "BufferDawn.h" +#include "ContextDawn.h" + +// Copy size must be a multiple of 4 bytes on dawn mac backend. +BufferDawn::BufferDawn(ContextDawn *context, + int totalCmoponents, + int numComponents, + std::vector *buffer, + bool isIndex) + : mUsageBit(isIndex ? dawn::BufferUsageBit::Index : dawn::BufferUsageBit::Vertex), + mTotoalComponents(totalCmoponents), + mStride(0), + mOffset(nullptr) +{ + mSize = numComponents * sizeof(float); + if (mTotoalComponents % 4 != 0) + { + int dummyCount = 4 - mTotoalComponents % 4; + for (int i = 0; i < dummyCount; i++) + { + buffer->push_back(0.0f); + } + } + mBuf = context->createBufferFromData( + buffer->data(), sizeof(float) * static_cast(buffer->size()), mUsageBit); +} + +BufferDawn::BufferDawn(ContextDawn *context, + int totalCmoponents, + int numComponents, + std::vector *buffer, + bool isIndex) + : mUsageBit(isIndex ? dawn::BufferUsageBit::Index : dawn::BufferUsageBit::Vertex), + mTotoalComponents(totalCmoponents), + mStride(0), + mOffset(nullptr) +{ + mSize = numComponents * sizeof(unsigned short); + if (mTotoalComponents % 4 != 0) + { + int dummyCount = 4 - mTotoalComponents % 4; + for (int i = 0; i < dummyCount; i++) + { + buffer->push_back(0.0f); + } + } + mBuf = context->createBufferFromData( + buffer->data(), sizeof(unsigned short) * static_cast(buffer->size()), mUsageBit); +} + +BufferDawn::~BufferDawn() +{ + mBuf = nullptr; +} diff --git a/src/aquarium-optimized/dawn/BufferDawn.h b/src/aquarium-optimized/dawn/BufferDawn.h index 080d23d..ff18f96 100644 --- a/src/aquarium-optimized/dawn/BufferDawn.h +++ b/src/aquarium-optimized/dawn/BufferDawn.h @@ -1,52 +1,51 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// BufferDawn.h: Defines the buffer wrapper of dawn, abstracting the vetex and index buffer binding. - -#pragma once -#ifndef BUFFERDAWN_H -#define BUFFERDAWN_H 1 - -#include -#include - -#include "../Buffer.h" - -class ContextDawn; - -class BufferDawn : public Buffer -{ - public: - BufferDawn(ContextDawn *context, - int totalCmoponents, - int numComponents, - std::vector *buffer, - bool isIndex); - BufferDawn(ContextDawn *context, - int totalCmoponents, - int numComponents, - std::vector *buffer, - bool isIndex); - ~BufferDawn() override; - - const dawn::Buffer &getBuffer() const { return mBuf; } - int getTotalComponents() const { return mTotoalComponents; } - - uint32_t getStride() const { return mStride; } - const void *getOffset() const { return mOffset; } - dawn::BufferUsageBit getUsageBit() const { return mUsageBit; } - int getDataSize() { return mSize; } - - private: - dawn::Buffer mBuf; - dawn::BufferUsageBit mUsageBit; - int mTotoalComponents; - uint32_t mStride; - void *mOffset; - int mSize; -}; - -#endif - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// BufferDawn.h: Defines the buffer wrapper of dawn, abstracting the vetex and index buffer binding. + +#pragma once +#ifndef BUFFERDAWN_H +#define BUFFERDAWN_H 1 + +#include +#include + +#include "../Buffer.h" + +class ContextDawn; + +class BufferDawn : public Buffer +{ + public: + BufferDawn(ContextDawn *context, + int totalCmoponents, + int numComponents, + std::vector *buffer, + bool isIndex); + BufferDawn(ContextDawn *context, + int totalCmoponents, + int numComponents, + std::vector *buffer, + bool isIndex); + ~BufferDawn() override; + + const dawn::Buffer &getBuffer() const { return mBuf; } + int getTotalComponents() const { return mTotoalComponents; } + + uint32_t getStride() const { return mStride; } + const void *getOffset() const { return mOffset; } + dawn::BufferUsageBit getUsageBit() const { return mUsageBit; } + int getDataSize() { return mSize; } + + private: + dawn::Buffer mBuf; + dawn::BufferUsageBit mUsageBit; + int mTotoalComponents; + uint32_t mStride; + void *mOffset; + int mSize; +}; + +#endif diff --git a/src/aquarium-optimized/dawn/ContextDawn.cpp b/src/aquarium-optimized/dawn/ContextDawn.cpp index d96e81a..7b3abf4 100644 --- a/src/aquarium-optimized/dawn/ContextDawn.cpp +++ b/src/aquarium-optimized/dawn/ContextDawn.cpp @@ -1,704 +1,718 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// DeviceDawn.cpp: Implements accessing functions to the graphics API of Dawn. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "BufferDawn.h" -#include "ContextDawn.h" -#include "FishModelDawn.h" -#include "FishModelInstancedDrawDawn.h" -#include "GenericModelDawn.h" -#include "InnerModelDawn.h" -#include "OutsideModelDawn.h" -#include "ProgramDawn.h" -#include "SeaweedModelDawn.h" -#include "TextureDawn.h" - -#include "common/Constants.h" -#include "imgui.h" -#include "imgui_impl_dawn.h" -#include "imgui_impl_glfw.h" -#include "utils/BackendBinding.h" -#include "utils/ComboRenderPipelineDescriptor.h" - -#include "../Aquarium.h" - -ContextDawn::ContextDawn(BACKENDTYPE backendType) - : queue(nullptr), - mDevice(nullptr), - mWindow(nullptr), - mInstance(), - mSwapchain(nullptr), - mCommandEncoder(nullptr), - mRenderPass(nullptr), - mRenderPassDescriptor({}), - mBackbuffer(nullptr), - mSceneRenderTargetView(nullptr), - mSceneDepthStencilView(nullptr), - mPipeline(nullptr), - mBindGroup(nullptr), - mPreferredSwapChainFormat(dawn::TextureFormat::RGBA8Unorm), - mEnableMSAA(false) -{ - mResourceHelper = new ResourceHelper("dawn", ""); - initAvailableToggleBitset(backendType); -} - -ContextDawn::~ContextDawn() -{ - delete mResourceHelper; - if (mWindow != nullptr) - { - destoryImgUI(); - } - - mSceneRenderTargetView = nullptr; - mSceneDepthStencilView = nullptr; - mBackbuffer = nullptr; - mPipeline = nullptr; - mBindGroup = nullptr; - mLightWorldPositionBuffer = nullptr; - mLightBuffer = nullptr; - mFogBuffer = nullptr; - mCommandEncoder = nullptr; - mCommandBuffers.clear(); - mRenderPass = nullptr; - mRenderPassDescriptor = {}; - groupLayoutGeneral = nullptr; - bindGroupGeneral = nullptr; - groupLayoutWorld = nullptr; - bindGroupWorld = nullptr; - mSwapchain = nullptr; - queue = nullptr; - mDevice = nullptr; -} - -bool ContextDawn::initialize( - BACKENDTYPE backend, - const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) -{ - dawn_native::BackendType backendType = dawn_native::BackendType::Null; - - switch (backend) - { - case BACKENDTYPE::BACKENDTYPEDAWND3D12: - { - backendType = dawn_native::BackendType::D3D12; - mBackendType = "Dawn D3D12"; - break; - } - case BACKENDTYPE::BACKENDTYPEDAWNVULKAN: - { - backendType = dawn_native::BackendType::Vulkan; - mBackendType = "Dawn Vulkan"; - break; - } - case BACKENDTYPE::BACKENDTYPEDAWNMETAL: - { - backendType = dawn_native::BackendType::Metal; - mBackendType = "Dawn Metal"; - break; - } - case BACKENDTYPE::BACKENDTYPEOPENGL: - { - backendType = dawn_native::BackendType::OpenGL; - mBackendType = "Dawn OpenGL"; - break; - } - default: - { - std::cerr << "Backend type can not reached." << std::endl; - return false; - } - } - - mEnableMSAA = toggleBitset.test(static_cast(TOGGLE::ENABLEMSAAx4)); - - // initialise GLFW - if (!glfwInit()) - { - std::cout << "Failed to initialise GLFW" << std::endl; - return false; - } - - utils::SetupGLFWWindowHintsForBackend(backendType); - // set full screen - glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - - GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); - const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); - mClientWidth = mode->width; - mClientHeight = mode->height; - - if (toggleBitset.test(static_cast(TOGGLE::ENABLEFULLSCREENMODE))) - { - mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", pMonitor, nullptr); - } - else - { - mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", nullptr, nullptr); - } - - if (mWindow == nullptr) - { - std::cout << "Failed to open GLFW window." << std::endl; - glfwTerminate(); - return false; - } - - // Get the resolution of screen - glfwGetFramebufferSize(mWindow, &mClientWidth, &mClientHeight); - - mInstance = std::make_unique(); - utils::DiscoverAdapter(mInstance.get(), mWindow, backendType); - - dawn_native::Adapter backendAdapter; - if (!GetHardwareAdapter(mInstance, &backendAdapter, backendType, toggleBitset)) - { - return false; - } - - DawnDevice backendDevice = backendAdapter.CreateDevice(); - DawnProcTable backendProcs = dawn_native::GetProcs(); - - utils::BackendBinding *binding = utils::CreateBinding(backendType, mWindow, backendDevice); - if (binding == nullptr) - { - return false; - } - - dawnSetProcs(&backendProcs); - mDevice = dawn::Device::Acquire(backendDevice); - - queue = mDevice.CreateQueue(); - dawn::SwapChainDescriptor swapChainDesc; - swapChainDesc.implementation = binding->GetSwapChainImplementation(); - mSwapchain = mDevice.CreateSwapChain(&swapChainDesc); - - mPreferredSwapChainFormat = - static_cast(binding->GetPreferredSwapChainTextureFormat()); - mSwapchain.Configure(mPreferredSwapChainFormat, kSwapchainBackBufferUsageBit, mClientWidth, - mClientHeight); - - dawn_native::PCIInfo info = backendAdapter.GetPCIInfo(); - mRenderer = info.name; - std::cout << mRenderer << std::endl; - - // When MSAA is enabled, we create an intermediate multisampled texture to render the scene to. - if (mEnableMSAA) - { - mSceneRenderTargetView = createMultisampledRenderTargetView(); - } - - mSceneDepthStencilView = createDepthStencilView(); - - // TODO(jiawei.shao@intel.com): support recreating swapchain when window is resized on all - // backends - if (backend == BACKENDTYPE::BACKENDTYPEDAWNVULKAN) - { - glfwSetFramebufferSizeCallback(mWindow, framebufferResizeCallback); - glfwSetWindowUserPointer(mWindow, this); - } - - // Setup Dear ImGui context - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - - // Setup Dear ImGui style - ImGui::StyleColorsDark(); - - // Setup Platform/Renderer bindings - // We use glfw to create window for dawn backend as well. - // Because imgui doesn't have dawn backend, we rewrite the functions by dawn API in - // imgui_impl_dawn.cpp and imgui_impl_dawn.h - ImGui_ImplGlfw_InitForOpenGL(mWindow, true); - ImGui_ImplDawn_Init(this, mPreferredSwapChainFormat, mEnableMSAA); - - return true; -} - -void ContextDawn::framebufferResizeCallback(GLFWwindow *window, int width, int height) { - ContextDawn *contextDawn = reinterpret_cast(glfwGetWindowUserPointer(window)); - contextDawn->mIsSwapchainOutOfDate = true; -} - -bool ContextDawn::GetHardwareAdapter( - std::unique_ptr &instance, - dawn_native::Adapter *backendAdapter, - dawn_native::BackendType backendType, - const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) -{ - bool enableIntegratedGpu = toggleBitset.test(static_cast(TOGGLE::INTEGRATEDGPU)); - bool enableDiscreteGpu = toggleBitset.test(static_cast(TOGGLE::DISCRETEGPU)); - bool useDefaultGpu = (enableDiscreteGpu | enableIntegratedGpu) == false ? true : false; - bool result = false; - - // Get an adapter for the backend to use, and create the Device. - for (auto &adapter : instance->GetAdapters()) - { - if (adapter.GetBackendType() == backendType) - { - if (useDefaultGpu || - (enableDiscreteGpu && - adapter.GetDeviceType() == dawn_native::DeviceType::DiscreteGPU) || - (enableIntegratedGpu && - adapter.GetDeviceType() == dawn_native::DeviceType::IntegratedGPU)) - { - *backendAdapter = adapter; - result = true; - break; - } - } - } - - if (!result) - { - std::cerr << "Failed to create adapter." << std::endl; - return false; - } - - return true; -} - -void ContextDawn::initAvailableToggleBitset(BACKENDTYPE backendType) -{ - mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEMSAAx4)); - mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)); - // DBO on dawn is not supported yet - if (backendType != BACKENDTYPE::BACKENDTYPEDAWND3D12) - { - mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET)); - } - mAvailableToggleBitset.set(static_cast(TOGGLE::DISCRETEGPU)); - mAvailableToggleBitset.set(static_cast(TOGGLE::INTEGRATEDGPU)); - mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEFULLSCREENMODE)); -} - -Texture *ContextDawn::createTexture(const std::string &name, const std::string &url) -{ - Texture *texture = new TextureDawn(this, name, url); - texture->loadTexture(); - return texture; -} - -Texture *ContextDawn::createTexture(const std::string &name, const std::vector &urls) -{ - Texture *texture = new TextureDawn(this, name, urls); - texture->loadTexture(); - return texture; -} - -dawn::Texture ContextDawn::createTexture(const dawn::TextureDescriptor &descriptor) const -{ - return mDevice.CreateTexture(&descriptor); -} - -dawn::Sampler ContextDawn::createSampler(const dawn::SamplerDescriptor &descriptor) const -{ - return mDevice.CreateSampler(&descriptor); -} - -dawn::Buffer ContextDawn::createBufferFromData(const void *pixels, int size, dawn::BufferUsageBit usage) const -{ - return utils::CreateBufferFromData(mDevice, pixels, size, usage); -} - -dawn::BufferCopyView ContextDawn::createBufferCopyView(const dawn::Buffer &buffer, - uint32_t offset, - uint32_t rowPitch, - uint32_t imageHeight) const { - - return utils::CreateBufferCopyView(buffer, offset, rowPitch, imageHeight); -} - -dawn::TextureCopyView ContextDawn::createTextureCopyView(dawn::Texture texture, - uint32_t level, - uint32_t slice, - dawn::Origin3D origin) -{ - - return utils::CreateTextureCopyView(texture, level, slice, origin); -} - -dawn::CommandBuffer ContextDawn::copyBufferToTexture(const dawn::BufferCopyView &bufferCopyView, const dawn::TextureCopyView &textureCopyView, const dawn::Extent3D& ext3D) const -{ - dawn::CommandEncoder encoder = mDevice.CreateCommandEncoder(); - encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &ext3D); - dawn::CommandBuffer copy = encoder.Finish(); - return copy; -} - -dawn::ShaderModule ContextDawn::createShaderModule(utils::ShaderStage stage, - const std::string &str) const -{ - return utils::CreateShaderModule(mDevice, stage, str.c_str()); -} - -dawn::BindGroupLayout ContextDawn::MakeBindGroupLayout( - std::initializer_list bindingsInitializer) const { - - return utils::MakeBindGroupLayout(mDevice, bindingsInitializer); -} - -dawn::PipelineLayout ContextDawn::MakeBasicPipelineLayout( - std::vector bindingsInitializer) const { - dawn::PipelineLayoutDescriptor descriptor; - - descriptor.bindGroupLayoutCount = static_cast(bindingsInitializer.size()); - descriptor.bindGroupLayouts = bindingsInitializer.data(); - - return mDevice.CreatePipelineLayout(&descriptor); -} - -dawn::RenderPipeline ContextDawn::createRenderPipeline( - dawn::PipelineLayout mPipelineLayout, - ProgramDawn *mProgramDawn, - const dawn::VertexInputDescriptor &mVertexInputDescriptor, - bool enableBlend) const -{ - const dawn::ShaderModule &mVsModule = mProgramDawn->getVSModule(); - const dawn::ShaderModule &mFsModule = mProgramDawn->getFSModule(); - - dawn::PipelineStageDescriptor cVertexStage; - cVertexStage.entryPoint = "main"; - cVertexStage.module = mVsModule; - - dawn::PipelineStageDescriptor cFragmentStage; - cFragmentStage.entryPoint = "main"; - cFragmentStage.module = mFsModule; - - dawn::BlendDescriptor blendDescriptor; - blendDescriptor.operation = dawn::BlendOperation::Add; - if (enableBlend) - { - blendDescriptor.srcFactor = dawn::BlendFactor::SrcAlpha; - blendDescriptor.dstFactor = dawn::BlendFactor::OneMinusSrcAlpha; - } - else - { - blendDescriptor.srcFactor = dawn::BlendFactor::One; - blendDescriptor.dstFactor = dawn::BlendFactor::Zero; - } - - dawn::ColorStateDescriptor ColorStateDescriptor; - ColorStateDescriptor.colorBlend = blendDescriptor; - ColorStateDescriptor.alphaBlend = blendDescriptor; - ColorStateDescriptor.writeMask = dawn::ColorWriteMask::All; - - dawn::RasterizationStateDescriptor rasterizationState; - rasterizationState.nextInChain = nullptr; - rasterizationState.frontFace = dawn::FrontFace::CCW; - rasterizationState.cullMode = dawn::CullMode::Back; - rasterizationState.depthBias = 0; - rasterizationState.depthBiasSlopeScale = 0.0; - rasterizationState.depthBiasClamp = 0.0; - - // test - utils::ComboRenderPipelineDescriptor descriptor(mDevice); - descriptor.layout = mPipelineLayout; - descriptor.cVertexStage.module = mVsModule; - descriptor.cFragmentStage.module = mFsModule; - descriptor.vertexInput = &mVertexInputDescriptor; - descriptor.depthStencilState = &descriptor.cDepthStencilState; - descriptor.cDepthStencilState.format = dawn::TextureFormat::Depth24PlusStencil8; - descriptor.cColorStates[0] = &ColorStateDescriptor; - descriptor.cColorStates[0]->format = mPreferredSwapChainFormat; - descriptor.cDepthStencilState.depthWriteEnabled = true; - descriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Less; - descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleList; - descriptor.sampleCount = mEnableMSAA ? 4 : 1; - descriptor.rasterizationState = &rasterizationState; - - dawn::RenderPipeline mPipeline = mDevice.CreateRenderPipeline(&descriptor); - - return mPipeline; -} - -dawn::TextureView ContextDawn::createMultisampledRenderTargetView() const -{ - dawn::TextureDescriptor descriptor; - descriptor.dimension = dawn::TextureDimension::e2D; - descriptor.size.width = mClientWidth; - descriptor.size.height = mClientHeight; - descriptor.size.depth = 1; - descriptor.arrayLayerCount = 1; - descriptor.sampleCount = 4; - descriptor.format = mPreferredSwapChainFormat; - descriptor.mipLevelCount = 1; - descriptor.usage = dawn::TextureUsageBit::OutputAttachment; - - return mDevice.CreateTexture(&descriptor).CreateDefaultView(); -} - -dawn::TextureView ContextDawn::createDepthStencilView() const -{ - dawn::TextureDescriptor descriptor; - descriptor.dimension = dawn::TextureDimension::e2D; - descriptor.size.width = mClientWidth; - descriptor.size.height = mClientHeight; - descriptor.size.depth = 1; - descriptor.arrayLayerCount = 1; - descriptor.sampleCount = mEnableMSAA ? 4 : 1; - descriptor.format = dawn::TextureFormat::Depth24PlusStencil8; - descriptor.mipLevelCount = 1; - descriptor.usage = dawn::TextureUsageBit::OutputAttachment; - auto depthStencilTexture = mDevice.CreateTexture(&descriptor); - return depthStencilTexture.CreateDefaultView(); -} - -dawn::Buffer ContextDawn::createBuffer(uint32_t size, dawn::BufferUsageBit bit) const -{ - dawn::BufferDescriptor descriptor; - descriptor.size = size; - descriptor.usage = bit; - - dawn::Buffer buffer = mDevice.CreateBuffer(&descriptor); - return buffer; -} - -void ContextDawn::setBufferData(const dawn::Buffer& buffer, uint32_t start, uint32_t size, const void* pixels) const -{ - buffer.SetSubData(start, size, reinterpret_cast(pixels)); -} - -dawn::BindGroup ContextDawn::makeBindGroup( - const dawn::BindGroupLayout &layout, - std::initializer_list bindingsInitializer) const -{ - return utils::MakeBindGroup(mDevice, layout, bindingsInitializer); -} - -void ContextDawn::initGeneralResources(Aquarium* aquarium) -{ - // initilize general uniform buffers - groupLayoutGeneral = MakeBindGroupLayout({ - { 0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer }, - { 1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer }, - }); - - mLightBuffer = - createBufferFromData(&aquarium->lightUniforms, sizeof(aquarium->lightUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - mFogBuffer = - createBufferFromData(&aquarium->fogUniforms, sizeof(aquarium->fogUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - - bindGroupGeneral = - makeBindGroup(groupLayoutGeneral, {{0, mLightBuffer, 0, sizeof(aquarium->lightUniforms)}, - {1, mFogBuffer, 0, sizeof(aquarium->fogUniforms)}}); - - setBufferData(mLightBuffer, 0, sizeof(LightUniforms), &aquarium->lightUniforms); - setBufferData(mFogBuffer, 0, sizeof(FogUniforms), &aquarium->fogUniforms); - - // initilize world uniform buffers - groupLayoutWorld = MakeBindGroupLayout({ - { 0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer }, - }); - - mLightWorldPositionBuffer = createBufferFromData( - &aquarium->lightWorldPositionUniform, sizeof(aquarium->lightWorldPositionUniform), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - - bindGroupWorld = makeBindGroup( - groupLayoutWorld, - { - {0, mLightWorldPositionBuffer, 0, sizeof(aquarium->lightWorldPositionUniform)}, - }); - - setBufferData(mLightWorldPositionBuffer, 0, sizeof(LightWorldPositionUniform), - &aquarium->lightWorldPositionUniform); -} - -void ContextDawn::updateWorldlUniforms(Aquarium* aquarium) -{ - setBufferData(mLightWorldPositionBuffer, 0, sizeof(LightWorldPositionUniform), - &aquarium->lightWorldPositionUniform); -} - -Buffer *ContextDawn::createBuffer(int numComponents, std::vector *buf, bool isIndex) -{ - Buffer *buffer = new BufferDawn(this, static_cast(buf->size()), numComponents, buf, isIndex); - return buffer; -} - -Buffer *ContextDawn::createBuffer(int numComponents, std::vector *buf, bool isIndex) -{ - Buffer *buffer = - new BufferDawn(this, static_cast(buf->size()), numComponents, buf, isIndex); - return buffer; -} - -Program *ContextDawn::createProgram(const std::string &mVId, const std::string &mFId) -{ - ProgramDawn *program = new ProgramDawn(this, mVId, mFId); - program->loadProgram(); - - return program; -} - -void ContextDawn::setWindowTitle(const std::string &text) -{ - glfwSetWindowTitle(mWindow, text.c_str()); -} - -bool ContextDawn::ShouldQuit() -{ - return glfwWindowShouldClose(mWindow); -} - -void ContextDawn::KeyBoardQuit() -{ - if (glfwGetKey(mWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS) - glfwSetWindowShouldClose(mWindow, GL_TRUE); -} - -// Submit commands of the frame -void ContextDawn::DoFlush() -{ - mRenderPass.EndPass(); - dawn::CommandBuffer cmd = mCommandEncoder.Finish(); - queue.Submit(1, &cmd); - - mSwapchain.Present(mBackbuffer); - - glfwPollEvents(); -} - -void ContextDawn::FlushInit() -{ - queue.Submit(mCommandBuffers.size(), mCommandBuffers.data()); -} - -void ContextDawn::Terminate() -{ - glfwTerminate(); -} - -void ContextDawn::showWindow() -{ - glfwShowWindow(mWindow); -} - -void ContextDawn::showFPS(const FPSTimer &fpsTimer) -{ - // Start the Dear ImGui frame - ImGui_ImplDawn_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - { - ImGui::Begin("Aquarium Native"); - - std::ostringstream rendererStream; - rendererStream << mRenderer << " " << mBackendType << " " - << mResourceHelper->getShaderVersion(); - std::string renderer = rendererStream.str(); - ImGui::Text(renderer.c_str()); - - std::ostringstream resolutionStream; - resolutionStream << "Resolution " << mClientWidth << "x" << mClientHeight; - std::string resolution = resolutionStream.str(); - ImGui::Text(resolution.c_str()); - - ImGui::PlotLines("[0,100 FPS]", fpsTimer.getHistoryFps(), NUM_HISTORY_DATA, 0, NULL, 0.0f, - 100.0f, ImVec2(0, 40)); - - ImGui::PlotHistogram("[0,100 ms/frame]", fpsTimer.getHistoryFrameTime(), NUM_HISTORY_DATA, - 0, NULL, 0.0f, 100.0f, ImVec2(0, 40)); - - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", - 1000.0f / fpsTimer.getAverageFPS(), fpsTimer.getAverageFPS()); - ImGui::End(); - } - - ImGui::Render(); - ImGui_ImplDawn_RenderDrawData(ImGui::GetDrawData()); -} - -void ContextDawn::destoryImgUI() -{ - ImGui_ImplDawn_Shutdown(); - ImGui_ImplGlfw_Shutdown(); - ImGui::DestroyContext(); -} - -void ContextDawn::preFrame() -{ - if (mIsSwapchainOutOfDate) { - glfwGetFramebufferSize(mWindow, &mClientWidth, &mClientHeight); - if (mEnableMSAA) { - mSceneRenderTargetView = createMultisampledRenderTargetView(); - } - mSceneDepthStencilView = createDepthStencilView(); - mSwapchain.Configure(mPreferredSwapChainFormat, kSwapchainBackBufferUsageBit, mClientWidth, - mClientHeight); - - mIsSwapchainOutOfDate = false; - } - - mCommandEncoder = mDevice.CreateCommandEncoder(); - mBackbuffer = mSwapchain.GetNextTexture(); - - if (mEnableMSAA) - { - // If MSAA is enabled, we render to a multisampled texture and then resolve to the backbuffer - mRenderPassDescriptor = utils::ComboRenderPassDescriptor({mSceneRenderTargetView}, - mSceneDepthStencilView); - mRenderPassDescriptor.cColorAttachmentsInfoPtr[0]->resolveTarget = - mBackbuffer.CreateDefaultView(); - } - else - { - // When MSAA is off, we render directly to the backbuffer - mRenderPassDescriptor = utils::ComboRenderPassDescriptor({mBackbuffer.CreateDefaultView()}, - mSceneDepthStencilView); - } - - mRenderPass = mCommandEncoder.BeginRenderPass(&mRenderPassDescriptor); -} - -Model * ContextDawn::createModel(Aquarium* aquarium, MODELGROUP type, MODELNAME name, bool blend) -{ - Model *model; - switch (type) - { - case MODELGROUP::FISH: - model = new FishModelDawn(this, aquarium, type, name, blend); - break; - case MODELGROUP::FISHINSTANCEDDRAW: - model = new FishModelInstancedDrawDawn(this, aquarium, type, name, blend); - break; - case MODELGROUP::GENERIC: - model = new GenericModelDawn(this, aquarium, type, name, blend); - break; - case MODELGROUP::INNER: - model = new InnerModelDawn(this, aquarium, type, name, blend); - break; - case MODELGROUP::SEAWEED: - model = new SeaweedModelDawn(this, aquarium, type, name, blend); - break; - case MODELGROUP::OUTSIDE: - model = new OutsideModelDawn(this, aquarium, type, name, blend); - break; - default: - model = nullptr; - std::cout << "can not create model type" << std::endl; - } - - return model; -} - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DeviceDawn.cpp: Implements accessing functions to the graphics API of Dawn. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "BufferDawn.h" +#include "ContextDawn.h" +#include "FishModelDawn.h" +#include "FishModelInstancedDrawDawn.h" +#include "GenericModelDawn.h" +#include "InnerModelDawn.h" +#include "OutsideModelDawn.h" +#include "ProgramDawn.h" +#include "SeaweedModelDawn.h" +#include "TextureDawn.h" + +#include "common/Constants.h" +#include "imgui.h" +#include "imgui_impl_dawn.h" +#include "imgui_impl_glfw.h" +#include "utils/BackendBinding.h" +#include "utils/ComboRenderPipelineDescriptor.h" + +#include "../Aquarium.h" + +ContextDawn::ContextDawn(BACKENDTYPE backendType) + : queue(nullptr), + mDevice(nullptr), + mWindow(nullptr), + mInstance(), + mSwapchain(nullptr), + mCommandEncoder(nullptr), + mRenderPass(nullptr), + mRenderPassDescriptor({}), + mBackbuffer(nullptr), + mSceneRenderTargetView(nullptr), + mSceneDepthStencilView(nullptr), + mPipeline(nullptr), + mBindGroup(nullptr), + mPreferredSwapChainFormat(dawn::TextureFormat::RGBA8Unorm), + mEnableMSAA(false) +{ + mResourceHelper = new ResourceHelper("dawn", ""); + initAvailableToggleBitset(backendType); +} + +ContextDawn::~ContextDawn() +{ + delete mResourceHelper; + if (mWindow != nullptr) + { + destoryImgUI(); + } + + mSceneRenderTargetView = nullptr; + mSceneDepthStencilView = nullptr; + mBackbuffer = nullptr; + mPipeline = nullptr; + mBindGroup = nullptr; + mLightWorldPositionBuffer = nullptr; + mLightBuffer = nullptr; + mFogBuffer = nullptr; + mCommandEncoder = nullptr; + mCommandBuffers.clear(); + mRenderPass = nullptr; + mRenderPassDescriptor = {}; + groupLayoutGeneral = nullptr; + bindGroupGeneral = nullptr; + groupLayoutWorld = nullptr; + bindGroupWorld = nullptr; + mSwapchain = nullptr; + queue = nullptr; + mDevice = nullptr; +} + +bool ContextDawn::initialize( + BACKENDTYPE backend, + const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) +{ + dawn_native::BackendType backendType = dawn_native::BackendType::Null; + + switch (backend) + { + case BACKENDTYPE::BACKENDTYPEDAWND3D12: + { + backendType = dawn_native::BackendType::D3D12; + mBackendType = "Dawn D3D12"; + break; + } + case BACKENDTYPE::BACKENDTYPEDAWNVULKAN: + { + backendType = dawn_native::BackendType::Vulkan; + mBackendType = "Dawn Vulkan"; + break; + } + case BACKENDTYPE::BACKENDTYPEDAWNMETAL: + { + backendType = dawn_native::BackendType::Metal; + mBackendType = "Dawn Metal"; + break; + } + case BACKENDTYPE::BACKENDTYPEOPENGL: + { + backendType = dawn_native::BackendType::OpenGL; + mBackendType = "Dawn OpenGL"; + break; + } + default: + { + std::cerr << "Backend type can not reached." << std::endl; + return false; + } + } + + mEnableMSAA = toggleBitset.test(static_cast(TOGGLE::ENABLEMSAAx4)); + + // initialise GLFW + if (!glfwInit()) + { + std::cout << "Failed to initialise GLFW" << std::endl; + return false; + } + + utils::SetupGLFWWindowHintsForBackend(backendType); + // set full screen + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + + GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); + const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); + mClientWidth = mode->width; + mClientHeight = mode->height; + + if (toggleBitset.test(static_cast(TOGGLE::ENABLEFULLSCREENMODE))) + { + mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", pMonitor, nullptr); + } + else + { + mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", nullptr, nullptr); + } + + if (mWindow == nullptr) + { + std::cout << "Failed to open GLFW window." << std::endl; + glfwTerminate(); + return false; + } + + // Get the resolution of screen + glfwGetFramebufferSize(mWindow, &mClientWidth, &mClientHeight); + + mInstance = std::make_unique(); + utils::DiscoverAdapter(mInstance.get(), mWindow, backendType); + + dawn_native::Adapter backendAdapter; + if (!GetHardwareAdapter(mInstance, &backendAdapter, backendType, toggleBitset)) + { + return false; + } + + DawnDevice backendDevice = backendAdapter.CreateDevice(); + DawnProcTable backendProcs = dawn_native::GetProcs(); + + utils::BackendBinding *binding = utils::CreateBinding(backendType, mWindow, backendDevice); + if (binding == nullptr) + { + return false; + } + + dawnSetProcs(&backendProcs); + mDevice = dawn::Device::Acquire(backendDevice); + + queue = mDevice.CreateQueue(); + dawn::SwapChainDescriptor swapChainDesc; + swapChainDesc.implementation = binding->GetSwapChainImplementation(); + mSwapchain = mDevice.CreateSwapChain(&swapChainDesc); + + mPreferredSwapChainFormat = + static_cast(binding->GetPreferredSwapChainTextureFormat()); + mSwapchain.Configure(mPreferredSwapChainFormat, kSwapchainBackBufferUsageBit, mClientWidth, + mClientHeight); + + dawn_native::PCIInfo info = backendAdapter.GetPCIInfo(); + mRenderer = info.name; + std::cout << mRenderer << std::endl; + + // When MSAA is enabled, we create an intermediate multisampled texture to render the scene to. + if (mEnableMSAA) + { + mSceneRenderTargetView = createMultisampledRenderTargetView(); + } + + mSceneDepthStencilView = createDepthStencilView(); + + // TODO(jiawei.shao@intel.com): support recreating swapchain when window is resized on all + // backends + if (backend == BACKENDTYPE::BACKENDTYPEDAWNVULKAN) + { + glfwSetFramebufferSizeCallback(mWindow, framebufferResizeCallback); + glfwSetWindowUserPointer(mWindow, this); + } + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + + // Setup Platform/Renderer bindings + // We use glfw to create window for dawn backend as well. + // Because imgui doesn't have dawn backend, we rewrite the functions by dawn API in + // imgui_impl_dawn.cpp and imgui_impl_dawn.h + ImGui_ImplGlfw_InitForOpenGL(mWindow, true); + ImGui_ImplDawn_Init(this, mPreferredSwapChainFormat, mEnableMSAA); + + return true; +} + +void ContextDawn::framebufferResizeCallback(GLFWwindow *window, int width, int height) +{ + ContextDawn *contextDawn = reinterpret_cast(glfwGetWindowUserPointer(window)); + contextDawn->mIsSwapchainOutOfDate = true; +} + +bool ContextDawn::GetHardwareAdapter( + std::unique_ptr &instance, + dawn_native::Adapter *backendAdapter, + dawn_native::BackendType backendType, + const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) +{ + bool enableIntegratedGpu = toggleBitset.test(static_cast(TOGGLE::INTEGRATEDGPU)); + bool enableDiscreteGpu = toggleBitset.test(static_cast(TOGGLE::DISCRETEGPU)); + bool useDefaultGpu = (enableDiscreteGpu | enableIntegratedGpu) == false ? true : false; + bool result = false; + + // Get an adapter for the backend to use, and create the Device. + for (auto &adapter : instance->GetAdapters()) + { + if (adapter.GetBackendType() == backendType) + { + if (useDefaultGpu || + (enableDiscreteGpu && + adapter.GetDeviceType() == dawn_native::DeviceType::DiscreteGPU) || + (enableIntegratedGpu && + adapter.GetDeviceType() == dawn_native::DeviceType::IntegratedGPU)) + { + *backendAdapter = adapter; + result = true; + break; + } + } + } + + if (!result) + { + std::cerr << "Failed to create adapter." << std::endl; + return false; + } + + return true; +} + +void ContextDawn::initAvailableToggleBitset(BACKENDTYPE backendType) +{ + mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEMSAAx4)); + mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEINSTANCEDDRAWS)); + // DBO on dawn is not supported yet + if (backendType != BACKENDTYPE::BACKENDTYPEDAWND3D12) + { + mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET)); + } + mAvailableToggleBitset.set(static_cast(TOGGLE::DISCRETEGPU)); + mAvailableToggleBitset.set(static_cast(TOGGLE::INTEGRATEDGPU)); + mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEFULLSCREENMODE)); +} + +Texture *ContextDawn::createTexture(const std::string &name, const std::string &url) +{ + Texture *texture = new TextureDawn(this, name, url); + texture->loadTexture(); + return texture; +} + +Texture *ContextDawn::createTexture(const std::string &name, const std::vector &urls) +{ + Texture *texture = new TextureDawn(this, name, urls); + texture->loadTexture(); + return texture; +} + +dawn::Texture ContextDawn::createTexture(const dawn::TextureDescriptor &descriptor) const +{ + return mDevice.CreateTexture(&descriptor); +} + +dawn::Sampler ContextDawn::createSampler(const dawn::SamplerDescriptor &descriptor) const +{ + return mDevice.CreateSampler(&descriptor); +} + +dawn::Buffer ContextDawn::createBufferFromData(const void *pixels, + int size, + dawn::BufferUsageBit usage) const +{ + return utils::CreateBufferFromData(mDevice, pixels, size, usage); +} + +dawn::BufferCopyView ContextDawn::createBufferCopyView(const dawn::Buffer &buffer, + uint32_t offset, + uint32_t rowPitch, + uint32_t imageHeight) const +{ + + return utils::CreateBufferCopyView(buffer, offset, rowPitch, imageHeight); +} + +dawn::TextureCopyView ContextDawn::createTextureCopyView(dawn::Texture texture, + uint32_t level, + uint32_t slice, + dawn::Origin3D origin) +{ + + return utils::CreateTextureCopyView(texture, level, slice, origin); +} + +dawn::CommandBuffer ContextDawn::copyBufferToTexture(const dawn::BufferCopyView &bufferCopyView, + const dawn::TextureCopyView &textureCopyView, + const dawn::Extent3D &ext3D) const +{ + dawn::CommandEncoder encoder = mDevice.CreateCommandEncoder(); + encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &ext3D); + dawn::CommandBuffer copy = encoder.Finish(); + return copy; +} + +dawn::ShaderModule ContextDawn::createShaderModule(utils::ShaderStage stage, + const std::string &str) const +{ + return utils::CreateShaderModule(mDevice, stage, str.c_str()); +} + +dawn::BindGroupLayout ContextDawn::MakeBindGroupLayout( + std::initializer_list bindingsInitializer) const +{ + + return utils::MakeBindGroupLayout(mDevice, bindingsInitializer); +} + +dawn::PipelineLayout ContextDawn::MakeBasicPipelineLayout( + std::vector bindingsInitializer) const +{ + dawn::PipelineLayoutDescriptor descriptor; + + descriptor.bindGroupLayoutCount = static_cast(bindingsInitializer.size()); + descriptor.bindGroupLayouts = bindingsInitializer.data(); + + return mDevice.CreatePipelineLayout(&descriptor); +} + +dawn::RenderPipeline ContextDawn::createRenderPipeline( + dawn::PipelineLayout mPipelineLayout, + ProgramDawn *mProgramDawn, + const dawn::VertexInputDescriptor &mVertexInputDescriptor, + bool enableBlend) const +{ + const dawn::ShaderModule &mVsModule = mProgramDawn->getVSModule(); + const dawn::ShaderModule &mFsModule = mProgramDawn->getFSModule(); + + dawn::PipelineStageDescriptor cVertexStage; + cVertexStage.entryPoint = "main"; + cVertexStage.module = mVsModule; + + dawn::PipelineStageDescriptor cFragmentStage; + cFragmentStage.entryPoint = "main"; + cFragmentStage.module = mFsModule; + + dawn::BlendDescriptor blendDescriptor; + blendDescriptor.operation = dawn::BlendOperation::Add; + if (enableBlend) + { + blendDescriptor.srcFactor = dawn::BlendFactor::SrcAlpha; + blendDescriptor.dstFactor = dawn::BlendFactor::OneMinusSrcAlpha; + } + else + { + blendDescriptor.srcFactor = dawn::BlendFactor::One; + blendDescriptor.dstFactor = dawn::BlendFactor::Zero; + } + + dawn::ColorStateDescriptor ColorStateDescriptor; + ColorStateDescriptor.colorBlend = blendDescriptor; + ColorStateDescriptor.alphaBlend = blendDescriptor; + ColorStateDescriptor.writeMask = dawn::ColorWriteMask::All; + + dawn::RasterizationStateDescriptor rasterizationState; + rasterizationState.nextInChain = nullptr; + rasterizationState.frontFace = dawn::FrontFace::CCW; + rasterizationState.cullMode = dawn::CullMode::Back; + rasterizationState.depthBias = 0; + rasterizationState.depthBiasSlopeScale = 0.0; + rasterizationState.depthBiasClamp = 0.0; + + // test + utils::ComboRenderPipelineDescriptor descriptor(mDevice); + descriptor.layout = mPipelineLayout; + descriptor.cVertexStage.module = mVsModule; + descriptor.cFragmentStage.module = mFsModule; + descriptor.vertexInput = &mVertexInputDescriptor; + descriptor.depthStencilState = &descriptor.cDepthStencilState; + descriptor.cDepthStencilState.format = dawn::TextureFormat::Depth24PlusStencil8; + descriptor.cColorStates[0] = &ColorStateDescriptor; + descriptor.cColorStates[0]->format = mPreferredSwapChainFormat; + descriptor.cDepthStencilState.depthWriteEnabled = true; + descriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Less; + descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleList; + descriptor.sampleCount = mEnableMSAA ? 4 : 1; + descriptor.rasterizationState = &rasterizationState; + + dawn::RenderPipeline mPipeline = mDevice.CreateRenderPipeline(&descriptor); + + return mPipeline; +} + +dawn::TextureView ContextDawn::createMultisampledRenderTargetView() const +{ + dawn::TextureDescriptor descriptor; + descriptor.dimension = dawn::TextureDimension::e2D; + descriptor.size.width = mClientWidth; + descriptor.size.height = mClientHeight; + descriptor.size.depth = 1; + descriptor.arrayLayerCount = 1; + descriptor.sampleCount = 4; + descriptor.format = mPreferredSwapChainFormat; + descriptor.mipLevelCount = 1; + descriptor.usage = dawn::TextureUsageBit::OutputAttachment; + + return mDevice.CreateTexture(&descriptor).CreateDefaultView(); +} + +dawn::TextureView ContextDawn::createDepthStencilView() const +{ + dawn::TextureDescriptor descriptor; + descriptor.dimension = dawn::TextureDimension::e2D; + descriptor.size.width = mClientWidth; + descriptor.size.height = mClientHeight; + descriptor.size.depth = 1; + descriptor.arrayLayerCount = 1; + descriptor.sampleCount = mEnableMSAA ? 4 : 1; + descriptor.format = dawn::TextureFormat::Depth24PlusStencil8; + descriptor.mipLevelCount = 1; + descriptor.usage = dawn::TextureUsageBit::OutputAttachment; + auto depthStencilTexture = mDevice.CreateTexture(&descriptor); + return depthStencilTexture.CreateDefaultView(); +} + +dawn::Buffer ContextDawn::createBuffer(uint32_t size, dawn::BufferUsageBit bit) const +{ + dawn::BufferDescriptor descriptor; + descriptor.size = size; + descriptor.usage = bit; + + dawn::Buffer buffer = mDevice.CreateBuffer(&descriptor); + return buffer; +} + +void ContextDawn::setBufferData(const dawn::Buffer &buffer, + uint32_t start, + uint32_t size, + const void *pixels) const +{ + buffer.SetSubData(start, size, reinterpret_cast(pixels)); +} + +dawn::BindGroup ContextDawn::makeBindGroup( + const dawn::BindGroupLayout &layout, + std::initializer_list bindingsInitializer) const +{ + return utils::MakeBindGroup(mDevice, layout, bindingsInitializer); +} + +void ContextDawn::initGeneralResources(Aquarium *aquarium) +{ + // initilize general uniform buffers + groupLayoutGeneral = MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + }); + + mLightBuffer = + createBufferFromData(&aquarium->lightUniforms, sizeof(aquarium->lightUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + mFogBuffer = + createBufferFromData(&aquarium->fogUniforms, sizeof(aquarium->fogUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + + bindGroupGeneral = + makeBindGroup(groupLayoutGeneral, {{0, mLightBuffer, 0, sizeof(aquarium->lightUniforms)}, + {1, mFogBuffer, 0, sizeof(aquarium->fogUniforms)}}); + + setBufferData(mLightBuffer, 0, sizeof(LightUniforms), &aquarium->lightUniforms); + setBufferData(mFogBuffer, 0, sizeof(FogUniforms), &aquarium->fogUniforms); + + // initilize world uniform buffers + groupLayoutWorld = MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + }); + + mLightWorldPositionBuffer = createBufferFromData( + &aquarium->lightWorldPositionUniform, sizeof(aquarium->lightWorldPositionUniform), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + + bindGroupWorld = makeBindGroup( + groupLayoutWorld, + { + {0, mLightWorldPositionBuffer, 0, sizeof(aquarium->lightWorldPositionUniform)}, + }); + + setBufferData(mLightWorldPositionBuffer, 0, sizeof(LightWorldPositionUniform), + &aquarium->lightWorldPositionUniform); +} + +void ContextDawn::updateWorldlUniforms(Aquarium *aquarium) +{ + setBufferData(mLightWorldPositionBuffer, 0, sizeof(LightWorldPositionUniform), + &aquarium->lightWorldPositionUniform); +} + +Buffer *ContextDawn::createBuffer(int numComponents, std::vector *buf, bool isIndex) +{ + Buffer *buffer = + new BufferDawn(this, static_cast(buf->size()), numComponents, buf, isIndex); + return buffer; +} + +Buffer *ContextDawn::createBuffer(int numComponents, std::vector *buf, bool isIndex) +{ + Buffer *buffer = + new BufferDawn(this, static_cast(buf->size()), numComponents, buf, isIndex); + return buffer; +} + +Program *ContextDawn::createProgram(const std::string &mVId, const std::string &mFId) +{ + ProgramDawn *program = new ProgramDawn(this, mVId, mFId); + program->loadProgram(); + + return program; +} + +void ContextDawn::setWindowTitle(const std::string &text) +{ + glfwSetWindowTitle(mWindow, text.c_str()); +} + +bool ContextDawn::ShouldQuit() +{ + return glfwWindowShouldClose(mWindow); +} + +void ContextDawn::KeyBoardQuit() +{ + if (glfwGetKey(mWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(mWindow, GL_TRUE); +} + +// Submit commands of the frame +void ContextDawn::DoFlush() +{ + mRenderPass.EndPass(); + dawn::CommandBuffer cmd = mCommandEncoder.Finish(); + queue.Submit(1, &cmd); + + mSwapchain.Present(mBackbuffer); + + glfwPollEvents(); +} + +void ContextDawn::FlushInit() +{ + queue.Submit(mCommandBuffers.size(), mCommandBuffers.data()); +} + +void ContextDawn::Terminate() +{ + glfwTerminate(); +} + +void ContextDawn::showWindow() +{ + glfwShowWindow(mWindow); +} + +void ContextDawn::showFPS(const FPSTimer &fpsTimer) +{ + // Start the Dear ImGui frame + ImGui_ImplDawn_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + { + ImGui::Begin("Aquarium Native"); + + std::ostringstream rendererStream; + rendererStream << mRenderer << " " << mBackendType << " " + << mResourceHelper->getShaderVersion(); + std::string renderer = rendererStream.str(); + ImGui::Text(renderer.c_str()); + + std::ostringstream resolutionStream; + resolutionStream << "Resolution " << mClientWidth << "x" << mClientHeight; + std::string resolution = resolutionStream.str(); + ImGui::Text(resolution.c_str()); + + ImGui::PlotLines("[0,100 FPS]", fpsTimer.getHistoryFps(), NUM_HISTORY_DATA, 0, NULL, 0.0f, + 100.0f, ImVec2(0, 40)); + + ImGui::PlotHistogram("[0,100 ms/frame]", fpsTimer.getHistoryFrameTime(), NUM_HISTORY_DATA, + 0, NULL, 0.0f, 100.0f, ImVec2(0, 40)); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", + 1000.0f / fpsTimer.getAverageFPS(), fpsTimer.getAverageFPS()); + ImGui::End(); + } + + ImGui::Render(); + ImGui_ImplDawn_RenderDrawData(ImGui::GetDrawData()); +} + +void ContextDawn::destoryImgUI() +{ + ImGui_ImplDawn_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); +} + +void ContextDawn::preFrame() +{ + if (mIsSwapchainOutOfDate) + { + glfwGetFramebufferSize(mWindow, &mClientWidth, &mClientHeight); + if (mEnableMSAA) + { + mSceneRenderTargetView = createMultisampledRenderTargetView(); + } + mSceneDepthStencilView = createDepthStencilView(); + mSwapchain.Configure(mPreferredSwapChainFormat, kSwapchainBackBufferUsageBit, mClientWidth, + mClientHeight); + + mIsSwapchainOutOfDate = false; + } + + mCommandEncoder = mDevice.CreateCommandEncoder(); + mBackbuffer = mSwapchain.GetNextTexture(); + + if (mEnableMSAA) + { + // If MSAA is enabled, we render to a multisampled texture and then resolve to the + // backbuffer + mRenderPassDescriptor = + utils::ComboRenderPassDescriptor({mSceneRenderTargetView}, mSceneDepthStencilView); + mRenderPassDescriptor.cColorAttachmentsInfoPtr[0]->resolveTarget = + mBackbuffer.CreateDefaultView(); + } + else + { + // When MSAA is off, we render directly to the backbuffer + mRenderPassDescriptor = utils::ComboRenderPassDescriptor({mBackbuffer.CreateDefaultView()}, + mSceneDepthStencilView); + } + + mRenderPass = mCommandEncoder.BeginRenderPass(&mRenderPassDescriptor); +} + +Model *ContextDawn::createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) +{ + Model *model; + switch (type) + { + case MODELGROUP::FISH: + model = new FishModelDawn(this, aquarium, type, name, blend); + break; + case MODELGROUP::FISHINSTANCEDDRAW: + model = new FishModelInstancedDrawDawn(this, aquarium, type, name, blend); + break; + case MODELGROUP::GENERIC: + model = new GenericModelDawn(this, aquarium, type, name, blend); + break; + case MODELGROUP::INNER: + model = new InnerModelDawn(this, aquarium, type, name, blend); + break; + case MODELGROUP::SEAWEED: + model = new SeaweedModelDawn(this, aquarium, type, name, blend); + break; + case MODELGROUP::OUTSIDE: + model = new OutsideModelDawn(this, aquarium, type, name, blend); + break; + default: + model = nullptr; + std::cout << "can not create model type" << std::endl; + } + + return model; +} diff --git a/src/aquarium-optimized/dawn/ContextDawn.h b/src/aquarium-optimized/dawn/ContextDawn.h index 60ea223..d7cc501 100644 --- a/src/aquarium-optimized/dawn/ContextDawn.h +++ b/src/aquarium-optimized/dawn/ContextDawn.h @@ -1,142 +1,147 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// ContextDawn.h : Defines the accessing to graphics API of Dawn. - -#pragma once -#ifndef CONTEXTDAWN_H -#define CONTEXTDAWN_H - -#include -#include - -#include "GLFW/glfw3.h" -#include "utils/DawnHelpers.h" - -#include "../Context.h" - -class TextureDawn; -class BufferDawn; -class ProgramDawn; -enum BACKENDTYPE: short; - -class ContextDawn : public Context -{ - public: - ContextDawn(BACKENDTYPE backendType); - ~ContextDawn(); - bool initialize( - BACKENDTYPE backend, - const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) override; - void setWindowTitle(const std::string &text) override; - bool ShouldQuit() override; - void KeyBoardQuit() override; - void DoFlush() override; - void FlushInit() override; - void Terminate() override; - void showWindow() override; - void showFPS(const FPSTimer &fpsTimer) override; - void destoryImgUI() override; - - void preFrame() override; - - Model *createModel(Aquarium* aquarium, MODELGROUP type, MODELNAME name, bool blend) override; - Buffer *createBuffer(int numComponents, std::vector *buffer, bool isIndex) override; - Buffer *createBuffer(int numComponents, - std::vector *buffer, - bool isIndex) override; - - Program *createProgram(const std::string &mVId, const std::string &mFId) override; - - Texture *createTexture(const std::string &name, const std::string &url) override; - Texture *createTexture(const std::string &name, const std::vector &urls) override; - dawn::Texture createTexture(const dawn::TextureDescriptor &descriptor) const; - dawn::Sampler createSampler(const dawn::SamplerDescriptor &descriptor) const; - dawn::Buffer createBufferFromData(const void* pixels, int size, dawn::BufferUsageBit usage) const; - dawn::BufferCopyView createBufferCopyView(const dawn::Buffer &buffer, - uint32_t offset, - uint32_t rowPitch, - uint32_t imageHeight) const; - dawn::CommandBuffer copyBufferToTexture(const dawn::BufferCopyView &bufferCopyView, - const dawn::TextureCopyView &textureCopyView, - const dawn::Extent3D &ext3D) const; - - dawn::TextureCopyView createTextureCopyView(dawn::Texture texture, - uint32_t level, - uint32_t slice, - dawn::Origin3D origin); - dawn::ShaderModule createShaderModule(utils::ShaderStage stage, const std::string &str) const; - dawn::BindGroupLayout MakeBindGroupLayout( - std::initializer_list bindingsInitializer) const; - dawn::PipelineLayout MakeBasicPipelineLayout( - std::vector bindingsInitializer) const; - dawn::RenderPipeline createRenderPipeline( - dawn::PipelineLayout mPipelineLayout, - ProgramDawn *mProgramDawn, - const dawn::VertexInputDescriptor &mVertexInputDescriptor, - bool enableBlend) const; - dawn::TextureView createMultisampledRenderTargetView() const; - dawn::TextureView createDepthStencilView() const; - dawn::Buffer createBuffer(uint32_t size, dawn::BufferUsageBit bit) const; - void setBufferData(const dawn::Buffer &buffer, uint32_t start, uint32_t size, const void* pixels) const; - dawn::BindGroup makeBindGroup( - const dawn::BindGroupLayout &layout, - std::initializer_list bindingsInitializer) const; - - void initGeneralResources(Aquarium* aquarium) override; - void updateWorldlUniforms(Aquarium* aquarium) override; - const dawn::Device &getDevice() const { return mDevice; } - const dawn::RenderPassEncoder &getRenderPass() const { return mRenderPass; } - - std::vector mCommandBuffers; - dawn::Queue queue; - - dawn::BindGroupLayout groupLayoutGeneral; - dawn::BindGroup bindGroupGeneral; - dawn::BindGroupLayout groupLayoutWorld; - dawn::BindGroup bindGroupWorld; - - dawn::Device mDevice; - - private: - bool GetHardwareAdapter( - std::unique_ptr &instance, - dawn_native::Adapter *backendAdapter, - dawn_native::BackendType backendType, - const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset); - void initAvailableToggleBitset(BACKENDTYPE backendType) override; - static void framebufferResizeCallback(GLFWwindow *window, int width, int height); - - // TODO(jiawei.shao@intel.com): remove dawn::TextureUsageBit::CopyDst when the bug in Dawn is - // fixed. - static constexpr dawn::TextureUsageBit kSwapchainBackBufferUsageBit = - dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::CopyDst; - - bool mIsSwapchainOutOfDate = false; - GLFWwindow *mWindow; - std::unique_ptr mInstance; - - dawn::SwapChain mSwapchain; - dawn::CommandEncoder mCommandEncoder; - dawn::RenderPassEncoder mRenderPass; - utils::ComboRenderPassDescriptor mRenderPassDescriptor; - - dawn::Texture mBackbuffer; - dawn::TextureView mSceneRenderTargetView; - dawn::TextureView mSceneDepthStencilView; - dawn::RenderPipeline mPipeline; - dawn::BindGroup mBindGroup; - dawn::TextureFormat mPreferredSwapChainFormat; - - dawn::Buffer mLightWorldPositionBuffer; - dawn::Buffer mLightBuffer; - dawn::Buffer mFogBuffer; - - bool mEnableMSAA; - std::string mRenderer; - std::string mBackendType; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ContextDawn.h : Defines the accessing to graphics API of Dawn. + +#pragma once +#ifndef CONTEXTDAWN_H +#define CONTEXTDAWN_H + +#include +#include + +#include "GLFW/glfw3.h" +#include "utils/DawnHelpers.h" + +#include "../Context.h" + +class TextureDawn; +class BufferDawn; +class ProgramDawn; +enum BACKENDTYPE : short; + +class ContextDawn : public Context +{ + public: + ContextDawn(BACKENDTYPE backendType); + ~ContextDawn(); + bool initialize( + BACKENDTYPE backend, + const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) override; + void setWindowTitle(const std::string &text) override; + bool ShouldQuit() override; + void KeyBoardQuit() override; + void DoFlush() override; + void FlushInit() override; + void Terminate() override; + void showWindow() override; + void showFPS(const FPSTimer &fpsTimer) override; + void destoryImgUI() override; + + void preFrame() override; + + Model *createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) override; + Buffer *createBuffer(int numComponents, std::vector *buffer, bool isIndex) override; + Buffer *createBuffer(int numComponents, + std::vector *buffer, + bool isIndex) override; + + Program *createProgram(const std::string &mVId, const std::string &mFId) override; + + Texture *createTexture(const std::string &name, const std::string &url) override; + Texture *createTexture(const std::string &name, const std::vector &urls) override; + dawn::Texture createTexture(const dawn::TextureDescriptor &descriptor) const; + dawn::Sampler createSampler(const dawn::SamplerDescriptor &descriptor) const; + dawn::Buffer createBufferFromData(const void *pixels, + int size, + dawn::BufferUsageBit usage) const; + dawn::BufferCopyView createBufferCopyView(const dawn::Buffer &buffer, + uint32_t offset, + uint32_t rowPitch, + uint32_t imageHeight) const; + dawn::CommandBuffer copyBufferToTexture(const dawn::BufferCopyView &bufferCopyView, + const dawn::TextureCopyView &textureCopyView, + const dawn::Extent3D &ext3D) const; + + dawn::TextureCopyView createTextureCopyView(dawn::Texture texture, + uint32_t level, + uint32_t slice, + dawn::Origin3D origin); + dawn::ShaderModule createShaderModule(utils::ShaderStage stage, const std::string &str) const; + dawn::BindGroupLayout MakeBindGroupLayout( + std::initializer_list bindingsInitializer) const; + dawn::PipelineLayout MakeBasicPipelineLayout( + std::vector bindingsInitializer) const; + dawn::RenderPipeline createRenderPipeline( + dawn::PipelineLayout mPipelineLayout, + ProgramDawn *mProgramDawn, + const dawn::VertexInputDescriptor &mVertexInputDescriptor, + bool enableBlend) const; + dawn::TextureView createMultisampledRenderTargetView() const; + dawn::TextureView createDepthStencilView() const; + dawn::Buffer createBuffer(uint32_t size, dawn::BufferUsageBit bit) const; + void setBufferData(const dawn::Buffer &buffer, + uint32_t start, + uint32_t size, + const void *pixels) const; + dawn::BindGroup makeBindGroup( + const dawn::BindGroupLayout &layout, + std::initializer_list bindingsInitializer) const; + + void initGeneralResources(Aquarium *aquarium) override; + void updateWorldlUniforms(Aquarium *aquarium) override; + const dawn::Device &getDevice() const { return mDevice; } + const dawn::RenderPassEncoder &getRenderPass() const { return mRenderPass; } + + std::vector mCommandBuffers; + dawn::Queue queue; + + dawn::BindGroupLayout groupLayoutGeneral; + dawn::BindGroup bindGroupGeneral; + dawn::BindGroupLayout groupLayoutWorld; + dawn::BindGroup bindGroupWorld; + + dawn::Device mDevice; + + private: + bool GetHardwareAdapter( + std::unique_ptr &instance, + dawn_native::Adapter *backendAdapter, + dawn_native::BackendType backendType, + const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset); + void initAvailableToggleBitset(BACKENDTYPE backendType) override; + static void framebufferResizeCallback(GLFWwindow *window, int width, int height); + + // TODO(jiawei.shao@intel.com): remove dawn::TextureUsageBit::CopyDst when the bug in Dawn is + // fixed. + static constexpr dawn::TextureUsageBit kSwapchainBackBufferUsageBit = + dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::CopyDst; + + bool mIsSwapchainOutOfDate = false; + GLFWwindow *mWindow; + std::unique_ptr mInstance; + + dawn::SwapChain mSwapchain; + dawn::CommandEncoder mCommandEncoder; + dawn::RenderPassEncoder mRenderPass; + utils::ComboRenderPassDescriptor mRenderPassDescriptor; + + dawn::Texture mBackbuffer; + dawn::TextureView mSceneRenderTargetView; + dawn::TextureView mSceneDepthStencilView; + dawn::RenderPipeline mPipeline; + dawn::BindGroup mBindGroup; + dawn::TextureFormat mPreferredSwapChainFormat; + + dawn::Buffer mLightWorldPositionBuffer; + dawn::Buffer mLightBuffer; + dawn::Buffer mFogBuffer; + + bool mEnableMSAA; + std::string mRenderer; + std::string mBackendType; +}; + +#endif diff --git a/src/aquarium-optimized/dawn/FishModelDawn.cpp b/src/aquarium-optimized/dawn/FishModelDawn.cpp index c1fd73c..141cff4 100644 --- a/src/aquarium-optimized/dawn/FishModelDawn.cpp +++ b/src/aquarium-optimized/dawn/FishModelDawn.cpp @@ -1,284 +1,284 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FishModelDawn.cpp: Implements fish model of Dawn. - -#include "BufferDawn.h" -#include "FishModelDawn.h" - -FishModelDawn::FishModelDawn(const Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : FishModel(type, name, blend), instance(0) -{ - mContextDawn = static_cast(context); - - mEnableDynamicBufferOffset = - aquarium->toggleBitset.test(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET)); - - mLightFactorUniforms.shininess = 5.0f; - mLightFactorUniforms.specularFactor = 0.3f; - - const Fish &fishInfo = fishTable[name - MODELNAME::MODELSMALLFISHA]; - mFishVertexUniforms.fishLength = fishInfo.fishLength; - mFishVertexUniforms.fishBendAmount = fishInfo.fishBendAmount; - mFishVertexUniforms.fishWaveLength = fishInfo.fishWaveLength; - - instance = aquarium->fishCount[fishInfo.modelName - MODELNAME::MODELSMALLFISHA]; - mFishPers = new FishPer[instance]; - if (mEnableDynamicBufferOffset) - { - mBindGroupPers = new dawn::BindGroup[1]; - } - else - { - mBindGroupPers = new dawn::BindGroup[instance]; - } -} - -void FishModelDawn::init() -{ - if (instance == 0) - return; - - mProgramDawn = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mTangentBuffer = static_cast(bufferMap["tangent"]); - mBiNormalBuffer = static_cast(bufferMap["binormal"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - mVertexInputDescriptor.cBuffers[0].attributeCount = 1; - mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; - mVertexInputDescriptor.cAttributes[0].offset = 0; - mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; - mVertexInputDescriptor.cBuffers[1].attributeCount = 1; - mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; - mVertexInputDescriptor.cAttributes[1].offset = 0; - mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; - mVertexInputDescriptor.cBuffers[2].attributeCount = 1; - mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; - mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; - mVertexInputDescriptor.cAttributes[2].offset = 0; - mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; - mVertexInputDescriptor.cBuffers[3].attributeCount = 1; - mVertexInputDescriptor.cBuffers[3].stride = mTangentBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[3].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[3].shaderLocation = 3; - mVertexInputDescriptor.cAttributes[3].offset = 0; - mVertexInputDescriptor.cBuffers[3].attributes = &mVertexInputDescriptor.cAttributes[3]; - mVertexInputDescriptor.cBuffers[4].attributeCount = 1; - mVertexInputDescriptor.cBuffers[4].stride = mBiNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[4].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[4].shaderLocation = 4; - mVertexInputDescriptor.cAttributes[4].offset = 0; - mVertexInputDescriptor.cBuffers[4].attributes = &mVertexInputDescriptor.cAttributes[4]; - mVertexInputDescriptor.bufferCount = 5; - mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; - - if (mSkyboxTexture && mReflectionTexture) - { - mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, - {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {5, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {6, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {7, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - }); - } - else - { - mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, - {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - }); - } - - if (mEnableDynamicBufferOffset) - { - mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer, true}, - }); - } - else - { - mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - }); - } - - mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ - mContextDawn->groupLayoutGeneral, - mContextDawn->groupLayoutWorld, - mGroupLayoutModel, - mGroupLayoutPer, - }); - - mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, - mVertexInputDescriptor, mBlend); - - mFishVertexBuffer = mContextDawn->createBufferFromData( - &mFishVertexUniforms, sizeof(FishVertexUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - mLightFactorBuffer = mContextDawn->createBufferFromData( - &mLightFactorUniforms, sizeof(LightFactorUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - mFishPersBuffer = mContextDawn->createBufferFromData( - mFishPers, sizeof(FishPer) * instance, - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - - // Fish models includes small, medium and big. Some of them contains reflection and skybox - // texture, but some doesn't. - if (mSkyboxTexture && mReflectionTexture) - { - mBindGroupModel = mContextDawn->makeBindGroup( - mGroupLayoutModel, {{0, mFishVertexBuffer, 0, sizeof(FishVertexUniforms)}, - {1, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, - {2, mReflectionTexture->getSampler()}, - {3, mSkyboxTexture->getSampler()}, - {4, mDiffuseTexture->getTextureView()}, - {5, mNormalTexture->getTextureView()}, - {6, mReflectionTexture->getTextureView()}, - {7, mSkyboxTexture->getTextureView()}}); - } - else - { - mBindGroupModel = mContextDawn->makeBindGroup( - mGroupLayoutModel, {{0, mFishVertexBuffer, 0, sizeof(FishVertexUniforms)}, - {1, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, - {2, mDiffuseTexture->getSampler()}, - {3, mDiffuseTexture->getTextureView()}, - {4, mNormalTexture->getTextureView()}}); - } - - if (mEnableDynamicBufferOffset) - { - mBindGroupPers[0] = mContextDawn->makeBindGroup(mGroupLayoutPer, - {{0, mFishPersBuffer, 0, sizeof(FishPer)}}); - } - else - { - for (int i = 0; i < instance; i++) - { - mBindGroupPers[i] = mContextDawn->makeBindGroup( - mGroupLayoutPer, {{0, mFishPersBuffer, sizeof(FishPer) * i, sizeof(FishPer)}}); - } - } - - mContextDawn->setBufferData(mLightFactorBuffer, 0, sizeof(LightFactorUniforms), - &mLightFactorUniforms); - mContextDawn->setBufferData(mFishVertexBuffer, 0, sizeof(FishVertexUniforms), - &mFishVertexUniforms); -} - -void FishModelDawn::prepareForDraw() const {} - -void FishModelDawn::draw() -{ - if (instance == 0) - return; - - uint64_t vertexBufferOffsets[1] = {0}; - - mContextDawn->setBufferData(mFishPersBuffer, 0, sizeof(FishPer) * instance, mFishPers); - - dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); - pass.SetPipeline(mPipeline); - pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); - pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); - pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); - pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(3, 1, &mTangentBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(4, 1, &mBiNormalBuffer->getBuffer(), vertexBufferOffsets); - pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); - - if (mEnableDynamicBufferOffset) - { - for (int i = 0; i < instance; i++) - { - uint64_t offset = 256u * i; - pass.SetBindGroup(3, mBindGroupPers[0], 1, &offset); - pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); - } - } - else - { - for (int i = 0; i < instance; i++) - { - pass.SetBindGroup(3, mBindGroupPers[i], 0, nullptr); - pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); - } - } -} - -void FishModelDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) {} - -void FishModelDawn::updateFishPerUniforms(float x, - float y, - float z, - float nextX, - float nextY, - float nextZ, - float scale, - float time, - int index) -{ - mFishPers[index].worldPosition[0] = x; - mFishPers[index].worldPosition[1] = y; - mFishPers[index].worldPosition[2] = z; - mFishPers[index].nextPosition[0] = nextX; - mFishPers[index].nextPosition[1] = nextY; - mFishPers[index].nextPosition[2] = nextZ; - mFishPers[index].scale = scale; - mFishPers[index].time = time; -} - -FishModelDawn::~FishModelDawn() -{ - mPipeline = nullptr; - mGroupLayoutModel = nullptr; - mGroupLayoutPer = nullptr; - mPipelineLayout = nullptr; - mBindGroupModel = nullptr; - mFishVertexBuffer = nullptr; - mLightFactorBuffer = nullptr; - mFishPersBuffer = nullptr; - delete mFishPers; - if (mEnableDynamicBufferOffset) - { - mBindGroupPers[0] = nullptr; - } - else - { - for (int i = 0; i < instance; i++) - { - mBindGroupPers[i] = nullptr; - } - } - - mBindGroupPers = nullptr; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FishModelDawn.cpp: Implements fish model of Dawn. + +#include "FishModelDawn.h" +#include "BufferDawn.h" + +FishModelDawn::FishModelDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : FishModel(type, name, blend), instance(0) +{ + mContextDawn = static_cast(context); + + mEnableDynamicBufferOffset = + aquarium->toggleBitset.test(static_cast(TOGGLE::ENABLEDYNAMICBUFFEROFFSET)); + + mLightFactorUniforms.shininess = 5.0f; + mLightFactorUniforms.specularFactor = 0.3f; + + const Fish &fishInfo = fishTable[name - MODELNAME::MODELSMALLFISHA]; + mFishVertexUniforms.fishLength = fishInfo.fishLength; + mFishVertexUniforms.fishBendAmount = fishInfo.fishBendAmount; + mFishVertexUniforms.fishWaveLength = fishInfo.fishWaveLength; + + instance = aquarium->fishCount[fishInfo.modelName - MODELNAME::MODELSMALLFISHA]; + mFishPers = new FishPer[instance]; + if (mEnableDynamicBufferOffset) + { + mBindGroupPers = new dawn::BindGroup[1]; + } + else + { + mBindGroupPers = new dawn::BindGroup[instance]; + } +} + +void FishModelDawn::init() +{ + if (instance == 0) + return; + + mProgramDawn = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mTangentBuffer = static_cast(bufferMap["tangent"]); + mBiNormalBuffer = static_cast(bufferMap["binormal"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + mVertexInputDescriptor.cBuffers[0].attributeCount = 1; + mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; + mVertexInputDescriptor.cAttributes[0].offset = 0; + mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; + mVertexInputDescriptor.cBuffers[1].attributeCount = 1; + mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; + mVertexInputDescriptor.cAttributes[1].offset = 0; + mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; + mVertexInputDescriptor.cBuffers[2].attributeCount = 1; + mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; + mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; + mVertexInputDescriptor.cAttributes[2].offset = 0; + mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; + mVertexInputDescriptor.cBuffers[3].attributeCount = 1; + mVertexInputDescriptor.cBuffers[3].stride = mTangentBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[3].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[3].shaderLocation = 3; + mVertexInputDescriptor.cAttributes[3].offset = 0; + mVertexInputDescriptor.cBuffers[3].attributes = &mVertexInputDescriptor.cAttributes[3]; + mVertexInputDescriptor.cBuffers[4].attributeCount = 1; + mVertexInputDescriptor.cBuffers[4].stride = mBiNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[4].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[4].shaderLocation = 4; + mVertexInputDescriptor.cAttributes[4].offset = 0; + mVertexInputDescriptor.cBuffers[4].attributes = &mVertexInputDescriptor.cAttributes[4]; + mVertexInputDescriptor.bufferCount = 5; + mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; + + if (mSkyboxTexture && mReflectionTexture) + { + mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {5, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {6, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {7, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + }); + } + else + { + mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + }); + } + + if (mEnableDynamicBufferOffset) + { + mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer, true}, + }); + } + else + { + mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + }); + } + + mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ + mContextDawn->groupLayoutGeneral, + mContextDawn->groupLayoutWorld, + mGroupLayoutModel, + mGroupLayoutPer, + }); + + mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, + mVertexInputDescriptor, mBlend); + + mFishVertexBuffer = mContextDawn->createBufferFromData( + &mFishVertexUniforms, sizeof(FishVertexUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + mLightFactorBuffer = mContextDawn->createBufferFromData( + &mLightFactorUniforms, sizeof(LightFactorUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + mFishPersBuffer = mContextDawn->createBufferFromData( + mFishPers, sizeof(FishPer) * instance, + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + + // Fish models includes small, medium and big. Some of them contains reflection and skybox + // texture, but some doesn't. + if (mSkyboxTexture && mReflectionTexture) + { + mBindGroupModel = mContextDawn->makeBindGroup( + mGroupLayoutModel, {{0, mFishVertexBuffer, 0, sizeof(FishVertexUniforms)}, + {1, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, + {2, mReflectionTexture->getSampler()}, + {3, mSkyboxTexture->getSampler()}, + {4, mDiffuseTexture->getTextureView()}, + {5, mNormalTexture->getTextureView()}, + {6, mReflectionTexture->getTextureView()}, + {7, mSkyboxTexture->getTextureView()}}); + } + else + { + mBindGroupModel = mContextDawn->makeBindGroup( + mGroupLayoutModel, {{0, mFishVertexBuffer, 0, sizeof(FishVertexUniforms)}, + {1, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, + {2, mDiffuseTexture->getSampler()}, + {3, mDiffuseTexture->getTextureView()}, + {4, mNormalTexture->getTextureView()}}); + } + + if (mEnableDynamicBufferOffset) + { + mBindGroupPers[0] = mContextDawn->makeBindGroup(mGroupLayoutPer, + {{0, mFishPersBuffer, 0, sizeof(FishPer)}}); + } + else + { + for (int i = 0; i < instance; i++) + { + mBindGroupPers[i] = mContextDawn->makeBindGroup( + mGroupLayoutPer, {{0, mFishPersBuffer, sizeof(FishPer) * i, sizeof(FishPer)}}); + } + } + + mContextDawn->setBufferData(mLightFactorBuffer, 0, sizeof(LightFactorUniforms), + &mLightFactorUniforms); + mContextDawn->setBufferData(mFishVertexBuffer, 0, sizeof(FishVertexUniforms), + &mFishVertexUniforms); +} + +void FishModelDawn::prepareForDraw() const {} + +void FishModelDawn::draw() +{ + if (instance == 0) + return; + + uint64_t vertexBufferOffsets[1] = {0}; + + mContextDawn->setBufferData(mFishPersBuffer, 0, sizeof(FishPer) * instance, mFishPers); + + dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); + pass.SetPipeline(mPipeline); + pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); + pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); + pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); + pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(3, 1, &mTangentBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(4, 1, &mBiNormalBuffer->getBuffer(), vertexBufferOffsets); + pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); + + if (mEnableDynamicBufferOffset) + { + for (int i = 0; i < instance; i++) + { + uint64_t offset = 256u * i; + pass.SetBindGroup(3, mBindGroupPers[0], 1, &offset); + pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); + } + } + else + { + for (int i = 0; i < instance; i++) + { + pass.SetBindGroup(3, mBindGroupPers[i], 0, nullptr); + pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); + } + } +} + +void FishModelDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) {} + +void FishModelDawn::updateFishPerUniforms(float x, + float y, + float z, + float nextX, + float nextY, + float nextZ, + float scale, + float time, + int index) +{ + mFishPers[index].worldPosition[0] = x; + mFishPers[index].worldPosition[1] = y; + mFishPers[index].worldPosition[2] = z; + mFishPers[index].nextPosition[0] = nextX; + mFishPers[index].nextPosition[1] = nextY; + mFishPers[index].nextPosition[2] = nextZ; + mFishPers[index].scale = scale; + mFishPers[index].time = time; +} + +FishModelDawn::~FishModelDawn() +{ + mPipeline = nullptr; + mGroupLayoutModel = nullptr; + mGroupLayoutPer = nullptr; + mPipelineLayout = nullptr; + mBindGroupModel = nullptr; + mFishVertexBuffer = nullptr; + mLightFactorBuffer = nullptr; + mFishPersBuffer = nullptr; + delete mFishPers; + if (mEnableDynamicBufferOffset) + { + mBindGroupPers[0] = nullptr; + } + else + { + for (int i = 0; i < instance; i++) + { + mBindGroupPers[i] = nullptr; + } + } + + mBindGroupPers = nullptr; +} diff --git a/src/aquarium-optimized/dawn/FishModelDawn.h b/src/aquarium-optimized/dawn/FishModelDawn.h index 2802502..5bc7de7 100644 --- a/src/aquarium-optimized/dawn/FishModelDawn.h +++ b/src/aquarium-optimized/dawn/FishModelDawn.h @@ -1,104 +1,104 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FishModelDawn.h: Defnes fish model of Dawn - -#pragma once -#ifndef FISHMODELDAWN_H -#define FISHMODELDAWN_H 1 - -#include "ContextDawn.h" -#include "ProgramDawn.h" -#include "dawn/dawncpp.h" -#include "utils/ComboRenderPipelineDescriptor.h" - -#include "../FishModel.h" - -class FishModelDawn : public FishModel -{ - public: - FishModelDawn(const Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - ~FishModelDawn(); - - void init() override; - void prepareForDraw() const override; - void draw() override; - - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - void updateFishPerUniforms(float x, - float y, - float z, - float nextX, - float nextY, - float nextZ, - float scale, - float time, - int index) override; - - struct FishVertexUniforms - { - float fishLength; - float fishWaveLength; - float fishBendAmount; - } mFishVertexUniforms; - - struct LightFactorUniforms - { - float shininess; - float specularFactor; - } mLightFactorUniforms; - - struct FishPer - { - float worldPosition[3]; - float scale; - float nextPosition[3]; - float time; - float padding[56]; // TODO(yizhou): the padding is to align with 256 byte offset. - }; - FishPer *mFishPers; - - TextureDawn *mDiffuseTexture; - TextureDawn *mNormalTexture; - TextureDawn *mReflectionTexture; - TextureDawn *mSkyboxTexture; - - BufferDawn *mPositionBuffer; - BufferDawn *mNormalBuffer; - BufferDawn *mTexCoordBuffer; - BufferDawn *mTangentBuffer; - BufferDawn *mBiNormalBuffer; - - BufferDawn *mIndicesBuffer; - - private: - utils::ComboVertexInputDescriptor mVertexInputDescriptor; - dawn::RenderPipeline mPipeline; - - dawn::BindGroupLayout mGroupLayoutModel; - dawn::BindGroupLayout mGroupLayoutPer; - dawn::PipelineLayout mPipelineLayout; - - dawn::BindGroup mBindGroupModel; - dawn::BindGroup *mBindGroupPers; - - dawn::Buffer mFishVertexBuffer; - dawn::Buffer mLightFactorBuffer; - - dawn::Buffer mFishPersBuffer; - - int instance; - - ProgramDawn *mProgramDawn; - const ContextDawn *mContextDawn; - - bool mEnableDynamicBufferOffset; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FishModelDawn.h: Defnes fish model of Dawn + +#pragma once +#ifndef FISHMODELDAWN_H +#define FISHMODELDAWN_H 1 + +#include "ContextDawn.h" +#include "ProgramDawn.h" +#include "dawn/dawncpp.h" +#include "utils/ComboRenderPipelineDescriptor.h" + +#include "../FishModel.h" + +class FishModelDawn : public FishModel +{ + public: + FishModelDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + ~FishModelDawn(); + + void init() override; + void prepareForDraw() const override; + void draw() override; + + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + void updateFishPerUniforms(float x, + float y, + float z, + float nextX, + float nextY, + float nextZ, + float scale, + float time, + int index) override; + + struct FishVertexUniforms + { + float fishLength; + float fishWaveLength; + float fishBendAmount; + } mFishVertexUniforms; + + struct LightFactorUniforms + { + float shininess; + float specularFactor; + } mLightFactorUniforms; + + struct FishPer + { + float worldPosition[3]; + float scale; + float nextPosition[3]; + float time; + float padding[56]; // TODO(yizhou): the padding is to align with 256 byte offset. + }; + FishPer *mFishPers; + + TextureDawn *mDiffuseTexture; + TextureDawn *mNormalTexture; + TextureDawn *mReflectionTexture; + TextureDawn *mSkyboxTexture; + + BufferDawn *mPositionBuffer; + BufferDawn *mNormalBuffer; + BufferDawn *mTexCoordBuffer; + BufferDawn *mTangentBuffer; + BufferDawn *mBiNormalBuffer; + + BufferDawn *mIndicesBuffer; + + private: + utils::ComboVertexInputDescriptor mVertexInputDescriptor; + dawn::RenderPipeline mPipeline; + + dawn::BindGroupLayout mGroupLayoutModel; + dawn::BindGroupLayout mGroupLayoutPer; + dawn::PipelineLayout mPipelineLayout; + + dawn::BindGroup mBindGroupModel; + dawn::BindGroup *mBindGroupPers; + + dawn::Buffer mFishVertexBuffer; + dawn::Buffer mLightFactorBuffer; + + dawn::Buffer mFishPersBuffer; + + int instance; + + ProgramDawn *mProgramDawn; + const ContextDawn *mContextDawn; + + bool mEnableDynamicBufferOffset; +}; + +#endif diff --git a/src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.cpp b/src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.cpp index 39582c2..e0ecc4a 100644 --- a/src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.cpp +++ b/src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.cpp @@ -1,238 +1,238 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FishModelDawn.cpp: Implements fish model of Dawn. - -#include "BufferDawn.h" -#include "FishModelInstancedDrawDawn.h" - -FishModelInstancedDrawDawn::FishModelInstancedDrawDawn(const Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : FishModel(type, name, blend), instance(0) -{ - mContextDawn = static_cast(context); - - mLightFactorUniforms.shininess = 5.0f; - mLightFactorUniforms.specularFactor = 0.3f; - - const Fish &fishInfo = fishTable[name - MODELNAME::MODELSMALLFISHAINSTANCEDDRAWS]; - mFishVertexUniforms.fishLength = fishInfo.fishLength; - mFishVertexUniforms.fishBendAmount = fishInfo.fishBendAmount; - mFishVertexUniforms.fishWaveLength = fishInfo.fishWaveLength; - - instance = aquarium->fishCount[fishInfo.modelName - MODELNAME::MODELSMALLFISHA]; - mFishPers = new FishPer[instance]; -} - -void FishModelInstancedDrawDawn::init() -{ - if (instance == 0) - return; - - mProgramDawn = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mTangentBuffer = static_cast(bufferMap["tangent"]); - mBiNormalBuffer = static_cast(bufferMap["binormal"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - mFishPersBuffer = mContextDawn->createBuffer( - sizeof(FishPer) * instance, dawn::BufferUsageBit::Vertex | dawn::BufferUsageBit::CopyDst); - - mVertexInputDescriptor.cBuffers[0].attributeCount = 1; - mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; - mVertexInputDescriptor.cAttributes[0].offset = 0; - mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; - mVertexInputDescriptor.cBuffers[1].attributeCount = 1; - mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; - mVertexInputDescriptor.cAttributes[1].offset = 0; - mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; - mVertexInputDescriptor.cBuffers[2].attributeCount = 1; - mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; - mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; - mVertexInputDescriptor.cAttributes[2].offset = 0; - mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; - mVertexInputDescriptor.cBuffers[3].attributeCount = 1; - mVertexInputDescriptor.cBuffers[3].stride = mTangentBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[3].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[3].shaderLocation = 3; - mVertexInputDescriptor.cAttributes[3].offset = 0; - mVertexInputDescriptor.cBuffers[3].attributes = &mVertexInputDescriptor.cAttributes[3]; - mVertexInputDescriptor.cBuffers[4].attributeCount = 1; - mVertexInputDescriptor.cBuffers[4].stride = mBiNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[4].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[4].shaderLocation = 4; - mVertexInputDescriptor.cAttributes[4].offset = offsetof(FishPer, worldPosition); - mVertexInputDescriptor.cBuffers[4].attributes = &mVertexInputDescriptor.cAttributes[4]; - mVertexInputDescriptor.cBuffers[5].attributeCount = 4; - mVertexInputDescriptor.cBuffers[5].stride = sizeof(FishPer); - mVertexInputDescriptor.cAttributes[5].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[5].shaderLocation = 5; - mVertexInputDescriptor.cAttributes[5].offset = 0; - mVertexInputDescriptor.cAttributes[6].format = dawn::VertexFormat::Float; - mVertexInputDescriptor.cAttributes[6].shaderLocation = 6; - mVertexInputDescriptor.cAttributes[6].offset = offsetof(FishPer, scale); - mVertexInputDescriptor.cAttributes[7].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[7].shaderLocation = 7; - mVertexInputDescriptor.cAttributes[7].offset = offsetof(FishPer, nextPosition); - mVertexInputDescriptor.cAttributes[8].format = dawn::VertexFormat::Float; - mVertexInputDescriptor.cAttributes[8].shaderLocation = 8; - mVertexInputDescriptor.cAttributes[9].offset = offsetof(FishPer, time); - mVertexInputDescriptor.cBuffers[5].attributes = &mVertexInputDescriptor.cAttributes[5]; - mVertexInputDescriptor.cBuffers[5].stepMode = dawn::InputStepMode::Instance; - mVertexInputDescriptor.bufferCount = 6; - mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; - - if (mSkyboxTexture && mReflectionTexture) - { - mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, - {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {5, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {6, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {7, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - }); - } - else - { - mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, - {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - }); - } - - mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - }); - - mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ - mContextDawn->groupLayoutGeneral, - mContextDawn->groupLayoutWorld, - mGroupLayoutModel, - mGroupLayoutPer, - }); - - mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, - mVertexInputDescriptor, mBlend); - - mFishVertexBuffer = mContextDawn->createBufferFromData( - &mFishVertexUniforms, sizeof(FishVertexUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - mLightFactorBuffer = mContextDawn->createBufferFromData( - &mLightFactorUniforms, sizeof(LightFactorUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - - // Fish models includes small, medium and big. Some of them contains reflection and skybox - // texture, but some doesn't. - if (mSkyboxTexture && mReflectionTexture) - { - mBindGroupModel = mContextDawn->makeBindGroup( - mGroupLayoutModel, {{0, mFishVertexBuffer, 0, sizeof(FishVertexUniforms)}, - {1, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, - {2, mReflectionTexture->getSampler()}, - {3, mSkyboxTexture->getSampler()}, - {4, mDiffuseTexture->getTextureView()}, - {5, mNormalTexture->getTextureView()}, - {6, mReflectionTexture->getTextureView()}, - {7, mSkyboxTexture->getTextureView()}}); - } - else - { - mBindGroupModel = mContextDawn->makeBindGroup( - mGroupLayoutModel, {{0, mFishVertexBuffer, 0, sizeof(FishVertexUniforms)}, - {1, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, - {2, mDiffuseTexture->getSampler()}, - {3, mDiffuseTexture->getTextureView()}, - {4, mNormalTexture->getTextureView()}}); - } - - mContextDawn->setBufferData(mLightFactorBuffer, 0, sizeof(LightFactorUniforms), - &mLightFactorUniforms); - mContextDawn->setBufferData(mFishVertexBuffer, 0, sizeof(FishVertexUniforms), - &mFishVertexUniforms); -} - -void FishModelInstancedDrawDawn::prepareForDraw() const {} - -void FishModelInstancedDrawDawn::draw() -{ - if (instance == 0) - return; - - uint64_t vertexBufferOffsets[1] = {0}; - - mContextDawn->setBufferData(mFishPersBuffer, 0, sizeof(FishPer) * instance, mFishPers); - - dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); - pass.SetPipeline(mPipeline); - pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); - pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); - pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); - pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(3, 1, &mTangentBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(4, 1, &mBiNormalBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(5, 1, &mFishPersBuffer, vertexBufferOffsets); - pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); - pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), instance, 0, 0, 0); -} - -void FishModelInstancedDrawDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) {} - -void FishModelInstancedDrawDawn::updateFishPerUniforms(float x, - float y, - float z, - float nextX, - float nextY, - float nextZ, - float scale, - float time, - int index) -{ - mFishPers[index].worldPosition[0] = x; - mFishPers[index].worldPosition[1] = y; - mFishPers[index].worldPosition[2] = z; - mFishPers[index].nextPosition[0] = nextX; - mFishPers[index].nextPosition[1] = nextY; - mFishPers[index].nextPosition[2] = nextZ; - mFishPers[index].scale = scale; - mFishPers[index].time = time; -} - -FishModelInstancedDrawDawn::~FishModelInstancedDrawDawn() -{ - mPipeline = nullptr; - mGroupLayoutModel = nullptr; - mGroupLayoutPer = nullptr; - mPipelineLayout = nullptr; - mBindGroupModel = nullptr; - mBindGroupPer = nullptr; - mFishVertexBuffer = nullptr; - mLightFactorBuffer = nullptr; - mFishPersBuffer = nullptr; - delete mFishPers; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FishModelDawn.cpp: Implements fish model of Dawn. + +#include "FishModelInstancedDrawDawn.h" +#include "BufferDawn.h" + +FishModelInstancedDrawDawn::FishModelInstancedDrawDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : FishModel(type, name, blend), instance(0) +{ + mContextDawn = static_cast(context); + + mLightFactorUniforms.shininess = 5.0f; + mLightFactorUniforms.specularFactor = 0.3f; + + const Fish &fishInfo = fishTable[name - MODELNAME::MODELSMALLFISHAINSTANCEDDRAWS]; + mFishVertexUniforms.fishLength = fishInfo.fishLength; + mFishVertexUniforms.fishBendAmount = fishInfo.fishBendAmount; + mFishVertexUniforms.fishWaveLength = fishInfo.fishWaveLength; + + instance = aquarium->fishCount[fishInfo.modelName - MODELNAME::MODELSMALLFISHA]; + mFishPers = new FishPer[instance]; +} + +void FishModelInstancedDrawDawn::init() +{ + if (instance == 0) + return; + + mProgramDawn = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mTangentBuffer = static_cast(bufferMap["tangent"]); + mBiNormalBuffer = static_cast(bufferMap["binormal"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + mFishPersBuffer = mContextDawn->createBuffer( + sizeof(FishPer) * instance, dawn::BufferUsageBit::Vertex | dawn::BufferUsageBit::CopyDst); + + mVertexInputDescriptor.cBuffers[0].attributeCount = 1; + mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; + mVertexInputDescriptor.cAttributes[0].offset = 0; + mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; + mVertexInputDescriptor.cBuffers[1].attributeCount = 1; + mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; + mVertexInputDescriptor.cAttributes[1].offset = 0; + mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; + mVertexInputDescriptor.cBuffers[2].attributeCount = 1; + mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; + mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; + mVertexInputDescriptor.cAttributes[2].offset = 0; + mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; + mVertexInputDescriptor.cBuffers[3].attributeCount = 1; + mVertexInputDescriptor.cBuffers[3].stride = mTangentBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[3].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[3].shaderLocation = 3; + mVertexInputDescriptor.cAttributes[3].offset = 0; + mVertexInputDescriptor.cBuffers[3].attributes = &mVertexInputDescriptor.cAttributes[3]; + mVertexInputDescriptor.cBuffers[4].attributeCount = 1; + mVertexInputDescriptor.cBuffers[4].stride = mBiNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[4].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[4].shaderLocation = 4; + mVertexInputDescriptor.cAttributes[4].offset = offsetof(FishPer, worldPosition); + mVertexInputDescriptor.cBuffers[4].attributes = &mVertexInputDescriptor.cAttributes[4]; + mVertexInputDescriptor.cBuffers[5].attributeCount = 4; + mVertexInputDescriptor.cBuffers[5].stride = sizeof(FishPer); + mVertexInputDescriptor.cAttributes[5].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[5].shaderLocation = 5; + mVertexInputDescriptor.cAttributes[5].offset = 0; + mVertexInputDescriptor.cAttributes[6].format = dawn::VertexFormat::Float; + mVertexInputDescriptor.cAttributes[6].shaderLocation = 6; + mVertexInputDescriptor.cAttributes[6].offset = offsetof(FishPer, scale); + mVertexInputDescriptor.cAttributes[7].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[7].shaderLocation = 7; + mVertexInputDescriptor.cAttributes[7].offset = offsetof(FishPer, nextPosition); + mVertexInputDescriptor.cAttributes[8].format = dawn::VertexFormat::Float; + mVertexInputDescriptor.cAttributes[8].shaderLocation = 8; + mVertexInputDescriptor.cAttributes[9].offset = offsetof(FishPer, time); + mVertexInputDescriptor.cBuffers[5].attributes = &mVertexInputDescriptor.cAttributes[5]; + mVertexInputDescriptor.cBuffers[5].stepMode = dawn::InputStepMode::Instance; + mVertexInputDescriptor.bufferCount = 6; + mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; + + if (mSkyboxTexture && mReflectionTexture) + { + mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {5, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {6, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {7, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + }); + } + else + { + mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + }); + } + + mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + }); + + mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ + mContextDawn->groupLayoutGeneral, + mContextDawn->groupLayoutWorld, + mGroupLayoutModel, + mGroupLayoutPer, + }); + + mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, + mVertexInputDescriptor, mBlend); + + mFishVertexBuffer = mContextDawn->createBufferFromData( + &mFishVertexUniforms, sizeof(FishVertexUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + mLightFactorBuffer = mContextDawn->createBufferFromData( + &mLightFactorUniforms, sizeof(LightFactorUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + + // Fish models includes small, medium and big. Some of them contains reflection and skybox + // texture, but some doesn't. + if (mSkyboxTexture && mReflectionTexture) + { + mBindGroupModel = mContextDawn->makeBindGroup( + mGroupLayoutModel, {{0, mFishVertexBuffer, 0, sizeof(FishVertexUniforms)}, + {1, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, + {2, mReflectionTexture->getSampler()}, + {3, mSkyboxTexture->getSampler()}, + {4, mDiffuseTexture->getTextureView()}, + {5, mNormalTexture->getTextureView()}, + {6, mReflectionTexture->getTextureView()}, + {7, mSkyboxTexture->getTextureView()}}); + } + else + { + mBindGroupModel = mContextDawn->makeBindGroup( + mGroupLayoutModel, {{0, mFishVertexBuffer, 0, sizeof(FishVertexUniforms)}, + {1, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, + {2, mDiffuseTexture->getSampler()}, + {3, mDiffuseTexture->getTextureView()}, + {4, mNormalTexture->getTextureView()}}); + } + + mContextDawn->setBufferData(mLightFactorBuffer, 0, sizeof(LightFactorUniforms), + &mLightFactorUniforms); + mContextDawn->setBufferData(mFishVertexBuffer, 0, sizeof(FishVertexUniforms), + &mFishVertexUniforms); +} + +void FishModelInstancedDrawDawn::prepareForDraw() const {} + +void FishModelInstancedDrawDawn::draw() +{ + if (instance == 0) + return; + + uint64_t vertexBufferOffsets[1] = {0}; + + mContextDawn->setBufferData(mFishPersBuffer, 0, sizeof(FishPer) * instance, mFishPers); + + dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); + pass.SetPipeline(mPipeline); + pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); + pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); + pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); + pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(3, 1, &mTangentBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(4, 1, &mBiNormalBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(5, 1, &mFishPersBuffer, vertexBufferOffsets); + pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); + pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), instance, 0, 0, 0); +} + +void FishModelInstancedDrawDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) {} + +void FishModelInstancedDrawDawn::updateFishPerUniforms(float x, + float y, + float z, + float nextX, + float nextY, + float nextZ, + float scale, + float time, + int index) +{ + mFishPers[index].worldPosition[0] = x; + mFishPers[index].worldPosition[1] = y; + mFishPers[index].worldPosition[2] = z; + mFishPers[index].nextPosition[0] = nextX; + mFishPers[index].nextPosition[1] = nextY; + mFishPers[index].nextPosition[2] = nextZ; + mFishPers[index].scale = scale; + mFishPers[index].time = time; +} + +FishModelInstancedDrawDawn::~FishModelInstancedDrawDawn() +{ + mPipeline = nullptr; + mGroupLayoutModel = nullptr; + mGroupLayoutPer = nullptr; + mPipelineLayout = nullptr; + mBindGroupModel = nullptr; + mBindGroupPer = nullptr; + mFishVertexBuffer = nullptr; + mLightFactorBuffer = nullptr; + mFishPersBuffer = nullptr; + delete mFishPers; +} diff --git a/src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.h b/src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.h index 781ff3e..f29f71e 100644 --- a/src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.h +++ b/src/aquarium-optimized/dawn/FishModelInstancedDrawDawn.h @@ -1,101 +1,101 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FishModelDawn.h: Defnes fish model of Dawn - -#pragma once -#ifndef FISHMODELINSTANCEDDRAWDAWN_H -#define FISHMODELINSTANCEDDRAWDAWN_H 1 - -#include "ContextDawn.h" -#include "ProgramDawn.h" -#include "dawn/dawncpp.h" -#include "utils/ComboRenderPipelineDescriptor.h" - -#include "../FishModel.h" - -class FishModelInstancedDrawDawn : public FishModel -{ - public: - FishModelInstancedDrawDawn(const Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - ~FishModelInstancedDrawDawn(); - - void init() override; - void prepareForDraw() const override; - void draw() override; - - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - void updateFishPerUniforms(float x, - float y, - float z, - float nextX, - float nextY, - float nextZ, - float scale, - float time, - int index) override; - - struct FishVertexUniforms - { - float fishLength; - float fishWaveLength; - float fishBendAmount; - } mFishVertexUniforms; - - struct LightFactorUniforms - { - float shininess; - float specularFactor; - } mLightFactorUniforms; - - struct FishPer - { - float worldPosition[3]; - float scale; - float nextPosition[3]; - float time; - }; - FishPer *mFishPers; - - TextureDawn *mDiffuseTexture; - TextureDawn *mNormalTexture; - TextureDawn *mReflectionTexture; - TextureDawn *mSkyboxTexture; - - BufferDawn *mPositionBuffer; - BufferDawn *mNormalBuffer; - BufferDawn *mTexCoordBuffer; - BufferDawn *mTangentBuffer; - BufferDawn *mBiNormalBuffer; - - BufferDawn *mIndicesBuffer; - - private: - utils::ComboVertexInputDescriptor mVertexInputDescriptor; - dawn::RenderPipeline mPipeline; - - dawn::BindGroupLayout mGroupLayoutModel; - dawn::BindGroupLayout mGroupLayoutPer; - dawn::PipelineLayout mPipelineLayout; - - dawn::BindGroup mBindGroupModel; - dawn::BindGroup mBindGroupPer; - - dawn::Buffer mFishVertexBuffer; - dawn::Buffer mLightFactorBuffer; - - dawn::Buffer mFishPersBuffer; - - int instance; - - ProgramDawn *mProgramDawn; - const ContextDawn *mContextDawn; -}; - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FishModelDawn.h: Defnes fish model of Dawn + +#pragma once +#ifndef FISHMODELINSTANCEDDRAWDAWN_H +#define FISHMODELINSTANCEDDRAWDAWN_H 1 + +#include "ContextDawn.h" +#include "ProgramDawn.h" +#include "dawn/dawncpp.h" +#include "utils/ComboRenderPipelineDescriptor.h" + +#include "../FishModel.h" + +class FishModelInstancedDrawDawn : public FishModel +{ + public: + FishModelInstancedDrawDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + ~FishModelInstancedDrawDawn(); + + void init() override; + void prepareForDraw() const override; + void draw() override; + + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + void updateFishPerUniforms(float x, + float y, + float z, + float nextX, + float nextY, + float nextZ, + float scale, + float time, + int index) override; + + struct FishVertexUniforms + { + float fishLength; + float fishWaveLength; + float fishBendAmount; + } mFishVertexUniforms; + + struct LightFactorUniforms + { + float shininess; + float specularFactor; + } mLightFactorUniforms; + + struct FishPer + { + float worldPosition[3]; + float scale; + float nextPosition[3]; + float time; + }; + FishPer *mFishPers; + + TextureDawn *mDiffuseTexture; + TextureDawn *mNormalTexture; + TextureDawn *mReflectionTexture; + TextureDawn *mSkyboxTexture; + + BufferDawn *mPositionBuffer; + BufferDawn *mNormalBuffer; + BufferDawn *mTexCoordBuffer; + BufferDawn *mTangentBuffer; + BufferDawn *mBiNormalBuffer; + + BufferDawn *mIndicesBuffer; + + private: + utils::ComboVertexInputDescriptor mVertexInputDescriptor; + dawn::RenderPipeline mPipeline; + + dawn::BindGroupLayout mGroupLayoutModel; + dawn::BindGroupLayout mGroupLayoutPer; + dawn::PipelineLayout mPipelineLayout; + + dawn::BindGroup mBindGroupModel; + dawn::BindGroup mBindGroupPer; + + dawn::Buffer mFishVertexBuffer; + dawn::Buffer mLightFactorBuffer; + + dawn::Buffer mFishPersBuffer; + + int instance; + + ProgramDawn *mProgramDawn; + const ContextDawn *mContextDawn; +}; + #endif \ No newline at end of file diff --git a/src/aquarium-optimized/dawn/GenericModelDawn.cpp b/src/aquarium-optimized/dawn/GenericModelDawn.cpp index c1cbca7..80094a5 100644 --- a/src/aquarium-optimized/dawn/GenericModelDawn.cpp +++ b/src/aquarium-optimized/dawn/GenericModelDawn.cpp @@ -1,242 +1,242 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "GenericModelDawn.h" - -#include "../Aquarium.h" - -GenericModelDawn::GenericModelDawn(const Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : Model(type, name, blend), instance(0) -{ - mContextDawn = static_cast(context); - - mLightFactorUniforms.shininess = 50.0f; - mLightFactorUniforms.specularFactor = 1.0f; -} - -GenericModelDawn::~GenericModelDawn() -{ - mPipeline = nullptr; - mGroupLayoutModel = nullptr; - mGroupLayoutPer = nullptr; - mPipelineLayout = nullptr; - mBindGroupModel = nullptr; - mBindGroupPer = nullptr; - mLightFactorBuffer = nullptr; - mWorldBuffer = nullptr; -} - -void GenericModelDawn::init() -{ - mProgramDawn = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mTangentBuffer = static_cast(bufferMap["tangent"]); - mBiNormalBuffer = static_cast(bufferMap["binormal"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - // Generic models use reflection, normal or diffuse shaders, of which groupLayouts are - // diiferent in texture binding. MODELGLOBEBASE use diffuse shader though it contains - // normal and reflection textures. - if (mNormalTexture && mName != MODELNAME::MODELGLOBEBASE) - { - mVertexInputDescriptor.cBuffers[0].attributeCount = 1; - mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; - mVertexInputDescriptor.cAttributes[0].offset = 0; - mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; - mVertexInputDescriptor.cBuffers[1].attributeCount = 1; - mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; - mVertexInputDescriptor.cAttributes[1].offset = 0; - mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; - mVertexInputDescriptor.cBuffers[2].attributeCount = 1; - mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; - mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; - mVertexInputDescriptor.cAttributes[2].offset = 0; - mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; - mVertexInputDescriptor.cBuffers[3].attributeCount = 1; - mVertexInputDescriptor.cBuffers[3].stride = mTangentBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[3].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[3].shaderLocation = 3; - mVertexInputDescriptor.cAttributes[3].offset = 0; - mVertexInputDescriptor.cBuffers[3].attributes = &mVertexInputDescriptor.cAttributes[3]; - mVertexInputDescriptor.cBuffers[4].attributeCount = 1; - mVertexInputDescriptor.cBuffers[4].stride = mBiNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[4].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[4].shaderLocation = 4; - mVertexInputDescriptor.cAttributes[4].offset = 0; - mVertexInputDescriptor.cBuffers[4].attributes = &mVertexInputDescriptor.cAttributes[4]; - mVertexInputDescriptor.bufferCount = 5; - mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; - } - else - { - mVertexInputDescriptor.cBuffers[0].attributeCount = 1; - mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; - mVertexInputDescriptor.cAttributes[0].offset = 0; - mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; - mVertexInputDescriptor.cBuffers[1].attributeCount = 1; - mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; - mVertexInputDescriptor.cAttributes[1].offset = 0; - mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; - mVertexInputDescriptor.cBuffers[2].attributeCount = 1; - mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; - mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; - mVertexInputDescriptor.cAttributes[2].offset = 0; - mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; - mVertexInputDescriptor.bufferCount = 3; - mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; - } - - if (mSkyboxTexture && mReflectionTexture && mName != MODELNAME::MODELGLOBEBASE) - { - mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {5, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {6, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - }); - } - else if (mNormalTexture && mName != MODELNAME::MODELGLOBEBASE) - { - mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - }); - } - else - { - mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - }); - } - - mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - }); - - mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ - mContextDawn->groupLayoutGeneral, - mContextDawn->groupLayoutWorld, - mGroupLayoutModel, - mGroupLayoutPer, - }); - - mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, - mVertexInputDescriptor, mBlend); - - mLightFactorBuffer = mContextDawn->createBufferFromData( - &mLightFactorUniforms, sizeof(mLightFactorUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - mWorldBuffer = mContextDawn->createBufferFromData( - &mWorldUniformPer, sizeof(mWorldUniformPer), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - - // Generic models use reflection, normal or diffuse shaders, of which grouplayouts are - // diiferent in texture binding. MODELGLOBEBASE use diffuse shader though it contains - // normal and reflection textures. - if (mSkyboxTexture && mReflectionTexture && mName != MODELNAME::MODELGLOBEBASE) - { - mBindGroupModel = mContextDawn->makeBindGroup( - mGroupLayoutModel, {{0, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, - {1, mReflectionTexture->getSampler()}, - {2, mSkyboxTexture->getSampler()}, - {3, mDiffuseTexture->getTextureView()}, - {4, mNormalTexture->getTextureView()}, - {5, mReflectionTexture->getTextureView()}, - {6, mSkyboxTexture->getTextureView()}}); - } - else if (mNormalTexture && mName != MODELNAME::MODELGLOBEBASE) - { - mBindGroupModel = mContextDawn->makeBindGroup( - mGroupLayoutModel, { - {0, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, - {1, mDiffuseTexture->getSampler()}, - {2, mDiffuseTexture->getTextureView()}, - {3, mNormalTexture->getTextureView()}, - }); - } - else - { - mBindGroupModel = mContextDawn->makeBindGroup( - mGroupLayoutModel, { - {0, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, - {1, mDiffuseTexture->getSampler()}, - {2, mDiffuseTexture->getTextureView()}, - }); - } - - mBindGroupPer = mContextDawn->makeBindGroup(mGroupLayoutPer, - { - {0, mWorldBuffer, 0, sizeof(WorldUniformPer)}, - }); - - mContextDawn->setBufferData(mLightFactorBuffer, 0, sizeof(LightFactorUniforms), - &mLightFactorUniforms); -} - -void GenericModelDawn::prepareForDraw() const -{ - mContextDawn->setBufferData(mWorldBuffer, 0, sizeof(WorldUniformPer), &mWorldUniformPer); -} - -void GenericModelDawn::draw() -{ - uint64_t vertexBufferOffsets[1] = {0}; - - dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); - pass.SetPipeline(mPipeline); - pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); - pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); - pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); - pass.SetBindGroup(3, mBindGroupPer, 0, nullptr); - pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); - // diffuseShader doesn't have to input tangent buffer or binormal buffer. - if (mTangentBuffer && mBiNormalBuffer && mName != MODELNAME::MODELGLOBEBASE) - { - pass.SetVertexBuffers(3, 1, &mTangentBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(4, 1, &mBiNormalBuffer->getBuffer(), vertexBufferOffsets); - } - pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); - pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), instance, 0, 0, 0); - instance = 0; -} - -void GenericModelDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) -{ - mWorldUniformPer.WorldUniforms[instance] = worldUniforms; - - instance++; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "GenericModelDawn.h" + +#include "../Aquarium.h" + +GenericModelDawn::GenericModelDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : Model(type, name, blend), instance(0) +{ + mContextDawn = static_cast(context); + + mLightFactorUniforms.shininess = 50.0f; + mLightFactorUniforms.specularFactor = 1.0f; +} + +GenericModelDawn::~GenericModelDawn() +{ + mPipeline = nullptr; + mGroupLayoutModel = nullptr; + mGroupLayoutPer = nullptr; + mPipelineLayout = nullptr; + mBindGroupModel = nullptr; + mBindGroupPer = nullptr; + mLightFactorBuffer = nullptr; + mWorldBuffer = nullptr; +} + +void GenericModelDawn::init() +{ + mProgramDawn = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mTangentBuffer = static_cast(bufferMap["tangent"]); + mBiNormalBuffer = static_cast(bufferMap["binormal"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + // Generic models use reflection, normal or diffuse shaders, of which groupLayouts are + // diiferent in texture binding. MODELGLOBEBASE use diffuse shader though it contains + // normal and reflection textures. + if (mNormalTexture && mName != MODELNAME::MODELGLOBEBASE) + { + mVertexInputDescriptor.cBuffers[0].attributeCount = 1; + mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; + mVertexInputDescriptor.cAttributes[0].offset = 0; + mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; + mVertexInputDescriptor.cBuffers[1].attributeCount = 1; + mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; + mVertexInputDescriptor.cAttributes[1].offset = 0; + mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; + mVertexInputDescriptor.cBuffers[2].attributeCount = 1; + mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; + mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; + mVertexInputDescriptor.cAttributes[2].offset = 0; + mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; + mVertexInputDescriptor.cBuffers[3].attributeCount = 1; + mVertexInputDescriptor.cBuffers[3].stride = mTangentBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[3].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[3].shaderLocation = 3; + mVertexInputDescriptor.cAttributes[3].offset = 0; + mVertexInputDescriptor.cBuffers[3].attributes = &mVertexInputDescriptor.cAttributes[3]; + mVertexInputDescriptor.cBuffers[4].attributeCount = 1; + mVertexInputDescriptor.cBuffers[4].stride = mBiNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[4].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[4].shaderLocation = 4; + mVertexInputDescriptor.cAttributes[4].offset = 0; + mVertexInputDescriptor.cBuffers[4].attributes = &mVertexInputDescriptor.cAttributes[4]; + mVertexInputDescriptor.bufferCount = 5; + mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; + } + else + { + mVertexInputDescriptor.cBuffers[0].attributeCount = 1; + mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; + mVertexInputDescriptor.cAttributes[0].offset = 0; + mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; + mVertexInputDescriptor.cBuffers[1].attributeCount = 1; + mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; + mVertexInputDescriptor.cAttributes[1].offset = 0; + mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; + mVertexInputDescriptor.cBuffers[2].attributeCount = 1; + mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; + mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; + mVertexInputDescriptor.cAttributes[2].offset = 0; + mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; + mVertexInputDescriptor.bufferCount = 3; + mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; + } + + if (mSkyboxTexture && mReflectionTexture && mName != MODELNAME::MODELGLOBEBASE) + { + mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {5, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {6, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + }); + } + else if (mNormalTexture && mName != MODELNAME::MODELGLOBEBASE) + { + mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + }); + } + else + { + mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + }); + } + + mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + }); + + mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ + mContextDawn->groupLayoutGeneral, + mContextDawn->groupLayoutWorld, + mGroupLayoutModel, + mGroupLayoutPer, + }); + + mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, + mVertexInputDescriptor, mBlend); + + mLightFactorBuffer = mContextDawn->createBufferFromData( + &mLightFactorUniforms, sizeof(mLightFactorUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + mWorldBuffer = mContextDawn->createBufferFromData( + &mWorldUniformPer, sizeof(mWorldUniformPer), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + + // Generic models use reflection, normal or diffuse shaders, of which grouplayouts are + // diiferent in texture binding. MODELGLOBEBASE use diffuse shader though it contains + // normal and reflection textures. + if (mSkyboxTexture && mReflectionTexture && mName != MODELNAME::MODELGLOBEBASE) + { + mBindGroupModel = mContextDawn->makeBindGroup( + mGroupLayoutModel, {{0, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, + {1, mReflectionTexture->getSampler()}, + {2, mSkyboxTexture->getSampler()}, + {3, mDiffuseTexture->getTextureView()}, + {4, mNormalTexture->getTextureView()}, + {5, mReflectionTexture->getTextureView()}, + {6, mSkyboxTexture->getTextureView()}}); + } + else if (mNormalTexture && mName != MODELNAME::MODELGLOBEBASE) + { + mBindGroupModel = mContextDawn->makeBindGroup( + mGroupLayoutModel, { + {0, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, + {1, mDiffuseTexture->getSampler()}, + {2, mDiffuseTexture->getTextureView()}, + {3, mNormalTexture->getTextureView()}, + }); + } + else + { + mBindGroupModel = mContextDawn->makeBindGroup( + mGroupLayoutModel, { + {0, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, + {1, mDiffuseTexture->getSampler()}, + {2, mDiffuseTexture->getTextureView()}, + }); + } + + mBindGroupPer = mContextDawn->makeBindGroup(mGroupLayoutPer, + { + {0, mWorldBuffer, 0, sizeof(WorldUniformPer)}, + }); + + mContextDawn->setBufferData(mLightFactorBuffer, 0, sizeof(LightFactorUniforms), + &mLightFactorUniforms); +} + +void GenericModelDawn::prepareForDraw() const +{ + mContextDawn->setBufferData(mWorldBuffer, 0, sizeof(WorldUniformPer), &mWorldUniformPer); +} + +void GenericModelDawn::draw() +{ + uint64_t vertexBufferOffsets[1] = {0}; + + dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); + pass.SetPipeline(mPipeline); + pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); + pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); + pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); + pass.SetBindGroup(3, mBindGroupPer, 0, nullptr); + pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); + // diffuseShader doesn't have to input tangent buffer or binormal buffer. + if (mTangentBuffer && mBiNormalBuffer && mName != MODELNAME::MODELGLOBEBASE) + { + pass.SetVertexBuffers(3, 1, &mTangentBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(4, 1, &mBiNormalBuffer->getBuffer(), vertexBufferOffsets); + } + pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); + pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), instance, 0, 0, 0); + instance = 0; +} + +void GenericModelDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) +{ + mWorldUniformPer.WorldUniforms[instance] = worldUniforms; + + instance++; +} diff --git a/src/aquarium-optimized/dawn/GenericModelDawn.h b/src/aquarium-optimized/dawn/GenericModelDawn.h index 097cf65..704d38b 100644 --- a/src/aquarium-optimized/dawn/GenericModelDawn.h +++ b/src/aquarium-optimized/dawn/GenericModelDawn.h @@ -1,80 +1,80 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// GenericModelDawn.h: Defnes generic model of Dawn - -#pragma once -#ifndef GENERICMODELDAWN_H -#define GENERICMODELDAWN_H 1 - -#include "ContextDawn.h" -#include "ProgramDawn.h" -#include "dawn/dawncpp.h" -#include "utils/ComboRenderPipelineDescriptor.h" - -#include "../Model.h" - -class GenericModelDawn : public Model -{ - public: - GenericModelDawn(const Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - ~GenericModelDawn(); - - void init() override; - void prepareForDraw() const override; - void draw() override; - - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - - TextureDawn *mDiffuseTexture; - TextureDawn *mNormalTexture; - TextureDawn *mReflectionTexture; - TextureDawn *mSkyboxTexture; - - BufferDawn *mPositionBuffer; - BufferDawn *mNormalBuffer; - BufferDawn *mTexCoordBuffer; - BufferDawn *mTangentBuffer; - BufferDawn *mBiNormalBuffer; - - BufferDawn *mIndicesBuffer; - - struct LightFactorUniforms - { - float shininess; - float specularFactor; - } mLightFactorUniforms; - - struct WorldUniformPer - { - WorldUniforms WorldUniforms[20]; - }; - WorldUniformPer mWorldUniformPer; - - private: - utils::ComboVertexInputDescriptor mVertexInputDescriptor; - dawn::RenderPipeline mPipeline; - - dawn::BindGroupLayout mGroupLayoutModel; - dawn::BindGroupLayout mGroupLayoutPer; - dawn::PipelineLayout mPipelineLayout; - - dawn::BindGroup mBindGroupModel; - dawn::BindGroup mBindGroupPer; - - dawn::Buffer mLightFactorBuffer; - dawn::Buffer mWorldBuffer; - - const ContextDawn *mContextDawn; - ProgramDawn *mProgramDawn; - - int instance; -}; - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// GenericModelDawn.h: Defnes generic model of Dawn + +#pragma once +#ifndef GENERICMODELDAWN_H +#define GENERICMODELDAWN_H 1 + +#include "ContextDawn.h" +#include "ProgramDawn.h" +#include "dawn/dawncpp.h" +#include "utils/ComboRenderPipelineDescriptor.h" + +#include "../Model.h" + +class GenericModelDawn : public Model +{ + public: + GenericModelDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + ~GenericModelDawn(); + + void init() override; + void prepareForDraw() const override; + void draw() override; + + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + + TextureDawn *mDiffuseTexture; + TextureDawn *mNormalTexture; + TextureDawn *mReflectionTexture; + TextureDawn *mSkyboxTexture; + + BufferDawn *mPositionBuffer; + BufferDawn *mNormalBuffer; + BufferDawn *mTexCoordBuffer; + BufferDawn *mTangentBuffer; + BufferDawn *mBiNormalBuffer; + + BufferDawn *mIndicesBuffer; + + struct LightFactorUniforms + { + float shininess; + float specularFactor; + } mLightFactorUniforms; + + struct WorldUniformPer + { + WorldUniforms WorldUniforms[20]; + }; + WorldUniformPer mWorldUniformPer; + + private: + utils::ComboVertexInputDescriptor mVertexInputDescriptor; + dawn::RenderPipeline mPipeline; + + dawn::BindGroupLayout mGroupLayoutModel; + dawn::BindGroupLayout mGroupLayoutPer; + dawn::PipelineLayout mPipelineLayout; + + dawn::BindGroup mBindGroupModel; + dawn::BindGroup mBindGroupPer; + + dawn::Buffer mLightFactorBuffer; + dawn::Buffer mWorldBuffer; + + const ContextDawn *mContextDawn; + ProgramDawn *mProgramDawn; + + int instance; +}; + #endif \ No newline at end of file diff --git a/src/aquarium-optimized/dawn/InnerModelDawn.cpp b/src/aquarium-optimized/dawn/InnerModelDawn.cpp index 681a808..8edcf41 100644 --- a/src/aquarium-optimized/dawn/InnerModelDawn.cpp +++ b/src/aquarium-optimized/dawn/InnerModelDawn.cpp @@ -1,161 +1,159 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// InnerModelDawn.cpp: Implements inner model of Dawn. - -#include "InnerModelDawn.h" - -InnerModelDawn::InnerModelDawn(const Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : Model(type, name, blend) -{ - mContextDawn = static_cast(context); - - mInnerUniforms.eta = 1.0f; - mInnerUniforms.tankColorFudge = 0.796f; - mInnerUniforms.refractionFudge = 3.0f; -} - -InnerModelDawn::~InnerModelDawn() -{ - mPipeline = nullptr; - mGroupLayoutModel = nullptr; - mGroupLayoutPer = nullptr; - mPipelineLayout = nullptr; - mBindGroupModel = nullptr; - mBindGroupPer = nullptr; - mInnerBuffer = nullptr; - mViewBuffer = nullptr; -} - -void InnerModelDawn::init() -{ - mProgramDawn = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mTangentBuffer = static_cast(bufferMap["tangent"]); - mBiNormalBuffer = static_cast(bufferMap["binormal"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - mVertexInputDescriptor.cBuffers[0].attributeCount = 1; - mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; - mVertexInputDescriptor.cAttributes[0].offset = 0; - mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; - mVertexInputDescriptor.cBuffers[1].attributeCount = 1; - mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; - mVertexInputDescriptor.cAttributes[1].offset = 0; - mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; - mVertexInputDescriptor.cBuffers[2].attributeCount = 1; - mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; - mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; - mVertexInputDescriptor.cAttributes[2].offset = 0; - mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; - mVertexInputDescriptor.cBuffers[3].attributeCount = 1; - mVertexInputDescriptor.cBuffers[3].stride = mTangentBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[3].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[3].shaderLocation = 3; - mVertexInputDescriptor.cAttributes[3].offset = 0; - mVertexInputDescriptor.cBuffers[3].attributes = &mVertexInputDescriptor.cAttributes[3]; - mVertexInputDescriptor.cBuffers[4].attributeCount = 1; - mVertexInputDescriptor.cBuffers[4].stride = mBiNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[4].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[4].shaderLocation = 4; - mVertexInputDescriptor.cAttributes[4].offset = 0; - mVertexInputDescriptor.cBuffers[4].attributes = &mVertexInputDescriptor.cAttributes[4]; - mVertexInputDescriptor.bufferCount = 5; - mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; - - mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {5, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - {6, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - }); - - mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - }); - - mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ - mContextDawn->groupLayoutGeneral, - mContextDawn->groupLayoutWorld, - mGroupLayoutModel, - mGroupLayoutPer, - }); - - mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, - mVertexInputDescriptor, mBlend); - - mInnerBuffer = mContextDawn->createBufferFromData( - &mInnerUniforms, sizeof(mInnerUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - mViewBuffer = mContextDawn->createBufferFromData( - &mWorldUniformPer, sizeof(WorldUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - - mBindGroupModel = - mContextDawn->makeBindGroup(mGroupLayoutModel, {{0, mInnerBuffer, 0, sizeof(InnerUniforms)}, - {1, mReflectionTexture->getSampler()}, - {2, mSkyboxTexture->getSampler()}, - {3, mDiffuseTexture->getTextureView()}, - {4, mNormalTexture->getTextureView()}, - {5, mReflectionTexture->getTextureView()}, - {6, mSkyboxTexture->getTextureView()}}); - - mBindGroupPer = - mContextDawn->makeBindGroup(mGroupLayoutPer, { - {0, mViewBuffer, 0, sizeof(WorldUniforms)}, - }); - - mContextDawn->setBufferData(mInnerBuffer, 0, sizeof(InnerUniforms), &mInnerUniforms); -} - -void InnerModelDawn::prepareForDraw() const -{ -} - -void InnerModelDawn::draw() -{ - uint64_t vertexBufferOffsets[1] = {0}; - - dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); - pass.SetPipeline(mPipeline); - pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); - pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); - pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); - pass.SetBindGroup(3, mBindGroupPer, 0, nullptr); - pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(3, 1, &mTangentBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(4, 1, &mBiNormalBuffer->getBuffer(), vertexBufferOffsets); - pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); - pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); -} - -void InnerModelDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) -{ - std::memcpy(&mWorldUniformPer, &worldUniforms, sizeof(WorldUniforms)); - - mContextDawn->setBufferData(mViewBuffer, 0, sizeof(WorldUniforms), &mWorldUniformPer); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// InnerModelDawn.cpp: Implements inner model of Dawn. + +#include "InnerModelDawn.h" + +InnerModelDawn::InnerModelDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : Model(type, name, blend) +{ + mContextDawn = static_cast(context); + + mInnerUniforms.eta = 1.0f; + mInnerUniforms.tankColorFudge = 0.796f; + mInnerUniforms.refractionFudge = 3.0f; +} + +InnerModelDawn::~InnerModelDawn() +{ + mPipeline = nullptr; + mGroupLayoutModel = nullptr; + mGroupLayoutPer = nullptr; + mPipelineLayout = nullptr; + mBindGroupModel = nullptr; + mBindGroupPer = nullptr; + mInnerBuffer = nullptr; + mViewBuffer = nullptr; +} + +void InnerModelDawn::init() +{ + mProgramDawn = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mTangentBuffer = static_cast(bufferMap["tangent"]); + mBiNormalBuffer = static_cast(bufferMap["binormal"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + mVertexInputDescriptor.cBuffers[0].attributeCount = 1; + mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; + mVertexInputDescriptor.cAttributes[0].offset = 0; + mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; + mVertexInputDescriptor.cBuffers[1].attributeCount = 1; + mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; + mVertexInputDescriptor.cAttributes[1].offset = 0; + mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; + mVertexInputDescriptor.cBuffers[2].attributeCount = 1; + mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; + mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; + mVertexInputDescriptor.cAttributes[2].offset = 0; + mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; + mVertexInputDescriptor.cBuffers[3].attributeCount = 1; + mVertexInputDescriptor.cBuffers[3].stride = mTangentBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[3].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[3].shaderLocation = 3; + mVertexInputDescriptor.cAttributes[3].offset = 0; + mVertexInputDescriptor.cBuffers[3].attributes = &mVertexInputDescriptor.cAttributes[3]; + mVertexInputDescriptor.cBuffers[4].attributeCount = 1; + mVertexInputDescriptor.cBuffers[4].stride = mBiNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[4].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[4].shaderLocation = 4; + mVertexInputDescriptor.cAttributes[4].offset = 0; + mVertexInputDescriptor.cBuffers[4].attributes = &mVertexInputDescriptor.cAttributes[4]; + mVertexInputDescriptor.bufferCount = 5; + mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; + + mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {3, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {4, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {5, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + {6, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + }); + + mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + }); + + mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ + mContextDawn->groupLayoutGeneral, + mContextDawn->groupLayoutWorld, + mGroupLayoutModel, + mGroupLayoutPer, + }); + + mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, + mVertexInputDescriptor, mBlend); + + mInnerBuffer = mContextDawn->createBufferFromData( + &mInnerUniforms, sizeof(mInnerUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + mViewBuffer = mContextDawn->createBufferFromData( + &mWorldUniformPer, sizeof(WorldUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + + mBindGroupModel = + mContextDawn->makeBindGroup(mGroupLayoutModel, {{0, mInnerBuffer, 0, sizeof(InnerUniforms)}, + {1, mReflectionTexture->getSampler()}, + {2, mSkyboxTexture->getSampler()}, + {3, mDiffuseTexture->getTextureView()}, + {4, mNormalTexture->getTextureView()}, + {5, mReflectionTexture->getTextureView()}, + {6, mSkyboxTexture->getTextureView()}}); + + mBindGroupPer = + mContextDawn->makeBindGroup(mGroupLayoutPer, { + {0, mViewBuffer, 0, sizeof(WorldUniforms)}, + }); + + mContextDawn->setBufferData(mInnerBuffer, 0, sizeof(InnerUniforms), &mInnerUniforms); +} + +void InnerModelDawn::prepareForDraw() const {} + +void InnerModelDawn::draw() +{ + uint64_t vertexBufferOffsets[1] = {0}; + + dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); + pass.SetPipeline(mPipeline); + pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); + pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); + pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); + pass.SetBindGroup(3, mBindGroupPer, 0, nullptr); + pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(3, 1, &mTangentBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(4, 1, &mBiNormalBuffer->getBuffer(), vertexBufferOffsets); + pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); + pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); +} + +void InnerModelDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) +{ + std::memcpy(&mWorldUniformPer, &worldUniforms, sizeof(WorldUniforms)); + + mContextDawn->setBufferData(mViewBuffer, 0, sizeof(WorldUniforms), &mWorldUniformPer); +} diff --git a/src/aquarium-optimized/dawn/InnerModelDawn.h b/src/aquarium-optimized/dawn/InnerModelDawn.h index 88dad43..8737038 100644 --- a/src/aquarium-optimized/dawn/InnerModelDawn.h +++ b/src/aquarium-optimized/dawn/InnerModelDawn.h @@ -1,71 +1,75 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// InnerModelDawn.h: Defines inner model of Dawn. - -#pragma once -#ifndef INNERMODELDAWN_H -#define INNERMODELDAWN_H 1 - -#include "ContextDawn.h" -#include "ProgramDawn.h" -#include "dawn/dawncpp.h" -#include "utils/ComboRenderPipelineDescriptor.h" - -#include "../Model.h" - -class InnerModelDawn : public Model -{ - public: - InnerModelDawn(const Context *context, Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend); - ~InnerModelDawn(); - - void init() override; - void prepareForDraw() const override; - void draw() override; - void updatePerInstanceUniforms(const WorldUniforms &WorldUniforms) override; - - struct InnerUniforms - { - float eta; - float tankColorFudge; - float refractionFudge; - float padding; - } mInnerUniforms; - - WorldUniforms mWorldUniformPer; - - TextureDawn *mDiffuseTexture; - TextureDawn *mNormalTexture; - TextureDawn *mReflectionTexture; - TextureDawn *mSkyboxTexture; - - BufferDawn *mPositionBuffer; - BufferDawn *mNormalBuffer; - BufferDawn *mTexCoordBuffer; - BufferDawn *mTangentBuffer; - BufferDawn *mBiNormalBuffer; - - BufferDawn *mIndicesBuffer; - - private: - utils::ComboVertexInputDescriptor mVertexInputDescriptor; - dawn::RenderPipeline mPipeline; - - dawn::BindGroupLayout mGroupLayoutModel; - dawn::BindGroupLayout mGroupLayoutPer; - dawn::PipelineLayout mPipelineLayout; - - dawn::BindGroup mBindGroupModel; - dawn::BindGroup mBindGroupPer; - - dawn::Buffer mInnerBuffer; - dawn::Buffer mViewBuffer; - - const ContextDawn *mContextDawn; - ProgramDawn *mProgramDawn; -}; - -#endif // !INNERMODELDAWN_H +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// InnerModelDawn.h: Defines inner model of Dawn. + +#pragma once +#ifndef INNERMODELDAWN_H +#define INNERMODELDAWN_H 1 + +#include "ContextDawn.h" +#include "ProgramDawn.h" +#include "dawn/dawncpp.h" +#include "utils/ComboRenderPipelineDescriptor.h" + +#include "../Model.h" + +class InnerModelDawn : public Model +{ + public: + InnerModelDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + ~InnerModelDawn(); + + void init() override; + void prepareForDraw() const override; + void draw() override; + void updatePerInstanceUniforms(const WorldUniforms &WorldUniforms) override; + + struct InnerUniforms + { + float eta; + float tankColorFudge; + float refractionFudge; + float padding; + } mInnerUniforms; + + WorldUniforms mWorldUniformPer; + + TextureDawn *mDiffuseTexture; + TextureDawn *mNormalTexture; + TextureDawn *mReflectionTexture; + TextureDawn *mSkyboxTexture; + + BufferDawn *mPositionBuffer; + BufferDawn *mNormalBuffer; + BufferDawn *mTexCoordBuffer; + BufferDawn *mTangentBuffer; + BufferDawn *mBiNormalBuffer; + + BufferDawn *mIndicesBuffer; + + private: + utils::ComboVertexInputDescriptor mVertexInputDescriptor; + dawn::RenderPipeline mPipeline; + + dawn::BindGroupLayout mGroupLayoutModel; + dawn::BindGroupLayout mGroupLayoutPer; + dawn::PipelineLayout mPipelineLayout; + + dawn::BindGroup mBindGroupModel; + dawn::BindGroup mBindGroupPer; + + dawn::Buffer mInnerBuffer; + dawn::Buffer mViewBuffer; + + const ContextDawn *mContextDawn; + ProgramDawn *mProgramDawn; +}; + +#endif // !INNERMODELDAWN_H diff --git a/src/aquarium-optimized/dawn/OutsideModelDawn.cpp b/src/aquarium-optimized/dawn/OutsideModelDawn.cpp index ac1853e..1d45a83 100644 --- a/src/aquarium-optimized/dawn/OutsideModelDawn.cpp +++ b/src/aquarium-optimized/dawn/OutsideModelDawn.cpp @@ -1,158 +1,156 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -#include "OutsideModelDawn.h" - -OutsideModelDawn::OutsideModelDawn(const Context *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : Model(type, name, blend) -{ - mContextDawn = static_cast(context); - - mLightFactorUniforms.shininess = 50.0f; - mLightFactorUniforms.specularFactor = 0.0f; -} - -OutsideModelDawn::~OutsideModelDawn() -{ - mPipeline = nullptr; - mGroupLayoutModel = nullptr; - mGroupLayoutPer = nullptr; - mPipelineLayout = nullptr; - mBindGroupModel = nullptr; - mBindGroupPer = nullptr; - mLightFactorBuffer = nullptr; - mViewBuffer = nullptr; -} - -void OutsideModelDawn::init() -{ - mProgramDawn = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mTangentBuffer = static_cast(bufferMap["tangent"]); - mBiNormalBuffer = static_cast(bufferMap["binormal"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - mVertexInputDescriptor.cBuffers[0].attributeCount = 1; - mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; - mVertexInputDescriptor.cAttributes[0].offset = 0; - mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; - mVertexInputDescriptor.cBuffers[1].attributeCount = 1; - mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; - mVertexInputDescriptor.cAttributes[1].offset = 0; - mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; - mVertexInputDescriptor.cBuffers[2].attributeCount = 1; - mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; - mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; - mVertexInputDescriptor.cAttributes[2].offset = 0; - mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; - mVertexInputDescriptor.cBuffers[3].attributeCount = 1; - mVertexInputDescriptor.cBuffers[3].stride = mTangentBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[3].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[3].shaderLocation = 3; - mVertexInputDescriptor.cAttributes[3].offset = 0; - mVertexInputDescriptor.cBuffers[3].attributes = &mVertexInputDescriptor.cAttributes[3]; - mVertexInputDescriptor.cBuffers[4].attributeCount = 1; - mVertexInputDescriptor.cBuffers[4].stride = mBiNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[4].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[4].shaderLocation = 4; - mVertexInputDescriptor.cAttributes[4].offset = 0; - mVertexInputDescriptor.cBuffers[4].attributes = &mVertexInputDescriptor.cAttributes[4]; - mVertexInputDescriptor.bufferCount = 5; - mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; - - mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - }); - - // Outside models use diffuse shaders. - mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - }); - - mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ - mContextDawn->groupLayoutGeneral, - mContextDawn->groupLayoutWorld, - mGroupLayoutModel, - mGroupLayoutPer, - }); - - mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, - mVertexInputDescriptor, mBlend); - - mLightFactorBuffer = mContextDawn->createBufferFromData( - &mLightFactorUniforms, sizeof(mLightFactorUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - mViewBuffer = mContextDawn->createBufferFromData( - &mWorldUniformPer, sizeof(WorldUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - - mBindGroupModel = mContextDawn->makeBindGroup( - mGroupLayoutModel, { - {0, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, - {1, mDiffuseTexture->getSampler()}, - {2, mDiffuseTexture->getTextureView()}, - }); - - mBindGroupPer = - mContextDawn->makeBindGroup(mGroupLayoutPer, { - {0, mViewBuffer, 0, sizeof(WorldUniforms)}, - }); - - mContextDawn->setBufferData(mLightFactorBuffer, 0, sizeof(LightFactorUniforms), - &mLightFactorUniforms); -} - -void OutsideModelDawn::prepareForDraw() const -{ -} - -void OutsideModelDawn::draw() -{ - uint64_t vertexBufferOffsets[1] = {0}; - - dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); - pass.SetPipeline(mPipeline); - pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); - pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); - pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); - pass.SetBindGroup(3, mBindGroupPer, 0, nullptr); - pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); - // diffuseShader doesn't have to input tangent buffer or binormal buffer. - if (mTangentBuffer && mBiNormalBuffer) - { - pass.SetVertexBuffers(3, 1, &mTangentBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(4, 1, &mBiNormalBuffer->getBuffer(), vertexBufferOffsets); - } - pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); - pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); -} - -void OutsideModelDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) -{ - memcpy(&mWorldUniformPer, &worldUniforms, sizeof(WorldUniforms)); - - mContextDawn->setBufferData(mViewBuffer, 0, sizeof(WorldUniforms), &mWorldUniformPer); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +#include "OutsideModelDawn.h" + +OutsideModelDawn::OutsideModelDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : Model(type, name, blend) +{ + mContextDawn = static_cast(context); + + mLightFactorUniforms.shininess = 50.0f; + mLightFactorUniforms.specularFactor = 0.0f; +} + +OutsideModelDawn::~OutsideModelDawn() +{ + mPipeline = nullptr; + mGroupLayoutModel = nullptr; + mGroupLayoutPer = nullptr; + mPipelineLayout = nullptr; + mBindGroupModel = nullptr; + mBindGroupPer = nullptr; + mLightFactorBuffer = nullptr; + mViewBuffer = nullptr; +} + +void OutsideModelDawn::init() +{ + mProgramDawn = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mTangentBuffer = static_cast(bufferMap["tangent"]); + mBiNormalBuffer = static_cast(bufferMap["binormal"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + mVertexInputDescriptor.cBuffers[0].attributeCount = 1; + mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; + mVertexInputDescriptor.cAttributes[0].offset = 0; + mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; + mVertexInputDescriptor.cBuffers[1].attributeCount = 1; + mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; + mVertexInputDescriptor.cAttributes[1].offset = 0; + mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; + mVertexInputDescriptor.cBuffers[2].attributeCount = 1; + mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; + mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; + mVertexInputDescriptor.cAttributes[2].offset = 0; + mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; + mVertexInputDescriptor.cBuffers[3].attributeCount = 1; + mVertexInputDescriptor.cBuffers[3].stride = mTangentBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[3].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[3].shaderLocation = 3; + mVertexInputDescriptor.cAttributes[3].offset = 0; + mVertexInputDescriptor.cBuffers[3].attributes = &mVertexInputDescriptor.cAttributes[3]; + mVertexInputDescriptor.cBuffers[4].attributeCount = 1; + mVertexInputDescriptor.cBuffers[4].stride = mBiNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[4].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[4].shaderLocation = 4; + mVertexInputDescriptor.cAttributes[4].offset = 0; + mVertexInputDescriptor.cBuffers[4].attributes = &mVertexInputDescriptor.cAttributes[4]; + mVertexInputDescriptor.bufferCount = 5; + mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; + + mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + }); + + // Outside models use diffuse shaders. + mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + }); + + mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ + mContextDawn->groupLayoutGeneral, + mContextDawn->groupLayoutWorld, + mGroupLayoutModel, + mGroupLayoutPer, + }); + + mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, + mVertexInputDescriptor, mBlend); + + mLightFactorBuffer = mContextDawn->createBufferFromData( + &mLightFactorUniforms, sizeof(mLightFactorUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + mViewBuffer = mContextDawn->createBufferFromData( + &mWorldUniformPer, sizeof(WorldUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + + mBindGroupModel = mContextDawn->makeBindGroup( + mGroupLayoutModel, { + {0, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, + {1, mDiffuseTexture->getSampler()}, + {2, mDiffuseTexture->getTextureView()}, + }); + + mBindGroupPer = + mContextDawn->makeBindGroup(mGroupLayoutPer, { + {0, mViewBuffer, 0, sizeof(WorldUniforms)}, + }); + + mContextDawn->setBufferData(mLightFactorBuffer, 0, sizeof(LightFactorUniforms), + &mLightFactorUniforms); +} + +void OutsideModelDawn::prepareForDraw() const {} + +void OutsideModelDawn::draw() +{ + uint64_t vertexBufferOffsets[1] = {0}; + + dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); + pass.SetPipeline(mPipeline); + pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); + pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); + pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); + pass.SetBindGroup(3, mBindGroupPer, 0, nullptr); + pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); + // diffuseShader doesn't have to input tangent buffer or binormal buffer. + if (mTangentBuffer && mBiNormalBuffer) + { + pass.SetVertexBuffers(3, 1, &mTangentBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(4, 1, &mBiNormalBuffer->getBuffer(), vertexBufferOffsets); + } + pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); + pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), 1, 0, 0, 0); +} + +void OutsideModelDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) +{ + memcpy(&mWorldUniformPer, &worldUniforms, sizeof(WorldUniforms)); + + mContextDawn->setBufferData(mViewBuffer, 0, sizeof(WorldUniforms), &mWorldUniformPer); +} diff --git a/src/aquarium-optimized/dawn/OutsideModelDawn.h b/src/aquarium-optimized/dawn/OutsideModelDawn.h index 4e9d964..14e6b52 100644 --- a/src/aquarium-optimized/dawn/OutsideModelDawn.h +++ b/src/aquarium-optimized/dawn/OutsideModelDawn.h @@ -1,70 +1,74 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// OutsideModelDawn.h: Defnes outside model of Dawn - -#pragma once -#ifndef OUTSIDEMODELDAWN_H -#define OUTSIDEMODELDAWN_H 1 - -#include "ContextDawn.h" -#include "ProgramDawn.h" -#include "dawn/dawncpp.h" -#include "utils/ComboRenderPipelineDescriptor.h" - -#include "../Model.h" - -class OutsideModelDawn : public Model -{ -public: - OutsideModelDawn(const Context *context, Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend); - ~OutsideModelDawn(); - - void init() override; - void prepareForDraw() const override; - void draw() override; - - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - - TextureDawn *mDiffuseTexture; - TextureDawn *mNormalTexture; - TextureDawn *mReflectionTexture; - TextureDawn *mSkyboxTexture; - - BufferDawn *mPositionBuffer; - BufferDawn *mNormalBuffer; - BufferDawn *mTexCoordBuffer; - BufferDawn *mTangentBuffer; - BufferDawn *mBiNormalBuffer; - - BufferDawn *mIndicesBuffer; - - struct LightFactorUniforms - { - float shininess; - float specularFactor; - } mLightFactorUniforms; - - WorldUniforms mWorldUniformPer; - - private: - utils::ComboVertexInputDescriptor mVertexInputDescriptor; - dawn::RenderPipeline mPipeline; - - dawn::BindGroupLayout mGroupLayoutModel; - dawn::BindGroupLayout mGroupLayoutPer; - dawn::PipelineLayout mPipelineLayout; - - dawn::BindGroup mBindGroupModel; - dawn::BindGroup mBindGroupPer; - - dawn::Buffer mLightFactorBuffer; - dawn::Buffer mViewBuffer; - - const ContextDawn *mContextDawn; - ProgramDawn *mProgramDawn; -}; - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// OutsideModelDawn.h: Defnes outside model of Dawn + +#pragma once +#ifndef OUTSIDEMODELDAWN_H +#define OUTSIDEMODELDAWN_H 1 + +#include "ContextDawn.h" +#include "ProgramDawn.h" +#include "dawn/dawncpp.h" +#include "utils/ComboRenderPipelineDescriptor.h" + +#include "../Model.h" + +class OutsideModelDawn : public Model +{ + public: + OutsideModelDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + ~OutsideModelDawn(); + + void init() override; + void prepareForDraw() const override; + void draw() override; + + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + + TextureDawn *mDiffuseTexture; + TextureDawn *mNormalTexture; + TextureDawn *mReflectionTexture; + TextureDawn *mSkyboxTexture; + + BufferDawn *mPositionBuffer; + BufferDawn *mNormalBuffer; + BufferDawn *mTexCoordBuffer; + BufferDawn *mTangentBuffer; + BufferDawn *mBiNormalBuffer; + + BufferDawn *mIndicesBuffer; + + struct LightFactorUniforms + { + float shininess; + float specularFactor; + } mLightFactorUniforms; + + WorldUniforms mWorldUniformPer; + + private: + utils::ComboVertexInputDescriptor mVertexInputDescriptor; + dawn::RenderPipeline mPipeline; + + dawn::BindGroupLayout mGroupLayoutModel; + dawn::BindGroupLayout mGroupLayoutPer; + dawn::PipelineLayout mPipelineLayout; + + dawn::BindGroup mBindGroupModel; + dawn::BindGroup mBindGroupPer; + + dawn::Buffer mLightFactorBuffer; + dawn::Buffer mViewBuffer; + + const ContextDawn *mContextDawn; + ProgramDawn *mProgramDawn; +}; + #endif \ No newline at end of file diff --git a/src/aquarium-optimized/dawn/ProgramDawn.cpp b/src/aquarium-optimized/dawn/ProgramDawn.cpp index 9f71e9a..994c928 100644 --- a/src/aquarium-optimized/dawn/ProgramDawn.cpp +++ b/src/aquarium-optimized/dawn/ProgramDawn.cpp @@ -1,46 +1,46 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include -#include -#include - -#include "ContextDawn.h" -#include "ProgramDawn.h" -#include "common/AQUARIUM_ASSERT.h" - -ProgramDawn::ProgramDawn(ContextDawn *context, const std::string &mVId, const std::string &mFId) - : Program(mVId, mFId), mVsModule(nullptr), mFsModule(nullptr), context(context) -{ -} - -ProgramDawn::~ProgramDawn() -{ - mVsModule = nullptr; - mFsModule = nullptr; -} - -void ProgramDawn::loadProgram() -{ - std::ifstream VertexShaderStream(mVId, std::ios::in); - std::string VertexShaderCode((std::istreambuf_iterator(VertexShaderStream)), - std::istreambuf_iterator()); - VertexShaderStream.close(); - - // Read the Fragment Shader code from the file - std::ifstream FragmentShaderStream(mFId, std::ios::in); - std::string FragmentShaderCode((std::istreambuf_iterator(FragmentShaderStream)), - std::istreambuf_iterator()); - FragmentShaderStream.close(); - - FragmentShaderCode = - std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noReflection)"), ""); - FragmentShaderCode = - std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noNormalMap)"), ""); - - mVsModule = context->createShaderModule(utils::ShaderStage::Vertex, VertexShaderCode); - mFsModule = context->createShaderModule(utils::ShaderStage::Fragment, FragmentShaderCode); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include +#include +#include + +#include "ContextDawn.h" +#include "ProgramDawn.h" +#include "common/AQUARIUM_ASSERT.h" + +ProgramDawn::ProgramDawn(ContextDawn *context, const std::string &mVId, const std::string &mFId) + : Program(mVId, mFId), mVsModule(nullptr), mFsModule(nullptr), context(context) +{ +} + +ProgramDawn::~ProgramDawn() +{ + mVsModule = nullptr; + mFsModule = nullptr; +} + +void ProgramDawn::loadProgram() +{ + std::ifstream VertexShaderStream(mVId, std::ios::in); + std::string VertexShaderCode((std::istreambuf_iterator(VertexShaderStream)), + std::istreambuf_iterator()); + VertexShaderStream.close(); + + // Read the Fragment Shader code from the file + std::ifstream FragmentShaderStream(mFId, std::ios::in); + std::string FragmentShaderCode((std::istreambuf_iterator(FragmentShaderStream)), + std::istreambuf_iterator()); + FragmentShaderStream.close(); + + FragmentShaderCode = + std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noReflection)"), ""); + FragmentShaderCode = + std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noNormalMap)"), ""); + + mVsModule = context->createShaderModule(utils::ShaderStage::Vertex, VertexShaderCode); + mFsModule = context->createShaderModule(utils::ShaderStage::Fragment, FragmentShaderCode); +} diff --git a/src/aquarium-optimized/dawn/ProgramDawn.h b/src/aquarium-optimized/dawn/ProgramDawn.h index ec59935..d7200e3 100644 --- a/src/aquarium-optimized/dawn/ProgramDawn.h +++ b/src/aquarium-optimized/dawn/ProgramDawn.h @@ -1,44 +1,43 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// ProgramDawn.h: Defines Program wrapper of Dawn. -// Load shaders from folder shaders/dawn. - -#pragma once -#ifndef PROGRAMDAWN_H -#define PROGRAMDAWN_H 1 - -#include "../Program.h" - -#include -#include - -#include "BufferDawn.h" -#include "TextureDawn.h" - -#include "../Aquarium.h" - -class ContextDawn; - -class ProgramDawn : public Program -{ -public: - ProgramDawn() {} - ProgramDawn(ContextDawn *context, const std::string &mVId, const std::string &mFId); - ~ProgramDawn() override; - - void loadProgram(); - dawn::ShaderModule getVSModule() { return mVsModule; } - dawn::ShaderModule getFSModule() { return mFsModule; } - - private: - dawn::ShaderModule mVsModule; - dawn::ShaderModule mFsModule; - - ContextDawn *context; -}; - -#endif - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramDawn.h: Defines Program wrapper of Dawn. +// Load shaders from folder shaders/dawn. + +#pragma once +#ifndef PROGRAMDAWN_H +#define PROGRAMDAWN_H 1 + +#include "../Program.h" + +#include +#include + +#include "BufferDawn.h" +#include "TextureDawn.h" + +#include "../Aquarium.h" + +class ContextDawn; + +class ProgramDawn : public Program +{ + public: + ProgramDawn() {} + ProgramDawn(ContextDawn *context, const std::string &mVId, const std::string &mFId); + ~ProgramDawn() override; + + void loadProgram(); + dawn::ShaderModule getVSModule() { return mVsModule; } + dawn::ShaderModule getFSModule() { return mFsModule; } + + private: + dawn::ShaderModule mVsModule; + dawn::ShaderModule mFsModule; + + ContextDawn *context; +}; + +#endif diff --git a/src/aquarium-optimized/dawn/SeaweedModelDawn.cpp b/src/aquarium-optimized/dawn/SeaweedModelDawn.cpp index de0d9f2..79eb2ff 100644 --- a/src/aquarium-optimized/dawn/SeaweedModelDawn.cpp +++ b/src/aquarium-optimized/dawn/SeaweedModelDawn.cpp @@ -1,151 +1,152 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// SeaweenModelDawn: Implements seaweed model of Dawn. - -#include "SeaweedModelDawn.h" - -SeaweedModelDawn::SeaweedModelDawn(const Context* context, Aquarium* aquarium, MODELGROUP type, MODELNAME name, bool blend) - : SeaweedModel(type, name, blend), instance(0) -{ - mContextDawn = static_cast(context); - mAquarium = aquarium; - - mLightFactorUniforms.shininess = 50.0f; - mLightFactorUniforms.specularFactor = 1.0f; -} - -SeaweedModelDawn::~SeaweedModelDawn() -{ - mPipeline = nullptr; - mGroupLayoutModel = nullptr; - mGroupLayoutPer = nullptr; - mPipelineLayout = nullptr; - mBindGroupModel = nullptr; - mBindGroupPer = nullptr; - mLightFactorBuffer = nullptr; - mViewBuffer = nullptr; - mTimeBuffer = nullptr; -} - -void SeaweedModelDawn::init() -{ - mProgramDawn = static_cast(mProgram); - - mDiffuseTexture = static_cast(textureMap["diffuse"]); - mNormalTexture = static_cast(textureMap["normalMap"]); - mReflectionTexture = static_cast(textureMap["reflectionMap"]); - mSkyboxTexture = static_cast(textureMap["skybox"]); - - mPositionBuffer = static_cast(bufferMap["position"]); - mNormalBuffer = static_cast(bufferMap["normal"]); - mTexCoordBuffer = static_cast(bufferMap["texCoord"]); - mIndicesBuffer = static_cast(bufferMap["indices"]); - - mVertexInputDescriptor.cBuffers[0].attributeCount = 1; - mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; - mVertexInputDescriptor.cAttributes[0].offset = 0; - mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; - mVertexInputDescriptor.cBuffers[1].attributeCount = 1; - mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; - mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; - mVertexInputDescriptor.cAttributes[1].offset = 0; - mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; - mVertexInputDescriptor.cBuffers[2].attributeCount = 1; - mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); - mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; - mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; - mVertexInputDescriptor.cAttributes[2].offset = 0; - mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; - mVertexInputDescriptor.bufferCount = 3; - mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; - - mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, - }); - - mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - }); - - mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ - mContextDawn->groupLayoutGeneral, - mContextDawn->groupLayoutWorld, - mGroupLayoutModel, - mGroupLayoutPer, - }); - - mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, - mVertexInputDescriptor, mBlend); - - mLightFactorBuffer = mContextDawn->createBufferFromData( - &mLightFactorUniforms, sizeof(mLightFactorUniforms), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - mTimeBuffer = mContextDawn->createBufferFromData( - &mSeaweedPer, sizeof(mSeaweedPer), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - mViewBuffer = mContextDawn->createBufferFromData( - &mWorldUniformPer, sizeof(WorldUniformPer), - dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); - - mBindGroupModel = mContextDawn->makeBindGroup( - mGroupLayoutModel, { - {0, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, - {1, mDiffuseTexture->getSampler()}, - {2, mDiffuseTexture->getTextureView()}, - }); - - mBindGroupPer = mContextDawn->makeBindGroup(mGroupLayoutPer, - { - {0, mViewBuffer, 0, sizeof(WorldUniformPer)}, - {1, mTimeBuffer, 0, sizeof(SeaweedPer)}, - }); - - mContextDawn->setBufferData(mLightFactorBuffer, 0, sizeof(mLightFactorUniforms), - &mLightFactorUniforms); -} - -void SeaweedModelDawn::prepareForDraw() const -{ - mContextDawn->setBufferData(mViewBuffer, 0, sizeof(WorldUniformPer), &mWorldUniformPer); - mContextDawn->setBufferData(mTimeBuffer, 0, sizeof(SeaweedPer), &mSeaweedPer); -} - -void SeaweedModelDawn::draw() -{ - uint64_t vertexBufferOffsets[1] = {0}; - - dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); - pass.SetPipeline(mPipeline); - pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); - pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); - pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); - pass.SetBindGroup(3, mBindGroupPer, 0, nullptr); - pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); - pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); - pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); - pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), instance, 0, 0, 0); - instance = 0; -} - -void SeaweedModelDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) -{ - mWorldUniformPer.worldUniforms[instance] = worldUniforms; - mSeaweedPer.time[instance] = mAquarium->g.mclock + instance; - - instance++; -} - -void SeaweedModelDawn::updateSeaweedModelTime(float time) -{ -} - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SeaweenModelDawn: Implements seaweed model of Dawn. + +#include "SeaweedModelDawn.h" + +SeaweedModelDawn::SeaweedModelDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : SeaweedModel(type, name, blend), instance(0) +{ + mContextDawn = static_cast(context); + mAquarium = aquarium; + + mLightFactorUniforms.shininess = 50.0f; + mLightFactorUniforms.specularFactor = 1.0f; +} + +SeaweedModelDawn::~SeaweedModelDawn() +{ + mPipeline = nullptr; + mGroupLayoutModel = nullptr; + mGroupLayoutPer = nullptr; + mPipelineLayout = nullptr; + mBindGroupModel = nullptr; + mBindGroupPer = nullptr; + mLightFactorBuffer = nullptr; + mViewBuffer = nullptr; + mTimeBuffer = nullptr; +} + +void SeaweedModelDawn::init() +{ + mProgramDawn = static_cast(mProgram); + + mDiffuseTexture = static_cast(textureMap["diffuse"]); + mNormalTexture = static_cast(textureMap["normalMap"]); + mReflectionTexture = static_cast(textureMap["reflectionMap"]); + mSkyboxTexture = static_cast(textureMap["skybox"]); + + mPositionBuffer = static_cast(bufferMap["position"]); + mNormalBuffer = static_cast(bufferMap["normal"]); + mTexCoordBuffer = static_cast(bufferMap["texCoord"]); + mIndicesBuffer = static_cast(bufferMap["indices"]); + + mVertexInputDescriptor.cBuffers[0].attributeCount = 1; + mVertexInputDescriptor.cBuffers[0].stride = mPositionBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; + mVertexInputDescriptor.cAttributes[0].offset = 0; + mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; + mVertexInputDescriptor.cBuffers[1].attributeCount = 1; + mVertexInputDescriptor.cBuffers[1].stride = mNormalBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float3; + mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; + mVertexInputDescriptor.cAttributes[1].offset = 0; + mVertexInputDescriptor.cBuffers[1].attributes = &mVertexInputDescriptor.cAttributes[1]; + mVertexInputDescriptor.cBuffers[2].attributeCount = 1; + mVertexInputDescriptor.cBuffers[2].stride = mTexCoordBuffer->getDataSize(); + mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::Float2; + mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; + mVertexInputDescriptor.cAttributes[2].offset = 0; + mVertexInputDescriptor.cBuffers[2].attributes = &mVertexInputDescriptor.cAttributes[2]; + mVertexInputDescriptor.bufferCount = 3; + mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; + + mGroupLayoutModel = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}, + }); + + mGroupLayoutPer = mContextDawn->MakeBindGroupLayout({ + {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + }); + + mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({ + mContextDawn->groupLayoutGeneral, + mContextDawn->groupLayoutWorld, + mGroupLayoutModel, + mGroupLayoutPer, + }); + + mPipeline = mContextDawn->createRenderPipeline(mPipelineLayout, mProgramDawn, + mVertexInputDescriptor, mBlend); + + mLightFactorBuffer = mContextDawn->createBufferFromData( + &mLightFactorUniforms, sizeof(mLightFactorUniforms), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + mTimeBuffer = mContextDawn->createBufferFromData( + &mSeaweedPer, sizeof(mSeaweedPer), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + mViewBuffer = mContextDawn->createBufferFromData( + &mWorldUniformPer, sizeof(WorldUniformPer), + dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform); + + mBindGroupModel = mContextDawn->makeBindGroup( + mGroupLayoutModel, { + {0, mLightFactorBuffer, 0, sizeof(LightFactorUniforms)}, + {1, mDiffuseTexture->getSampler()}, + {2, mDiffuseTexture->getTextureView()}, + }); + + mBindGroupPer = mContextDawn->makeBindGroup(mGroupLayoutPer, + { + {0, mViewBuffer, 0, sizeof(WorldUniformPer)}, + {1, mTimeBuffer, 0, sizeof(SeaweedPer)}, + }); + + mContextDawn->setBufferData(mLightFactorBuffer, 0, sizeof(mLightFactorUniforms), + &mLightFactorUniforms); +} + +void SeaweedModelDawn::prepareForDraw() const +{ + mContextDawn->setBufferData(mViewBuffer, 0, sizeof(WorldUniformPer), &mWorldUniformPer); + mContextDawn->setBufferData(mTimeBuffer, 0, sizeof(SeaweedPer), &mSeaweedPer); +} + +void SeaweedModelDawn::draw() +{ + uint64_t vertexBufferOffsets[1] = {0}; + + dawn::RenderPassEncoder pass = mContextDawn->getRenderPass(); + pass.SetPipeline(mPipeline); + pass.SetBindGroup(0, mContextDawn->bindGroupGeneral, 0, nullptr); + pass.SetBindGroup(1, mContextDawn->bindGroupWorld, 0, nullptr); + pass.SetBindGroup(2, mBindGroupModel, 0, nullptr); + pass.SetBindGroup(3, mBindGroupPer, 0, nullptr); + pass.SetVertexBuffers(0, 1, &mPositionBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(1, 1, &mNormalBuffer->getBuffer(), vertexBufferOffsets); + pass.SetVertexBuffers(2, 1, &mTexCoordBuffer->getBuffer(), vertexBufferOffsets); + pass.SetIndexBuffer(mIndicesBuffer->getBuffer(), 0); + pass.DrawIndexed(mIndicesBuffer->getTotalComponents(), instance, 0, 0, 0); + instance = 0; +} + +void SeaweedModelDawn::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) +{ + mWorldUniformPer.worldUniforms[instance] = worldUniforms; + mSeaweedPer.time[instance] = mAquarium->g.mclock + instance; + + instance++; +} + +void SeaweedModelDawn::updateSeaweedModelTime(float time) {} diff --git a/src/aquarium-optimized/dawn/SeaweedModelDawn.h b/src/aquarium-optimized/dawn/SeaweedModelDawn.h index b38b943..844f8b9 100644 --- a/src/aquarium-optimized/dawn/SeaweedModelDawn.h +++ b/src/aquarium-optimized/dawn/SeaweedModelDawn.h @@ -1,82 +1,86 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// SeaweedModelDawn.h: Defines seaweed model of Dawn. - -#pragma once -#ifndef SEAWEEDMODELDAWN_H -#define SEAWEEDMODELDAWN_H 1 - -#include "ContextDawn.h" -#include "ProgramDawn.h" -#include "dawn/dawncpp.h" -#include "utils/ComboRenderPipelineDescriptor.h" - -#include "../SeaweedModel.h" - -class SeaweedModelDawn : public SeaweedModel -{ - public: - SeaweedModelDawn(const Context *context, Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend); - ~SeaweedModelDawn(); - - void init() override; - void prepareForDraw() const override; - void draw() override; - - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - - TextureDawn *mDiffuseTexture; - TextureDawn *mNormalTexture; - TextureDawn *mReflectionTexture; - TextureDawn *mSkyboxTexture; - - BufferDawn *mPositionBuffer; - BufferDawn *mNormalBuffer; - BufferDawn *mTexCoordBuffer; - - BufferDawn *mIndicesBuffer; - void updateSeaweedModelTime(float time) override; - - struct LightFactorUniforms - { - float shininess; - float specularFactor; - } mLightFactorUniforms; - - struct SeaweedPer - { - float time[20]; - } mSeaweedPer; - - struct WorldUniformPer - { - WorldUniforms worldUniforms[20]; - }; - WorldUniformPer mWorldUniformPer; - - private: - utils::ComboVertexInputDescriptor mVertexInputDescriptor; - dawn::RenderPipeline mPipeline; - - dawn::BindGroupLayout mGroupLayoutModel; - dawn::BindGroupLayout mGroupLayoutPer; - dawn::PipelineLayout mPipelineLayout; - - dawn::BindGroup mBindGroupModel; - dawn::BindGroup mBindGroupPer; - - dawn::Buffer mLightFactorBuffer; - dawn::Buffer mTimeBuffer; - dawn::Buffer mViewBuffer; - - const ContextDawn *mContextDawn; - ProgramDawn *mProgramDawn; - Aquarium * mAquarium; - - int instance; -}; - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SeaweedModelDawn.h: Defines seaweed model of Dawn. + +#pragma once +#ifndef SEAWEEDMODELDAWN_H +#define SEAWEEDMODELDAWN_H 1 + +#include "ContextDawn.h" +#include "ProgramDawn.h" +#include "dawn/dawncpp.h" +#include "utils/ComboRenderPipelineDescriptor.h" + +#include "../SeaweedModel.h" + +class SeaweedModelDawn : public SeaweedModel +{ + public: + SeaweedModelDawn(const Context *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + ~SeaweedModelDawn(); + + void init() override; + void prepareForDraw() const override; + void draw() override; + + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + + TextureDawn *mDiffuseTexture; + TextureDawn *mNormalTexture; + TextureDawn *mReflectionTexture; + TextureDawn *mSkyboxTexture; + + BufferDawn *mPositionBuffer; + BufferDawn *mNormalBuffer; + BufferDawn *mTexCoordBuffer; + + BufferDawn *mIndicesBuffer; + void updateSeaweedModelTime(float time) override; + + struct LightFactorUniforms + { + float shininess; + float specularFactor; + } mLightFactorUniforms; + + struct SeaweedPer + { + float time[20]; + } mSeaweedPer; + + struct WorldUniformPer + { + WorldUniforms worldUniforms[20]; + }; + WorldUniformPer mWorldUniformPer; + + private: + utils::ComboVertexInputDescriptor mVertexInputDescriptor; + dawn::RenderPipeline mPipeline; + + dawn::BindGroupLayout mGroupLayoutModel; + dawn::BindGroupLayout mGroupLayoutPer; + dawn::PipelineLayout mPipelineLayout; + + dawn::BindGroup mBindGroupModel; + dawn::BindGroup mBindGroupPer; + + dawn::Buffer mLightFactorBuffer; + dawn::Buffer mTimeBuffer; + dawn::Buffer mViewBuffer; + + const ContextDawn *mContextDawn; + ProgramDawn *mProgramDawn; + Aquarium *mAquarium; + + int instance; +}; + #endif // !SEAWEEDMODEL_H \ No newline at end of file diff --git a/src/aquarium-optimized/dawn/TextureDawn.cpp b/src/aquarium-optimized/dawn/TextureDawn.cpp index 24f059a..cc75dcf 100644 --- a/src/aquarium-optimized/dawn/TextureDawn.cpp +++ b/src/aquarium-optimized/dawn/TextureDawn.cpp @@ -1,192 +1,192 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// TextureDawn.cpp: Wrap textures of Dawn. Load image files and wrap into a Dawn texture. - -#include -#include - -#include "ContextDawn.h" -#include "TextureDawn.h" - -#include "common/AQUARIUM_ASSERT.h" - -TextureDawn::~TextureDawn() { - - DestoryImageData(mPixelVec); - DestoryImageData(mResizedVec); - mTextureView = nullptr; - mTexture = nullptr; - mSampler = nullptr; -} - -TextureDawn::TextureDawn(ContextDawn *context, const std::string &name, const std::string &url) - : Texture(name, url, true), - mTextureDimension(dawn::TextureDimension::e2D), - mTextureViewDimension(dawn::TextureViewDimension::e2D), - mTexture(nullptr), - mSampler(nullptr), - mFormat(dawn::TextureFormat::RGBA8Unorm), - mTextureView(nullptr), - mContext(context) -{ -} - -TextureDawn::TextureDawn(ContextDawn *context, - const std::string &name, - const std::vector &urls) - : Texture(name, urls, false), - mTextureDimension(dawn::TextureDimension::e2D), - mTextureViewDimension(dawn::TextureViewDimension::Cube), - mFormat(dawn::TextureFormat::RGBA8Unorm), - mContext(context) -{ -} - -void TextureDawn::loadTexture() -{ - dawn::SamplerDescriptor samplerDesc; - const int kPadding = 256; - loadImage(mUrls, &mPixelVec); - - if (mTextureViewDimension == dawn::TextureViewDimension::Cube) - { - dawn::TextureDescriptor descriptor; - descriptor.dimension = mTextureDimension; - descriptor.size.width = mWidth; - descriptor.size.height = mHeight; - descriptor.size.depth = 1; - descriptor.arrayLayerCount = 6; - descriptor.sampleCount = 1; - descriptor.format = mFormat; - descriptor.mipLevelCount = 1; - descriptor.usage = dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::Sampled; - mTexture = mContext->createTexture(descriptor); - - for (unsigned int i = 0; i < 6; i++) - { - dawn::Buffer stagingBuffer = mContext->createBufferFromData( - mPixelVec[i], mWidth * mHeight * 4, dawn::BufferUsageBit::CopySrc); - dawn::BufferCopyView bufferCopyView = - mContext->createBufferCopyView(stagingBuffer, 0, mWidth * 4, mHeight); - dawn::TextureCopyView textureCopyView = - mContext->createTextureCopyView(mTexture, 0, i, {0, 0, 0}); - dawn::Extent3D copySize = { static_cast(mWidth), static_cast(mHeight), 1 }; - mContext->mCommandBuffers.emplace_back( - mContext->copyBufferToTexture(bufferCopyView, textureCopyView, copySize)); - } - - dawn::TextureViewDescriptor viewDescriptor; - viewDescriptor.nextInChain = nullptr; - viewDescriptor.dimension = dawn::TextureViewDimension::Cube; - viewDescriptor.format = mFormat; - viewDescriptor.baseMipLevel = 0; - viewDescriptor.mipLevelCount = 1; - viewDescriptor.baseArrayLayer = 0; - viewDescriptor.arrayLayerCount = 6; - - mTextureView = mTexture.CreateView(&viewDescriptor); - - samplerDesc.addressModeU = dawn::AddressMode::ClampToEdge; - samplerDesc.addressModeV = dawn::AddressMode::ClampToEdge; - samplerDesc.addressModeW = dawn::AddressMode::ClampToEdge; - samplerDesc.minFilter = dawn::FilterMode::Linear; - samplerDesc.magFilter = dawn::FilterMode::Linear; - samplerDesc.mipmapFilter = dawn::FilterMode::Nearest; - samplerDesc.lodMinClamp = 0.0f; - samplerDesc.lodMaxClamp = 1000.0f; - samplerDesc.compare = dawn::CompareFunction::Never; - - mSampler = mContext->createSampler(samplerDesc); - } - else // dawn::TextureViewDimension::e2D - { - int resizedWidth; - if (mWidth % kPadding == 0) - { - resizedWidth = mWidth; - } - else - { - resizedWidth = (mWidth / 256 + 1) * 256; - } - generateMipmap(mPixelVec[0], mWidth, mHeight, 0, mResizedVec, resizedWidth, mHeight, 0, 4, - true); - - dawn::TextureDescriptor descriptor; - descriptor.dimension = mTextureDimension; - descriptor.size.width = resizedWidth; - descriptor.size.height = mHeight; - descriptor.size.depth = 1; - descriptor.arrayLayerCount = 1; - descriptor.sampleCount = 1; - descriptor.format = mFormat; - descriptor.mipLevelCount = static_cast(std::floor( - static_cast(std::log2(std::min(mWidth, mHeight))))) + - 1; - descriptor.usage = dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::Sampled; - mTexture = mContext->createTexture(descriptor); - - int count = 0; - for (unsigned int i = 0; i < descriptor.mipLevelCount; ++i, ++count) - { - int height = mHeight >> i; - int width = resizedWidth >> i; - if (height == 0) - { - height = 1; - } - - dawn::Buffer stagingBuffer = mContext->createBufferFromData( - mResizedVec[i], resizedWidth * height * 4, dawn::BufferUsageBit::CopySrc); - dawn::BufferCopyView bufferCopyView = - mContext->createBufferCopyView(stagingBuffer, 0, resizedWidth * 4, height); - dawn::TextureCopyView textureCopyView = - mContext->createTextureCopyView(mTexture, i, 0, {0, 0, 0}); - dawn::Extent3D copySize = {static_cast(width), - static_cast(height), - 1}; - mContext->mCommandBuffers.emplace_back( - mContext->copyBufferToTexture(bufferCopyView, textureCopyView, copySize)); - } - - dawn::TextureViewDescriptor viewDescriptor; - viewDescriptor.nextInChain = nullptr; - viewDescriptor.dimension = dawn::TextureViewDimension::e2D; - viewDescriptor.format = mFormat; - viewDescriptor.baseMipLevel = 0; - viewDescriptor.mipLevelCount = - static_cast( - std::floor(static_cast(std::log2(std::min(mWidth, mHeight))))) + - 1; - viewDescriptor.baseArrayLayer = 0; - viewDescriptor.arrayLayerCount = 1; - - mTextureView = mTexture.CreateView(&viewDescriptor); - - samplerDesc.addressModeU = dawn::AddressMode::ClampToEdge; - samplerDesc.addressModeV = dawn::AddressMode::ClampToEdge; - samplerDesc.addressModeW = dawn::AddressMode::ClampToEdge; - samplerDesc.minFilter = dawn::FilterMode::Linear; - samplerDesc.magFilter = dawn::FilterMode::Linear; - samplerDesc.lodMinClamp = 0.0f; - samplerDesc.lodMaxClamp = 1000.0f; - samplerDesc.compare = dawn::CompareFunction::Never; - - if (isPowerOf2(mWidth) && isPowerOf2(mHeight)) - { - samplerDesc.mipmapFilter = dawn::FilterMode::Linear; - } - else - { - samplerDesc.mipmapFilter = dawn::FilterMode::Nearest; - } - - mSampler = mContext->createSampler(samplerDesc); - } - - // TODO(yizhou): check if the pixel destory should delay or fence -} - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TextureDawn.cpp: Wrap textures of Dawn. Load image files and wrap into a Dawn texture. + +#include +#include + +#include "ContextDawn.h" +#include "TextureDawn.h" + +#include "common/AQUARIUM_ASSERT.h" + +TextureDawn::~TextureDawn() +{ + + DestoryImageData(mPixelVec); + DestoryImageData(mResizedVec); + mTextureView = nullptr; + mTexture = nullptr; + mSampler = nullptr; +} + +TextureDawn::TextureDawn(ContextDawn *context, const std::string &name, const std::string &url) + : Texture(name, url, true), + mTextureDimension(dawn::TextureDimension::e2D), + mTextureViewDimension(dawn::TextureViewDimension::e2D), + mTexture(nullptr), + mSampler(nullptr), + mFormat(dawn::TextureFormat::RGBA8Unorm), + mTextureView(nullptr), + mContext(context) +{ +} + +TextureDawn::TextureDawn(ContextDawn *context, + const std::string &name, + const std::vector &urls) + : Texture(name, urls, false), + mTextureDimension(dawn::TextureDimension::e2D), + mTextureViewDimension(dawn::TextureViewDimension::Cube), + mFormat(dawn::TextureFormat::RGBA8Unorm), + mContext(context) +{ +} + +void TextureDawn::loadTexture() +{ + dawn::SamplerDescriptor samplerDesc; + const int kPadding = 256; + loadImage(mUrls, &mPixelVec); + + if (mTextureViewDimension == dawn::TextureViewDimension::Cube) + { + dawn::TextureDescriptor descriptor; + descriptor.dimension = mTextureDimension; + descriptor.size.width = mWidth; + descriptor.size.height = mHeight; + descriptor.size.depth = 1; + descriptor.arrayLayerCount = 6; + descriptor.sampleCount = 1; + descriptor.format = mFormat; + descriptor.mipLevelCount = 1; + descriptor.usage = dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::Sampled; + mTexture = mContext->createTexture(descriptor); + + for (unsigned int i = 0; i < 6; i++) + { + dawn::Buffer stagingBuffer = mContext->createBufferFromData( + mPixelVec[i], mWidth * mHeight * 4, dawn::BufferUsageBit::CopySrc); + dawn::BufferCopyView bufferCopyView = + mContext->createBufferCopyView(stagingBuffer, 0, mWidth * 4, mHeight); + dawn::TextureCopyView textureCopyView = + mContext->createTextureCopyView(mTexture, 0, i, {0, 0, 0}); + dawn::Extent3D copySize = {static_cast(mWidth), + static_cast(mHeight), 1}; + mContext->mCommandBuffers.emplace_back( + mContext->copyBufferToTexture(bufferCopyView, textureCopyView, copySize)); + } + + dawn::TextureViewDescriptor viewDescriptor; + viewDescriptor.nextInChain = nullptr; + viewDescriptor.dimension = dawn::TextureViewDimension::Cube; + viewDescriptor.format = mFormat; + viewDescriptor.baseMipLevel = 0; + viewDescriptor.mipLevelCount = 1; + viewDescriptor.baseArrayLayer = 0; + viewDescriptor.arrayLayerCount = 6; + + mTextureView = mTexture.CreateView(&viewDescriptor); + + samplerDesc.addressModeU = dawn::AddressMode::ClampToEdge; + samplerDesc.addressModeV = dawn::AddressMode::ClampToEdge; + samplerDesc.addressModeW = dawn::AddressMode::ClampToEdge; + samplerDesc.minFilter = dawn::FilterMode::Linear; + samplerDesc.magFilter = dawn::FilterMode::Linear; + samplerDesc.mipmapFilter = dawn::FilterMode::Nearest; + samplerDesc.lodMinClamp = 0.0f; + samplerDesc.lodMaxClamp = 1000.0f; + samplerDesc.compare = dawn::CompareFunction::Never; + + mSampler = mContext->createSampler(samplerDesc); + } + else // dawn::TextureViewDimension::e2D + { + int resizedWidth; + if (mWidth % kPadding == 0) + { + resizedWidth = mWidth; + } + else + { + resizedWidth = (mWidth / 256 + 1) * 256; + } + generateMipmap(mPixelVec[0], mWidth, mHeight, 0, mResizedVec, resizedWidth, mHeight, 0, 4, + true); + + dawn::TextureDescriptor descriptor; + descriptor.dimension = mTextureDimension; + descriptor.size.width = resizedWidth; + descriptor.size.height = mHeight; + descriptor.size.depth = 1; + descriptor.arrayLayerCount = 1; + descriptor.sampleCount = 1; + descriptor.format = mFormat; + descriptor.mipLevelCount = static_cast(std::floor( + static_cast(std::log2(std::min(mWidth, mHeight))))) + + 1; + descriptor.usage = dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::Sampled; + mTexture = mContext->createTexture(descriptor); + + int count = 0; + for (unsigned int i = 0; i < descriptor.mipLevelCount; ++i, ++count) + { + int height = mHeight >> i; + int width = resizedWidth >> i; + if (height == 0) + { + height = 1; + } + + dawn::Buffer stagingBuffer = mContext->createBufferFromData( + mResizedVec[i], resizedWidth * height * 4, dawn::BufferUsageBit::CopySrc); + dawn::BufferCopyView bufferCopyView = + mContext->createBufferCopyView(stagingBuffer, 0, resizedWidth * 4, height); + dawn::TextureCopyView textureCopyView = + mContext->createTextureCopyView(mTexture, i, 0, {0, 0, 0}); + dawn::Extent3D copySize = {static_cast(width), static_cast(height), + 1}; + mContext->mCommandBuffers.emplace_back( + mContext->copyBufferToTexture(bufferCopyView, textureCopyView, copySize)); + } + + dawn::TextureViewDescriptor viewDescriptor; + viewDescriptor.nextInChain = nullptr; + viewDescriptor.dimension = dawn::TextureViewDimension::e2D; + viewDescriptor.format = mFormat; + viewDescriptor.baseMipLevel = 0; + viewDescriptor.mipLevelCount = + static_cast( + std::floor(static_cast(std::log2(std::min(mWidth, mHeight))))) + + 1; + viewDescriptor.baseArrayLayer = 0; + viewDescriptor.arrayLayerCount = 1; + + mTextureView = mTexture.CreateView(&viewDescriptor); + + samplerDesc.addressModeU = dawn::AddressMode::ClampToEdge; + samplerDesc.addressModeV = dawn::AddressMode::ClampToEdge; + samplerDesc.addressModeW = dawn::AddressMode::ClampToEdge; + samplerDesc.minFilter = dawn::FilterMode::Linear; + samplerDesc.magFilter = dawn::FilterMode::Linear; + samplerDesc.lodMinClamp = 0.0f; + samplerDesc.lodMaxClamp = 1000.0f; + samplerDesc.compare = dawn::CompareFunction::Never; + + if (isPowerOf2(mWidth) && isPowerOf2(mHeight)) + { + samplerDesc.mipmapFilter = dawn::FilterMode::Linear; + } + else + { + samplerDesc.mipmapFilter = dawn::FilterMode::Nearest; + } + + mSampler = mContext->createSampler(samplerDesc); + } + + // TODO(yizhou): check if the pixel destory should delay or fence +} diff --git a/src/aquarium-optimized/dawn/TextureDawn.h b/src/aquarium-optimized/dawn/TextureDawn.h index 7d2610b..d0c7370 100644 --- a/src/aquarium-optimized/dawn/TextureDawn.h +++ b/src/aquarium-optimized/dawn/TextureDawn.h @@ -1,47 +1,47 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// TextureDawn.h: Wrap textures of Dawn. - -#pragma once -#ifndef TEXTUREDAWN_H -#define TEXTUREDAWN_H - -#include - -#include "../Texture.h" - -class ContextDawn; - -class TextureDawn : public Texture -{ - public: - ~TextureDawn() override; - TextureDawn(ContextDawn *context, const std::string &name, const std::string &url); - TextureDawn(ContextDawn *context, - const std::string &name, - const std::vector &urls); - - const dawn::Texture &getTextureId() const { return mTexture; } - const dawn::Sampler &getSampler() const { return mSampler; } - dawn::TextureDimension getTextureDimension() { return mTextureDimension; } - dawn::TextureViewDimension getTextureViewDimension() { return mTextureViewDimension; } - dawn::TextureView getTextureView() { return mTextureView; } - - void loadTexture() override; - - private: - dawn::TextureDimension mTextureDimension; // texture 2D or CubeMap - dawn::TextureViewDimension mTextureViewDimension; - dawn::Texture mTexture; - dawn::Sampler mSampler; - dawn::TextureFormat mFormat; - dawn::TextureView mTextureView; - std::vector mPixelVec; - std::vector mResizedVec; - ContextDawn *mContext; -}; - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TextureDawn.h: Wrap textures of Dawn. + +#pragma once +#ifndef TEXTUREDAWN_H +#define TEXTUREDAWN_H + +#include + +#include "../Texture.h" + +class ContextDawn; + +class TextureDawn : public Texture +{ + public: + ~TextureDawn() override; + TextureDawn(ContextDawn *context, const std::string &name, const std::string &url); + TextureDawn(ContextDawn *context, + const std::string &name, + const std::vector &urls); + + const dawn::Texture &getTextureId() const { return mTexture; } + const dawn::Sampler &getSampler() const { return mSampler; } + dawn::TextureDimension getTextureDimension() { return mTextureDimension; } + dawn::TextureViewDimension getTextureViewDimension() { return mTextureViewDimension; } + dawn::TextureView getTextureView() { return mTextureView; } + + void loadTexture() override; + + private: + dawn::TextureDimension mTextureDimension; // texture 2D or CubeMap + dawn::TextureViewDimension mTextureViewDimension; + dawn::Texture mTexture; + dawn::Sampler mSampler; + dawn::TextureFormat mFormat; + dawn::TextureView mTextureView; + std::vector mPixelVec; + std::vector mResizedVec; + ContextDawn *mContext; +}; + #endif // !TEXTUREDAWN_H \ No newline at end of file diff --git a/src/aquarium-optimized/dawn/imgui_impl_dawn.cpp b/src/aquarium-optimized/dawn/imgui_impl_dawn.cpp index c5cbe1a..bd77997 100644 --- a/src/aquarium-optimized/dawn/imgui_impl_dawn.cpp +++ b/src/aquarium-optimized/dawn/imgui_impl_dawn.cpp @@ -1,385 +1,385 @@ -// dear imgui: Renderer for Dawn -// This needs to be used along with a Platform Binding (e.g. GLFW) - -#include "ProgramDawn.h" - -#include "imgui_impl_dawn.h" -#include "imgui.h" -#include "utils/ComboRenderPipelineDescriptor.h" - -// Dawn data -dawn::RenderPipeline mPipeline(nullptr); -dawn::BindGroup mBindGroup(nullptr); -dawn::TextureFormat mFormat(dawn::TextureFormat::RGBA8Unorm); -dawn::ShaderModule mVsModule(nullptr); -dawn::ShaderModule mFsModule(nullptr); - -dawn::Buffer mIndexBuffer(nullptr); -dawn::Buffer mVertexBuffer(nullptr); -dawn::Buffer mConstantBuffer(nullptr); -dawn::Buffer mStagingBuffer(nullptr); -dawn::Texture mTexture(nullptr); -dawn::TextureView mTextureView; -dawn::Sampler mSampler(nullptr); - -ProgramDawn *mProgramDawn(nullptr); -ContextDawn *mContextDawn(nullptr); - -int mIndexBufferSize = 0; -int mVertexBufferSize = 0; -bool mEnableMSAA = false; -ImDrawVert mVertexData[40000]; -ImDrawIdx mIndexData[10000]; - -struct VERTEX_CONSTANT_BUFFER -{ - float mvp[4][4]; -}; - -static void ImGui_ImplDawn_SetupRenderState(ImDrawData *draw_data, - const dawn::RenderPassEncoder &pass) -{ - // Setup orthographic projection matrix into our constant buffer - // Our visible imgui space lies from draw_data->DisplayPos (top left) to - // draw_data->DisplayPos+data_data->DisplaySize (bottom right). - VERTEX_CONSTANT_BUFFER vertex_constant_buffer; - { - float L = draw_data->DisplayPos.x; - float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; - float T = draw_data->DisplayPos.y; - float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; - float mvp[4][4] = { - {2.0f / (R - L), 0.0f, 0.0f, 0.0f}, - {0.0f, 2.0f / (T - B), 0.0f, 0.0f}, - {0.0f, 0.0f, 0.5f, 0.0f}, - {(R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f}, - }; - memcpy(&vertex_constant_buffer.mvp, mvp, sizeof(mvp)); - } - mConstantBuffer.SetSubData(0, sizeof(VERTEX_CONSTANT_BUFFER), &vertex_constant_buffer.mvp); - - // TODO(yizhou): setting viewport isn't supported in dawn yet. - // Setup viewport - // pass.SetViewport(0.0f, 0.0f, draw_data->DisplaySize.x, draw_data->DisplaySize.y, 0.0f, 1.0f); - - uint64_t vertexBufferOffsets[1] = {0}; - - pass.SetPipeline(mPipeline); - pass.SetBindGroup(0, mBindGroup, 0, nullptr); - pass.SetVertexBuffers(0, 1, &mVertexBuffer, vertexBufferOffsets); - pass.SetIndexBuffer(mIndexBuffer, 0); -} - -// Render function -// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call -// this directly from your main loop) -void ImGui_ImplDawn_RenderDrawData(ImDrawData *draw_data) -{ - // Avoid rendering when minimized - if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) - return; - - // Create and grow vertex/index buffers if needed - if (mVertexBuffer.Get() == nullptr || mVertexBufferSize < draw_data->TotalVtxCount) - { - mVertexBufferSize = draw_data->TotalVtxCount + 5000; - mVertexBufferSize = mVertexBufferSize % 4 == 0 - ? mVertexBufferSize - : mVertexBufferSize + 4 - mVertexBufferSize % 4; - - dawn::BufferDescriptor descriptor; - descriptor.size = mVertexBufferSize * sizeof(ImDrawVert); - descriptor.usage = dawn::BufferUsageBit::Vertex | dawn::BufferUsageBit::CopyDst; - - mVertexBuffer = mContextDawn->mDevice.CreateBuffer(&descriptor); - } - - if (mIndexBuffer.Get() == nullptr || mIndexBufferSize < draw_data->TotalIdxCount) - { - mIndexBufferSize = draw_data->TotalIdxCount + 10000; - mIndexBufferSize = mIndexBufferSize % 4 == 0 ? mIndexBufferSize - : mIndexBufferSize + 4 - mIndexBufferSize % 4; - - dawn::BufferDescriptor descriptor; - descriptor.size = mIndexBufferSize * sizeof(ImDrawIdx); - descriptor.usage = dawn::BufferUsageBit::Index | dawn::BufferUsageBit::CopyDst; - - mIndexBuffer = mContextDawn->mDevice.CreateBuffer(&descriptor); - } - - // Upload vertex/index data into a single contiguous GPU buffer - uint32_t vtx_dst = 0; - uint32_t idx_dst = 0; - ImDrawVert *pVertex = mVertexData; - ImDrawIdx *pIndex = mIndexData; - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList *cmd_list = draw_data->CmdLists[n]; - memcpy(pVertex, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); - memcpy(pIndex, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); - - pVertex += cmd_list->VtxBuffer.Size; - pIndex += cmd_list->IdxBuffer.Size; - vtx_dst += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); - idx_dst += cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx); - } - vtx_dst = vtx_dst % 4 == 0 ? vtx_dst : vtx_dst + 4 - vtx_dst % 4; - idx_dst = idx_dst % 4 == 0 ? idx_dst : idx_dst + 4 - idx_dst % 4; - - if (vtx_dst != 0 && idx_dst != 0) - { - mContextDawn->setBufferData(mVertexBuffer, 0, vtx_dst, mVertexData); - mContextDawn->setBufferData(mIndexBuffer, 0, idx_dst, mIndexData); - } - - const dawn::RenderPassEncoder &pass = mContextDawn->getRenderPass(); - - // Setup desired Dawn state - ImGui_ImplDawn_SetupRenderState(draw_data, pass); - - // Render pass - // (Because we merged all buffers into a single one, we maintain our own offset into them) - int global_vtx_offset = 0; - int global_idx_offset = 0; - ImVec2 clip_off = draw_data->DisplayPos; - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList *cmd_list = draw_data->CmdLists[n]; - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) - { - const ImDrawCmd *pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback != NULL) - { - // User callback, registered via ImDrawList::AddCallback() - // (ImDrawCallback_ResetRenderState is a special callback value used by the user to - // request the renderer to reset render state.) - if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) - ImGui_ImplDawn_SetupRenderState(draw_data, pass); - else - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - // Apply Scissor, Bind texture, Draw - pass.SetScissorRect(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y, - pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); - pass.DrawIndexed(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, - pcmd->VtxOffset + global_vtx_offset, 0); - } - } - global_idx_offset += cmd_list->IdxBuffer.Size; - global_vtx_offset += cmd_list->VtxBuffer.Size; - } -} - -static void ImGui_ImplDawn_CreateFontsTexture() -{ - // Build texture atlas - ImGuiIO &io = ImGui::GetIO(); - unsigned char *pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); - - // Upload texture to graphics system - { - dawn::TextureDescriptor descriptor; - descriptor.dimension = dawn::TextureDimension::e2D; - descriptor.size.width = width; - descriptor.size.height = height; - descriptor.size.depth = 1; - descriptor.arrayLayerCount = 1; - descriptor.sampleCount = 1; - descriptor.format = mFormat; - descriptor.mipLevelCount = 1; - descriptor.usage = dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::Sampled; - mTexture = mContextDawn->createTexture(descriptor); - - mStagingBuffer = mContextDawn->createBufferFromData(pixels, width * height * 4, - dawn::BufferUsageBit::CopySrc); - dawn::BufferCopyView bufferCopyView = - mContextDawn->createBufferCopyView(mStagingBuffer, 0, width * 4, height); - dawn::TextureCopyView textureCopyView = - mContextDawn->createTextureCopyView(mTexture, 0, 0, {0, 0, 0}); - dawn::Extent3D copySize = {static_cast(width), static_cast(height), 1}; - dawn::CommandBuffer copyCommand = - mContextDawn->copyBufferToTexture(bufferCopyView, textureCopyView, copySize); - mContextDawn->queue.Submit(1, ©Command); - - // Create texture view - dawn::TextureViewDescriptor viewDescriptor; - viewDescriptor.nextInChain = nullptr; - viewDescriptor.dimension = dawn::TextureViewDimension::e2D; - viewDescriptor.format = mFormat; - viewDescriptor.baseMipLevel = 0; - viewDescriptor.mipLevelCount = 1; - viewDescriptor.baseArrayLayer = 0; - viewDescriptor.arrayLayerCount = 1; - - mTextureView = mTexture.CreateView(&viewDescriptor); - - dawn::SamplerDescriptor samplerDesc; - samplerDesc.addressModeU = dawn::AddressMode::Repeat; - samplerDesc.addressModeV = dawn::AddressMode::Repeat; - samplerDesc.addressModeW = dawn::AddressMode::Repeat; - samplerDesc.minFilter = dawn::FilterMode::Linear; - samplerDesc.magFilter = dawn::FilterMode::Linear; - samplerDesc.lodMinClamp = 0.0f; - samplerDesc.lodMaxClamp = 0.0f; - samplerDesc.compare = dawn::CompareFunction::Always; - samplerDesc.mipmapFilter = dawn::FilterMode::Linear; - - mSampler = mContextDawn->createSampler(samplerDesc); - } - - io.Fonts->TexID = (ImTextureID)mTextureView.Get(); -} - -bool ImGui_ImplDawn_CreateDeviceObjects() -{ - if (!mContextDawn->mDevice) - return false; - - utils::ComboVertexInputDescriptor mVertexInputDescriptor; - mVertexInputDescriptor.cBuffers[0].attributeCount = 3; - mVertexInputDescriptor.cBuffers[0].stride = sizeof(ImDrawVert); - mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float2; - mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; - mVertexInputDescriptor.cAttributes[0].offset = 0; - mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float2; - mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; - mVertexInputDescriptor.cAttributes[1].offset = IM_OFFSETOF(ImDrawVert, uv); - mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::UChar4Norm; - mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; - mVertexInputDescriptor.cAttributes[2].offset = IM_OFFSETOF(ImDrawVert, col); - - mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; - mVertexInputDescriptor.bufferCount = 1; - mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; - - // Create bind group layout - dawn::BindGroupLayout layout = mContextDawn->MakeBindGroupLayout( - {{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}}); - - dawn::PipelineLayout mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({layout}); - - const ResourceHelper *resourceHelper = mContextDawn->getResourceHelper(); - const std::string &programPath = resourceHelper->getProgramPath(); - mProgramDawn = new ProgramDawn(mContextDawn, programPath + "imguiVertexShader", - programPath + "imguiFragmentShader"); - mProgramDawn->loadProgram(); - - const dawn::ShaderModule &mVsModule = mProgramDawn->getVSModule(); - const dawn::ShaderModule &mFsModule = mProgramDawn->getFSModule(); - - dawn::PipelineStageDescriptor cVertexStage; - cVertexStage.entryPoint = "main"; - cVertexStage.module = mVsModule; - - dawn::PipelineStageDescriptor cFragmentStage; - cFragmentStage.entryPoint = "main"; - cFragmentStage.module = mFsModule; - - dawn::BlendDescriptor blendDescriptor; - blendDescriptor.operation = dawn::BlendOperation::Add; - blendDescriptor.srcFactor = dawn::BlendFactor::SrcAlpha; - blendDescriptor.dstFactor = dawn::BlendFactor::OneMinusSrcAlpha; - dawn::BlendDescriptor alphaDescriptor; - alphaDescriptor.operation = dawn::BlendOperation::Add; - alphaDescriptor.srcFactor = dawn::BlendFactor::OneMinusSrcAlpha; - alphaDescriptor.dstFactor = dawn::BlendFactor::Zero; - - dawn::ColorStateDescriptor ColorStateDescriptor; - ColorStateDescriptor.colorBlend = blendDescriptor; - ColorStateDescriptor.alphaBlend = alphaDescriptor; - ColorStateDescriptor.writeMask = dawn::ColorWriteMask::All; - - dawn::RasterizationStateDescriptor rasterizationState; - rasterizationState.nextInChain = nullptr; - rasterizationState.frontFace = dawn::FrontFace::CCW; - rasterizationState.cullMode = dawn::CullMode::None; - rasterizationState.depthBias = 0; - rasterizationState.depthBiasSlopeScale = 0.0; - rasterizationState.depthBiasClamp = 0.0; - - // create graphics mPipeline - utils::ComboRenderPipelineDescriptor mPipelineDescriptor(mContextDawn->mDevice); - mPipelineDescriptor.layout = mPipelineLayout; - mPipelineDescriptor.cVertexStage.module = mVsModule; - mPipelineDescriptor.cFragmentStage.module = mFsModule; - mPipelineDescriptor.vertexInput = &mVertexInputDescriptor; - mPipelineDescriptor.depthStencilState = &mPipelineDescriptor.cDepthStencilState; - mPipelineDescriptor.cDepthStencilState.format = dawn::TextureFormat::Depth24PlusStencil8; - mPipelineDescriptor.cColorStates[0] = &ColorStateDescriptor; - mPipelineDescriptor.cColorStates[0]->format = mFormat; - mPipelineDescriptor.cDepthStencilState.depthWriteEnabled = false; - mPipelineDescriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Always; - mPipelineDescriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleList; - mPipelineDescriptor.sampleCount = mEnableMSAA ? 4 : 1; - mPipelineDescriptor.rasterizationState = &rasterizationState; - - mPipeline = mContextDawn->mDevice.CreateRenderPipeline(&mPipelineDescriptor); - - ImGui_ImplDawn_CreateFontsTexture(); - - // Create uniform buffer - dawn::BufferDescriptor descriptor; - descriptor.size = sizeof(VERTEX_CONSTANT_BUFFER); - descriptor.usage = dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform | - dawn::BufferUsageBit::Uniform; - - mConstantBuffer = mContextDawn->mDevice.CreateBuffer(&descriptor); - - mBindGroup = mContextDawn->makeBindGroup( - layout, {{0, mConstantBuffer, 0, sizeof(VERTEX_CONSTANT_BUFFER)}, - {1, mSampler}, - {2, mTextureView}}); - - return true; -} - -bool ImGui_ImplDawn_Init(ContextDawn *context, dawn::TextureFormat rtv_format, bool enableMSAA) -{ - // Setup back-end capabilities flags - ImGuiIO &io = ImGui::GetIO(); - io.BackendRendererName = "imgui_impl_Dawn"; - io.BackendFlags |= - ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, - // allowing for large meshes. - - mFormat = rtv_format; - mContextDawn = context; - - mIndexBuffer = NULL; - mVertexBuffer = NULL; - mIndexBufferSize = 3000; - mVertexBufferSize = 3000; - mEnableMSAA = enableMSAA; - - return true; -} - -void ImGui_ImplDawn_Shutdown() -{ - delete mProgramDawn; - - mPipeline = nullptr; - mBindGroup = nullptr; - mVsModule = nullptr; - mFsModule = nullptr; - - mIndexBuffer = nullptr; - mVertexBuffer = nullptr; - mStagingBuffer = nullptr; - mTexture = nullptr; - mSampler = nullptr; - mConstantBuffer = nullptr; - mTextureView = nullptr; -} - -void ImGui_ImplDawn_NewFrame() -{ - if (!mPipeline.Get()) - ImGui_ImplDawn_CreateDeviceObjects(); -} +// dear imgui: Renderer for Dawn +// This needs to be used along with a Platform Binding (e.g. GLFW) + +#include "ProgramDawn.h" + +#include "imgui.h" +#include "imgui_impl_dawn.h" +#include "utils/ComboRenderPipelineDescriptor.h" + +// Dawn data +dawn::RenderPipeline mPipeline(nullptr); +dawn::BindGroup mBindGroup(nullptr); +dawn::TextureFormat mFormat(dawn::TextureFormat::RGBA8Unorm); +dawn::ShaderModule mVsModule(nullptr); +dawn::ShaderModule mFsModule(nullptr); + +dawn::Buffer mIndexBuffer(nullptr); +dawn::Buffer mVertexBuffer(nullptr); +dawn::Buffer mConstantBuffer(nullptr); +dawn::Buffer mStagingBuffer(nullptr); +dawn::Texture mTexture(nullptr); +dawn::TextureView mTextureView; +dawn::Sampler mSampler(nullptr); + +ProgramDawn *mProgramDawn(nullptr); +ContextDawn *mContextDawn(nullptr); + +int mIndexBufferSize = 0; +int mVertexBufferSize = 0; +bool mEnableMSAA = false; +ImDrawVert mVertexData[40000]; +ImDrawIdx mIndexData[10000]; + +struct VERTEX_CONSTANT_BUFFER +{ + float mvp[4][4]; +}; + +static void ImGui_ImplDawn_SetupRenderState(ImDrawData *draw_data, + const dawn::RenderPassEncoder &pass) +{ + // Setup orthographic projection matrix into our constant buffer + // Our visible imgui space lies from draw_data->DisplayPos (top left) to + // draw_data->DisplayPos+data_data->DisplaySize (bottom right). + VERTEX_CONSTANT_BUFFER vertex_constant_buffer; + { + float L = draw_data->DisplayPos.x; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; + float T = draw_data->DisplayPos.y; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; + float mvp[4][4] = { + {2.0f / (R - L), 0.0f, 0.0f, 0.0f}, + {0.0f, 2.0f / (T - B), 0.0f, 0.0f}, + {0.0f, 0.0f, 0.5f, 0.0f}, + {(R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f}, + }; + memcpy(&vertex_constant_buffer.mvp, mvp, sizeof(mvp)); + } + mConstantBuffer.SetSubData(0, sizeof(VERTEX_CONSTANT_BUFFER), &vertex_constant_buffer.mvp); + + // TODO(yizhou): setting viewport isn't supported in dawn yet. + // Setup viewport + // pass.SetViewport(0.0f, 0.0f, draw_data->DisplaySize.x, draw_data->DisplaySize.y, 0.0f, 1.0f); + + uint64_t vertexBufferOffsets[1] = {0}; + + pass.SetPipeline(mPipeline); + pass.SetBindGroup(0, mBindGroup, 0, nullptr); + pass.SetVertexBuffers(0, 1, &mVertexBuffer, vertexBufferOffsets); + pass.SetIndexBuffer(mIndexBuffer, 0); +} + +// Render function +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call +// this directly from your main loop) +void ImGui_ImplDawn_RenderDrawData(ImDrawData *draw_data) +{ + // Avoid rendering when minimized + if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) + return; + + // Create and grow vertex/index buffers if needed + if (mVertexBuffer.Get() == nullptr || mVertexBufferSize < draw_data->TotalVtxCount) + { + mVertexBufferSize = draw_data->TotalVtxCount + 5000; + mVertexBufferSize = mVertexBufferSize % 4 == 0 + ? mVertexBufferSize + : mVertexBufferSize + 4 - mVertexBufferSize % 4; + + dawn::BufferDescriptor descriptor; + descriptor.size = mVertexBufferSize * sizeof(ImDrawVert); + descriptor.usage = dawn::BufferUsageBit::Vertex | dawn::BufferUsageBit::CopyDst; + + mVertexBuffer = mContextDawn->mDevice.CreateBuffer(&descriptor); + } + + if (mIndexBuffer.Get() == nullptr || mIndexBufferSize < draw_data->TotalIdxCount) + { + mIndexBufferSize = draw_data->TotalIdxCount + 10000; + mIndexBufferSize = mIndexBufferSize % 4 == 0 ? mIndexBufferSize + : mIndexBufferSize + 4 - mIndexBufferSize % 4; + + dawn::BufferDescriptor descriptor; + descriptor.size = mIndexBufferSize * sizeof(ImDrawIdx); + descriptor.usage = dawn::BufferUsageBit::Index | dawn::BufferUsageBit::CopyDst; + + mIndexBuffer = mContextDawn->mDevice.CreateBuffer(&descriptor); + } + + // Upload vertex/index data into a single contiguous GPU buffer + uint32_t vtx_dst = 0; + uint32_t idx_dst = 0; + ImDrawVert *pVertex = mVertexData; + ImDrawIdx *pIndex = mIndexData; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList *cmd_list = draw_data->CmdLists[n]; + memcpy(pVertex, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); + memcpy(pIndex, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + + pVertex += cmd_list->VtxBuffer.Size; + pIndex += cmd_list->IdxBuffer.Size; + vtx_dst += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); + idx_dst += cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx); + } + vtx_dst = vtx_dst % 4 == 0 ? vtx_dst : vtx_dst + 4 - vtx_dst % 4; + idx_dst = idx_dst % 4 == 0 ? idx_dst : idx_dst + 4 - idx_dst % 4; + + if (vtx_dst != 0 && idx_dst != 0) + { + mContextDawn->setBufferData(mVertexBuffer, 0, vtx_dst, mVertexData); + mContextDawn->setBufferData(mIndexBuffer, 0, idx_dst, mIndexData); + } + + const dawn::RenderPassEncoder &pass = mContextDawn->getRenderPass(); + + // Setup desired Dawn state + ImGui_ImplDawn_SetupRenderState(draw_data, pass); + + // Render pass + // (Because we merged all buffers into a single one, we maintain our own offset into them) + int global_vtx_offset = 0; + int global_idx_offset = 0; + ImVec2 clip_off = draw_data->DisplayPos; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList *cmd_list = draw_data->CmdLists[n]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd *pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != NULL) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to + // request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplDawn_SetupRenderState(draw_data, pass); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Apply Scissor, Bind texture, Draw + pass.SetScissorRect(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y, + pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); + pass.DrawIndexed(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, + pcmd->VtxOffset + global_vtx_offset, 0); + } + } + global_idx_offset += cmd_list->IdxBuffer.Size; + global_vtx_offset += cmd_list->VtxBuffer.Size; + } +} + +static void ImGui_ImplDawn_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO &io = ImGui::GetIO(); + unsigned char *pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + // Upload texture to graphics system + { + dawn::TextureDescriptor descriptor; + descriptor.dimension = dawn::TextureDimension::e2D; + descriptor.size.width = width; + descriptor.size.height = height; + descriptor.size.depth = 1; + descriptor.arrayLayerCount = 1; + descriptor.sampleCount = 1; + descriptor.format = mFormat; + descriptor.mipLevelCount = 1; + descriptor.usage = dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::Sampled; + mTexture = mContextDawn->createTexture(descriptor); + + mStagingBuffer = mContextDawn->createBufferFromData(pixels, width * height * 4, + dawn::BufferUsageBit::CopySrc); + dawn::BufferCopyView bufferCopyView = + mContextDawn->createBufferCopyView(mStagingBuffer, 0, width * 4, height); + dawn::TextureCopyView textureCopyView = + mContextDawn->createTextureCopyView(mTexture, 0, 0, {0, 0, 0}); + dawn::Extent3D copySize = {static_cast(width), static_cast(height), 1}; + dawn::CommandBuffer copyCommand = + mContextDawn->copyBufferToTexture(bufferCopyView, textureCopyView, copySize); + mContextDawn->queue.Submit(1, ©Command); + + // Create texture view + dawn::TextureViewDescriptor viewDescriptor; + viewDescriptor.nextInChain = nullptr; + viewDescriptor.dimension = dawn::TextureViewDimension::e2D; + viewDescriptor.format = mFormat; + viewDescriptor.baseMipLevel = 0; + viewDescriptor.mipLevelCount = 1; + viewDescriptor.baseArrayLayer = 0; + viewDescriptor.arrayLayerCount = 1; + + mTextureView = mTexture.CreateView(&viewDescriptor); + + dawn::SamplerDescriptor samplerDesc; + samplerDesc.addressModeU = dawn::AddressMode::Repeat; + samplerDesc.addressModeV = dawn::AddressMode::Repeat; + samplerDesc.addressModeW = dawn::AddressMode::Repeat; + samplerDesc.minFilter = dawn::FilterMode::Linear; + samplerDesc.magFilter = dawn::FilterMode::Linear; + samplerDesc.lodMinClamp = 0.0f; + samplerDesc.lodMaxClamp = 0.0f; + samplerDesc.compare = dawn::CompareFunction::Always; + samplerDesc.mipmapFilter = dawn::FilterMode::Linear; + + mSampler = mContextDawn->createSampler(samplerDesc); + } + + io.Fonts->TexID = (ImTextureID)mTextureView.Get(); +} + +bool ImGui_ImplDawn_CreateDeviceObjects() +{ + if (!mContextDawn->mDevice) + return false; + + utils::ComboVertexInputDescriptor mVertexInputDescriptor; + mVertexInputDescriptor.cBuffers[0].attributeCount = 3; + mVertexInputDescriptor.cBuffers[0].stride = sizeof(ImDrawVert); + mVertexInputDescriptor.cAttributes[0].format = dawn::VertexFormat::Float2; + mVertexInputDescriptor.cAttributes[0].shaderLocation = 0; + mVertexInputDescriptor.cAttributes[0].offset = 0; + mVertexInputDescriptor.cAttributes[1].format = dawn::VertexFormat::Float2; + mVertexInputDescriptor.cAttributes[1].shaderLocation = 1; + mVertexInputDescriptor.cAttributes[1].offset = IM_OFFSETOF(ImDrawVert, uv); + mVertexInputDescriptor.cAttributes[2].format = dawn::VertexFormat::UChar4Norm; + mVertexInputDescriptor.cAttributes[2].shaderLocation = 2; + mVertexInputDescriptor.cAttributes[2].offset = IM_OFFSETOF(ImDrawVert, col); + + mVertexInputDescriptor.cBuffers[0].attributes = &mVertexInputDescriptor.cAttributes[0]; + mVertexInputDescriptor.bufferCount = 1; + mVertexInputDescriptor.indexFormat = dawn::IndexFormat::Uint16; + + // Create bind group layout + dawn::BindGroupLayout layout = mContextDawn->MakeBindGroupLayout( + {{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {2, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}}); + + dawn::PipelineLayout mPipelineLayout = mContextDawn->MakeBasicPipelineLayout({layout}); + + const ResourceHelper *resourceHelper = mContextDawn->getResourceHelper(); + const std::string &programPath = resourceHelper->getProgramPath(); + mProgramDawn = new ProgramDawn(mContextDawn, programPath + "imguiVertexShader", + programPath + "imguiFragmentShader"); + mProgramDawn->loadProgram(); + + const dawn::ShaderModule &mVsModule = mProgramDawn->getVSModule(); + const dawn::ShaderModule &mFsModule = mProgramDawn->getFSModule(); + + dawn::PipelineStageDescriptor cVertexStage; + cVertexStage.entryPoint = "main"; + cVertexStage.module = mVsModule; + + dawn::PipelineStageDescriptor cFragmentStage; + cFragmentStage.entryPoint = "main"; + cFragmentStage.module = mFsModule; + + dawn::BlendDescriptor blendDescriptor; + blendDescriptor.operation = dawn::BlendOperation::Add; + blendDescriptor.srcFactor = dawn::BlendFactor::SrcAlpha; + blendDescriptor.dstFactor = dawn::BlendFactor::OneMinusSrcAlpha; + dawn::BlendDescriptor alphaDescriptor; + alphaDescriptor.operation = dawn::BlendOperation::Add; + alphaDescriptor.srcFactor = dawn::BlendFactor::OneMinusSrcAlpha; + alphaDescriptor.dstFactor = dawn::BlendFactor::Zero; + + dawn::ColorStateDescriptor ColorStateDescriptor; + ColorStateDescriptor.colorBlend = blendDescriptor; + ColorStateDescriptor.alphaBlend = alphaDescriptor; + ColorStateDescriptor.writeMask = dawn::ColorWriteMask::All; + + dawn::RasterizationStateDescriptor rasterizationState; + rasterizationState.nextInChain = nullptr; + rasterizationState.frontFace = dawn::FrontFace::CCW; + rasterizationState.cullMode = dawn::CullMode::None; + rasterizationState.depthBias = 0; + rasterizationState.depthBiasSlopeScale = 0.0; + rasterizationState.depthBiasClamp = 0.0; + + // create graphics mPipeline + utils::ComboRenderPipelineDescriptor mPipelineDescriptor(mContextDawn->mDevice); + mPipelineDescriptor.layout = mPipelineLayout; + mPipelineDescriptor.cVertexStage.module = mVsModule; + mPipelineDescriptor.cFragmentStage.module = mFsModule; + mPipelineDescriptor.vertexInput = &mVertexInputDescriptor; + mPipelineDescriptor.depthStencilState = &mPipelineDescriptor.cDepthStencilState; + mPipelineDescriptor.cDepthStencilState.format = dawn::TextureFormat::Depth24PlusStencil8; + mPipelineDescriptor.cColorStates[0] = &ColorStateDescriptor; + mPipelineDescriptor.cColorStates[0]->format = mFormat; + mPipelineDescriptor.cDepthStencilState.depthWriteEnabled = false; + mPipelineDescriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Always; + mPipelineDescriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleList; + mPipelineDescriptor.sampleCount = mEnableMSAA ? 4 : 1; + mPipelineDescriptor.rasterizationState = &rasterizationState; + + mPipeline = mContextDawn->mDevice.CreateRenderPipeline(&mPipelineDescriptor); + + ImGui_ImplDawn_CreateFontsTexture(); + + // Create uniform buffer + dawn::BufferDescriptor descriptor; + descriptor.size = sizeof(VERTEX_CONSTANT_BUFFER); + descriptor.usage = dawn::BufferUsageBit::CopyDst | dawn::BufferUsageBit::Uniform | + dawn::BufferUsageBit::Uniform; + + mConstantBuffer = mContextDawn->mDevice.CreateBuffer(&descriptor); + + mBindGroup = mContextDawn->makeBindGroup( + layout, {{0, mConstantBuffer, 0, sizeof(VERTEX_CONSTANT_BUFFER)}, + {1, mSampler}, + {2, mTextureView}}); + + return true; +} + +bool ImGui_ImplDawn_Init(ContextDawn *context, dawn::TextureFormat rtv_format, bool enableMSAA) +{ + // Setup back-end capabilities flags + ImGuiIO &io = ImGui::GetIO(); + io.BackendRendererName = "imgui_impl_Dawn"; + io.BackendFlags |= + ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, + // allowing for large meshes. + + mFormat = rtv_format; + mContextDawn = context; + + mIndexBuffer = NULL; + mVertexBuffer = NULL; + mIndexBufferSize = 3000; + mVertexBufferSize = 3000; + mEnableMSAA = enableMSAA; + + return true; +} + +void ImGui_ImplDawn_Shutdown() +{ + delete mProgramDawn; + + mPipeline = nullptr; + mBindGroup = nullptr; + mVsModule = nullptr; + mFsModule = nullptr; + + mIndexBuffer = nullptr; + mVertexBuffer = nullptr; + mStagingBuffer = nullptr; + mTexture = nullptr; + mSampler = nullptr; + mConstantBuffer = nullptr; + mTextureView = nullptr; +} + +void ImGui_ImplDawn_NewFrame() +{ + if (!mPipeline.Get()) + ImGui_ImplDawn_CreateDeviceObjects(); +} diff --git a/src/aquarium-optimized/dawn/imgui_impl_dawn.h b/src/aquarium-optimized/dawn/imgui_impl_dawn.h index 50a0c02..6d73720 100644 --- a/src/aquarium-optimized/dawn/imgui_impl_dawn.h +++ b/src/aquarium-optimized/dawn/imgui_impl_dawn.h @@ -1,21 +1,21 @@ -// dear imgui: Renderer for Dawn -// This needs to be used along with a Platform Binding (e.g. GLFW) - -#pragma once - -#include -#include - -#include "ContextDawn.h" -#include "imgui.h" -#include "utils/DawnHelpers.h" - -IMGUI_IMPL_API bool ImGui_ImplDawn_Init(ContextDawn *context, - dawn::TextureFormat rtv_format, - bool enableMSAA); -IMGUI_IMPL_API void ImGui_ImplDawn_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplDawn_NewFrame(); -IMGUI_IMPL_API void ImGui_ImplDawn_RenderDrawData(ImDrawData *draw_data); - -// Use if you want to reset your rendering mDevice without losing ImGui state. -IMGUI_IMPL_API bool ImGui_ImplDawn_CreateDeviceObjects(); +// dear imgui: Renderer for Dawn +// This needs to be used along with a Platform Binding (e.g. GLFW) + +#pragma once + +#include +#include + +#include "ContextDawn.h" +#include "imgui.h" +#include "utils/DawnHelpers.h" + +IMGUI_IMPL_API bool ImGui_ImplDawn_Init(ContextDawn *context, + dawn::TextureFormat rtv_format, + bool enableMSAA); +IMGUI_IMPL_API void ImGui_ImplDawn_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplDawn_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplDawn_RenderDrawData(ImDrawData *draw_data); + +// Use if you want to reset your rendering mDevice without losing ImGui state. +IMGUI_IMPL_API bool ImGui_ImplDawn_CreateDeviceObjects(); diff --git a/src/aquarium-optimized/opengl/BufferGL.cpp b/src/aquarium-optimized/opengl/BufferGL.cpp index 3f40599..a9e59c5 100644 --- a/src/aquarium-optimized/opengl/BufferGL.cpp +++ b/src/aquarium-optimized/opengl/BufferGL.cpp @@ -1,46 +1,46 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// BufferGL.cpp: Implements the index or vertex buffer wrappers and resource bindings of OpenGL. - -#include "BufferGL.h" -#include "common/AQUARIUM_ASSERT.h" - -BufferGL::BufferGL(ContextGL *context, - int totalCmoponents, - int numComponents, - bool isIndex, - unsigned int type, - bool normalize) - : mContext(context), - mBuf(0), - mTarget(isIndex ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER), - mNumComponents(numComponents), - mTotoalComponents(totalCmoponents), - mNumElements(mTotoalComponents / numComponents), - mType(type), - mNormalize(normalize), - mStride(0), - mOffset(nullptr) -{ - mBuf = mContext->generateBuffer(); -} - -void BufferGL::loadBuffer(const std::vector &buf) -{ - mContext->bindBuffer(mTarget, mBuf); - mContext->uploadBuffer(mTarget, buf); -} - -void BufferGL::loadBuffer(const std::vector &buf) -{ - mContext->bindBuffer(mTarget, mBuf); - mContext->uploadBuffer(mTarget, buf); -} - -BufferGL::~BufferGL() -{ - mContext->deleteBuffer(mBuf); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// BufferGL.cpp: Implements the index or vertex buffer wrappers and resource bindings of OpenGL. + +#include "BufferGL.h" +#include "common/AQUARIUM_ASSERT.h" + +BufferGL::BufferGL(ContextGL *context, + int totalCmoponents, + int numComponents, + bool isIndex, + unsigned int type, + bool normalize) + : mContext(context), + mBuf(0), + mTarget(isIndex ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER), + mNumComponents(numComponents), + mTotoalComponents(totalCmoponents), + mNumElements(mTotoalComponents / numComponents), + mType(type), + mNormalize(normalize), + mStride(0), + mOffset(nullptr) +{ + mBuf = mContext->generateBuffer(); +} + +void BufferGL::loadBuffer(const std::vector &buf) +{ + mContext->bindBuffer(mTarget, mBuf); + mContext->uploadBuffer(mTarget, buf); +} + +void BufferGL::loadBuffer(const std::vector &buf) +{ + mContext->bindBuffer(mTarget, mBuf); + mContext->uploadBuffer(mTarget, buf); +} + +BufferGL::~BufferGL() +{ + mContext->deleteBuffer(mBuf); +} diff --git a/src/aquarium-optimized/opengl/BufferGL.h b/src/aquarium-optimized/opengl/BufferGL.h index 08dd7d3..c531e8d 100644 --- a/src/aquarium-optimized/opengl/BufferGL.h +++ b/src/aquarium-optimized/opengl/BufferGL.h @@ -1,68 +1,68 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// BufferGL.h: Defines the buffer wrapper of OpenGL. - -#pragma once -#ifndef BUFFERGL_H -#define BUFFERGL_H 1 - -#ifdef EGL_EGL_PROTOTYPES -#include -#include -#include "EGL/egl.h" -#include "EGL/eglext.h" -#include "EGL/eglext_angle.h" -#include "EGL/eglplatform.h" -#include "EGLWindow.h" -#else -#include "glad/glad.h" -#endif - -#include - -#include "ContextGL.h" - -#include "../Buffer.h" - -class ContextGL; - -class BufferGL : public Buffer -{ - public: - BufferGL(ContextGL *context, - int totalCmoponents, - int numComponents, - bool isIndex, - unsigned int type, - bool normalize); - ~BufferGL() override; - - unsigned int getBuffer() const { return mBuf; } - int getNumComponents() const { return mNumComponents; } - int getTotalComponents() const { return mTotoalComponents; } - int getNumberElements() const { return mNumElements; } - unsigned int getType() const { return mType; } - bool getNormalize() const { return mNormalize; } - int getStride() const { return mStride; } - void *getOffset() const { return mOffset; } - unsigned int getTarget() const { return mTarget; } - void loadBuffer(const std::vector &buf); - void loadBuffer(const std::vector &buf); - - private: - ContextGL *mContext; - unsigned int mBuf; - unsigned int mTarget; - int mNumComponents; - int mTotoalComponents; - int mNumElements; - unsigned int mType; - bool mNormalize; - int mStride; - void *mOffset; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// BufferGL.h: Defines the buffer wrapper of OpenGL. + +#pragma once +#ifndef BUFFERGL_H +#define BUFFERGL_H 1 + +#ifdef EGL_EGL_PROTOTYPES +#include +#include +#include "EGL/egl.h" +#include "EGL/eglext.h" +#include "EGL/eglext_angle.h" +#include "EGL/eglplatform.h" +#include "EGLWindow.h" +#else +#include "glad/glad.h" +#endif + +#include + +#include "ContextGL.h" + +#include "../Buffer.h" + +class ContextGL; + +class BufferGL : public Buffer +{ + public: + BufferGL(ContextGL *context, + int totalCmoponents, + int numComponents, + bool isIndex, + unsigned int type, + bool normalize); + ~BufferGL() override; + + unsigned int getBuffer() const { return mBuf; } + int getNumComponents() const { return mNumComponents; } + int getTotalComponents() const { return mTotoalComponents; } + int getNumberElements() const { return mNumElements; } + unsigned int getType() const { return mType; } + bool getNormalize() const { return mNormalize; } + int getStride() const { return mStride; } + void *getOffset() const { return mOffset; } + unsigned int getTarget() const { return mTarget; } + void loadBuffer(const std::vector &buf); + void loadBuffer(const std::vector &buf); + + private: + ContextGL *mContext; + unsigned int mBuf; + unsigned int mTarget; + int mNumComponents; + int mTotoalComponents; + int mNumElements; + unsigned int mType; + bool mNormalize; + int mStride; + void *mOffset; +}; + +#endif diff --git a/src/aquarium-optimized/opengl/ContextGL.cpp b/src/aquarium-optimized/opengl/ContextGL.cpp index 52a923e..fc5446d 100644 --- a/src/aquarium-optimized/opengl/ContextGL.cpp +++ b/src/aquarium-optimized/opengl/ContextGL.cpp @@ -1,769 +1,769 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// ContextGL.cpp: Implements accessing functions to the graphics API of OpenGL. - -#include "common/AQUARIUM_ASSERT.h" - -#include -#include -#include - -#include "BufferGL.h" -#include "ContextGL.h" -#include "FishModelGL.h" -#include "GenericModelGL.h" -#include "InnerModelGL.h" -#include "OutsideModelGL.h" -#include "ProgramGL.h" -#include "SeaweedModelGL.h" -#include "TextureGL.h" - -#include "imgui.h" -#include "imgui_impl_glfw.h" -#include "imgui_impl_opengl3.h" - -#ifdef EGL_EGL_PROTOTYPES -#define GLFW_EXPOSE_NATIVE_WIN32 -#include -#endif - -ContextGL::ContextGL(BACKENDTYPE backendType) : mWindow(nullptr) -{ - initAvailableToggleBitset(backendType); -} - -ContextGL::~ContextGL() -{ - delete mResourceHelper; - destoryImgUI(); -} - -bool ContextGL::initialize(BACKENDTYPE backend, - const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) -{ - // initialise GLFW - if (!glfwInit()) - { - std::cout << "Failed to initialise GLFW" << std::endl; - return false; - } - -#ifdef GL_GLEXT_PROTOTYPES - // TODO(yizhou) : Enable msaa in angle. Render into a multisample Texture and then blit to a - // none multisample texture. - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - mResourceHelper = new ResourceHelper("opengl", std::string("100")); -#else - if (toggleBitset.test(static_cast(TOGGLE::ENABLEMSAAx4))) - { - glfwWindowHint(GLFW_SAMPLES, 4); - } - - mResourceHelper = new ResourceHelper("opengl", "450"); - -#ifdef __APPLE__ - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); - mGLSLVersion = "#version 410"; -#elif _WIN32 || __linux__ - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); - mGLSLVersion = "#version 450"; -#endif - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); -#endif - - GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); - const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); - mClientWidth = mode->width; - mClientHeight = mode->height; - - glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - if (toggleBitset.test(static_cast(TOGGLE::ENABLEFULLSCREENMODE))) - { - mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", pMonitor, nullptr); - } - else - { - mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", nullptr, nullptr); - } - - if (mWindow == nullptr) - { - std::cout << "Failed to open GLFW window." << std::endl; - glfwTerminate(); - return false; - } - - setWindowTitle("Aquarium"); - glfwSetFramebufferSizeCallback(mWindow, framebufferResizeCallback); - glfwSetWindowUserPointer(mWindow, this); - -#ifndef GL_GLES_PROTOTYPES - glfwWindowHint(GLFW_DECORATED, GL_FALSE); - glfwMakeContextCurrent(mWindow); -#else - mGLSLVersion = "#version 300 es"; - - std::vector display_attribs; - - display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE); - //display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE); - display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE); - display_attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE); - display_attribs.push_back(-1); - display_attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE); - display_attribs.push_back(-1); - display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE); - display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); - display_attribs.push_back(EGL_NONE); - - HWND hwnd = glfwGetWin32Window(mWindow); - mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, - reinterpret_cast(GetDC(hwnd)), - &display_attribs[0]); - if (mDisplay == EGL_NO_DISPLAY) { - std::cout << "EGL display query failed with error " << std::endl; - } - GLint mEGLMajorVersion = 0; - GLint mEGLMinorVersion = 0; - if (eglInitialize(mDisplay, &mEGLMajorVersion, &mEGLMinorVersion) == EGL_FALSE) - { - return false; - } - - const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS); - - std::vector configAttributes = { - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, - EGL_DEPTH_SIZE, 24, - EGL_STENCIL_SIZE, 8, - EGL_SAMPLE_BUFFERS, 0, - EGL_SAMPLES, EGL_DONT_CARE - }; - - // Add dynamic attributes - bool hasPixelFormatFloat = strstr(displayExtensions, "EGL_EXT_pixel_format_float") != nullptr; - if (!hasPixelFormatFloat) - { - return false; - } - if (hasPixelFormatFloat) - { - configAttributes.push_back(EGL_COLOR_COMPONENT_TYPE_EXT); - configAttributes.push_back(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT); - } - - // Finish the attribute list - configAttributes.push_back(EGL_NONE); - - if (!FindEGLConfig(mDisplay, configAttributes.data(), &mConfig)) - { - std::cout << "Could not find a suitable EGL config!" << std::endl; - return false; - } - - GLint mRedBits, mGreenBits, mBlueBits, mSamples, mAlphaBits, mDepthBits, mStencilBits; - eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mAlphaBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLES, &mSamples); - - std::vector surfaceAttributes; - if (strstr(displayExtensions, "EGL_NV_post_sub_buffer") != nullptr) - { - surfaceAttributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV); - surfaceAttributes.push_back(EGL_TRUE); - } - - surfaceAttributes.push_back(EGL_NONE); - - mSurface = eglCreateWindowSurface(mDisplay, mConfig, reinterpret_cast(hwnd), &surfaceAttributes[0]); - - if (eglGetError() != EGL_SUCCESS) - { - return false; - } - ASSERT(mSurface != EGL_NO_SURFACE); - - mContext = createContext(EGL_NO_CONTEXT); - if (mContext == EGL_NO_CONTEXT) - { - return false; - } - - eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); - if (eglGetError() != EGL_SUCCESS) - { - return false; - } - - eglSwapInterval(mDisplay, 0); - -#endif - - // Set the window full screen - // glfwSetWindowPos(window, 0, 0); - - #ifndef EGL_EGL_PROTOTYPES - if (!gladLoadGL()) - { - std::cout << "Something went wrong!" << std::endl; - exit(-1); - } - #endif - - // Setup Dear ImGui context - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGui::StyleColorsDark(); - - // Setup Platform/Renderer bindings - ImGui_ImplGlfw_InitForOpenGL(mWindow, true); - ImGui_ImplOpenGL3_Init(mGLSLVersion.c_str()); - - std::string renderer((const char *)glGetString(GL_RENDERER)); - size_t index = renderer.find("/"); - mRenderer = renderer.substr(0, index); - std::cout << mRenderer << std::endl; - - return true; -} - -#ifdef GL_GLEXT_PROTOTYPES -EGLContext ContextGL::createContext(EGLContext share) const -{ - const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS); - - // EGL_KHR_create_context is required to request a ES3+ context. - bool hasKHRCreateContext = strstr(displayExtensions, "EGL_KHR_create_context") != nullptr; - - eglBindAPI(EGL_OPENGL_ES_API); - if (eglGetError() != EGL_SUCCESS) - { - return EGL_NO_CONTEXT; - } - - std::vector contextAttributes; - if (hasKHRCreateContext) - { - contextAttributes.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR); - contextAttributes.push_back(3); - - contextAttributes.push_back(EGL_CONTEXT_MINOR_VERSION_KHR); - contextAttributes.push_back(0); - - contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG); - contextAttributes.push_back(EGL_TRUE); - - contextAttributes.push_back(EGL_CONTEXT_OPENGL_NO_ERROR_KHR); - contextAttributes.push_back(EGL_TRUE); - } - contextAttributes.push_back(EGL_NONE); - - EGLContext context = eglCreateContext(mDisplay, mConfig, nullptr, &contextAttributes[0]); - if (eglGetError() != EGL_SUCCESS) - { - return EGL_NO_CONTEXT; - } - - return context; -} - -EGLBoolean ContextGL::FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config) -{ - EGLint numConfigs = 0; - eglGetConfigs(dpy, nullptr, 0, &numConfigs); - std::vector allConfigs(numConfigs); - eglGetConfigs(dpy, allConfigs.data(), static_cast(allConfigs.size()), &numConfigs); - - for (size_t i = 0; i < allConfigs.size(); i++) - { - bool matchFound = true; - for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2) - { - if (curAttrib[1] == EGL_DONT_CARE) - { - continue; - } - - EGLint actualValue = EGL_DONT_CARE; - eglGetConfigAttrib(dpy, allConfigs[i], curAttrib[0], &actualValue); - if (curAttrib[1] != actualValue) - { - matchFound = false; - break; - } - } - - if (matchFound) - { - *config = allConfigs[i]; - return EGL_TRUE; - } - } - - return EGL_FALSE; -} -#endif - -void ContextGL::framebufferResizeCallback(GLFWwindow *window, int width, int height) -{ - ContextGL *contextGL = reinterpret_cast(glfwGetWindowUserPointer(window)); - contextGL->mClientWidth = width; - contextGL->mClientHeight = height; - glViewport(0, 0, width, height); -} - -Texture *ContextGL::createTexture(const std::string &name, const std::string &url) -{ - TextureGL *texture = new TextureGL(this, name, url); - texture->loadTexture(); - return texture; -} - -Texture *ContextGL::createTexture(const std::string &name, const std::vector &urls) -{ - TextureGL *texture = new TextureGL(this, name, urls); - texture->loadTexture(); - return texture; -} - -unsigned int ContextGL::generateTexture() -{ - unsigned int texture; - glGenTextures(1, &texture); - return texture; -} - -void ContextGL::bindTexture(unsigned int target, unsigned int textureId) -{ - glBindTexture(target, textureId); -} - -void ContextGL::deleteTexture(unsigned int texture) -{ - glDeleteTextures(1, &texture); -} - -void ContextGL::uploadTexture(unsigned int target, - unsigned int format, - int width, - int height, - unsigned char *pixels) -{ - glTexImage2D(target, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, pixels); - ASSERT(glGetError() == GL_NO_ERROR); -} - -void ContextGL::setParameter(unsigned int target, unsigned int pname, int param) -{ - glTexParameteri(target, pname, param); -} - -void ContextGL::generateMipmap(unsigned int target) -{ - glGenerateMipmap(target); -} - -void ContextGL::initState() -{ - glEnable(GL_DEPTH_TEST); - glColorMask(true, true, true, true); - glClearColor(0, 0.8f, 1, 0); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBlendEquation(GL_FUNC_ADD); - glEnable(GL_CULL_FACE); - glDepthMask(true); -} - -void ContextGL::initAvailableToggleBitset(BACKENDTYPE backendType) -{ - mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEMSAAx4)); - mAvailableToggleBitset.set(static_cast(TOGGLE::UPATEANDDRAWFOREACHMODEL)); - mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEFULLSCREENMODE)); -} - -Buffer *ContextGL::createBuffer(int numComponents, std::vector *buf, bool isIndex) -{ - BufferGL *buffer = new BufferGL(this, static_cast(buf->size()), numComponents, isIndex, GL_FLOAT, false); - buffer->loadBuffer(*buf); - - return buffer; -} - -Buffer *ContextGL::createBuffer(int numComponents, std::vector *buf, bool isIndex) -{ - BufferGL *buffer = new BufferGL(this, static_cast(buf->size()), numComponents, isIndex, - GL_UNSIGNED_SHORT, true); - buffer->loadBuffer(*buf); - - return buffer; -} - -Program *ContextGL::createProgram(const std::string &mVId, const std::string &mFId) -{ - ProgramGL *program = new ProgramGL(this, mVId, mFId); - program->loadProgram(); - - return program; -} - -void ContextGL::setWindowTitle(const std::string &text) -{ - glfwSetWindowTitle(mWindow, text.c_str()); -} - -bool ContextGL::ShouldQuit() -{ - return glfwWindowShouldClose(mWindow); -} - -void ContextGL::KeyBoardQuit() -{ - if (glfwGetKey(mWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS) - glfwSetWindowShouldClose(mWindow, GL_TRUE); -} - -void ContextGL::DoFlush() -{ -#ifdef GL_GLEXT_PROTOTYPES - eglSwapBuffers(mDisplay, mSurface); -#else - glfwSwapBuffers(mWindow); -#endif - glfwPollEvents(); -} - -void ContextGL::Terminate() -{ - glfwTerminate(); -} - -void ContextGL::showWindow() -{ - glfwGetFramebufferSize(mWindow, &mClientWidth, &mClientHeight); - glViewport(0, 0, mClientWidth, mClientHeight); - glfwShowWindow(mWindow); -} - -void ContextGL::showFPS(const FPSTimer &fpsTimer) -{ - // Start the Dear ImGui frame - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - { - ImGui::Begin("Aquarium Native"); - - std::ostringstream rendererStream; - std::string backend = mResourceHelper->getBackendName(); - for (auto & c: backend ) c = toupper(c); -#ifdef EGL_EGL_PROTOTYPES - rendererStream << mRenderer; -#else - rendererStream << mRenderer << " " << backend << " " << mResourceHelper->getShaderVersion(); -#endif - std::string renderer = rendererStream.str(); - ImGui::Text(renderer.c_str()); - - std::ostringstream resolutionStream; - resolutionStream <<"Resolution " << mClientWidth << "x" << mClientHeight; - std::string resolution = resolutionStream.str(); - ImGui::Text(resolution.c_str()); - - ImGui::PlotLines("[0,100 FPS]", fpsTimer.getHistoryFps(), NUM_HISTORY_DATA, 0, NULL, 0.0f, 100.0f, ImVec2 (0,40)); - - ImGui::PlotHistogram("[0,100 ms/frame]", fpsTimer.getHistoryFrameTime(), NUM_HISTORY_DATA, - 0, NULL, 0.0f, 100.0f, ImVec2(0, 40)); - - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", - 1000.0f / fpsTimer.getAverageFPS(), fpsTimer.getAverageFPS()); - ImGui::End(); - } - - // Rendering - ImGui::Render(); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); -} - -void ContextGL::destoryImgUI() -{ - // Cleanup - ImGui_ImplOpenGL3_Shutdown(); - ImGui_ImplGlfw_Shutdown(); - ImGui::DestroyContext(); -} - -int ContextGL::getUniformLocation(unsigned int programId, const std::string &name) const -{ - GLint index = glGetUniformLocation(programId, name.c_str()); - ASSERT(glGetError() == GL_NO_ERROR); - return index; -} - -int ContextGL::getAttribLocation(unsigned int programId, const std::string &name) const -{ - GLint index = glGetAttribLocation(programId, name.c_str()); - ASSERT(glGetError() == GL_NO_ERROR); - return index; -} - -void ContextGL::enableBlend(bool flag) const -{ - if (flag) - { - glEnable(GL_BLEND); - } - else - { - glDisable(GL_BLEND); - } -} - -void ContextGL::drawElements(const BufferGL &buffer) const -{ - GLint totalComponents = buffer.getTotalComponents(); - GLenum type = buffer.getType(); - glDrawElements(GL_TRIANGLES, totalComponents, type, 0); - - ASSERT(glGetError() == GL_NO_ERROR); -} - -Model *ContextGL::createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) -{ - Model *model; - switch (type) - { - case MODELGROUP::FISH: - model = new FishModelGL(this, aquarium, type, name, blend); - break; - case MODELGROUP::GENERIC: - model = new GenericModelGL(this, aquarium, type, name, blend); - break; - case MODELGROUP::INNER: - model = new InnerModelGL(this, aquarium, type, name, blend); - break; - case MODELGROUP::SEAWEED: - model = new SeaweedModelGL(this, aquarium, type, name, blend); - break; - case MODELGROUP::OUTSIDE: - model = new OutsideModelGL(this, aquarium, type, name, blend); - break; - default: - model = nullptr; - std::cout << "can not create model type" << std::endl; - } - - return model; -} - -void ContextGL::preFrame() -{ - glClearColor(0.0f, 1.0f, 0.0f, 1.0f); - glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - - ASSERT(glGetError() == GL_NO_ERROR); -} - -void ContextGL::setUniform(int index, const float *v, int type) const -{ - ASSERT(index != -1); - switch (type) - { - case GL_FLOAT: - { - glUniform1f(index, *v); - break; - } - case GL_FLOAT_VEC4: - { - glUniform4fv(index, 1, v); - break; - } - case GL_FLOAT_VEC3: - { - glUniform3fv(index, 1, v); - break; - } - case GL_FLOAT_VEC2: - { - glUniform2fv(index, 1, v); - break; - } - case GL_FLOAT_MAT4: - { - glUniformMatrix4fv(index, 1, false, v); - break; - } - default: - { - std::cout << "set uniform error" << std::endl; - } - } - - ASSERT(glGetError() == GL_NO_ERROR); -} - -void ContextGL::setTexture(const TextureGL &texture, int index, int unit) const -{ - ASSERT(index != -1); - glUniform1i(index, unit); - glActiveTexture(GL_TEXTURE0 + unit); - glBindTexture(texture.getTarget(), texture.getTextureId()); - - ASSERT(glGetError() == GL_NO_ERROR); -} - -void ContextGL::setAttribs(const BufferGL &bufferGL, int index) const -{ - ASSERT(index != -1); - glBindBuffer(bufferGL.getTarget(), bufferGL.getBuffer()); - - glEnableVertexAttribArray(index); - glVertexAttribPointer(index, bufferGL.getNumComponents(), bufferGL.getType(), - bufferGL.getNormalize(), bufferGL.getStride(), bufferGL.getOffset()); - - ASSERT(glGetError() == GL_NO_ERROR); -} - -void ContextGL::setIndices(const BufferGL &bufferGL) const -{ - glBindBuffer(bufferGL.getTarget(), bufferGL.getBuffer()); -} - -unsigned int ContextGL::generateVAO() -{ - unsigned int vao; - glGenVertexArrays(1, &vao); - return vao; -} - -void ContextGL::bindVAO(unsigned int vao) const -{ - glBindVertexArray(vao); -} - -void ContextGL::deleteVAO(unsigned int mVAO) -{ - glDeleteVertexArrays(1, &mVAO); -} - -unsigned int ContextGL::generateBuffer() -{ - unsigned int buf; - glGenBuffers(1, &buf); - return buf; -} - -void ContextGL::deleteBuffer(unsigned int buf) -{ - glDeleteBuffers(1, &buf); -} - -void ContextGL::bindBuffer(unsigned int target, unsigned int buf) -{ - glBindBuffer(target, buf); -} - -void ContextGL::uploadBuffer(unsigned int target, const std::vector &buf) -{ - glBufferData(target, sizeof(GLfloat) * buf.size(), buf.data(), GL_STATIC_DRAW); - - ASSERT(glGetError() == GL_NO_ERROR); -} - -void ContextGL::uploadBuffer(unsigned int target, const std::vector &buf) -{ - glBufferData(target, sizeof(GLushort) * buf.size(), buf.data(), GL_STATIC_DRAW); - - ASSERT(glGetError() == GL_NO_ERROR); -} - -unsigned int ContextGL::generateProgram() -{ - return glCreateProgram(); -} - -void ContextGL::setProgram(unsigned int program) -{ - glUseProgram(program); -} - -void ContextGL::deleteProgram(unsigned int program) -{ - glDeleteProgram(program); -} - -bool ContextGL::compileProgram(unsigned int programId, - const std::string &VertexShaderCode, - const std::string &FragmentShaderCode) -{ - // Create the shaders - GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); - GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); - - GLint Result = GL_FALSE; - int InfoLogLength; - - // Compile Vertex Shader - char const *VertexSourcePointer = VertexShaderCode.c_str(); - glShaderSource(VertexShaderID, 1, &VertexSourcePointer, nullptr); - glCompileShader(VertexShaderID); - - // Check Vertex Shader - glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); - if (!Result) - { - glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); - std::vector VertexShaderErrorMessage(InfoLogLength); - glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]); - std::cout << stdout << &VertexShaderErrorMessage[0] << std::endl; - } - - // Compile Fragment Shader - char const *FragmentSourcePointer = FragmentShaderCode.c_str(); - glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, nullptr); - glCompileShader(FragmentShaderID); - - // Check Fragment Shader - glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); - if (!Result) - { - glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); - std::vector FragmentShaderErrorMessage(InfoLogLength); - glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]); - std::cout << stdout << &FragmentShaderErrorMessage[0] << std::endl; - } - - // Link the program - glAttachShader(programId, VertexShaderID); - glAttachShader(programId, FragmentShaderID); - glLinkProgram(programId); - - // Check the program - glGetProgramiv(programId, GL_LINK_STATUS, &Result); - if (!Result) - { - glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &InfoLogLength); - std::vector ProgramErrorMessage(std::max(InfoLogLength, int(1))); - glGetProgramInfoLog(programId, InfoLogLength, nullptr, &ProgramErrorMessage[0]); - std::cout << stdout << &ProgramErrorMessage[0] << std::endl; - } - glDeleteShader(VertexShaderID); - glDeleteShader(FragmentShaderID); - - return true; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ContextGL.cpp: Implements accessing functions to the graphics API of OpenGL. + +#include "common/AQUARIUM_ASSERT.h" + +#include +#include +#include + +#include "BufferGL.h" +#include "ContextGL.h" +#include "FishModelGL.h" +#include "GenericModelGL.h" +#include "InnerModelGL.h" +#include "OutsideModelGL.h" +#include "ProgramGL.h" +#include "SeaweedModelGL.h" +#include "TextureGL.h" + +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_opengl3.h" + +#ifdef EGL_EGL_PROTOTYPES +#define GLFW_EXPOSE_NATIVE_WIN32 +#include +#endif + +ContextGL::ContextGL(BACKENDTYPE backendType) : mWindow(nullptr) +{ + initAvailableToggleBitset(backendType); +} + +ContextGL::~ContextGL() +{ + delete mResourceHelper; + destoryImgUI(); +} + +bool ContextGL::initialize(BACKENDTYPE backend, + const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) +{ + // initialise GLFW + if (!glfwInit()) + { + std::cout << "Failed to initialise GLFW" << std::endl; + return false; + } + +#ifdef GL_GLEXT_PROTOTYPES + // TODO(yizhou) : Enable msaa in angle. Render into a multisample Texture and then blit to a + // none multisample texture. + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + mResourceHelper = new ResourceHelper("opengl", std::string("100")); +#else + if (toggleBitset.test(static_cast(TOGGLE::ENABLEMSAAx4))) + { + glfwWindowHint(GLFW_SAMPLES, 4); + } + + mResourceHelper = new ResourceHelper("opengl", "450"); + +#ifdef __APPLE__ + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); + mGLSLVersion = "#version 410"; +#elif _WIN32 || __linux__ + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); + mGLSLVersion = "#version 450"; +#endif + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); +#endif + + GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); + const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); + mClientWidth = mode->width; + mClientHeight = mode->height; + + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + if (toggleBitset.test(static_cast(TOGGLE::ENABLEFULLSCREENMODE))) + { + mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", pMonitor, nullptr); + } + else + { + mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", nullptr, nullptr); + } + + if (mWindow == nullptr) + { + std::cout << "Failed to open GLFW window." << std::endl; + glfwTerminate(); + return false; + } + + setWindowTitle("Aquarium"); + glfwSetFramebufferSizeCallback(mWindow, framebufferResizeCallback); + glfwSetWindowUserPointer(mWindow, this); + +#ifndef GL_GLES_PROTOTYPES + glfwWindowHint(GLFW_DECORATED, GL_FALSE); + glfwMakeContextCurrent(mWindow); +#else + mGLSLVersion = "#version 300 es"; + + std::vector display_attribs; + + display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE); + // display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE); + display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE); + display_attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE); + display_attribs.push_back(-1); + display_attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE); + display_attribs.push_back(-1); + display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE); + display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); + display_attribs.push_back(EGL_NONE); + + HWND hwnd = glfwGetWin32Window(mWindow); + mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, + reinterpret_cast(GetDC(hwnd)), &display_attribs[0]); + if (mDisplay == EGL_NO_DISPLAY) + { + std::cout << "EGL display query failed with error " << std::endl; + } + GLint mEGLMajorVersion = 0; + GLint mEGLMinorVersion = 0; + if (eglInitialize(mDisplay, &mEGLMajorVersion, &mEGLMinorVersion) == EGL_FALSE) + { + return false; + } + + const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS); + + std::vector configAttributes = { + EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, + EGL_SAMPLE_BUFFERS, 0, EGL_SAMPLES, EGL_DONT_CARE}; + + // Add dynamic attributes + bool hasPixelFormatFloat = strstr(displayExtensions, "EGL_EXT_pixel_format_float") != nullptr; + if (!hasPixelFormatFloat) + { + return false; + } + if (hasPixelFormatFloat) + { + configAttributes.push_back(EGL_COLOR_COMPONENT_TYPE_EXT); + configAttributes.push_back(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT); + } + + // Finish the attribute list + configAttributes.push_back(EGL_NONE); + + if (!FindEGLConfig(mDisplay, configAttributes.data(), &mConfig)) + { + std::cout << "Could not find a suitable EGL config!" << std::endl; + return false; + } + + GLint mRedBits, mGreenBits, mBlueBits, mSamples, mAlphaBits, mDepthBits, mStencilBits; + eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mAlphaBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLES, &mSamples); + + std::vector surfaceAttributes; + if (strstr(displayExtensions, "EGL_NV_post_sub_buffer") != nullptr) + { + surfaceAttributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV); + surfaceAttributes.push_back(EGL_TRUE); + } + + surfaceAttributes.push_back(EGL_NONE); + + mSurface = eglCreateWindowSurface( + mDisplay, mConfig, reinterpret_cast(hwnd), &surfaceAttributes[0]); + + if (eglGetError() != EGL_SUCCESS) + { + return false; + } + ASSERT(mSurface != EGL_NO_SURFACE); + + mContext = createContext(EGL_NO_CONTEXT); + if (mContext == EGL_NO_CONTEXT) + { + return false; + } + + eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); + if (eglGetError() != EGL_SUCCESS) + { + return false; + } + + eglSwapInterval(mDisplay, 0); + +#endif + + // Set the window full screen + // glfwSetWindowPos(window, 0, 0); + +#ifndef EGL_EGL_PROTOTYPES + if (!gladLoadGL()) + { + std::cout << "Something went wrong!" << std::endl; + exit(-1); + } +#endif + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGui::StyleColorsDark(); + + // Setup Platform/Renderer bindings + ImGui_ImplGlfw_InitForOpenGL(mWindow, true); + ImGui_ImplOpenGL3_Init(mGLSLVersion.c_str()); + + std::string renderer((const char *)glGetString(GL_RENDERER)); + size_t index = renderer.find("/"); + mRenderer = renderer.substr(0, index); + std::cout << mRenderer << std::endl; + + return true; +} + +#ifdef GL_GLEXT_PROTOTYPES +EGLContext ContextGL::createContext(EGLContext share) const +{ + const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS); + + // EGL_KHR_create_context is required to request a ES3+ context. + bool hasKHRCreateContext = strstr(displayExtensions, "EGL_KHR_create_context") != nullptr; + + eglBindAPI(EGL_OPENGL_ES_API); + if (eglGetError() != EGL_SUCCESS) + { + return EGL_NO_CONTEXT; + } + + std::vector contextAttributes; + if (hasKHRCreateContext) + { + contextAttributes.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR); + contextAttributes.push_back(3); + + contextAttributes.push_back(EGL_CONTEXT_MINOR_VERSION_KHR); + contextAttributes.push_back(0); + + contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG); + contextAttributes.push_back(EGL_TRUE); + + contextAttributes.push_back(EGL_CONTEXT_OPENGL_NO_ERROR_KHR); + contextAttributes.push_back(EGL_TRUE); + } + contextAttributes.push_back(EGL_NONE); + + EGLContext context = eglCreateContext(mDisplay, mConfig, nullptr, &contextAttributes[0]); + if (eglGetError() != EGL_SUCCESS) + { + return EGL_NO_CONTEXT; + } + + return context; +} + +EGLBoolean ContextGL::FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config) +{ + EGLint numConfigs = 0; + eglGetConfigs(dpy, nullptr, 0, &numConfigs); + std::vector allConfigs(numConfigs); + eglGetConfigs(dpy, allConfigs.data(), static_cast(allConfigs.size()), &numConfigs); + + for (size_t i = 0; i < allConfigs.size(); i++) + { + bool matchFound = true; + for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2) + { + if (curAttrib[1] == EGL_DONT_CARE) + { + continue; + } + + EGLint actualValue = EGL_DONT_CARE; + eglGetConfigAttrib(dpy, allConfigs[i], curAttrib[0], &actualValue); + if (curAttrib[1] != actualValue) + { + matchFound = false; + break; + } + } + + if (matchFound) + { + *config = allConfigs[i]; + return EGL_TRUE; + } + } + + return EGL_FALSE; +} +#endif + +void ContextGL::framebufferResizeCallback(GLFWwindow *window, int width, int height) +{ + ContextGL *contextGL = reinterpret_cast(glfwGetWindowUserPointer(window)); + contextGL->mClientWidth = width; + contextGL->mClientHeight = height; + glViewport(0, 0, width, height); +} + +Texture *ContextGL::createTexture(const std::string &name, const std::string &url) +{ + TextureGL *texture = new TextureGL(this, name, url); + texture->loadTexture(); + return texture; +} + +Texture *ContextGL::createTexture(const std::string &name, const std::vector &urls) +{ + TextureGL *texture = new TextureGL(this, name, urls); + texture->loadTexture(); + return texture; +} + +unsigned int ContextGL::generateTexture() +{ + unsigned int texture; + glGenTextures(1, &texture); + return texture; +} + +void ContextGL::bindTexture(unsigned int target, unsigned int textureId) +{ + glBindTexture(target, textureId); +} + +void ContextGL::deleteTexture(unsigned int texture) +{ + glDeleteTextures(1, &texture); +} + +void ContextGL::uploadTexture(unsigned int target, + unsigned int format, + int width, + int height, + unsigned char *pixels) +{ + glTexImage2D(target, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, pixels); + ASSERT(glGetError() == GL_NO_ERROR); +} + +void ContextGL::setParameter(unsigned int target, unsigned int pname, int param) +{ + glTexParameteri(target, pname, param); +} + +void ContextGL::generateMipmap(unsigned int target) +{ + glGenerateMipmap(target); +} + +void ContextGL::initState() +{ + glEnable(GL_DEPTH_TEST); + glColorMask(true, true, true, true); + glClearColor(0, 0.8f, 1, 0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + glEnable(GL_CULL_FACE); + glDepthMask(true); +} + +void ContextGL::initAvailableToggleBitset(BACKENDTYPE backendType) +{ + mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEMSAAx4)); + mAvailableToggleBitset.set(static_cast(TOGGLE::UPATEANDDRAWFOREACHMODEL)); + mAvailableToggleBitset.set(static_cast(TOGGLE::ENABLEFULLSCREENMODE)); +} + +Buffer *ContextGL::createBuffer(int numComponents, std::vector *buf, bool isIndex) +{ + BufferGL *buffer = + new BufferGL(this, static_cast(buf->size()), numComponents, isIndex, GL_FLOAT, false); + buffer->loadBuffer(*buf); + + return buffer; +} + +Buffer *ContextGL::createBuffer(int numComponents, std::vector *buf, bool isIndex) +{ + BufferGL *buffer = new BufferGL(this, static_cast(buf->size()), numComponents, isIndex, + GL_UNSIGNED_SHORT, true); + buffer->loadBuffer(*buf); + + return buffer; +} + +Program *ContextGL::createProgram(const std::string &mVId, const std::string &mFId) +{ + ProgramGL *program = new ProgramGL(this, mVId, mFId); + program->loadProgram(); + + return program; +} + +void ContextGL::setWindowTitle(const std::string &text) +{ + glfwSetWindowTitle(mWindow, text.c_str()); +} + +bool ContextGL::ShouldQuit() +{ + return glfwWindowShouldClose(mWindow); +} + +void ContextGL::KeyBoardQuit() +{ + if (glfwGetKey(mWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(mWindow, GL_TRUE); +} + +void ContextGL::DoFlush() +{ +#ifdef GL_GLEXT_PROTOTYPES + eglSwapBuffers(mDisplay, mSurface); +#else + glfwSwapBuffers(mWindow); +#endif + glfwPollEvents(); +} + +void ContextGL::Terminate() +{ + glfwTerminate(); +} + +void ContextGL::showWindow() +{ + glfwGetFramebufferSize(mWindow, &mClientWidth, &mClientHeight); + glViewport(0, 0, mClientWidth, mClientHeight); + glfwShowWindow(mWindow); +} + +void ContextGL::showFPS(const FPSTimer &fpsTimer) +{ + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + { + ImGui::Begin("Aquarium Native"); + + std::ostringstream rendererStream; + std::string backend = mResourceHelper->getBackendName(); + for (auto &c : backend) + c = toupper(c); +#ifdef EGL_EGL_PROTOTYPES + rendererStream << mRenderer; +#else + rendererStream << mRenderer << " " << backend << " " << mResourceHelper->getShaderVersion(); +#endif + std::string renderer = rendererStream.str(); + ImGui::Text(renderer.c_str()); + + std::ostringstream resolutionStream; + resolutionStream << "Resolution " << mClientWidth << "x" << mClientHeight; + std::string resolution = resolutionStream.str(); + ImGui::Text(resolution.c_str()); + + ImGui::PlotLines("[0,100 FPS]", fpsTimer.getHistoryFps(), NUM_HISTORY_DATA, 0, NULL, 0.0f, + 100.0f, ImVec2(0, 40)); + + ImGui::PlotHistogram("[0,100 ms/frame]", fpsTimer.getHistoryFrameTime(), NUM_HISTORY_DATA, + 0, NULL, 0.0f, 100.0f, ImVec2(0, 40)); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", + 1000.0f / fpsTimer.getAverageFPS(), fpsTimer.getAverageFPS()); + ImGui::End(); + } + + // Rendering + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); +} + +void ContextGL::destoryImgUI() +{ + // Cleanup + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); +} + +int ContextGL::getUniformLocation(unsigned int programId, const std::string &name) const +{ + GLint index = glGetUniformLocation(programId, name.c_str()); + ASSERT(glGetError() == GL_NO_ERROR); + return index; +} + +int ContextGL::getAttribLocation(unsigned int programId, const std::string &name) const +{ + GLint index = glGetAttribLocation(programId, name.c_str()); + ASSERT(glGetError() == GL_NO_ERROR); + return index; +} + +void ContextGL::enableBlend(bool flag) const +{ + if (flag) + { + glEnable(GL_BLEND); + } + else + { + glDisable(GL_BLEND); + } +} + +void ContextGL::drawElements(const BufferGL &buffer) const +{ + GLint totalComponents = buffer.getTotalComponents(); + GLenum type = buffer.getType(); + glDrawElements(GL_TRIANGLES, totalComponents, type, 0); + + ASSERT(glGetError() == GL_NO_ERROR); +} + +Model *ContextGL::createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) +{ + Model *model; + switch (type) + { + case MODELGROUP::FISH: + model = new FishModelGL(this, aquarium, type, name, blend); + break; + case MODELGROUP::GENERIC: + model = new GenericModelGL(this, aquarium, type, name, blend); + break; + case MODELGROUP::INNER: + model = new InnerModelGL(this, aquarium, type, name, blend); + break; + case MODELGROUP::SEAWEED: + model = new SeaweedModelGL(this, aquarium, type, name, blend); + break; + case MODELGROUP::OUTSIDE: + model = new OutsideModelGL(this, aquarium, type, name, blend); + break; + default: + model = nullptr; + std::cout << "can not create model type" << std::endl; + } + + return model; +} + +void ContextGL::preFrame() +{ + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + ASSERT(glGetError() == GL_NO_ERROR); +} + +void ContextGL::setUniform(int index, const float *v, int type) const +{ + ASSERT(index != -1); + switch (type) + { + case GL_FLOAT: + { + glUniform1f(index, *v); + break; + } + case GL_FLOAT_VEC4: + { + glUniform4fv(index, 1, v); + break; + } + case GL_FLOAT_VEC3: + { + glUniform3fv(index, 1, v); + break; + } + case GL_FLOAT_VEC2: + { + glUniform2fv(index, 1, v); + break; + } + case GL_FLOAT_MAT4: + { + glUniformMatrix4fv(index, 1, false, v); + break; + } + default: + { + std::cout << "set uniform error" << std::endl; + } + } + + ASSERT(glGetError() == GL_NO_ERROR); +} + +void ContextGL::setTexture(const TextureGL &texture, int index, int unit) const +{ + ASSERT(index != -1); + glUniform1i(index, unit); + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(texture.getTarget(), texture.getTextureId()); + + ASSERT(glGetError() == GL_NO_ERROR); +} + +void ContextGL::setAttribs(const BufferGL &bufferGL, int index) const +{ + ASSERT(index != -1); + glBindBuffer(bufferGL.getTarget(), bufferGL.getBuffer()); + + glEnableVertexAttribArray(index); + glVertexAttribPointer(index, bufferGL.getNumComponents(), bufferGL.getType(), + bufferGL.getNormalize(), bufferGL.getStride(), bufferGL.getOffset()); + + ASSERT(glGetError() == GL_NO_ERROR); +} + +void ContextGL::setIndices(const BufferGL &bufferGL) const +{ + glBindBuffer(bufferGL.getTarget(), bufferGL.getBuffer()); +} + +unsigned int ContextGL::generateVAO() +{ + unsigned int vao; + glGenVertexArrays(1, &vao); + return vao; +} + +void ContextGL::bindVAO(unsigned int vao) const +{ + glBindVertexArray(vao); +} + +void ContextGL::deleteVAO(unsigned int mVAO) +{ + glDeleteVertexArrays(1, &mVAO); +} + +unsigned int ContextGL::generateBuffer() +{ + unsigned int buf; + glGenBuffers(1, &buf); + return buf; +} + +void ContextGL::deleteBuffer(unsigned int buf) +{ + glDeleteBuffers(1, &buf); +} + +void ContextGL::bindBuffer(unsigned int target, unsigned int buf) +{ + glBindBuffer(target, buf); +} + +void ContextGL::uploadBuffer(unsigned int target, const std::vector &buf) +{ + glBufferData(target, sizeof(GLfloat) * buf.size(), buf.data(), GL_STATIC_DRAW); + + ASSERT(glGetError() == GL_NO_ERROR); +} + +void ContextGL::uploadBuffer(unsigned int target, const std::vector &buf) +{ + glBufferData(target, sizeof(GLushort) * buf.size(), buf.data(), GL_STATIC_DRAW); + + ASSERT(glGetError() == GL_NO_ERROR); +} + +unsigned int ContextGL::generateProgram() +{ + return glCreateProgram(); +} + +void ContextGL::setProgram(unsigned int program) +{ + glUseProgram(program); +} + +void ContextGL::deleteProgram(unsigned int program) +{ + glDeleteProgram(program); +} + +bool ContextGL::compileProgram(unsigned int programId, + const std::string &VertexShaderCode, + const std::string &FragmentShaderCode) +{ + // Create the shaders + GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + GLint Result = GL_FALSE; + int InfoLogLength; + + // Compile Vertex Shader + char const *VertexSourcePointer = VertexShaderCode.c_str(); + glShaderSource(VertexShaderID, 1, &VertexSourcePointer, nullptr); + glCompileShader(VertexShaderID); + + // Check Vertex Shader + glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + if (!Result) + { + glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + std::vector VertexShaderErrorMessage(InfoLogLength); + glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]); + std::cout << stdout << &VertexShaderErrorMessage[0] << std::endl; + } + + // Compile Fragment Shader + char const *FragmentSourcePointer = FragmentShaderCode.c_str(); + glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, nullptr); + glCompileShader(FragmentShaderID); + + // Check Fragment Shader + glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + if (!Result) + { + glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + std::vector FragmentShaderErrorMessage(InfoLogLength); + glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, + &FragmentShaderErrorMessage[0]); + std::cout << stdout << &FragmentShaderErrorMessage[0] << std::endl; + } + + // Link the program + glAttachShader(programId, VertexShaderID); + glAttachShader(programId, FragmentShaderID); + glLinkProgram(programId); + + // Check the program + glGetProgramiv(programId, GL_LINK_STATUS, &Result); + if (!Result) + { + glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &InfoLogLength); + std::vector ProgramErrorMessage(std::max(InfoLogLength, int(1))); + glGetProgramInfoLog(programId, InfoLogLength, nullptr, &ProgramErrorMessage[0]); + std::cout << stdout << &ProgramErrorMessage[0] << std::endl; + } + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return true; +} diff --git a/src/aquarium-optimized/opengl/ContextGL.h b/src/aquarium-optimized/opengl/ContextGL.h index e55f68e..35da74c 100644 --- a/src/aquarium-optimized/opengl/ContextGL.h +++ b/src/aquarium-optimized/opengl/ContextGL.h @@ -1,116 +1,116 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// ContextGL.h: Defines the accessing to graphics API of OpenGL. - -#ifndef ContextGL_H -#define ContextGL_H 1 - -#ifdef EGL_EGL_PROTOTYPES -#include -#include "EGL/egl.h" -#include "EGL/eglext.h" -#include "EGL/eglplatform.h" -#include "EGL/eglext_angle.h" -#include -#include "EGLWindow.h" -#else -#include "glad/glad.h" -#endif - -#include - -#include "GLFW/glfw3.h" - -#include "../Context.h" - -class BufferGL; -class TextureGL; -enum BACKENDTYPE: short; - -class ContextGL : public Context -{ - public: - ContextGL(BACKENDTYPE backendType); - ~ContextGL(); - bool initialize( - BACKENDTYPE backend, - const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) override; - void setWindowTitle(const std::string &text) override; - bool ShouldQuit() override; - void KeyBoardQuit() override; - void DoFlush() override; - void Terminate() override; - void showWindow() override; - void showFPS(const FPSTimer &fpsTimer) override; - void destoryImgUI() override; - - void preFrame() override; - void enableBlend(bool flag) const; - - Model *createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) override; - int getUniformLocation(unsigned int programId, const std::string &name) const; - int getAttribLocation(unsigned int programId, const std::string & name) const; - void setUniform(int index, const float *v, int type) const; - void setTexture(const TextureGL &texture, int index, int unit) const; - void setAttribs(const BufferGL &bufferGL, int index) const; - void setIndices(const BufferGL &bufferGL) const; - void drawElements(const BufferGL &buffer) const; - - Buffer *createBuffer(int numComponents, std::vector *buffer, bool isIndex) override; - Buffer *createBuffer(int numComponents, - std::vector *buffer, - bool isIndex) override; - unsigned int generateBuffer(); - void deleteBuffer(unsigned int buf); - void bindBuffer(unsigned int target, unsigned int buf); - void uploadBuffer(unsigned int target, const std::vector &buf); - void uploadBuffer(unsigned int target, const std::vector &buf); - - Program *createProgram(const std::string &mVId, const std::string &mFId) override; - unsigned int generateProgram(); - void setProgram(unsigned int program); - void deleteProgram(unsigned int program); - bool compileProgram(unsigned int programId, - const std::string &VertexShaderCode, - const std::string &FragmentShaderCode); - void bindVAO(unsigned int vao) const; - unsigned int generateVAO(); - void deleteVAO(unsigned int vao); - - Texture *createTexture(const std::string &name, const std::string &url) override; - Texture *createTexture(const std::string &name, const std::vector &urls) override; - unsigned int generateTexture(); - void bindTexture(unsigned int target, unsigned int texture); - void deleteTexture(unsigned int texture); - void uploadTexture(unsigned int target, - unsigned int format, - int width, - int height, - unsigned char *pixel); - void setParameter(unsigned int target, unsigned int pname, int param); - void generateMipmap(unsigned int target); - - private: - void initState(); - void initAvailableToggleBitset(BACKENDTYPE backendType) override; - static void framebufferResizeCallback(GLFWwindow *window, int width, int height); - - GLFWwindow *mWindow; - std::string mGLSLVersion; - std::string mRenderer; - -#ifdef EGL_EGL_PROTOTYPES - EGLBoolean FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config); - EGLContext createContext(EGLContext share) const; - - EGLSurface mSurface; - EGLContext mContext; - EGLDisplay mDisplay; - EGLConfig mConfig; -#endif -}; - -#endif // !ContextGL_H +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ContextGL.h: Defines the accessing to graphics API of OpenGL. + +#ifndef ContextGL_H +#define ContextGL_H 1 + +#ifdef EGL_EGL_PROTOTYPES +#include +#include +#include "EGL/egl.h" +#include "EGL/eglext.h" +#include "EGL/eglext_angle.h" +#include "EGL/eglplatform.h" +#include "EGLWindow.h" +#else +#include "glad/glad.h" +#endif + +#include + +#include "GLFW/glfw3.h" + +#include "../Context.h" + +class BufferGL; +class TextureGL; +enum BACKENDTYPE : short; + +class ContextGL : public Context +{ + public: + ContextGL(BACKENDTYPE backendType); + ~ContextGL(); + bool initialize( + BACKENDTYPE backend, + const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset) override; + void setWindowTitle(const std::string &text) override; + bool ShouldQuit() override; + void KeyBoardQuit() override; + void DoFlush() override; + void Terminate() override; + void showWindow() override; + void showFPS(const FPSTimer &fpsTimer) override; + void destoryImgUI() override; + + void preFrame() override; + void enableBlend(bool flag) const; + + Model *createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) override; + int getUniformLocation(unsigned int programId, const std::string &name) const; + int getAttribLocation(unsigned int programId, const std::string &name) const; + void setUniform(int index, const float *v, int type) const; + void setTexture(const TextureGL &texture, int index, int unit) const; + void setAttribs(const BufferGL &bufferGL, int index) const; + void setIndices(const BufferGL &bufferGL) const; + void drawElements(const BufferGL &buffer) const; + + Buffer *createBuffer(int numComponents, std::vector *buffer, bool isIndex) override; + Buffer *createBuffer(int numComponents, + std::vector *buffer, + bool isIndex) override; + unsigned int generateBuffer(); + void deleteBuffer(unsigned int buf); + void bindBuffer(unsigned int target, unsigned int buf); + void uploadBuffer(unsigned int target, const std::vector &buf); + void uploadBuffer(unsigned int target, const std::vector &buf); + + Program *createProgram(const std::string &mVId, const std::string &mFId) override; + unsigned int generateProgram(); + void setProgram(unsigned int program); + void deleteProgram(unsigned int program); + bool compileProgram(unsigned int programId, + const std::string &VertexShaderCode, + const std::string &FragmentShaderCode); + void bindVAO(unsigned int vao) const; + unsigned int generateVAO(); + void deleteVAO(unsigned int vao); + + Texture *createTexture(const std::string &name, const std::string &url) override; + Texture *createTexture(const std::string &name, const std::vector &urls) override; + unsigned int generateTexture(); + void bindTexture(unsigned int target, unsigned int texture); + void deleteTexture(unsigned int texture); + void uploadTexture(unsigned int target, + unsigned int format, + int width, + int height, + unsigned char *pixel); + void setParameter(unsigned int target, unsigned int pname, int param); + void generateMipmap(unsigned int target); + + private: + void initState(); + void initAvailableToggleBitset(BACKENDTYPE backendType) override; + static void framebufferResizeCallback(GLFWwindow *window, int width, int height); + + GLFWwindow *mWindow; + std::string mGLSLVersion; + std::string mRenderer; + +#ifdef EGL_EGL_PROTOTYPES + EGLBoolean FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config); + EGLContext createContext(EGLContext share) const; + + EGLSurface mSurface; + EGLContext mContext; + EGLDisplay mDisplay; + EGLConfig mConfig; +#endif +}; + +#endif // !ContextGL_H diff --git a/src/aquarium-optimized/opengl/FishModelGL.cpp b/src/aquarium-optimized/opengl/FishModelGL.cpp index d057460..740a54e 100644 --- a/src/aquarium-optimized/opengl/FishModelGL.cpp +++ b/src/aquarium-optimized/opengl/FishModelGL.cpp @@ -1,181 +1,181 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FishModelGL.h: Implements fish model of OpenGL. - -#include "ContextGL.h" -#include "FishModelGL.h" -#include "ProgramGL.h" - -FishModelGL::FishModelGL(const ContextGL *mContextGL, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : FishModel(type, name, blend), mContextGL(mContextGL) -{ - mViewInverseUniform.first = aquarium->lightWorldPositionUniform.viewInverse; - mLightWorldPosUniform.first = aquarium->lightWorldPositionUniform.lightWorldPos; - mLightColorUniform.first = aquarium->lightUniforms.lightColor; - mSpecularUniform.first = aquarium->lightUniforms.specular; - mShininessUniform.first = 5.0f; - mSpecularFactorUniform.first = 0.3f; - mAmbientUniform.first = aquarium->lightUniforms.ambient; - mFogPowerUniform.first = g_fogPower; - mFogMultUniform.first = g_fogMult; - mFogOffsetUniform.first = g_fogOffset; - mFogColorUniform.first = aquarium->fogUniforms.fogColor; - - mViewProjectionUniform.first = aquarium->lightWorldPositionUniform.viewProjection; - mScaleUniform.first = 1; - - const Fish &fishInfo = fishTable[name - MODELNAME::MODELSMALLFISHA]; - mFishLengthUniform.first = fishInfo.fishLength; - mFishBendAmountUniform.first = fishInfo.fishBendAmount; - mFishWaveLengthUniform.first = fishInfo.fishWaveLength; -} - -void FishModelGL::init() -{ - ProgramGL *programGL = static_cast(mProgram); - mViewInverseUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "viewInverse"); - mLightWorldPosUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "lightWorldPos"); - mLightColorUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "lightColor"); - mSpecularUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "specular"); - mAmbientUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "ambient"); - mShininessUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "shininess"); - mSpecularFactorUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "specularFactor"); - - mFogPowerUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogPower"); - mFogMultUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogMult"); - mFogOffsetUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "fogOffset"); - mFogColorUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogColor"); - - mViewProjectionUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "viewProjection"); - mFishLengthUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "fishLength"); - mFishWaveLengthUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "fishWaveLength"); - mFishBendAmountUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "fishBendAmount"); - - mWorldPositionUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "worldPosition"); - mNextPositionUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "nextPosition"); - mScaleUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "scale"); - mTimeUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "time"); - - mDiffuseTexture.first = static_cast(textureMap["diffuse"]); - mDiffuseTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "diffuse"); - mNormalTexture.first = static_cast(textureMap["normalMap"]); - mNormalTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "normalMap"); - mReflectionTexture.first = static_cast(textureMap["reflectionMap"]); - mReflectionTexture.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "reflectionMap"); - mSkyboxTexture.first = static_cast(textureMap["skybox"]); - mSkyboxTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "skybox"); - - mPositionBuffer.first = static_cast(bufferMap["position"]); - mPositionBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "position"); - mNormalBuffer.first = static_cast(bufferMap["normal"]); - mNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "normal"); - mTexCoordBuffer.first = static_cast(bufferMap["texCoord"]); - mTexCoordBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "texCoord"); - mTangentBuffer.first = static_cast(bufferMap["tangent"]); - mTangentBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "tangent"); - mBiNormalBuffer.first = static_cast(bufferMap["binormal"]); - mBiNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "binormal"); - - mIndicesBuffer = static_cast(bufferMap["indices"]); -} - -void FishModelGL::draw() -{ - mContextGL->drawElements(*mIndicesBuffer); -} - -void FishModelGL::prepareForDraw() const -{ - mProgram->setProgram(); - mContextGL->enableBlend(mBlend); - - ProgramGL *programGL = static_cast(mProgram); - mContextGL->bindVAO(programGL->getVAOId()); - - mContextGL->setAttribs(*mPositionBuffer.first, mPositionBuffer.second); - mContextGL->setAttribs(*mNormalBuffer.first, mNormalBuffer.second); - mContextGL->setAttribs(*mTexCoordBuffer.first, mTexCoordBuffer.second); - - mContextGL->setAttribs(*mTangentBuffer.first, mTangentBuffer.second); - mContextGL->setAttribs(*mBiNormalBuffer.first, mBiNormalBuffer.second); - - mContextGL->setIndices(*mIndicesBuffer); - - mContextGL->setUniform(mViewInverseUniform.second, mViewInverseUniform.first, GL_FLOAT_MAT4); - mContextGL->setUniform(mLightWorldPosUniform.second, mLightWorldPosUniform.first, - GL_FLOAT_VEC3); - mContextGL->setUniform(mLightColorUniform.second, mLightColorUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mSpecularUniform.second, mSpecularUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mShininessUniform.second, &mShininessUniform.first, GL_FLOAT); - mContextGL->setUniform(mSpecularFactorUniform.second, &mSpecularFactorUniform.first, GL_FLOAT); - mContextGL->setUniform(mAmbientUniform.second, mAmbientUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mFogPowerUniform.second, &mFogPowerUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogMultUniform.second, &mFogMultUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogOffsetUniform.second, &mFogOffsetUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogColorUniform.second, mFogColorUniform.first, GL_FLOAT_VEC4); - - mContextGL->setUniform(mViewProjectionUniform.second, mViewProjectionUniform.first, - GL_FLOAT_MAT4); - mContextGL->setUniform(mFishBendAmountUniform.second, &mFishBendAmountUniform.first, GL_FLOAT); - mContextGL->setUniform(mFishLengthUniform.second, &mFishLengthUniform.first, GL_FLOAT); - mContextGL->setUniform(mFishWaveLengthUniform.second, &mFishWaveLengthUniform.first, GL_FLOAT); - - // Fish models includes small, medium and big. Some of them contains reflection and skybox - // texture, but some doesn't. - mContextGL->setTexture(*mDiffuseTexture.first, mDiffuseTexture.second, 0); - mContextGL->setTexture(*mNormalTexture.first, mNormalTexture.second, 1); - if (mSkyboxTexture.second != -1 && mReflectionTexture.second != -1) - { - mContextGL->setTexture(*mReflectionTexture.first, mReflectionTexture.second, 2); - mContextGL->setTexture(*mSkyboxTexture.first, mSkyboxTexture.second, 3); - } -} - -void FishModelGL::updatePerInstanceUniforms(const WorldUniforms &WorldUniforms) -{ - mContextGL->setUniform(mScaleUniform.second, &mScaleUniform.first, GL_FLOAT); - mContextGL->setUniform(mTimeUniform.second, &mTimeUniform.first, GL_FLOAT); - mContextGL->setUniform(mWorldPositionUniform.second, mWorldPositionUniform.first, - GL_FLOAT_VEC3); - mContextGL->setUniform(mNextPositionUniform.second, mNextPositionUniform.first, GL_FLOAT_VEC3); -} - -void FishModelGL::updateFishPerUniforms(float x, - float y, - float z, - float nextX, - float nextY, - float nextZ, - float scale, - float time, - int index) -{ - mWorldPositionUniform.first[0] = x; - mWorldPositionUniform.first[1] = y; - mWorldPositionUniform.first[2] = z; - mNextPositionUniform.first[0] = nextX; - mNextPositionUniform.first[1] = nextY; - mNextPositionUniform.first[2] = nextZ; - mScaleUniform.first = scale; - mTimeUniform.first = time; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FishModelGL.h: Implements fish model of OpenGL. + +#include "FishModelGL.h" +#include "ContextGL.h" +#include "ProgramGL.h" + +FishModelGL::FishModelGL(const ContextGL *mContextGL, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : FishModel(type, name, blend), mContextGL(mContextGL) +{ + mViewInverseUniform.first = aquarium->lightWorldPositionUniform.viewInverse; + mLightWorldPosUniform.first = aquarium->lightWorldPositionUniform.lightWorldPos; + mLightColorUniform.first = aquarium->lightUniforms.lightColor; + mSpecularUniform.first = aquarium->lightUniforms.specular; + mShininessUniform.first = 5.0f; + mSpecularFactorUniform.first = 0.3f; + mAmbientUniform.first = aquarium->lightUniforms.ambient; + mFogPowerUniform.first = g_fogPower; + mFogMultUniform.first = g_fogMult; + mFogOffsetUniform.first = g_fogOffset; + mFogColorUniform.first = aquarium->fogUniforms.fogColor; + + mViewProjectionUniform.first = aquarium->lightWorldPositionUniform.viewProjection; + mScaleUniform.first = 1; + + const Fish &fishInfo = fishTable[name - MODELNAME::MODELSMALLFISHA]; + mFishLengthUniform.first = fishInfo.fishLength; + mFishBendAmountUniform.first = fishInfo.fishBendAmount; + mFishWaveLengthUniform.first = fishInfo.fishWaveLength; +} + +void FishModelGL::init() +{ + ProgramGL *programGL = static_cast(mProgram); + mViewInverseUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "viewInverse"); + mLightWorldPosUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "lightWorldPos"); + mLightColorUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "lightColor"); + mSpecularUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "specular"); + mAmbientUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "ambient"); + mShininessUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "shininess"); + mSpecularFactorUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "specularFactor"); + + mFogPowerUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogPower"); + mFogMultUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogMult"); + mFogOffsetUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "fogOffset"); + mFogColorUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogColor"); + + mViewProjectionUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "viewProjection"); + mFishLengthUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "fishLength"); + mFishWaveLengthUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "fishWaveLength"); + mFishBendAmountUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "fishBendAmount"); + + mWorldPositionUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "worldPosition"); + mNextPositionUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "nextPosition"); + mScaleUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "scale"); + mTimeUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "time"); + + mDiffuseTexture.first = static_cast(textureMap["diffuse"]); + mDiffuseTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "diffuse"); + mNormalTexture.first = static_cast(textureMap["normalMap"]); + mNormalTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "normalMap"); + mReflectionTexture.first = static_cast(textureMap["reflectionMap"]); + mReflectionTexture.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "reflectionMap"); + mSkyboxTexture.first = static_cast(textureMap["skybox"]); + mSkyboxTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "skybox"); + + mPositionBuffer.first = static_cast(bufferMap["position"]); + mPositionBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "position"); + mNormalBuffer.first = static_cast(bufferMap["normal"]); + mNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "normal"); + mTexCoordBuffer.first = static_cast(bufferMap["texCoord"]); + mTexCoordBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "texCoord"); + mTangentBuffer.first = static_cast(bufferMap["tangent"]); + mTangentBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "tangent"); + mBiNormalBuffer.first = static_cast(bufferMap["binormal"]); + mBiNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "binormal"); + + mIndicesBuffer = static_cast(bufferMap["indices"]); +} + +void FishModelGL::draw() +{ + mContextGL->drawElements(*mIndicesBuffer); +} + +void FishModelGL::prepareForDraw() const +{ + mProgram->setProgram(); + mContextGL->enableBlend(mBlend); + + ProgramGL *programGL = static_cast(mProgram); + mContextGL->bindVAO(programGL->getVAOId()); + + mContextGL->setAttribs(*mPositionBuffer.first, mPositionBuffer.second); + mContextGL->setAttribs(*mNormalBuffer.first, mNormalBuffer.second); + mContextGL->setAttribs(*mTexCoordBuffer.first, mTexCoordBuffer.second); + + mContextGL->setAttribs(*mTangentBuffer.first, mTangentBuffer.second); + mContextGL->setAttribs(*mBiNormalBuffer.first, mBiNormalBuffer.second); + + mContextGL->setIndices(*mIndicesBuffer); + + mContextGL->setUniform(mViewInverseUniform.second, mViewInverseUniform.first, GL_FLOAT_MAT4); + mContextGL->setUniform(mLightWorldPosUniform.second, mLightWorldPosUniform.first, + GL_FLOAT_VEC3); + mContextGL->setUniform(mLightColorUniform.second, mLightColorUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mSpecularUniform.second, mSpecularUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mShininessUniform.second, &mShininessUniform.first, GL_FLOAT); + mContextGL->setUniform(mSpecularFactorUniform.second, &mSpecularFactorUniform.first, GL_FLOAT); + mContextGL->setUniform(mAmbientUniform.second, mAmbientUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mFogPowerUniform.second, &mFogPowerUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogMultUniform.second, &mFogMultUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogOffsetUniform.second, &mFogOffsetUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogColorUniform.second, mFogColorUniform.first, GL_FLOAT_VEC4); + + mContextGL->setUniform(mViewProjectionUniform.second, mViewProjectionUniform.first, + GL_FLOAT_MAT4); + mContextGL->setUniform(mFishBendAmountUniform.second, &mFishBendAmountUniform.first, GL_FLOAT); + mContextGL->setUniform(mFishLengthUniform.second, &mFishLengthUniform.first, GL_FLOAT); + mContextGL->setUniform(mFishWaveLengthUniform.second, &mFishWaveLengthUniform.first, GL_FLOAT); + + // Fish models includes small, medium and big. Some of them contains reflection and skybox + // texture, but some doesn't. + mContextGL->setTexture(*mDiffuseTexture.first, mDiffuseTexture.second, 0); + mContextGL->setTexture(*mNormalTexture.first, mNormalTexture.second, 1); + if (mSkyboxTexture.second != -1 && mReflectionTexture.second != -1) + { + mContextGL->setTexture(*mReflectionTexture.first, mReflectionTexture.second, 2); + mContextGL->setTexture(*mSkyboxTexture.first, mSkyboxTexture.second, 3); + } +} + +void FishModelGL::updatePerInstanceUniforms(const WorldUniforms &WorldUniforms) +{ + mContextGL->setUniform(mScaleUniform.second, &mScaleUniform.first, GL_FLOAT); + mContextGL->setUniform(mTimeUniform.second, &mTimeUniform.first, GL_FLOAT); + mContextGL->setUniform(mWorldPositionUniform.second, mWorldPositionUniform.first, + GL_FLOAT_VEC3); + mContextGL->setUniform(mNextPositionUniform.second, mNextPositionUniform.first, GL_FLOAT_VEC3); +} + +void FishModelGL::updateFishPerUniforms(float x, + float y, + float z, + float nextX, + float nextY, + float nextZ, + float scale, + float time, + int index) +{ + mWorldPositionUniform.first[0] = x; + mWorldPositionUniform.first[1] = y; + mWorldPositionUniform.first[2] = z; + mNextPositionUniform.first[0] = nextX; + mNextPositionUniform.first[1] = nextY; + mNextPositionUniform.first[2] = nextZ; + mScaleUniform.first = scale; + mTimeUniform.first = time; +} diff --git a/src/aquarium-optimized/opengl/FishModelGL.h b/src/aquarium-optimized/opengl/FishModelGL.h index 362f0c8..26c8899 100644 --- a/src/aquarium-optimized/opengl/FishModelGL.h +++ b/src/aquarium-optimized/opengl/FishModelGL.h @@ -1,80 +1,85 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FishModelGL.h: Defines fish model of OpenGL. - -#ifndef FishModelGL_H -#define FishModelGL_H 1 - -#include - -#include "../FishModel.h" - -class TextureGL; -class BufferGL; - -class FishModelGL : public FishModel -{ - public: - FishModelGL(const ContextGL *context, Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend); - void prepareForDraw() const override; - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - - void init() override; - void draw() override; - - void updateFishPerUniforms(float x, - float y, - float z, - float nextX, - float nextY, - float nextZ, - float scale, - float time, - int index) override; - - std::pair mViewInverseUniform; - std::pair mLightWorldPosUniform; - std::pair mLightColorUniform; - std::pair mSpecularUniform; - std::pair mShininessUniform; - std::pair mSpecularFactorUniform; - - std::pair mAmbientUniform; - - std::pair mFogPowerUniform; - std::pair mFogMultUniform; - std::pair mFogOffsetUniform; - std::pair mFogColorUniform; - - std::pair mViewProjectionUniform; - std::pair mFishLengthUniform; - std::pair mFishWaveLengthUniform; - std::pair mFishBendAmountUniform; - - std::pair mWorldPositionUniform; - std::pair mNextPositionUniform; - std::pair mScaleUniform; - std::pair mTimeUniform; - - std::pair mDiffuseTexture; - std::pair mNormalTexture; - std::pair mReflectionTexture; - std::pair mSkyboxTexture; - - std::pair mPositionBuffer; - std::pair mNormalBuffer; - std::pair mTexCoordBuffer; - - std::pair mTangentBuffer; - std::pair mBiNormalBuffer; - - BufferGL *mIndicesBuffer; - - private: - const ContextGL *mContextGL; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FishModelGL.h: Defines fish model of OpenGL. + +#ifndef FishModelGL_H +#define FishModelGL_H 1 + +#include + +#include "../FishModel.h" +#include "ContextGL.h" + +class TextureGL; +class BufferGL; + +class FishModelGL : public FishModel +{ + public: + FishModelGL(const ContextGL *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + void prepareForDraw() const override; + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + + void init() override; + void draw() override; + + void updateFishPerUniforms(float x, + float y, + float z, + float nextX, + float nextY, + float nextZ, + float scale, + float time, + int index) override; + + std::pair mViewInverseUniform; + std::pair mLightWorldPosUniform; + std::pair mLightColorUniform; + std::pair mSpecularUniform; + std::pair mShininessUniform; + std::pair mSpecularFactorUniform; + + std::pair mAmbientUniform; + + std::pair mFogPowerUniform; + std::pair mFogMultUniform; + std::pair mFogOffsetUniform; + std::pair mFogColorUniform; + + std::pair mViewProjectionUniform; + std::pair mFishLengthUniform; + std::pair mFishWaveLengthUniform; + std::pair mFishBendAmountUniform; + + std::pair mWorldPositionUniform; + std::pair mNextPositionUniform; + std::pair mScaleUniform; + std::pair mTimeUniform; + + std::pair mDiffuseTexture; + std::pair mNormalTexture; + std::pair mReflectionTexture; + std::pair mSkyboxTexture; + + std::pair mPositionBuffer; + std::pair mNormalBuffer; + std::pair mTexCoordBuffer; + + std::pair mTangentBuffer; + std::pair mBiNormalBuffer; + + BufferGL *mIndicesBuffer; + + private: + const ContextGL *mContextGL; +}; + +#endif diff --git a/src/aquarium-optimized/opengl/GenericModelGL.cpp b/src/aquarium-optimized/opengl/GenericModelGL.cpp index 6d59ac8..5fce6cc 100644 --- a/src/aquarium-optimized/opengl/GenericModelGL.cpp +++ b/src/aquarium-optimized/opengl/GenericModelGL.cpp @@ -1,136 +1,136 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// GenericModelGL.cpp: Implement generic model of OpenGL. - -#include "GenericModelGL.h" - -GenericModelGL::GenericModelGL(const ContextGL *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : Model(type, name, blend), mContextGL(context) -{ - mViewInverseUniform.first = aquarium->lightWorldPositionUniform.viewInverse; - mLightWorldPosUniform.first = aquarium->lightWorldPositionUniform.lightWorldPos; - mLightColorUniform.first = aquarium->lightUniforms.lightColor; - mSpecularUniform.first = aquarium->lightUniforms.specular; - mShininessUniform.first = 50.0f; - mSpecularFactorUniform.first = 1.0f; - mAmbientUniform.first = aquarium->lightUniforms.ambient; - mWorldUniform.first = aquarium->worldUniforms.world; - mWorldViewProjectionUniform.first = aquarium->worldUniforms.worldViewProjection; - mWorldInverseTransposeUniform.first = aquarium->worldUniforms.worldInverseTranspose; - mFogPowerUniform.first = g_fogPower; - mFogMultUniform.first = g_fogMult; - mFogOffsetUniform.first = g_fogOffset; - mFogColorUniform.first = aquarium->fogUniforms.fogColor; -} - -void GenericModelGL::init() -{ - ProgramGL *programGL = static_cast(mProgram); - mWorldViewProjectionUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "worldViewProjection"); - mWorldUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "world"); - mWorldInverseTransposeUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "worldInverseTranspose"); - - mViewInverseUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "viewInverse"); - mLightWorldPosUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "lightWorldPos"); - mLightColorUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "lightColor"); - mSpecularUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "specular"); - mAmbientUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "ambient"); - mShininessUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "shininess"); - mSpecularFactorUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "specularFactor"); - - mFogPowerUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogPower"); - mFogMultUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogMult"); - mFogOffsetUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "fogOffset"); - mFogColorUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogColor"); - - mDiffuseTexture.first = static_cast(textureMap["diffuse"]); - mDiffuseTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "diffuse"); - mNormalTexture.first = static_cast(textureMap["normalMap"]); - mNormalTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "normalMap"); - - mPositionBuffer.first = static_cast(bufferMap["position"]); - mPositionBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "position"); - mNormalBuffer.first = static_cast(bufferMap["normal"]); - mNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "normal"); - mTexCoordBuffer.first = static_cast(bufferMap["texCoord"]); - mTexCoordBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "texCoord"); - mTangentBuffer.first = static_cast(bufferMap["tangent"]); - mTangentBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "tangent"); - mBiNormalBuffer.first = static_cast(bufferMap["binormal"]); - mBiNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "binormal"); - - mIndicesBuffer = static_cast(bufferMap["indices"]); -} - -void GenericModelGL::draw() -{ - mContextGL->drawElements(*mIndicesBuffer); -} - -void GenericModelGL::prepareForDraw() const -{ - mProgram->setProgram(); - mContextGL->enableBlend(mBlend); - - ProgramGL *programGL = static_cast(mProgram); - mContextGL->bindVAO(programGL->getVAOId()); - - mContextGL->setAttribs(*mPositionBuffer.first, mPositionBuffer.second); - mContextGL->setAttribs(*mNormalBuffer.first, mNormalBuffer.second); - mContextGL->setAttribs(*mTexCoordBuffer.first, mTexCoordBuffer.second); - - // diffuseVertexShader doesn't contains tangent and binormal but normalMapVertexShader - // contains the two buffers. - if (mTangentBuffer.second != -1 && mBiNormalBuffer.second != -1) - { - mContextGL->setAttribs(*mTangentBuffer.first, mTangentBuffer.second); - mContextGL->setAttribs(*mBiNormalBuffer.first, mBiNormalBuffer.second); - } - - mContextGL->setIndices(*mIndicesBuffer); - - mContextGL->setUniform(mViewInverseUniform.second, mViewInverseUniform.first, GL_FLOAT_MAT4); - mContextGL->setUniform(mLightWorldPosUniform.second, mLightWorldPosUniform.first, - GL_FLOAT_VEC3); - mContextGL->setUniform(mLightColorUniform.second, mLightColorUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mSpecularUniform.second, mSpecularUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mShininessUniform.second, &mShininessUniform.first, GL_FLOAT); - mContextGL->setUniform(mSpecularFactorUniform.second, &mSpecularFactorUniform.first, GL_FLOAT); - mContextGL->setUniform(mAmbientUniform.second, mAmbientUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mFogPowerUniform.second, &mFogPowerUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogMultUniform.second, &mFogMultUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogOffsetUniform.second, &mFogOffsetUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogColorUniform.second, mFogColorUniform.first, GL_FLOAT_VEC4); - - mContextGL->setTexture(*mDiffuseTexture.first, mDiffuseTexture.second, 0); - // Generic models includes Arch, coral, rock, ship, etc. diffuseFragmentShader doesn't contain - // normalMap texture but normalMapFragmentShader contains. - if (mNormalTexture.second != -1) - { - mContextGL->setTexture(*mNormalTexture.first, mNormalTexture.second, 1); - } -} - -void GenericModelGL::updatePerInstanceUniforms(const WorldUniforms &mWorldUniforms) -{ - mContextGL->setUniform(mWorldUniform.second, mWorldUniform.first, GL_FLOAT_MAT4); - mContextGL->setUniform(mWorldViewProjectionUniform.second, mWorldViewProjectionUniform.first, - GL_FLOAT_MAT4); - mContextGL->setUniform(mWorldInverseTransposeUniform.second, - mWorldInverseTransposeUniform.first, GL_FLOAT_MAT4); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// GenericModelGL.cpp: Implement generic model of OpenGL. + +#include "GenericModelGL.h" + +GenericModelGL::GenericModelGL(const ContextGL *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : Model(type, name, blend), mContextGL(context) +{ + mViewInverseUniform.first = aquarium->lightWorldPositionUniform.viewInverse; + mLightWorldPosUniform.first = aquarium->lightWorldPositionUniform.lightWorldPos; + mLightColorUniform.first = aquarium->lightUniforms.lightColor; + mSpecularUniform.first = aquarium->lightUniforms.specular; + mShininessUniform.first = 50.0f; + mSpecularFactorUniform.first = 1.0f; + mAmbientUniform.first = aquarium->lightUniforms.ambient; + mWorldUniform.first = aquarium->worldUniforms.world; + mWorldViewProjectionUniform.first = aquarium->worldUniforms.worldViewProjection; + mWorldInverseTransposeUniform.first = aquarium->worldUniforms.worldInverseTranspose; + mFogPowerUniform.first = g_fogPower; + mFogMultUniform.first = g_fogMult; + mFogOffsetUniform.first = g_fogOffset; + mFogColorUniform.first = aquarium->fogUniforms.fogColor; +} + +void GenericModelGL::init() +{ + ProgramGL *programGL = static_cast(mProgram); + mWorldViewProjectionUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "worldViewProjection"); + mWorldUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "world"); + mWorldInverseTransposeUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "worldInverseTranspose"); + + mViewInverseUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "viewInverse"); + mLightWorldPosUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "lightWorldPos"); + mLightColorUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "lightColor"); + mSpecularUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "specular"); + mAmbientUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "ambient"); + mShininessUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "shininess"); + mSpecularFactorUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "specularFactor"); + + mFogPowerUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogPower"); + mFogMultUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogMult"); + mFogOffsetUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "fogOffset"); + mFogColorUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogColor"); + + mDiffuseTexture.first = static_cast(textureMap["diffuse"]); + mDiffuseTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "diffuse"); + mNormalTexture.first = static_cast(textureMap["normalMap"]); + mNormalTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "normalMap"); + + mPositionBuffer.first = static_cast(bufferMap["position"]); + mPositionBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "position"); + mNormalBuffer.first = static_cast(bufferMap["normal"]); + mNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "normal"); + mTexCoordBuffer.first = static_cast(bufferMap["texCoord"]); + mTexCoordBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "texCoord"); + mTangentBuffer.first = static_cast(bufferMap["tangent"]); + mTangentBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "tangent"); + mBiNormalBuffer.first = static_cast(bufferMap["binormal"]); + mBiNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "binormal"); + + mIndicesBuffer = static_cast(bufferMap["indices"]); +} + +void GenericModelGL::draw() +{ + mContextGL->drawElements(*mIndicesBuffer); +} + +void GenericModelGL::prepareForDraw() const +{ + mProgram->setProgram(); + mContextGL->enableBlend(mBlend); + + ProgramGL *programGL = static_cast(mProgram); + mContextGL->bindVAO(programGL->getVAOId()); + + mContextGL->setAttribs(*mPositionBuffer.first, mPositionBuffer.second); + mContextGL->setAttribs(*mNormalBuffer.first, mNormalBuffer.second); + mContextGL->setAttribs(*mTexCoordBuffer.first, mTexCoordBuffer.second); + + // diffuseVertexShader doesn't contains tangent and binormal but normalMapVertexShader + // contains the two buffers. + if (mTangentBuffer.second != -1 && mBiNormalBuffer.second != -1) + { + mContextGL->setAttribs(*mTangentBuffer.first, mTangentBuffer.second); + mContextGL->setAttribs(*mBiNormalBuffer.first, mBiNormalBuffer.second); + } + + mContextGL->setIndices(*mIndicesBuffer); + + mContextGL->setUniform(mViewInverseUniform.second, mViewInverseUniform.first, GL_FLOAT_MAT4); + mContextGL->setUniform(mLightWorldPosUniform.second, mLightWorldPosUniform.first, + GL_FLOAT_VEC3); + mContextGL->setUniform(mLightColorUniform.second, mLightColorUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mSpecularUniform.second, mSpecularUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mShininessUniform.second, &mShininessUniform.first, GL_FLOAT); + mContextGL->setUniform(mSpecularFactorUniform.second, &mSpecularFactorUniform.first, GL_FLOAT); + mContextGL->setUniform(mAmbientUniform.second, mAmbientUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mFogPowerUniform.second, &mFogPowerUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogMultUniform.second, &mFogMultUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogOffsetUniform.second, &mFogOffsetUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogColorUniform.second, mFogColorUniform.first, GL_FLOAT_VEC4); + + mContextGL->setTexture(*mDiffuseTexture.first, mDiffuseTexture.second, 0); + // Generic models includes Arch, coral, rock, ship, etc. diffuseFragmentShader doesn't contain + // normalMap texture but normalMapFragmentShader contains. + if (mNormalTexture.second != -1) + { + mContextGL->setTexture(*mNormalTexture.first, mNormalTexture.second, 1); + } +} + +void GenericModelGL::updatePerInstanceUniforms(const WorldUniforms &mWorldUniforms) +{ + mContextGL->setUniform(mWorldUniform.second, mWorldUniform.first, GL_FLOAT_MAT4); + mContextGL->setUniform(mWorldViewProjectionUniform.second, mWorldViewProjectionUniform.first, + GL_FLOAT_MAT4); + mContextGL->setUniform(mWorldInverseTransposeUniform.second, + mWorldInverseTransposeUniform.first, GL_FLOAT_MAT4); +} diff --git a/src/aquarium-optimized/opengl/GenericModelGL.h b/src/aquarium-optimized/opengl/GenericModelGL.h index d07edbc..e306a68 100644 --- a/src/aquarium-optimized/opengl/GenericModelGL.h +++ b/src/aquarium-optimized/opengl/GenericModelGL.h @@ -1,64 +1,64 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// GenericModel.h: Defines generic model of OpenGL. - -#pragma once -#ifndef GENERICMODELGL_H -#define GENERICMODELGL_H 1 - -#include "ContextGL.h" -#include "ProgramGL.h" - -#include "../Model.h" - -class GenericModelGL : public Model -{ - public: - GenericModelGL(const ContextGL *context, - Aquarium* aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - void prepareForDraw() const override; - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - void init() override; - void draw() override; - - std::pair mWorldViewProjectionUniform; - std::pair mWorldUniform; - std::pair mWorldInverseTransposeUniform; - - std::pair mViewInverseUniform; - std::pair mLightWorldPosUniform; - std::pair mLightColorUniform; - std::pair mSpecularUniform; - std::pair mShininessUniform; - std::pair mSpecularFactorUniform; - - std::pair mAmbientUniform; - - std::pair mFogPowerUniform; - std::pair mFogMultUniform; - std::pair mFogOffsetUniform; - std::pair mFogColorUniform; - - std::pair mDiffuseTexture; - std::pair mNormalTexture; - - std::pair mPositionBuffer; - std::pair mNormalBuffer; - std::pair mTexCoordBuffer; - - std::pair mTangentBuffer; - std::pair mBiNormalBuffer; - - BufferGL *mIndicesBuffer; - - private: - const ContextGL *mContextGL; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// GenericModel.h: Defines generic model of OpenGL. + +#pragma once +#ifndef GENERICMODELGL_H +#define GENERICMODELGL_H 1 + +#include "ContextGL.h" +#include "ProgramGL.h" + +#include "../Model.h" + +class GenericModelGL : public Model +{ + public: + GenericModelGL(const ContextGL *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + void prepareForDraw() const override; + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + void init() override; + void draw() override; + + std::pair mWorldViewProjectionUniform; + std::pair mWorldUniform; + std::pair mWorldInverseTransposeUniform; + + std::pair mViewInverseUniform; + std::pair mLightWorldPosUniform; + std::pair mLightColorUniform; + std::pair mSpecularUniform; + std::pair mShininessUniform; + std::pair mSpecularFactorUniform; + + std::pair mAmbientUniform; + + std::pair mFogPowerUniform; + std::pair mFogMultUniform; + std::pair mFogOffsetUniform; + std::pair mFogColorUniform; + + std::pair mDiffuseTexture; + std::pair mNormalTexture; + + std::pair mPositionBuffer; + std::pair mNormalBuffer; + std::pair mTexCoordBuffer; + + std::pair mTangentBuffer; + std::pair mBiNormalBuffer; + + BufferGL *mIndicesBuffer; + + private: + const ContextGL *mContextGL; +}; + +#endif diff --git a/src/aquarium-optimized/opengl/InnerModelGL.cpp b/src/aquarium-optimized/opengl/InnerModelGL.cpp index 09776a3..07d4a07 100644 --- a/src/aquarium-optimized/opengl/InnerModelGL.cpp +++ b/src/aquarium-optimized/opengl/InnerModelGL.cpp @@ -1,132 +1,132 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// InnerModelGL.cpp: Implement inner model of OpenGL. - -#include "InnerModelGL.h" - -InnerModelGL::InnerModelGL(const ContextGL *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : Model(type, name, blend), mContextGL(context) -{ - mViewInverseUniform.first = aquarium->lightWorldPositionUniform.viewInverse; - mLightWorldPosUniform.first = aquarium->lightWorldPositionUniform.lightWorldPos; - - mWorldUniform.first = aquarium->worldUniforms.world; - mWorldViewProjectionUniform.first = aquarium->worldUniforms.worldViewProjection; - mWorldInverseTransposeUniform.first = aquarium->worldUniforms.worldInverseTranspose; - - mEtaUniform.first = 1.0f; - mTankColorFudgeUniform.first = 0.796f; - mRefractionFudgeUniform.first = 3.0f; - - mFogPowerUniform.first = g_fogPower; - mFogMultUniform.first = g_fogMult; - mFogOffsetUniform.first = g_fogOffset; - mFogColorUniform.first = aquarium->fogUniforms.fogColor; -} - -void InnerModelGL::init() -{ - ProgramGL *programGL = static_cast(mProgram); - mWorldViewProjectionUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "worldViewProjection"); - mWorldUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "world"); - mWorldInverseTransposeUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "worldInverseTranspose"); - - mViewInverseUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "viewInverse"); - mLightWorldPosUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "lightWorldPos"); - - mFogPowerUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogPower"); - mFogMultUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogMult"); - mFogOffsetUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "fogOffset"); - mFogColorUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogColor"); - - mEtaUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "eta"); - mTankColorFudgeUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "tankColorFudge"); - mRefractionFudgeUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "refractionFudge"); - - mDiffuseTexture.first = static_cast(textureMap["diffuse"]); - mDiffuseTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "diffuse"); - mNormalTexture.first = static_cast(textureMap["normalMap"]); - mNormalTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "normalMap"); - mReflectionTexture.first = static_cast(textureMap["reflectionMap"]); - mReflectionTexture.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "reflectionMap"); - mSkyboxTexture.first = static_cast(textureMap["skybox"]); - mSkyboxTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "skybox"); - - mPositionBuffer.first = static_cast(bufferMap["position"]); - mPositionBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "position"); - mNormalBuffer.first = static_cast(bufferMap["normal"]); - mNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "normal"); - mTexCoordBuffer.first = static_cast(bufferMap["texCoord"]); - mTexCoordBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "texCoord"); - mTangentBuffer.first = static_cast(bufferMap["tangent"]); - mTangentBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "tangent"); - mBiNormalBuffer.first = static_cast(bufferMap["binormal"]); - mBiNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "binormal"); - - mIndicesBuffer = static_cast(bufferMap["indices"]); -} - -void InnerModelGL::draw() -{ - mContextGL->drawElements(*mIndicesBuffer); -} - -void InnerModelGL::prepareForDraw() const -{ - mProgram->setProgram(); - mContextGL->enableBlend(mBlend); - - ProgramGL *programGL = static_cast(mProgram); - mContextGL->bindVAO(programGL->getVAOId()); - - mContextGL->setAttribs(*mPositionBuffer.first, mPositionBuffer.second); - mContextGL->setAttribs(*mNormalBuffer.first, mNormalBuffer.second); - mContextGL->setAttribs(*mTexCoordBuffer.first, mTexCoordBuffer.second); - - mContextGL->setAttribs(*mTangentBuffer.first, mTangentBuffer.second); - mContextGL->setAttribs(*mBiNormalBuffer.first, mBiNormalBuffer.second); - - mContextGL->setIndices(*mIndicesBuffer); - - mContextGL->setUniform(mViewInverseUniform.second, mViewInverseUniform.first, GL_FLOAT_MAT4); - // lightWorldPosition is optimized away on mesa because it's not used by shader - // mContextGL->setUniform(mLightWorldPosUniform.second, mLightWorldPosUniform.first, - // GL_FLOAT_VEC3); - mContextGL->setUniform(mFogPowerUniform.second, &mFogPowerUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogMultUniform.second, &mFogMultUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogOffsetUniform.second, &mFogOffsetUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogColorUniform.second, mFogColorUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mEtaUniform.second, &mEtaUniform.first, GL_FLOAT); - mContextGL->setUniform(mTankColorFudgeUniform.second, &mTankColorFudgeUniform.first, GL_FLOAT); - mContextGL->setUniform(mRefractionFudgeUniform.second, &mRefractionFudgeUniform.first, - GL_FLOAT); - - mContextGL->setTexture(*mDiffuseTexture.first, mDiffuseTexture.second, 0); - mContextGL->setTexture(*mNormalTexture.first, mNormalTexture.second, 1); - mContextGL->setTexture(*mReflectionTexture.first, mReflectionTexture.second, 2); - mContextGL->setTexture(*mSkyboxTexture.first, mSkyboxTexture.second, 3); -} - -void InnerModelGL::updatePerInstanceUniforms(const WorldUniforms &mWorldUniforms) -{ - mContextGL->setUniform(mWorldUniform.second, mWorldUniform.first, GL_FLOAT_MAT4); - mContextGL->setUniform(mWorldViewProjectionUniform.second, mWorldViewProjectionUniform.first, - GL_FLOAT_MAT4); - mContextGL->setUniform(mWorldInverseTransposeUniform.second, - mWorldInverseTransposeUniform.first, GL_FLOAT_MAT4); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// InnerModelGL.cpp: Implement inner model of OpenGL. + +#include "InnerModelGL.h" + +InnerModelGL::InnerModelGL(const ContextGL *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : Model(type, name, blend), mContextGL(context) +{ + mViewInverseUniform.first = aquarium->lightWorldPositionUniform.viewInverse; + mLightWorldPosUniform.first = aquarium->lightWorldPositionUniform.lightWorldPos; + + mWorldUniform.first = aquarium->worldUniforms.world; + mWorldViewProjectionUniform.first = aquarium->worldUniforms.worldViewProjection; + mWorldInverseTransposeUniform.first = aquarium->worldUniforms.worldInverseTranspose; + + mEtaUniform.first = 1.0f; + mTankColorFudgeUniform.first = 0.796f; + mRefractionFudgeUniform.first = 3.0f; + + mFogPowerUniform.first = g_fogPower; + mFogMultUniform.first = g_fogMult; + mFogOffsetUniform.first = g_fogOffset; + mFogColorUniform.first = aquarium->fogUniforms.fogColor; +} + +void InnerModelGL::init() +{ + ProgramGL *programGL = static_cast(mProgram); + mWorldViewProjectionUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "worldViewProjection"); + mWorldUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "world"); + mWorldInverseTransposeUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "worldInverseTranspose"); + + mViewInverseUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "viewInverse"); + mLightWorldPosUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "lightWorldPos"); + + mFogPowerUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogPower"); + mFogMultUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogMult"); + mFogOffsetUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "fogOffset"); + mFogColorUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogColor"); + + mEtaUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "eta"); + mTankColorFudgeUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "tankColorFudge"); + mRefractionFudgeUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "refractionFudge"); + + mDiffuseTexture.first = static_cast(textureMap["diffuse"]); + mDiffuseTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "diffuse"); + mNormalTexture.first = static_cast(textureMap["normalMap"]); + mNormalTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "normalMap"); + mReflectionTexture.first = static_cast(textureMap["reflectionMap"]); + mReflectionTexture.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "reflectionMap"); + mSkyboxTexture.first = static_cast(textureMap["skybox"]); + mSkyboxTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "skybox"); + + mPositionBuffer.first = static_cast(bufferMap["position"]); + mPositionBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "position"); + mNormalBuffer.first = static_cast(bufferMap["normal"]); + mNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "normal"); + mTexCoordBuffer.first = static_cast(bufferMap["texCoord"]); + mTexCoordBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "texCoord"); + mTangentBuffer.first = static_cast(bufferMap["tangent"]); + mTangentBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "tangent"); + mBiNormalBuffer.first = static_cast(bufferMap["binormal"]); + mBiNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "binormal"); + + mIndicesBuffer = static_cast(bufferMap["indices"]); +} + +void InnerModelGL::draw() +{ + mContextGL->drawElements(*mIndicesBuffer); +} + +void InnerModelGL::prepareForDraw() const +{ + mProgram->setProgram(); + mContextGL->enableBlend(mBlend); + + ProgramGL *programGL = static_cast(mProgram); + mContextGL->bindVAO(programGL->getVAOId()); + + mContextGL->setAttribs(*mPositionBuffer.first, mPositionBuffer.second); + mContextGL->setAttribs(*mNormalBuffer.first, mNormalBuffer.second); + mContextGL->setAttribs(*mTexCoordBuffer.first, mTexCoordBuffer.second); + + mContextGL->setAttribs(*mTangentBuffer.first, mTangentBuffer.second); + mContextGL->setAttribs(*mBiNormalBuffer.first, mBiNormalBuffer.second); + + mContextGL->setIndices(*mIndicesBuffer); + + mContextGL->setUniform(mViewInverseUniform.second, mViewInverseUniform.first, GL_FLOAT_MAT4); + // lightWorldPosition is optimized away on mesa because it's not used by shader + // mContextGL->setUniform(mLightWorldPosUniform.second, mLightWorldPosUniform.first, + // GL_FLOAT_VEC3); + mContextGL->setUniform(mFogPowerUniform.second, &mFogPowerUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogMultUniform.second, &mFogMultUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogOffsetUniform.second, &mFogOffsetUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogColorUniform.second, mFogColorUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mEtaUniform.second, &mEtaUniform.first, GL_FLOAT); + mContextGL->setUniform(mTankColorFudgeUniform.second, &mTankColorFudgeUniform.first, GL_FLOAT); + mContextGL->setUniform(mRefractionFudgeUniform.second, &mRefractionFudgeUniform.first, + GL_FLOAT); + + mContextGL->setTexture(*mDiffuseTexture.first, mDiffuseTexture.second, 0); + mContextGL->setTexture(*mNormalTexture.first, mNormalTexture.second, 1); + mContextGL->setTexture(*mReflectionTexture.first, mReflectionTexture.second, 2); + mContextGL->setTexture(*mSkyboxTexture.first, mSkyboxTexture.second, 3); +} + +void InnerModelGL::updatePerInstanceUniforms(const WorldUniforms &mWorldUniforms) +{ + mContextGL->setUniform(mWorldUniform.second, mWorldUniform.first, GL_FLOAT_MAT4); + mContextGL->setUniform(mWorldViewProjectionUniform.second, mWorldViewProjectionUniform.first, + GL_FLOAT_MAT4); + mContextGL->setUniform(mWorldInverseTransposeUniform.second, + mWorldInverseTransposeUniform.first, GL_FLOAT_MAT4); +} diff --git a/src/aquarium-optimized/opengl/InnerModelGL.h b/src/aquarium-optimized/opengl/InnerModelGL.h index e3f55d0..db90328 100644 --- a/src/aquarium-optimized/opengl/InnerModelGL.h +++ b/src/aquarium-optimized/opengl/InnerModelGL.h @@ -1,61 +1,65 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Defines inner model of OpenGL. - -#pragma once -#ifndef INNERMODELGL_H -#define INNERMODELGL_H 1 - -#include "ContextGL.h" -#include "ProgramGL.h" - -#include "../Model.h" - -class InnerModelGL : public Model -{ - public: - InnerModelGL(const ContextGL *context, Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend); - void prepareForDraw() const override; - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - void init() override; - void draw() override; - - std::pair mWorldViewProjectionUniform; - std::pair mWorldUniform; - std::pair mWorldInverseUniform; - std::pair mWorldInverseTransposeUniform; - - std::pair mViewInverseUniform; - std::pair mLightWorldPosUniform; - - std::pair mEtaUniform; - std::pair mTankColorFudgeUniform; - std::pair mRefractionFudgeUniform; - - std::pair mFogPowerUniform; - std::pair mFogMultUniform; - std::pair mFogOffsetUniform; - std::pair mFogColorUniform; - - std::pair mDiffuseTexture; - std::pair mNormalTexture; - std::pair mReflectionTexture; - std::pair mSkyboxTexture; - - std::pair mPositionBuffer; - std::pair mNormalBuffer; - std::pair mTexCoordBuffer; - - std::pair mTangentBuffer; - std::pair mBiNormalBuffer; - - BufferGL *mIndicesBuffer; - - private: - const ContextGL *mContextGL; -}; - -#endif // !INNERMODELGL_H +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Defines inner model of OpenGL. + +#pragma once +#ifndef INNERMODELGL_H +#define INNERMODELGL_H 1 + +#include "ContextGL.h" +#include "ProgramGL.h" + +#include "../Model.h" + +class InnerModelGL : public Model +{ + public: + InnerModelGL(const ContextGL *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + void prepareForDraw() const override; + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + void init() override; + void draw() override; + + std::pair mWorldViewProjectionUniform; + std::pair mWorldUniform; + std::pair mWorldInverseUniform; + std::pair mWorldInverseTransposeUniform; + + std::pair mViewInverseUniform; + std::pair mLightWorldPosUniform; + + std::pair mEtaUniform; + std::pair mTankColorFudgeUniform; + std::pair mRefractionFudgeUniform; + + std::pair mFogPowerUniform; + std::pair mFogMultUniform; + std::pair mFogOffsetUniform; + std::pair mFogColorUniform; + + std::pair mDiffuseTexture; + std::pair mNormalTexture; + std::pair mReflectionTexture; + std::pair mSkyboxTexture; + + std::pair mPositionBuffer; + std::pair mNormalBuffer; + std::pair mTexCoordBuffer; + + std::pair mTangentBuffer; + std::pair mBiNormalBuffer; + + BufferGL *mIndicesBuffer; + + private: + const ContextGL *mContextGL; +}; + +#endif // !INNERMODELGL_H diff --git a/src/aquarium-optimized/opengl/OutsideModelGL.cpp b/src/aquarium-optimized/opengl/OutsideModelGL.cpp index 323a637..cd86936 100644 --- a/src/aquarium-optimized/opengl/OutsideModelGL.cpp +++ b/src/aquarium-optimized/opengl/OutsideModelGL.cpp @@ -1,116 +1,116 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// OutsideModelGL.cpp: Implement outside model of OpenGL. - -#include "OutsideModelGL.h" - -OutsideModelGL::OutsideModelGL(const ContextGL *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : Model(type, name, blend), mContextGL(context) -{ - mViewInverseUniform.first = aquarium->lightWorldPositionUniform.viewInverse; - mLightWorldPosUniform.first = aquarium->lightWorldPositionUniform.lightWorldPos; - mLightColorUniform.first = aquarium->lightUniforms.lightColor; - mSpecularUniform.first = aquarium->lightUniforms.specular; - mShininessUniform.first = 50.0f; - mSpecularFactorUniform.first = 0.0f; - mAmbientUniform.first = aquarium->lightUniforms.ambient; - mWorldUniform.first = aquarium->worldUniforms.world; - mWorldViewProjectionUniform.first = aquarium->worldUniforms.worldViewProjection; - mWorldInverseTransposeUniform.first = aquarium->worldUniforms.worldInverseTranspose; - mFogPowerUniform.first = 0; - mFogMultUniform.first = 0; - mFogOffsetUniform.first = 0; - mFogColorUniform.first = aquarium->fogUniforms.fogColor; -} - -void OutsideModelGL::init() -{ - ProgramGL *programGL = static_cast(mProgram); - mWorldViewProjectionUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "worldViewProjection"); - mWorldUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "world"); - mWorldInverseTransposeUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "worldInverseTranspose"); - - mViewInverseUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "viewInverse"); - mLightWorldPosUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "lightWorldPos"); - mLightColorUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "lightColor"); - mSpecularUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "specular"); - mAmbientUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "ambient"); - mShininessUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "shininess"); - mSpecularFactorUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "specularFactor"); - - mFogPowerUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogPower"); - mFogMultUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogMult"); - mFogOffsetUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "fogOffset"); - mFogColorUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogColor"); - - mDiffuseTexture.first = static_cast(textureMap["diffuse"]); - mDiffuseTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "diffuse"); - - mPositionBuffer.first = static_cast(bufferMap["position"]); - mPositionBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "position"); - mNormalBuffer.first = static_cast(bufferMap["normal"]); - mNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "normal"); - mTexCoordBuffer.first = static_cast(bufferMap["texCoord"]); - mTexCoordBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "texCoord"); - - mIndicesBuffer = static_cast(bufferMap["indices"]); -} - -void OutsideModelGL::draw() -{ - mContextGL->drawElements(*mIndicesBuffer); -} - -void OutsideModelGL::prepareForDraw() const -{ - mProgram->setProgram(); - mContextGL->enableBlend(mBlend); - - ProgramGL *programGL = static_cast(mProgram); - mContextGL->bindVAO(programGL->getVAOId()); - - mContextGL->setAttribs(*mPositionBuffer.first, mPositionBuffer.second); - mContextGL->setAttribs(*mNormalBuffer.first, mNormalBuffer.second); - mContextGL->setAttribs(*mTexCoordBuffer.first, mTexCoordBuffer.second); - - mContextGL->setIndices(*mIndicesBuffer); - - mContextGL->setUniform(mViewInverseUniform.second, mViewInverseUniform.first, GL_FLOAT_MAT4); - mContextGL->setUniform(mLightWorldPosUniform.second, mLightWorldPosUniform.first, - GL_FLOAT_VEC3); - mContextGL->setUniform(mLightColorUniform.second, mLightColorUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mSpecularUniform.second, mSpecularUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mShininessUniform.second, &mShininessUniform.first, GL_FLOAT); - mContextGL->setUniform(mSpecularFactorUniform.second, &mSpecularFactorUniform.first, GL_FLOAT); - mContextGL->setUniform(mAmbientUniform.second, mAmbientUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mFogPowerUniform.second, &mFogPowerUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogMultUniform.second, &mFogMultUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogOffsetUniform.second, &mFogOffsetUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogColorUniform.second, mFogColorUniform.first, GL_FLOAT_VEC4); - - mContextGL->setTexture(*mDiffuseTexture.first, mDiffuseTexture.second, 0); -} - -void OutsideModelGL::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) -{ - mContextGL->setUniform(mWorldUniform.second, mWorldUniform.first, GL_FLOAT_MAT4); - mContextGL->setUniform(mWorldViewProjectionUniform.second, mWorldViewProjectionUniform.first, - GL_FLOAT_MAT4); - mContextGL->setUniform(mWorldInverseTransposeUniform.second, - mWorldInverseTransposeUniform.first, GL_FLOAT_MAT4); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// OutsideModelGL.cpp: Implement outside model of OpenGL. + +#include "OutsideModelGL.h" + +OutsideModelGL::OutsideModelGL(const ContextGL *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : Model(type, name, blend), mContextGL(context) +{ + mViewInverseUniform.first = aquarium->lightWorldPositionUniform.viewInverse; + mLightWorldPosUniform.first = aquarium->lightWorldPositionUniform.lightWorldPos; + mLightColorUniform.first = aquarium->lightUniforms.lightColor; + mSpecularUniform.first = aquarium->lightUniforms.specular; + mShininessUniform.first = 50.0f; + mSpecularFactorUniform.first = 0.0f; + mAmbientUniform.first = aquarium->lightUniforms.ambient; + mWorldUniform.first = aquarium->worldUniforms.world; + mWorldViewProjectionUniform.first = aquarium->worldUniforms.worldViewProjection; + mWorldInverseTransposeUniform.first = aquarium->worldUniforms.worldInverseTranspose; + mFogPowerUniform.first = 0; + mFogMultUniform.first = 0; + mFogOffsetUniform.first = 0; + mFogColorUniform.first = aquarium->fogUniforms.fogColor; +} + +void OutsideModelGL::init() +{ + ProgramGL *programGL = static_cast(mProgram); + mWorldViewProjectionUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "worldViewProjection"); + mWorldUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "world"); + mWorldInverseTransposeUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "worldInverseTranspose"); + + mViewInverseUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "viewInverse"); + mLightWorldPosUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "lightWorldPos"); + mLightColorUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "lightColor"); + mSpecularUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "specular"); + mAmbientUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "ambient"); + mShininessUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "shininess"); + mSpecularFactorUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "specularFactor"); + + mFogPowerUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogPower"); + mFogMultUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogMult"); + mFogOffsetUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "fogOffset"); + mFogColorUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogColor"); + + mDiffuseTexture.first = static_cast(textureMap["diffuse"]); + mDiffuseTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "diffuse"); + + mPositionBuffer.first = static_cast(bufferMap["position"]); + mPositionBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "position"); + mNormalBuffer.first = static_cast(bufferMap["normal"]); + mNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "normal"); + mTexCoordBuffer.first = static_cast(bufferMap["texCoord"]); + mTexCoordBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "texCoord"); + + mIndicesBuffer = static_cast(bufferMap["indices"]); +} + +void OutsideModelGL::draw() +{ + mContextGL->drawElements(*mIndicesBuffer); +} + +void OutsideModelGL::prepareForDraw() const +{ + mProgram->setProgram(); + mContextGL->enableBlend(mBlend); + + ProgramGL *programGL = static_cast(mProgram); + mContextGL->bindVAO(programGL->getVAOId()); + + mContextGL->setAttribs(*mPositionBuffer.first, mPositionBuffer.second); + mContextGL->setAttribs(*mNormalBuffer.first, mNormalBuffer.second); + mContextGL->setAttribs(*mTexCoordBuffer.first, mTexCoordBuffer.second); + + mContextGL->setIndices(*mIndicesBuffer); + + mContextGL->setUniform(mViewInverseUniform.second, mViewInverseUniform.first, GL_FLOAT_MAT4); + mContextGL->setUniform(mLightWorldPosUniform.second, mLightWorldPosUniform.first, + GL_FLOAT_VEC3); + mContextGL->setUniform(mLightColorUniform.second, mLightColorUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mSpecularUniform.second, mSpecularUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mShininessUniform.second, &mShininessUniform.first, GL_FLOAT); + mContextGL->setUniform(mSpecularFactorUniform.second, &mSpecularFactorUniform.first, GL_FLOAT); + mContextGL->setUniform(mAmbientUniform.second, mAmbientUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mFogPowerUniform.second, &mFogPowerUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogMultUniform.second, &mFogMultUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogOffsetUniform.second, &mFogOffsetUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogColorUniform.second, mFogColorUniform.first, GL_FLOAT_VEC4); + + mContextGL->setTexture(*mDiffuseTexture.first, mDiffuseTexture.second, 0); +} + +void OutsideModelGL::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) +{ + mContextGL->setUniform(mWorldUniform.second, mWorldUniform.first, GL_FLOAT_MAT4); + mContextGL->setUniform(mWorldViewProjectionUniform.second, mWorldViewProjectionUniform.first, + GL_FLOAT_MAT4); + mContextGL->setUniform(mWorldInverseTransposeUniform.second, + mWorldInverseTransposeUniform.first, GL_FLOAT_MAT4); +} diff --git a/src/aquarium-optimized/opengl/OutsideModelGL.h b/src/aquarium-optimized/opengl/OutsideModelGL.h index b261356..ac66d92 100644 --- a/src/aquarium-optimized/opengl/OutsideModelGL.h +++ b/src/aquarium-optimized/opengl/OutsideModelGL.h @@ -1,60 +1,60 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// OutsideModelGL.h: Define the outside model of OpenGL. - -#pragma once -#ifndef OutsideModelGL_H -#define OutsideModelGL_H 1 - -#include "ContextGL.h" -#include "ProgramGL.h" - -#include "../Model.h" - -class OutsideModelGL : public Model -{ - public: - OutsideModelGL(const ContextGL *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - void prepareForDraw() const override; - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - void init() override; - void draw() override; - - std::pair mWorldViewProjectionUniform; - std::pair mWorldUniform; - std::pair mWorldInverseTransposeUniform; - - std::pair mViewInverseUniform; - std::pair mLightWorldPosUniform; - std::pair mLightColorUniform; - std::pair mSpecularUniform; - std::pair mShininessUniform; - std::pair mSpecularFactorUniform; - - std::pair mAmbientUniform; - - std::pair mFogPowerUniform; - std::pair mFogMultUniform; - std::pair mFogOffsetUniform; - std::pair mFogColorUniform; - - std::pair mDiffuseTexture; - - std::pair mPositionBuffer; - std::pair mNormalBuffer; - std::pair mTexCoordBuffer; - - BufferGL *mIndicesBuffer; - - private: - const ContextGL *mContextGL; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// OutsideModelGL.h: Define the outside model of OpenGL. + +#pragma once +#ifndef OutsideModelGL_H +#define OutsideModelGL_H 1 + +#include "ContextGL.h" +#include "ProgramGL.h" + +#include "../Model.h" + +class OutsideModelGL : public Model +{ + public: + OutsideModelGL(const ContextGL *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + void prepareForDraw() const override; + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + void init() override; + void draw() override; + + std::pair mWorldViewProjectionUniform; + std::pair mWorldUniform; + std::pair mWorldInverseTransposeUniform; + + std::pair mViewInverseUniform; + std::pair mLightWorldPosUniform; + std::pair mLightColorUniform; + std::pair mSpecularUniform; + std::pair mShininessUniform; + std::pair mSpecularFactorUniform; + + std::pair mAmbientUniform; + + std::pair mFogPowerUniform; + std::pair mFogMultUniform; + std::pair mFogOffsetUniform; + std::pair mFogColorUniform; + + std::pair mDiffuseTexture; + + std::pair mPositionBuffer; + std::pair mNormalBuffer; + std::pair mTexCoordBuffer; + + BufferGL *mIndicesBuffer; + + private: + const ContextGL *mContextGL; +}; + +#endif diff --git a/src/aquarium-optimized/opengl/ProgramGL.cpp b/src/aquarium-optimized/opengl/ProgramGL.cpp index fc32446..61fd6b3 100644 --- a/src/aquarium-optimized/opengl/ProgramGL.cpp +++ b/src/aquarium-optimized/opengl/ProgramGL.cpp @@ -1,99 +1,100 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// ProgramGL.cpp: Implement Program wrapper of OpenGL. -// Load shaders from folder shaders/opengl. -// Compiles OpenGL shaders and check if compiled success. -// Apply Buffers, Textures and Uniforms to program. - -#ifdef EGL_EGL_PROTOTYPES -#include -#include -#include "EGL/egl.h" -#include "EGL/eglext.h" -#include "EGL/eglext_angle.h" -#include "EGL/eglplatform.h" -#include "EGLWindow.h" -#else -#include "glad/glad.h" -#endif - -#include -#include -#include -#include -#include -#include - -#include "common/AQUARIUM_ASSERT.h" -#include "ProgramGL.h" - -#include "../Buffer.h" -#include "../Texture.h" - -ProgramGL::ProgramGL(ContextGL *context, std::string mVId, std::string mFId) - : Program(mVId, mFId), mProgramId(0u), mContext(context) -{ - mProgramId= context->generateProgram(); - mVAO = context->generateVAO(); -} - -ProgramGL::~ProgramGL() -{ - mContext->deleteVAO(mVAO); - mContext->deleteProgram(mProgramId); -} - -void ProgramGL::loadProgram() -{ - std::ifstream VertexShaderStream(mVId, std::ios::in); - std::string VertexShaderCode((std::istreambuf_iterator(VertexShaderStream)), - std::istreambuf_iterator()); - VertexShaderStream.close(); - - // Read the Fragment Shader code from the file - std::ifstream FragmentShaderStream(mFId, std::ios::in); - std::string FragmentShaderCode((std::istreambuf_iterator(FragmentShaderStream)), - std::istreambuf_iterator()); - FragmentShaderStream.close(); - - const std::string fogUniforms = - R"(uniform float fogPower; - uniform float fogMult; - uniform float fogOffset; - uniform vec4 fogColor;)"; - const std::string fogCode = - R"(outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), - clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0));)"; - -#ifdef __APPLE__ - VertexShaderCode = std::regex_replace(VertexShaderCode, std::regex(R"(#version 450 core)"), - R"(#version 410 core)"); - FragmentShaderCode = std::regex_replace(FragmentShaderCode, std::regex(R"(#version 450 core)"), - R"(#version 410 core)"); -#endif - - // enable fog, reflection and normalMaps - FragmentShaderCode = - std::regex_replace(FragmentShaderCode, std::regex(R"(// #fogUniforms)"), fogUniforms); - FragmentShaderCode = - std::regex_replace(FragmentShaderCode, std::regex(R"(// #fogCode)"), fogCode); - - FragmentShaderCode = - std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noReflection)"), ""); - FragmentShaderCode = - std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noNormalMap)"), ""); - - bool status = mContext->compileProgram(mProgramId, VertexShaderCode, FragmentShaderCode); - ASSERT(status); - if (!status) { - std::cout << "Error occurs in compiling program!" << std::endl; - } -} - -void ProgramGL::setProgram() -{ - mContext->setProgram(mProgramId); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramGL.cpp: Implement Program wrapper of OpenGL. +// Load shaders from folder shaders/opengl. +// Compiles OpenGL shaders and check if compiled success. +// Apply Buffers, Textures and Uniforms to program. + +#ifdef EGL_EGL_PROTOTYPES +#include +#include +#include "EGL/egl.h" +#include "EGL/eglext.h" +#include "EGL/eglext_angle.h" +#include "EGL/eglplatform.h" +#include "EGLWindow.h" +#else +#include "glad/glad.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "ProgramGL.h" +#include "common/AQUARIUM_ASSERT.h" + +#include "../Buffer.h" +#include "../Texture.h" + +ProgramGL::ProgramGL(ContextGL *context, std::string mVId, std::string mFId) + : Program(mVId, mFId), mProgramId(0u), mContext(context) +{ + mProgramId = context->generateProgram(); + mVAO = context->generateVAO(); +} + +ProgramGL::~ProgramGL() +{ + mContext->deleteVAO(mVAO); + mContext->deleteProgram(mProgramId); +} + +void ProgramGL::loadProgram() +{ + std::ifstream VertexShaderStream(mVId, std::ios::in); + std::string VertexShaderCode((std::istreambuf_iterator(VertexShaderStream)), + std::istreambuf_iterator()); + VertexShaderStream.close(); + + // Read the Fragment Shader code from the file + std::ifstream FragmentShaderStream(mFId, std::ios::in); + std::string FragmentShaderCode((std::istreambuf_iterator(FragmentShaderStream)), + std::istreambuf_iterator()); + FragmentShaderStream.close(); + + const std::string fogUniforms = + R"(uniform float fogPower; + uniform float fogMult; + uniform float fogOffset; + uniform vec4 fogColor;)"; + const std::string fogCode = + R"(outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0));)"; + +#ifdef __APPLE__ + VertexShaderCode = std::regex_replace(VertexShaderCode, std::regex(R"(#version 450 core)"), + R"(#version 410 core)"); + FragmentShaderCode = std::regex_replace(FragmentShaderCode, std::regex(R"(#version 450 core)"), + R"(#version 410 core)"); +#endif + + // enable fog, reflection and normalMaps + FragmentShaderCode = + std::regex_replace(FragmentShaderCode, std::regex(R"(// #fogUniforms)"), fogUniforms); + FragmentShaderCode = + std::regex_replace(FragmentShaderCode, std::regex(R"(// #fogCode)"), fogCode); + + FragmentShaderCode = + std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noReflection)"), ""); + FragmentShaderCode = + std::regex_replace(FragmentShaderCode, std::regex(R"(\n.*?// #noNormalMap)"), ""); + + bool status = mContext->compileProgram(mProgramId, VertexShaderCode, FragmentShaderCode); + ASSERT(status); + if (!status) + { + std::cout << "Error occurs in compiling program!" << std::endl; + } +} + +void ProgramGL::setProgram() +{ + mContext->setProgram(mProgramId); +} diff --git a/src/aquarium-optimized/opengl/ProgramGL.h b/src/aquarium-optimized/opengl/ProgramGL.h index 8446e7a..e1eb26a 100644 --- a/src/aquarium-optimized/opengl/ProgramGL.h +++ b/src/aquarium-optimized/opengl/ProgramGL.h @@ -1,45 +1,44 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// ProgramGL.h: Defines Program wrapper of OpenGL. -// Load shaders from folder shaders/opengl. -// Compiles OpenGL shaders and check if compiled success. -// Apply Buffers, Textures and Uniforms to program. - -#pragma once -#ifndef PROGRAMGL_H -#define PROGRAMGL_H 1 - -#include -#include - -#include "BufferGL.h" -#include "ContextGL.h" -#include "TextureGL.h" - -#include "../Aquarium.h" -#include "../Program.h" - -class ProgramGL : public Program -{ -public: - ProgramGL() {} - ProgramGL(ContextGL *, std::string mVId, std::string mFId); - ~ProgramGL() override; - - void setProgram() override; - GLuint getProgramId() const { return mProgramId; } - GLuint getVAOId() { return mVAO; } - void loadProgram(); - - private: - GLuint mProgramId; - GLuint mVAO; - - ContextGL *mContext; -}; - -#endif - +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramGL.h: Defines Program wrapper of OpenGL. +// Load shaders from folder shaders/opengl. +// Compiles OpenGL shaders and check if compiled success. +// Apply Buffers, Textures and Uniforms to program. + +#pragma once +#ifndef PROGRAMGL_H +#define PROGRAMGL_H 1 + +#include +#include + +#include "BufferGL.h" +#include "ContextGL.h" +#include "TextureGL.h" + +#include "../Aquarium.h" +#include "../Program.h" + +class ProgramGL : public Program +{ + public: + ProgramGL() {} + ProgramGL(ContextGL *, std::string mVId, std::string mFId); + ~ProgramGL() override; + + void setProgram() override; + GLuint getProgramId() const { return mProgramId; } + GLuint getVAOId() { return mVAO; } + void loadProgram(); + + private: + GLuint mProgramId; + GLuint mVAO; + + ContextGL *mContext; +}; + +#endif diff --git a/src/aquarium-optimized/opengl/SeaweedModelGL.cpp b/src/aquarium-optimized/opengl/SeaweedModelGL.cpp index 04aee55..1affef8 100644 --- a/src/aquarium-optimized/opengl/SeaweedModelGL.cpp +++ b/src/aquarium-optimized/opengl/SeaweedModelGL.cpp @@ -1,119 +1,119 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// SeaweedModelGL.cpp: Impplment seaweed model of OpenGL. - -#include "SeaweedModelGL.h" - -SeaweedModelGL::SeaweedModelGL(const ContextGL *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend) - : SeaweedModel(type, name, blend), mContextGL(context) -{ - mViewInverseUniform.first = aquarium->lightWorldPositionUniform.viewInverse; - mLightWorldPosUniform.first = aquarium->lightWorldPositionUniform.lightWorldPos; - mLightColorUniform.first = aquarium->lightUniforms.lightColor; - mSpecularUniform.first = aquarium->lightUniforms.specular; - mShininessUniform.first = 50.0f; - mSpecularFactorUniform.first = 1.0f; - mAmbientUniform.first = aquarium->lightUniforms.ambient; - mWorldUniform.first = aquarium->worldUniforms.world; - mFogPowerUniform.first = g_fogPower; - mFogMultUniform.first = g_fogMult; - mFogOffsetUniform.first = g_fogOffset; - mFogColorUniform.first = aquarium->fogUniforms.fogColor; - mViewProjectionUniform.first = aquarium->lightWorldPositionUniform.viewProjection; -} - -void SeaweedModelGL::init() -{ - ProgramGL *programGL = static_cast(mProgram); - mWorldUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "world"); - - mViewInverseUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "viewInverse"); - mLightWorldPosUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "lightWorldPos"); - mLightColorUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "lightColor"); - mSpecularUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "specular"); - mAmbientUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "ambient"); - mShininessUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "shininess"); - mSpecularFactorUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "specularFactor"); - - mFogPowerUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogPower"); - mFogMultUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogMult"); - mFogOffsetUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "fogOffset"); - mFogColorUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogColor"); - - mViewProjectionUniform.second = - mContextGL->getUniformLocation(programGL->getProgramId(), "viewProjection"); - mTimeUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "time"); - - mDiffuseTexture.first = static_cast(textureMap["diffuse"]); - mDiffuseTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "diffuse"); - - mPositionBuffer.first = static_cast(bufferMap["position"]); - mPositionBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "position"); - mNormalBuffer.first = static_cast(bufferMap["normal"]); - mNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "normal"); - mTexCoordBuffer.first = static_cast(bufferMap["texCoord"]); - mTexCoordBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "texCoord"); - - mIndicesBuffer = static_cast(bufferMap["indices"]); -} - -void SeaweedModelGL::draw() -{ - mContextGL->drawElements(*mIndicesBuffer); -} - -void SeaweedModelGL::prepareForDraw() const -{ - mProgram->setProgram(); - mContextGL->enableBlend(mBlend); - - ProgramGL *programGL = static_cast(mProgram); - mContextGL->bindVAO(programGL->getVAOId()); - - mContextGL->setAttribs(*mPositionBuffer.first, mPositionBuffer.second); - mContextGL->setAttribs(*mNormalBuffer.first, mNormalBuffer.second); - mContextGL->setAttribs(*mTexCoordBuffer.first, mTexCoordBuffer.second); - - mContextGL->setIndices(*mIndicesBuffer); - - mContextGL->setUniform(mViewInverseUniform.second, mViewInverseUniform.first, GL_FLOAT_MAT4); - mContextGL->setUniform(mLightWorldPosUniform.second, mLightWorldPosUniform.first, - GL_FLOAT_VEC3); - mContextGL->setUniform(mLightColorUniform.second, mLightColorUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mSpecularUniform.second, mSpecularUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mShininessUniform.second, &mShininessUniform.first, GL_FLOAT); - mContextGL->setUniform(mSpecularFactorUniform.second, &mSpecularFactorUniform.first, GL_FLOAT); - mContextGL->setUniform(mAmbientUniform.second, mAmbientUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mFogPowerUniform.second, &mFogPowerUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogMultUniform.second, &mFogMultUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogOffsetUniform.second, &mFogOffsetUniform.first, GL_FLOAT); - mContextGL->setUniform(mFogColorUniform.second, mFogColorUniform.first, GL_FLOAT_VEC4); - mContextGL->setUniform(mViewProjectionUniform.second, mViewProjectionUniform.first, - GL_FLOAT_MAT4); - - mContextGL->setTexture(*mDiffuseTexture.first, mDiffuseTexture.second, 0); -} - -void SeaweedModelGL::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) -{ - mContextGL->setUniform(mWorldUniform.second, mWorldUniform.first, GL_FLOAT_MAT4); - mContextGL->setUniform(mTimeUniform.second, &mTimeUniform.first, GL_FLOAT); -} - -void SeaweedModelGL::updateSeaweedModelTime(float time) -{ - mTimeUniform.first = time; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SeaweedModelGL.cpp: Impplment seaweed model of OpenGL. + +#include "SeaweedModelGL.h" + +SeaweedModelGL::SeaweedModelGL(const ContextGL *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend) + : SeaweedModel(type, name, blend), mContextGL(context) +{ + mViewInverseUniform.first = aquarium->lightWorldPositionUniform.viewInverse; + mLightWorldPosUniform.first = aquarium->lightWorldPositionUniform.lightWorldPos; + mLightColorUniform.first = aquarium->lightUniforms.lightColor; + mSpecularUniform.first = aquarium->lightUniforms.specular; + mShininessUniform.first = 50.0f; + mSpecularFactorUniform.first = 1.0f; + mAmbientUniform.first = aquarium->lightUniforms.ambient; + mWorldUniform.first = aquarium->worldUniforms.world; + mFogPowerUniform.first = g_fogPower; + mFogMultUniform.first = g_fogMult; + mFogOffsetUniform.first = g_fogOffset; + mFogColorUniform.first = aquarium->fogUniforms.fogColor; + mViewProjectionUniform.first = aquarium->lightWorldPositionUniform.viewProjection; +} + +void SeaweedModelGL::init() +{ + ProgramGL *programGL = static_cast(mProgram); + mWorldUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "world"); + + mViewInverseUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "viewInverse"); + mLightWorldPosUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "lightWorldPos"); + mLightColorUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "lightColor"); + mSpecularUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "specular"); + mAmbientUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "ambient"); + mShininessUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "shininess"); + mSpecularFactorUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "specularFactor"); + + mFogPowerUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogPower"); + mFogMultUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogMult"); + mFogOffsetUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "fogOffset"); + mFogColorUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "fogColor"); + + mViewProjectionUniform.second = + mContextGL->getUniformLocation(programGL->getProgramId(), "viewProjection"); + mTimeUniform.second = mContextGL->getUniformLocation(programGL->getProgramId(), "time"); + + mDiffuseTexture.first = static_cast(textureMap["diffuse"]); + mDiffuseTexture.second = mContextGL->getUniformLocation(programGL->getProgramId(), "diffuse"); + + mPositionBuffer.first = static_cast(bufferMap["position"]); + mPositionBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "position"); + mNormalBuffer.first = static_cast(bufferMap["normal"]); + mNormalBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "normal"); + mTexCoordBuffer.first = static_cast(bufferMap["texCoord"]); + mTexCoordBuffer.second = mContextGL->getAttribLocation(programGL->getProgramId(), "texCoord"); + + mIndicesBuffer = static_cast(bufferMap["indices"]); +} + +void SeaweedModelGL::draw() +{ + mContextGL->drawElements(*mIndicesBuffer); +} + +void SeaweedModelGL::prepareForDraw() const +{ + mProgram->setProgram(); + mContextGL->enableBlend(mBlend); + + ProgramGL *programGL = static_cast(mProgram); + mContextGL->bindVAO(programGL->getVAOId()); + + mContextGL->setAttribs(*mPositionBuffer.first, mPositionBuffer.second); + mContextGL->setAttribs(*mNormalBuffer.first, mNormalBuffer.second); + mContextGL->setAttribs(*mTexCoordBuffer.first, mTexCoordBuffer.second); + + mContextGL->setIndices(*mIndicesBuffer); + + mContextGL->setUniform(mViewInverseUniform.second, mViewInverseUniform.first, GL_FLOAT_MAT4); + mContextGL->setUniform(mLightWorldPosUniform.second, mLightWorldPosUniform.first, + GL_FLOAT_VEC3); + mContextGL->setUniform(mLightColorUniform.second, mLightColorUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mSpecularUniform.second, mSpecularUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mShininessUniform.second, &mShininessUniform.first, GL_FLOAT); + mContextGL->setUniform(mSpecularFactorUniform.second, &mSpecularFactorUniform.first, GL_FLOAT); + mContextGL->setUniform(mAmbientUniform.second, mAmbientUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mFogPowerUniform.second, &mFogPowerUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogMultUniform.second, &mFogMultUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogOffsetUniform.second, &mFogOffsetUniform.first, GL_FLOAT); + mContextGL->setUniform(mFogColorUniform.second, mFogColorUniform.first, GL_FLOAT_VEC4); + mContextGL->setUniform(mViewProjectionUniform.second, mViewProjectionUniform.first, + GL_FLOAT_MAT4); + + mContextGL->setTexture(*mDiffuseTexture.first, mDiffuseTexture.second, 0); +} + +void SeaweedModelGL::updatePerInstanceUniforms(const WorldUniforms &worldUniforms) +{ + mContextGL->setUniform(mWorldUniform.second, mWorldUniform.first, GL_FLOAT_MAT4); + mContextGL->setUniform(mTimeUniform.second, &mTimeUniform.first, GL_FLOAT); +} + +void SeaweedModelGL::updateSeaweedModelTime(float time) +{ + mTimeUniform.first = time; +} diff --git a/src/aquarium-optimized/opengl/SeaweedModelGL.h b/src/aquarium-optimized/opengl/SeaweedModelGL.h index a3751ef..d28d819 100644 --- a/src/aquarium-optimized/opengl/SeaweedModelGL.h +++ b/src/aquarium-optimized/opengl/SeaweedModelGL.h @@ -1,63 +1,63 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// SeaweedModelGL.h: Define seaweed model of OpeGL. - -#pragma once -#ifndef SEAWEEDMODELGL_H -#define SEAWEEDMODELGL_H 1 - -#include "ContextGL.h" -#include "ProgramGL.h" - -#include "../SeaweedModel.h" - -class SeaweedModelGL : public SeaweedModel -{ - public: - SeaweedModelGL(const ContextGL *context, - Aquarium *aquarium, - MODELGROUP type, - MODELNAME name, - bool blend); - void prepareForDraw() const override; - void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; - void init() override; - void draw() override; - - void updateSeaweedModelTime(float time) override; - - std::pair mWorldUniform; - - std::pair mViewInverseUniform; - std::pair mLightWorldPosUniform; - std::pair mLightColorUniform; - std::pair mSpecularUniform; - std::pair mShininessUniform; - std::pair mSpecularFactorUniform; - - std::pair mAmbientUniform; - - std::pair mFogPowerUniform; - std::pair mFogMultUniform; - std::pair mFogOffsetUniform; - std::pair mFogColorUniform; - - std::pair mViewProjectionUniform; - std::pair mTimeUniform; - - std::pair mDiffuseTexture; - - std::pair mPositionBuffer; - std::pair mNormalBuffer; - std::pair mTexCoordBuffer; - - BufferGL *mIndicesBuffer; - - private: - const ContextGL *mContextGL; -}; - -#endif // !SEAWEEDMODELGL_H +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SeaweedModelGL.h: Define seaweed model of OpeGL. + +#pragma once +#ifndef SEAWEEDMODELGL_H +#define SEAWEEDMODELGL_H 1 + +#include "ContextGL.h" +#include "ProgramGL.h" + +#include "../SeaweedModel.h" + +class SeaweedModelGL : public SeaweedModel +{ + public: + SeaweedModelGL(const ContextGL *context, + Aquarium *aquarium, + MODELGROUP type, + MODELNAME name, + bool blend); + void prepareForDraw() const override; + void updatePerInstanceUniforms(const WorldUniforms &worldUniforms) override; + void init() override; + void draw() override; + + void updateSeaweedModelTime(float time) override; + + std::pair mWorldUniform; + + std::pair mViewInverseUniform; + std::pair mLightWorldPosUniform; + std::pair mLightColorUniform; + std::pair mSpecularUniform; + std::pair mShininessUniform; + std::pair mSpecularFactorUniform; + + std::pair mAmbientUniform; + + std::pair mFogPowerUniform; + std::pair mFogMultUniform; + std::pair mFogOffsetUniform; + std::pair mFogColorUniform; + + std::pair mViewProjectionUniform; + std::pair mTimeUniform; + + std::pair mDiffuseTexture; + + std::pair mPositionBuffer; + std::pair mNormalBuffer; + std::pair mTexCoordBuffer; + + BufferGL *mIndicesBuffer; + + private: + const ContextGL *mContextGL; +}; + +#endif // !SEAWEEDMODELGL_H diff --git a/src/aquarium-optimized/opengl/TextureGL.cpp b/src/aquarium-optimized/opengl/TextureGL.cpp index ed8e92a..bb2fec2 100644 --- a/src/aquarium-optimized/opengl/TextureGL.cpp +++ b/src/aquarium-optimized/opengl/TextureGL.cpp @@ -1,71 +1,71 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// TextureGL.cpp. Wrap textures of OpenGL. Load image files and wrap into an OpenGL texture. - -#include "TextureGL.h" - -#include "common/AQUARIUM_ASSERT.h" - -// initializs texture 2d -TextureGL::TextureGL(ContextGL *context, std::string name, std::string url) - : Texture(name, url, true), mTarget(GL_TEXTURE_2D), mFormat(GL_RGBA), mContext(context) -{ - mTextureId = context->generateTexture(); -} - -// initializs cube map -TextureGL::TextureGL(ContextGL *context, std::string name, const std::vector &urls) - : Texture(name, urls, false), mTarget(GL_TEXTURE_CUBE_MAP), mFormat(GL_RGBA), mContext(context) -{ - ASSERT(urls.size() == 6); - mTextureId = context->generateTexture(); -} - -void TextureGL::loadTexture() -{ - mContext->bindTexture(mTarget, mTextureId); - - std::vector pixelVec; - loadImage(mUrls, &pixelVec); - - if (mTarget == GL_TEXTURE_CUBE_MAP) - { - for (unsigned int i = 0; i < 6; i++) - { - mContext->uploadTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, mFormat, mWidth, mHeight, - pixelVec[i]); - } - - mContext->setParameter(mTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - mContext->setParameter(mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - mContext->setParameter(mTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - mContext->setParameter(mTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - else // GL_TEXTURE_2D - { - mContext->uploadTexture(mTarget, mFormat, mWidth, mHeight, pixelVec[0]); - - if (isPowerOf2(mWidth) && isPowerOf2(mHeight)) - { - mContext->setParameter(mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - mContext->generateMipmap(mTarget); - } - else - { - mContext->setParameter(mTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - mContext->setParameter(mTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - mContext->setParameter(mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - mContext->setParameter(mTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - - DestoryImageData(pixelVec); -} - -TextureGL::~TextureGL() -{ - mContext->deleteTexture(mTextureId); -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TextureGL.cpp. Wrap textures of OpenGL. Load image files and wrap into an OpenGL texture. + +#include "TextureGL.h" + +#include "common/AQUARIUM_ASSERT.h" + +// initializs texture 2d +TextureGL::TextureGL(ContextGL *context, std::string name, std::string url) + : Texture(name, url, true), mTarget(GL_TEXTURE_2D), mFormat(GL_RGBA), mContext(context) +{ + mTextureId = context->generateTexture(); +} + +// initializs cube map +TextureGL::TextureGL(ContextGL *context, std::string name, const std::vector &urls) + : Texture(name, urls, false), mTarget(GL_TEXTURE_CUBE_MAP), mFormat(GL_RGBA), mContext(context) +{ + ASSERT(urls.size() == 6); + mTextureId = context->generateTexture(); +} + +void TextureGL::loadTexture() +{ + mContext->bindTexture(mTarget, mTextureId); + + std::vector pixelVec; + loadImage(mUrls, &pixelVec); + + if (mTarget == GL_TEXTURE_CUBE_MAP) + { + for (unsigned int i = 0; i < 6; i++) + { + mContext->uploadTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, mFormat, mWidth, mHeight, + pixelVec[i]); + } + + mContext->setParameter(mTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + mContext->setParameter(mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + mContext->setParameter(mTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + mContext->setParameter(mTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + else // GL_TEXTURE_2D + { + mContext->uploadTexture(mTarget, mFormat, mWidth, mHeight, pixelVec[0]); + + if (isPowerOf2(mWidth) && isPowerOf2(mHeight)) + { + mContext->setParameter(mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + mContext->generateMipmap(mTarget); + } + else + { + mContext->setParameter(mTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + mContext->setParameter(mTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + mContext->setParameter(mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + mContext->setParameter(mTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + DestoryImageData(pixelVec); +} + +TextureGL::~TextureGL() +{ + mContext->deleteTexture(mTextureId); +} diff --git a/src/aquarium-optimized/opengl/TextureGL.h b/src/aquarium-optimized/opengl/TextureGL.h index 4a13b7d..6f3337c 100644 --- a/src/aquarium-optimized/opengl/TextureGL.h +++ b/src/aquarium-optimized/opengl/TextureGL.h @@ -1,55 +1,54 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// TextureGL.h: Define Texture wrapper class of OpenGL. - -#pragma once -#ifndef TEXTUREGL_H -#define TEXTUREGL_H 1 - -#include -#include -#include - -#ifdef EGL_EGL_PROTOTYPES -#include -#include -#include "EGL/egl.h" -#include "EGL/eglext.h" -#include "EGL/eglext_angle.h" -#include "EGL/eglplatform.h" -#include "EGLWindow.h" -#else -#include "glad/glad.h" -#endif - -#include "ContextGL.h" - -#include "../Texture.h" - -class ContextGL; - -class TextureGL : public Texture -{ - public: - ~TextureGL() override; - TextureGL(ContextGL *context, std::string name, std::string url); - TextureGL(ContextGL *context, std::string name, const std::vector &urls); - - unsigned int getTextureId() const { return mTextureId; } - unsigned int getTarget() const { return mTarget; } - void setTextureId(unsigned int texId) { mTextureId = texId; } - - void loadTexture() override; - - private: - - unsigned int mTarget; - unsigned int mTextureId; - unsigned int mFormat; - ContextGL *mContext; -}; - -#endif // !TEXTUREGL_H +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TextureGL.h: Define Texture wrapper class of OpenGL. + +#pragma once +#ifndef TEXTUREGL_H +#define TEXTUREGL_H 1 + +#include +#include +#include + +#ifdef EGL_EGL_PROTOTYPES +#include +#include +#include "EGL/egl.h" +#include "EGL/eglext.h" +#include "EGL/eglext_angle.h" +#include "EGL/eglplatform.h" +#include "EGLWindow.h" +#else +#include "glad/glad.h" +#endif + +#include "ContextGL.h" + +#include "../Texture.h" + +class ContextGL; + +class TextureGL : public Texture +{ + public: + ~TextureGL() override; + TextureGL(ContextGL *context, std::string name, std::string url); + TextureGL(ContextGL *context, std::string name, const std::vector &urls); + + unsigned int getTextureId() const { return mTextureId; } + unsigned int getTarget() const { return mTarget; } + void setTextureId(unsigned int texId) { mTextureId = texId; } + + void loadTexture() override; + + private: + unsigned int mTarget; + unsigned int mTextureId; + unsigned int mFormat; + ContextGL *mContext; +}; + +#endif // !TEXTUREGL_H diff --git a/src/aquarium-optimized/opengl/imgui_impl_opengl3.cpp b/src/aquarium-optimized/opengl/imgui_impl_opengl3.cpp index ba6a5fa..ee96ca8 100644 --- a/src/aquarium-optimized/opengl/imgui_impl_opengl3.cpp +++ b/src/aquarium-optimized/opengl/imgui_impl_opengl3.cpp @@ -1,732 +1,732 @@ -// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline -// - Desktop GL: 3.x 4.x -// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) -// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) - -// Implemented features: -// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. -// Read the FAQ about ImTextureID in imgui.cpp. [x] Renderer: Desktop GL only: Support for large -// meshes (64k+ vertices) with 16-bits indices. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example -// of using this. If you are new to dear imgui, read examples/README.txt and read the documentation -// at the top of imgui.cpp. https://github.com/ocornut/imgui - -// CHANGELOG -// (minor and older changes stripped away, please see git history for details) -// 2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable -// ImGuiBackendFlags_RendererHasVtxOffset flag. 2019-04-30: OpenGL: Added support for special -// ImDrawCallback_ResetRenderState callback to reset render state. 2019-03-29: OpenGL: Not calling -// glBindBuffer more than necessary in the render loop. 2019-03-15: OpenGL: Added a dummy GL call + -// comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early. -// 2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0). -// 2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN -// even if defined by the headers/loader. 2019-02-11: OpenGL: Projecting clipping rectangles -// correctly using draw_data->FramebufferScale to allow multi-viewports for retina display. -// 2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450). -// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. -// 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN. -// 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments -// indicative that any loader can be used. 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and -// Android. GLSL version default to "#version 300 ES". 2018-07-30: OpenGL: Support for GLSL 300 ES -// and 410 core. Fixes for Emscripten compilation. 2018-07-10: OpenGL: Support for more GLSL -// versions (based on the GLSL version string). Added error output when shaders fail to -// compile/link. 2018-06-08: Misc: Extracted imgui_impl_opengl3.cpp/.h away from the old combined -// GLFW/SDL+OpenGL3 examples. 2018-06-08: OpenGL: Use draw_data->DisplayPos and -// draw_data->DisplaySize to setup projection matrix and clipping rectangle. 2018-05-25: OpenGL: -// Removed unnecessary backup/restore of GL_ELEMENT_ARRAY_BUFFER_BINDING since this is part of the -// VAO state. 2018-05-14: OpenGL: Making the call to glBindSampler() optional so 3.2 context won't -// fail if the function is a NULL pointer. 2018-03-06: OpenGL: Added const char* glsl_version -// parameter to ImGui_ImplOpenGL3_Init() so user can override the GLSL version e.g. "#version 150". -// 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used -// with multiple shared GL context. 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback -// and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself. -// 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150. -// 2017-09-01: OpenGL: Save and restore current bound sampler. Save and restore current polygon -// mode. 2017-05-01: OpenGL: Fixed save and restore of current blend func state. 2017-05-01: -// OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE. 2016-09-05: OpenGL: Fixed save and -// restore of current scissor rectangle. 2016-07-29: OpenGL: Explicitly setting -// GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) - -//---------------------------------------- -// OpenGL GLSL GLSL -// version version string -//---------------------------------------- -// 2.0 110 "#version 110" -// 2.1 120 "#version 120" -// 3.0 130 "#version 130" -// 3.1 140 "#version 140" -// 3.2 150 "#version 150" -// 3.3 330 "#version 330 core" -// 4.0 400 "#version 400 core" -// 4.1 410 "#version 410 core" -// 4.2 420 "#version 410 core" -// 4.3 430 "#version 430 core" -// ES 2.0 100 "#version 100" = WebGL 1.0 -// ES 3.0 300 "#version 300 es" = WebGL 2.0 -//---------------------------------------- - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) -#define _CRT_SECURE_NO_WARNINGS -#endif - -#include "imgui_impl_opengl3.h" -#include -#include "imgui.h" -#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier -#include // intptr_t -#else -#include // intptr_t -#endif -#if defined(__APPLE__) -#include "TargetConditionals.h" -#endif - -// Auto-detect GL version -#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) -#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__)) -#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es" -#elif defined(__EMSCRIPTEN__) -#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100" -#endif -#endif - -#if defined(IMGUI_IMPL_OPENGL_ES2) -#include -#elif defined(IMGUI_IMPL_OPENGL_ES3) -#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) -#include // Use GL ES 3 -#else -#include // Use GL ES 3 -#endif -#else -// About Desktop OpenGL function loaders: -// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function -// pointers. Helper libraries are often used for this purpose! Here we are supporting a few common -// ones (gl3w, glew, glad). You may use another loader/header of your choice (glext, glLoadGen, -// etc.), or chose to manually implement your own. -#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) -#include // Needs to be initialized with gl3wInit() in user's code -#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) -#include // Needs to be initialized with glewInit() in user's code -#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) -#include // Needs to be initialized with gladLoadGL() in user's code -#else -#include -#include "EGL/egl.h" -#include "EGL/eglext.h" -#include "EGL/eglext_angle.h" -#include "EGL/eglplatform.h" -#include "GLES3/gl32.h" -#endif -#endif - -// Desktop GL has glDrawElementsBaseVertex() which GL ES and WebGL don't have. -#if defined(IMGUI_IMPL_OPENGL_ES2) || defined(IMGUI_IMPL_OPENGL_ES3) -#define IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX 0 -#else -#define IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX 1 -#endif - -// OpenGL Data -static char g_GlslVersionString[32] = ""; -static GLuint g_FontTexture = 0; -static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; -static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location -static int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, - g_AttribLocationVtxColor = 0; // Vertex attributes location -static unsigned int g_VboHandle = 0, g_ElementsHandle = 0; - -// Functions -bool ImGui_ImplOpenGL3_Init(const char *glsl_version) -{ - // Setup back-end capabilities flags - ImGuiIO &io = ImGui::GetIO(); - io.BackendRendererName = "imgui_impl_opengl3"; -#if IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX - io.BackendFlags |= - ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, - // allowing for large meshes. -#endif - - // Store GLSL version string so we can refer to it later in case we recreate shaders. Note: GLSL - // version is NOT the same as GL version. Leave this to NULL if unsure. -#if defined(IMGUI_IMPL_OPENGL_ES2) - if (glsl_version == NULL) - glsl_version = "#version 100"; -#elif defined(IMGUI_IMPL_OPENGL_ES3) - if (glsl_version == NULL) - glsl_version = "#version 300 es"; -#else - if (glsl_version == NULL) - glsl_version = "#version 130"; -#endif - IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString)); - strcpy(g_GlslVersionString, glsl_version); - strcat(g_GlslVersionString, "\n"); - - // Make a dummy GL call (we don't actually need the result) - // IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function - // loader used by this code. Desktop OpenGL 3/4 need a function loader. See the - // IMGUI_IMPL_OPENGL_LOADER_xxx explanation above. - GLint current_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); - - return true; -} - -void ImGui_ImplOpenGL3_Shutdown() -{ - ImGui_ImplOpenGL3_DestroyDeviceObjects(); -} - -void ImGui_ImplOpenGL3_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplOpenGL3_CreateDeviceObjects(); -} - -static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData *draw_data, - int fb_width, - int fb_height, - GLuint vertex_array_object) -{ - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor - // enabled, polygon fill - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); -#ifdef GL_POLYGON_MODE - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -#endif - - // Setup viewport, orthographic projection matrix - // Our visible imgui space lies from draw_data->DisplayPos (top left) to - // draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single - // viewport apps. - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - float L = draw_data->DisplayPos.x; - float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; - float T = draw_data->DisplayPos.y; - float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; - const float ortho_projection[4][4] = { - {2.0f / (R - L), 0.0f, 0.0f, 0.0f}, - {0.0f, 2.0f / (T - B), 0.0f, 0.0f}, - {0.0f, 0.0f, -1.0f, 0.0f}, - {(R + L) / (L - R), (T + B) / (B - T), 0.0f, 1.0f}, - }; - glUseProgram(g_ShaderHandle); - glUniform1i(g_AttribLocationTex, 0); - glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); -#ifdef GL_SAMPLER_BINDING - glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may - // set that otherwise. -#endif - - (void)vertex_array_object; -#ifndef IMGUI_IMPL_OPENGL_ES2 - glBindVertexArray(vertex_array_object); -#endif - - // Bind vertex/index buffers and setup attributes for ImDrawVert - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); - glEnableVertexAttribArray(g_AttribLocationVtxPos); - glEnableVertexAttribArray(g_AttribLocationVtxUV); - glEnableVertexAttribArray(g_AttribLocationVtxColor); - glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), - (GLvoid *)IM_OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), - (GLvoid *)IM_OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, - sizeof(ImDrawVert), (GLvoid *)IM_OFFSETOF(ImDrawVert, col)); -} - -// OpenGL3 Render function. -// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call -// this directly from your main loop) Note that this implementation is little overcomplicated -// because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to -// run within any OpenGL engine that doesn't do so. -void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != - // framebuffer coordinates) - int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); - int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); - if (fb_width <= 0 || fb_height <= 0) - return; - - // Backup GL state - GLenum last_active_texture; - glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&last_active_texture); - glActiveTexture(GL_TEXTURE0); - GLint last_program; - glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); -#ifdef GL_SAMPLER_BINDING - GLint last_sampler; - glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); -#endif - GLint last_array_buffer; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); -#ifndef IMGUI_IMPL_OPENGL_ES2 - GLint last_vertex_array_object; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object); -#endif -#ifdef GL_POLYGON_MODE - GLint last_polygon_mode[2]; - glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); -#endif - GLint last_viewport[4]; - glGetIntegerv(GL_VIEWPORT, last_viewport); - GLint last_scissor_box[4]; - glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); - GLenum last_blend_src_rgb; - glGetIntegerv(GL_BLEND_SRC_RGB, (GLint *)&last_blend_src_rgb); - GLenum last_blend_dst_rgb; - glGetIntegerv(GL_BLEND_DST_RGB, (GLint *)&last_blend_dst_rgb); - GLenum last_blend_src_alpha; - glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint *)&last_blend_src_alpha); - GLenum last_blend_dst_alpha; - glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint *)&last_blend_dst_alpha); - GLenum last_blend_equation_rgb; - glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint *)&last_blend_equation_rgb); - GLenum last_blend_equation_alpha; - glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint *)&last_blend_equation_alpha); - GLboolean last_enable_blend = glIsEnabled(GL_BLEND); - GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); - GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); - GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - bool clip_origin_lower_left = true; -#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) - GLenum last_clip_origin = 0; - glGetIntegerv(GL_CLIP_ORIGIN, - (GLint *)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) - if (last_clip_origin == GL_UPPER_LEFT) - clip_origin_lower_left = false; -#endif - - // Setup desired GL state - // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. - // VAO are not shared among GL contexts) The renderer would actually work without any VAO bound, - // but then our VertexAttrib calls would overwrite the default one currently bound. - GLuint vertex_array_object = 0; -#ifndef IMGUI_IMPL_OPENGL_ES2 - glGenVertexArrays(1, &vertex_array_object); -#endif - ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); - - // Will project scissor/clipping rectangles into framebuffer space - ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports - ImVec2 clip_scale = - draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) - - // Render command lists - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList *cmd_list = draw_data->CmdLists[n]; - - // Upload vertex/index buffers - glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), - (const GLvoid *)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), - (const GLvoid *)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) - { - const ImDrawCmd *pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback != NULL) - { - // User callback, registered via ImDrawList::AddCallback() - // (ImDrawCallback_ResetRenderState is a special callback value used by the user to - // request the renderer to reset render state.) - if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) - ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, - vertex_array_object); - else - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - // Project scissor/clipping rectangles into framebuffer space - ImVec4 clip_rect; - clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x; - clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y; - clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x; - clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y; - - if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && - clip_rect.w >= 0.0f) - { - // Apply scissor/clipping rectangle - if (clip_origin_lower_left) - glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), - (int)(clip_rect.z - clip_rect.x), - (int)(clip_rect.w - clip_rect.y)); - else - glScissor( - (int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, - (int)clip_rect - .w); // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) - - // Bind texture, Draw - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); -#if IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX - glDrawElementsBaseVertex( - GL_TRIANGLES, (GLsizei)pcmd->ElemCount, - sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, - (void *)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), - (GLint)pcmd->VtxOffset); -#else - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, - sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, - (void *)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))); -#endif - } - } - } - } - - // Destroy the temporary VAO -#ifndef IMGUI_IMPL_OPENGL_ES2 - glDeleteVertexArrays(1, &vertex_array_object); -#endif - - // Restore modified GL state - glUseProgram(last_program); - glBindTexture(GL_TEXTURE_2D, last_texture); -#ifdef GL_SAMPLER_BINDING - glBindSampler(0, last_sampler); -#endif - glActiveTexture(last_active_texture); -#ifndef IMGUI_IMPL_OPENGL_ES2 - glBindVertexArray(last_vertex_array_object); -#endif - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); - glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); - glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, - last_blend_dst_alpha); - if (last_enable_blend) - glEnable(GL_BLEND); - else - glDisable(GL_BLEND); - if (last_enable_cull_face) - glEnable(GL_CULL_FACE); - else - glDisable(GL_CULL_FACE); - if (last_enable_depth_test) - glEnable(GL_DEPTH_TEST); - else - glDisable(GL_DEPTH_TEST); - if (last_enable_scissor_test) - glEnable(GL_SCISSOR_TEST); - else - glDisable(GL_SCISSOR_TEST); -#ifdef GL_POLYGON_MODE - glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); -#endif - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], - (GLsizei)last_viewport[3]); - glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], - (GLsizei)last_scissor_box[3]); -} - -bool ImGui_ImplOpenGL3_CreateFontsTexture() -{ - // Build texture atlas - ImGuiIO &io = ImGui::GetIO(); - unsigned char *pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32( - &pixels, &width, - &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so - // small) because it is more likely to be compatible with user's existing - // shaders. If your ImTextureId represent a higher-level concept than just a GL - // texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU - // memory. - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -#ifdef GL_UNPACK_ROW_LENGTH - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); -#endif - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplOpenGL3_DestroyFontsTexture() -{ - if (g_FontTexture) - { - ImGuiIO &io = ImGui::GetIO(); - glDeleteTextures(1, &g_FontTexture); - io.Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -// If you get an error please report on github. You may try different GL context version or GLSL -// version. See GL<>GLSL version table at the top of this file. -static bool CheckShader(GLuint handle, const char *desc) -{ - GLint status = 0, log_length = 0; - glGetShaderiv(handle, GL_COMPILE_STATUS, &status); - glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); - if ((GLboolean)status == GL_FALSE) - fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", - desc); - if (log_length > 1) - { - ImVector buf; - buf.resize((int)(log_length + 1)); - glGetShaderInfoLog(handle, log_length, NULL, (GLchar *)buf.begin()); - fprintf(stderr, "%s\n", buf.begin()); - } - return (GLboolean)status == GL_TRUE; -} - -// If you get an error please report on GitHub. You may try different GL context version or GLSL -// version. -static bool CheckProgram(GLuint handle, const char *desc) -{ - GLint status = 0, log_length = 0; - glGetProgramiv(handle, GL_LINK_STATUS, &status); - glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); - if ((GLboolean)status == GL_FALSE) - fprintf( - stderr, - "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! (with GLSL '%s')\n", - desc, g_GlslVersionString); - if (log_length > 1) - { - ImVector buf; - buf.resize((int)(log_length + 1)); - glGetProgramInfoLog(handle, log_length, NULL, (GLchar *)buf.begin()); - fprintf(stderr, "%s\n", buf.begin()); - } - return (GLboolean)status == GL_TRUE; -} - -bool ImGui_ImplOpenGL3_CreateDeviceObjects() -{ - // Backup GL state - GLint last_texture, last_array_buffer; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); -#ifndef IMGUI_IMPL_OPENGL_ES2 - GLint last_vertex_array; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); -#endif - - // Parse GLSL version string - int glsl_version = 130; - sscanf(g_GlslVersionString, "#version %d", &glsl_version); - - const GLchar *vertex_shader_glsl_120 = - "uniform mat4 ProjMtx;\n" - "attribute vec2 Position;\n" - "attribute vec2 UV;\n" - "attribute vec4 Color;\n" - "varying vec2 Frag_UV;\n" - "varying vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; - - const GLchar *vertex_shader_glsl_130 = - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 UV;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; - - const GLchar *vertex_shader_glsl_300_es = - "precision mediump float;\n" - "layout (location = 0) in vec2 Position;\n" - "layout (location = 1) in vec2 UV;\n" - "layout (location = 2) in vec4 Color;\n" - "uniform mat4 ProjMtx;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; - - const GLchar *vertex_shader_glsl_410_core = - "layout (location = 0) in vec2 Position;\n" - "layout (location = 1) in vec2 UV;\n" - "layout (location = 2) in vec4 Color;\n" - "uniform mat4 ProjMtx;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; - - const GLchar *fragment_shader_glsl_120 = - "#ifdef GL_ES\n" - " precision mediump float;\n" - "#endif\n" - "uniform sampler2D Texture;\n" - "varying vec2 Frag_UV;\n" - "varying vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n" - "}\n"; - - const GLchar *fragment_shader_glsl_130 = - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - const GLchar *fragment_shader_glsl_300_es = - "precision mediump float;\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "layout (location = 0) out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - const GLchar *fragment_shader_glsl_410_core = - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "uniform sampler2D Texture;\n" - "layout (location = 0) out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - // Select shaders matching our GLSL versions - const GLchar *vertex_shader = NULL; - const GLchar *fragment_shader = NULL; - if (glsl_version < 130) - { - vertex_shader = vertex_shader_glsl_120; - fragment_shader = fragment_shader_glsl_120; - } - else if (glsl_version >= 410) - { - vertex_shader = vertex_shader_glsl_410_core; - fragment_shader = fragment_shader_glsl_410_core; - } - else if (glsl_version == 300) - { - vertex_shader = vertex_shader_glsl_300_es; - fragment_shader = fragment_shader_glsl_300_es; - } - else - { - vertex_shader = vertex_shader_glsl_130; - fragment_shader = fragment_shader_glsl_130; - } - - // Create shaders - const GLchar *vertex_shader_with_version[2] = {g_GlslVersionString, vertex_shader}; - g_VertHandle = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL); - glCompileShader(g_VertHandle); - CheckShader(g_VertHandle, "vertex shader"); - - const GLchar *fragment_shader_with_version[2] = {g_GlslVersionString, fragment_shader}; - g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL); - glCompileShader(g_FragHandle); - CheckShader(g_FragHandle, "fragment shader"); - - g_ShaderHandle = glCreateProgram(); - glAttachShader(g_ShaderHandle, g_VertHandle); - glAttachShader(g_ShaderHandle, g_FragHandle); - glLinkProgram(g_ShaderHandle); - CheckProgram(g_ShaderHandle, "shader program"); - - g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); - g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); - g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position"); - g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV"); - g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color"); - - // Create buffers - glGenBuffers(1, &g_VboHandle); - glGenBuffers(1, &g_ElementsHandle); - - ImGui_ImplOpenGL3_CreateFontsTexture(); - - // Restore modified GL state - glBindTexture(GL_TEXTURE_2D, last_texture); - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); -#ifndef IMGUI_IMPL_OPENGL_ES2 - glBindVertexArray(last_vertex_array); -#endif - - return true; -} - -void ImGui_ImplOpenGL3_DestroyDeviceObjects() -{ - if (g_VboHandle) - glDeleteBuffers(1, &g_VboHandle); - if (g_ElementsHandle) - glDeleteBuffers(1, &g_ElementsHandle); - g_VboHandle = g_ElementsHandle = 0; - - if (g_ShaderHandle && g_VertHandle) - glDetachShader(g_ShaderHandle, g_VertHandle); - if (g_VertHandle) - glDeleteShader(g_VertHandle); - g_VertHandle = 0; - - if (g_ShaderHandle && g_FragHandle) - glDetachShader(g_ShaderHandle, g_FragHandle); - if (g_FragHandle) - glDeleteShader(g_FragHandle); - g_FragHandle = 0; - - if (g_ShaderHandle) - glDeleteProgram(g_ShaderHandle); - g_ShaderHandle = 0; - - ImGui_ImplOpenGL3_DestroyFontsTexture(); -} +// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline +// - Desktop GL: 3.x 4.x +// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) +// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. +// Read the FAQ about ImTextureID in imgui.cpp. [x] Renderer: Desktop GL only: Support for large +// meshes (64k+ vertices) with 16-bits indices. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example +// of using this. If you are new to dear imgui, read examples/README.txt and read the documentation +// at the top of imgui.cpp. https://github.com/ocornut/imgui + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable +// ImGuiBackendFlags_RendererHasVtxOffset flag. 2019-04-30: OpenGL: Added support for special +// ImDrawCallback_ResetRenderState callback to reset render state. 2019-03-29: OpenGL: Not calling +// glBindBuffer more than necessary in the render loop. 2019-03-15: OpenGL: Added a dummy GL call + +// comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early. +// 2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0). +// 2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN +// even if defined by the headers/loader. 2019-02-11: OpenGL: Projecting clipping rectangles +// correctly using draw_data->FramebufferScale to allow multi-viewports for retina display. +// 2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450). +// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. +// 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN. +// 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments +// indicative that any loader can be used. 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and +// Android. GLSL version default to "#version 300 ES". 2018-07-30: OpenGL: Support for GLSL 300 ES +// and 410 core. Fixes for Emscripten compilation. 2018-07-10: OpenGL: Support for more GLSL +// versions (based on the GLSL version string). Added error output when shaders fail to +// compile/link. 2018-06-08: Misc: Extracted imgui_impl_opengl3.cpp/.h away from the old combined +// GLFW/SDL+OpenGL3 examples. 2018-06-08: OpenGL: Use draw_data->DisplayPos and +// draw_data->DisplaySize to setup projection matrix and clipping rectangle. 2018-05-25: OpenGL: +// Removed unnecessary backup/restore of GL_ELEMENT_ARRAY_BUFFER_BINDING since this is part of the +// VAO state. 2018-05-14: OpenGL: Making the call to glBindSampler() optional so 3.2 context won't +// fail if the function is a NULL pointer. 2018-03-06: OpenGL: Added const char* glsl_version +// parameter to ImGui_ImplOpenGL3_Init() so user can override the GLSL version e.g. "#version 150". +// 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used +// with multiple shared GL context. 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback +// and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself. +// 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150. +// 2017-09-01: OpenGL: Save and restore current bound sampler. Save and restore current polygon +// mode. 2017-05-01: OpenGL: Fixed save and restore of current blend func state. 2017-05-01: +// OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE. 2016-09-05: OpenGL: Fixed save and +// restore of current scissor rectangle. 2016-07-29: OpenGL: Explicitly setting +// GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) + +//---------------------------------------- +// OpenGL GLSL GLSL +// version version string +//---------------------------------------- +// 2.0 110 "#version 110" +// 2.1 120 "#version 120" +// 3.0 130 "#version 130" +// 3.1 140 "#version 140" +// 3.2 150 "#version 150" +// 3.3 330 "#version 330 core" +// 4.0 400 "#version 400 core" +// 4.1 410 "#version 410 core" +// 4.2 420 "#version 410 core" +// 4.3 430 "#version 430 core" +// ES 2.0 100 "#version 100" = WebGL 1.0 +// ES 3.0 300 "#version 300 es" = WebGL 2.0 +//---------------------------------------- + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "imgui_impl_opengl3.h" +#include +#include "imgui.h" +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif +#if defined(__APPLE__) +#include "TargetConditionals.h" +#endif + +// Auto-detect GL version +#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) +#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__)) +#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es" +#elif defined(__EMSCRIPTEN__) +#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100" +#endif +#endif + +#if defined(IMGUI_IMPL_OPENGL_ES2) +#include +#elif defined(IMGUI_IMPL_OPENGL_ES3) +#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) +#include // Use GL ES 3 +#else +#include // Use GL ES 3 +#endif +#else +// About Desktop OpenGL function loaders: +// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function +// pointers. Helper libraries are often used for this purpose! Here we are supporting a few common +// ones (gl3w, glew, glad). You may use another loader/header of your choice (glext, glLoadGen, +// etc.), or chose to manually implement your own. +#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) +#include // Needs to be initialized with gl3wInit() in user's code +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) +#include // Needs to be initialized with glewInit() in user's code +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) +#include // Needs to be initialized with gladLoadGL() in user's code +#else +#include +#include "EGL/egl.h" +#include "EGL/eglext.h" +#include "EGL/eglext_angle.h" +#include "EGL/eglplatform.h" +#include "GLES3/gl32.h" +#endif +#endif + +// Desktop GL has glDrawElementsBaseVertex() which GL ES and WebGL don't have. +#if defined(IMGUI_IMPL_OPENGL_ES2) || defined(IMGUI_IMPL_OPENGL_ES3) +#define IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX 0 +#else +#define IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX 1 +#endif + +// OpenGL Data +static char g_GlslVersionString[32] = ""; +static GLuint g_FontTexture = 0; +static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location +static int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, + g_AttribLocationVtxColor = 0; // Vertex attributes location +static unsigned int g_VboHandle = 0, g_ElementsHandle = 0; + +// Functions +bool ImGui_ImplOpenGL3_Init(const char *glsl_version) +{ + // Setup back-end capabilities flags + ImGuiIO &io = ImGui::GetIO(); + io.BackendRendererName = "imgui_impl_opengl3"; +#if IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX + io.BackendFlags |= + ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, + // allowing for large meshes. +#endif + + // Store GLSL version string so we can refer to it later in case we recreate shaders. Note: GLSL + // version is NOT the same as GL version. Leave this to NULL if unsure. +#if defined(IMGUI_IMPL_OPENGL_ES2) + if (glsl_version == NULL) + glsl_version = "#version 100"; +#elif defined(IMGUI_IMPL_OPENGL_ES3) + if (glsl_version == NULL) + glsl_version = "#version 300 es"; +#else + if (glsl_version == NULL) + glsl_version = "#version 130"; +#endif + IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString)); + strcpy(g_GlslVersionString, glsl_version); + strcat(g_GlslVersionString, "\n"); + + // Make a dummy GL call (we don't actually need the result) + // IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function + // loader used by this code. Desktop OpenGL 3/4 need a function loader. See the + // IMGUI_IMPL_OPENGL_LOADER_xxx explanation above. + GLint current_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); + + return true; +} + +void ImGui_ImplOpenGL3_Shutdown() +{ + ImGui_ImplOpenGL3_DestroyDeviceObjects(); +} + +void ImGui_ImplOpenGL3_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplOpenGL3_CreateDeviceObjects(); +} + +static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData *draw_data, + int fb_width, + int fb_height, + GLuint vertex_array_object) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor + // enabled, polygon fill + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); +#ifdef GL_POLYGON_MODE + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif + + // Setup viewport, orthographic projection matrix + // Our visible imgui space lies from draw_data->DisplayPos (top left) to + // draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single + // viewport apps. + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + float L = draw_data->DisplayPos.x; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; + float T = draw_data->DisplayPos.y; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; + const float ortho_projection[4][4] = { + {2.0f / (R - L), 0.0f, 0.0f, 0.0f}, + {0.0f, 2.0f / (T - B), 0.0f, 0.0f}, + {0.0f, 0.0f, -1.0f, 0.0f}, + {(R + L) / (L - R), (T + B) / (B - T), 0.0f, 1.0f}, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); +#ifdef GL_SAMPLER_BINDING + glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may + // set that otherwise. +#endif + + (void)vertex_array_object; +#ifndef IMGUI_IMPL_OPENGL_ES2 + glBindVertexArray(vertex_array_object); +#endif + + // Bind vertex/index buffers and setup attributes for ImDrawVert + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); + glEnableVertexAttribArray(g_AttribLocationVtxPos); + glEnableVertexAttribArray(g_AttribLocationVtxUV); + glEnableVertexAttribArray(g_AttribLocationVtxColor); + glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), + (GLvoid *)IM_OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), + (GLvoid *)IM_OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, + sizeof(ImDrawVert), (GLvoid *)IM_OFFSETOF(ImDrawVert, col)); +} + +// OpenGL3 Render function. +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call +// this directly from your main loop) Note that this implementation is little overcomplicated +// because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to +// run within any OpenGL engine that doesn't do so. +void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != + // framebuffer coordinates) + int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + if (fb_width <= 0 || fb_height <= 0) + return; + + // Backup GL state + GLenum last_active_texture; + glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&last_active_texture); + glActiveTexture(GL_TEXTURE0); + GLint last_program; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); +#ifdef GL_SAMPLER_BINDING + GLint last_sampler; + glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); +#endif + GLint last_array_buffer; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); +#ifndef IMGUI_IMPL_OPENGL_ES2 + GLint last_vertex_array_object; + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object); +#endif +#ifdef GL_POLYGON_MODE + GLint last_polygon_mode[2]; + glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); +#endif + GLint last_viewport[4]; + glGetIntegerv(GL_VIEWPORT, last_viewport); + GLint last_scissor_box[4]; + glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); + GLenum last_blend_src_rgb; + glGetIntegerv(GL_BLEND_SRC_RGB, (GLint *)&last_blend_src_rgb); + GLenum last_blend_dst_rgb; + glGetIntegerv(GL_BLEND_DST_RGB, (GLint *)&last_blend_dst_rgb); + GLenum last_blend_src_alpha; + glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint *)&last_blend_src_alpha); + GLenum last_blend_dst_alpha; + glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint *)&last_blend_dst_alpha); + GLenum last_blend_equation_rgb; + glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint *)&last_blend_equation_rgb); + GLenum last_blend_equation_alpha; + glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint *)&last_blend_equation_alpha); + GLboolean last_enable_blend = glIsEnabled(GL_BLEND); + GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); + GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); + GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); + bool clip_origin_lower_left = true; +#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) + GLenum last_clip_origin = 0; + glGetIntegerv(GL_CLIP_ORIGIN, + (GLint *)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) + if (last_clip_origin == GL_UPPER_LEFT) + clip_origin_lower_left = false; +#endif + + // Setup desired GL state + // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. + // VAO are not shared among GL contexts) The renderer would actually work without any VAO bound, + // but then our VertexAttrib calls would overwrite the default one currently bound. + GLuint vertex_array_object = 0; +#ifndef IMGUI_IMPL_OPENGL_ES2 + glGenVertexArrays(1, &vertex_array_object); +#endif + ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); + + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = + draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) + + // Render command lists + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList *cmd_list = draw_data->CmdLists[n]; + + // Upload vertex/index buffers + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), + (const GLvoid *)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), + (const GLvoid *)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd *pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != NULL) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to + // request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, + vertex_array_object); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec4 clip_rect; + clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x; + clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y; + clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x; + clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y; + + if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && + clip_rect.w >= 0.0f) + { + // Apply scissor/clipping rectangle + if (clip_origin_lower_left) + glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), + (int)(clip_rect.z - clip_rect.x), + (int)(clip_rect.w - clip_rect.y)); + else + glScissor( + (int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, + (int)clip_rect + .w); // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) + + // Bind texture, Draw + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); +#if IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX + glDrawElementsBaseVertex( + GL_TRIANGLES, (GLsizei)pcmd->ElemCount, + sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, + (void *)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), + (GLint)pcmd->VtxOffset); +#else + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, + sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, + (void *)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))); +#endif + } + } + } + } + + // Destroy the temporary VAO +#ifndef IMGUI_IMPL_OPENGL_ES2 + glDeleteVertexArrays(1, &vertex_array_object); +#endif + + // Restore modified GL state + glUseProgram(last_program); + glBindTexture(GL_TEXTURE_2D, last_texture); +#ifdef GL_SAMPLER_BINDING + glBindSampler(0, last_sampler); +#endif + glActiveTexture(last_active_texture); +#ifndef IMGUI_IMPL_OPENGL_ES2 + glBindVertexArray(last_vertex_array_object); +#endif + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); + glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, + last_blend_dst_alpha); + if (last_enable_blend) + glEnable(GL_BLEND); + else + glDisable(GL_BLEND); + if (last_enable_cull_face) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); + if (last_enable_depth_test) + glEnable(GL_DEPTH_TEST); + else + glDisable(GL_DEPTH_TEST); + if (last_enable_scissor_test) + glEnable(GL_SCISSOR_TEST); + else + glDisable(GL_SCISSOR_TEST); +#ifdef GL_POLYGON_MODE + glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); +#endif + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], + (GLsizei)last_viewport[3]); + glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], + (GLsizei)last_scissor_box[3]); +} + +bool ImGui_ImplOpenGL3_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO &io = ImGui::GetIO(); + unsigned char *pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32( + &pixels, &width, + &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so + // small) because it is more likely to be compatible with user's existing + // shaders. If your ImTextureId represent a higher-level concept than just a GL + // texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU + // memory. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +#ifdef GL_UNPACK_ROW_LENGTH + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); +#endif + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplOpenGL3_DestroyFontsTexture() +{ + if (g_FontTexture) + { + ImGuiIO &io = ImGui::GetIO(); + glDeleteTextures(1, &g_FontTexture); + io.Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +// If you get an error please report on github. You may try different GL context version or GLSL +// version. See GL<>GLSL version table at the top of this file. +static bool CheckShader(GLuint handle, const char *desc) +{ + GLint status = 0, log_length = 0; + glGetShaderiv(handle, GL_COMPILE_STATUS, &status); + glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); + if ((GLboolean)status == GL_FALSE) + fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", + desc); + if (log_length > 1) + { + ImVector buf; + buf.resize((int)(log_length + 1)); + glGetShaderInfoLog(handle, log_length, NULL, (GLchar *)buf.begin()); + fprintf(stderr, "%s\n", buf.begin()); + } + return (GLboolean)status == GL_TRUE; +} + +// If you get an error please report on GitHub. You may try different GL context version or GLSL +// version. +static bool CheckProgram(GLuint handle, const char *desc) +{ + GLint status = 0, log_length = 0; + glGetProgramiv(handle, GL_LINK_STATUS, &status); + glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); + if ((GLboolean)status == GL_FALSE) + fprintf( + stderr, + "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! (with GLSL '%s')\n", + desc, g_GlslVersionString); + if (log_length > 1) + { + ImVector buf; + buf.resize((int)(log_length + 1)); + glGetProgramInfoLog(handle, log_length, NULL, (GLchar *)buf.begin()); + fprintf(stderr, "%s\n", buf.begin()); + } + return (GLboolean)status == GL_TRUE; +} + +bool ImGui_ImplOpenGL3_CreateDeviceObjects() +{ + // Backup GL state + GLint last_texture, last_array_buffer; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); +#ifndef IMGUI_IMPL_OPENGL_ES2 + GLint last_vertex_array; + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); +#endif + + // Parse GLSL version string + int glsl_version = 130; + sscanf(g_GlslVersionString, "#version %d", &glsl_version); + + const GLchar *vertex_shader_glsl_120 = + "uniform mat4 ProjMtx;\n" + "attribute vec2 Position;\n" + "attribute vec2 UV;\n" + "attribute vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar *vertex_shader_glsl_130 = + "uniform mat4 ProjMtx;\n" + "in vec2 Position;\n" + "in vec2 UV;\n" + "in vec4 Color;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar *vertex_shader_glsl_300_es = + "precision mediump float;\n" + "layout (location = 0) in vec2 Position;\n" + "layout (location = 1) in vec2 UV;\n" + "layout (location = 2) in vec4 Color;\n" + "uniform mat4 ProjMtx;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar *vertex_shader_glsl_410_core = + "layout (location = 0) in vec2 Position;\n" + "layout (location = 1) in vec2 UV;\n" + "layout (location = 2) in vec4 Color;\n" + "uniform mat4 ProjMtx;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar *fragment_shader_glsl_120 = + "#ifdef GL_ES\n" + " precision mediump float;\n" + "#endif\n" + "uniform sampler2D Texture;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n" + "}\n"; + + const GLchar *fragment_shader_glsl_130 = + "uniform sampler2D Texture;\n" + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + "}\n"; + + const GLchar *fragment_shader_glsl_300_es = + "precision mediump float;\n" + "uniform sampler2D Texture;\n" + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "layout (location = 0) out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + "}\n"; + + const GLchar *fragment_shader_glsl_410_core = + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "uniform sampler2D Texture;\n" + "layout (location = 0) out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + "}\n"; + + // Select shaders matching our GLSL versions + const GLchar *vertex_shader = NULL; + const GLchar *fragment_shader = NULL; + if (glsl_version < 130) + { + vertex_shader = vertex_shader_glsl_120; + fragment_shader = fragment_shader_glsl_120; + } + else if (glsl_version >= 410) + { + vertex_shader = vertex_shader_glsl_410_core; + fragment_shader = fragment_shader_glsl_410_core; + } + else if (glsl_version == 300) + { + vertex_shader = vertex_shader_glsl_300_es; + fragment_shader = fragment_shader_glsl_300_es; + } + else + { + vertex_shader = vertex_shader_glsl_130; + fragment_shader = fragment_shader_glsl_130; + } + + // Create shaders + const GLchar *vertex_shader_with_version[2] = {g_GlslVersionString, vertex_shader}; + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL); + glCompileShader(g_VertHandle); + CheckShader(g_VertHandle, "vertex shader"); + + const GLchar *fragment_shader_with_version[2] = {g_GlslVersionString, fragment_shader}; + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL); + glCompileShader(g_FragHandle); + CheckShader(g_FragHandle, "fragment shader"); + + g_ShaderHandle = glCreateProgram(); + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + CheckProgram(g_ShaderHandle, "shader program"); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + // Create buffers + glGenBuffers(1, &g_VboHandle); + glGenBuffers(1, &g_ElementsHandle); + + ImGui_ImplOpenGL3_CreateFontsTexture(); + + // Restore modified GL state + glBindTexture(GL_TEXTURE_2D, last_texture); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); +#ifndef IMGUI_IMPL_OPENGL_ES2 + glBindVertexArray(last_vertex_array); +#endif + + return true; +} + +void ImGui_ImplOpenGL3_DestroyDeviceObjects() +{ + if (g_VboHandle) + glDeleteBuffers(1, &g_VboHandle); + if (g_ElementsHandle) + glDeleteBuffers(1, &g_ElementsHandle); + g_VboHandle = g_ElementsHandle = 0; + + if (g_ShaderHandle && g_VertHandle) + glDetachShader(g_ShaderHandle, g_VertHandle); + if (g_VertHandle) + glDeleteShader(g_VertHandle); + g_VertHandle = 0; + + if (g_ShaderHandle && g_FragHandle) + glDetachShader(g_ShaderHandle, g_FragHandle); + if (g_FragHandle) + glDeleteShader(g_FragHandle); + g_FragHandle = 0; + + if (g_ShaderHandle) + glDeleteProgram(g_ShaderHandle); + g_ShaderHandle = 0; + + ImGui_ImplOpenGL3_DestroyFontsTexture(); +} diff --git a/src/aquarium-optimized/opengl/imgui_impl_opengl3.h b/src/aquarium-optimized/opengl/imgui_impl_opengl3.h index 092304b..a0e0da1 100644 --- a/src/aquarium-optimized/opengl/imgui_impl_opengl3.h +++ b/src/aquarium-optimized/opengl/imgui_impl_opengl3.h @@ -1,50 +1,50 @@ -// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline -// - Desktop GL: 3.x 4.x -// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) -// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) - -// Implemented features: -// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. -// Read the FAQ about ImTextureID in imgui.cpp. [x] Renderer: Desktop GL only: Support for large -// meshes (64k+ vertices) with 16-bits indices. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example -// of using this. If you are new to dear imgui, read examples/README.txt and read the documentation -// at the top of imgui.cpp. https://github.com/ocornut/imgui - -// About Desktop OpenGL function loaders: -// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function -// pointers. Helper libraries are often used for this purpose! Here we are supporting a few common -// ones (gl3w, glew, glad). You may use another loader/header of your choice (glext, glLoadGen, -// etc.), or chose to manually implement your own. - -// About GLSL version: -// The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string. -// On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it -// defaults to "#version 300 es" Only override if your GL version doesn't handle this GLSL version. -// See GLSL version table at the top of imgui_impl_opengl3.cpp. - -#pragma once - -// Specific OpenGL versions -//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten -//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android - -#include "imgui.h" - -// Set default OpenGL3 loader to be gl3w -#if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) && !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) && \ - !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) -#define IMGUI_IMPL_OPENGL_LOADER_GL3W -#endif - -IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char *glsl_version = NULL); -IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame(); -IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data); - -// Called by Init/NewFrame/Shutdown -IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture(); -IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture(); -IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects(); -IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); +// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline +// - Desktop GL: 3.x 4.x +// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) +// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. +// Read the FAQ about ImTextureID in imgui.cpp. [x] Renderer: Desktop GL only: Support for large +// meshes (64k+ vertices) with 16-bits indices. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example +// of using this. If you are new to dear imgui, read examples/README.txt and read the documentation +// at the top of imgui.cpp. https://github.com/ocornut/imgui + +// About Desktop OpenGL function loaders: +// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function +// pointers. Helper libraries are often used for this purpose! Here we are supporting a few common +// ones (gl3w, glew, glad). You may use another loader/header of your choice (glext, glLoadGen, +// etc.), or chose to manually implement your own. + +// About GLSL version: +// The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string. +// On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it +// defaults to "#version 300 es" Only override if your GL version doesn't handle this GLSL version. +// See GLSL version table at the top of imgui_impl_opengl3.cpp. + +#pragma once + +// Specific OpenGL versions +//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten +//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android + +#include "imgui.h" + +// Set default OpenGL3 loader to be gl3w +#if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) && !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) && \ + !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) +#define IMGUI_IMPL_OPENGL_LOADER_GL3W +#endif + +IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char *glsl_version = NULL); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data); + +// Called by Init/NewFrame/Shutdown +IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture(); +IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); diff --git a/src/common/AQUARIUM_ASSERT.h b/src/common/AQUARIUM_ASSERT.h index 65e6690..3efb4f3 100644 --- a/src/common/AQUARIUM_ASSERT.h +++ b/src/common/AQUARIUM_ASSERT.h @@ -1,36 +1,40 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -#pragma once -#ifndef AQUARIUM_ASSERT_H -#define AQUARIUM_ASSERT_H 1 - -#include - -//TODO(yizhou) : replace this ASSERT by the code template of ANGLE or Chromium -#ifndef NDEBUG -#define ASSERT(expression) { \ - if (!(expression)) { \ - printf("Assertion(%s) failed: file \"%s\", line %d\n", \ - #expression, __FILE__, __LINE__); \ - abort(); \ - } \ - } -#else -#define ASSERT(expression) NULL; -#endif - -#ifndef NDEBUG -#define SWALLOW_ERROR(expression) { \ - if (!(expression)) { \ - printf("Assertion(%s) failed: file \"%s\", line %d\n", \ - #expression, __FILE__, __LINE__); \ - } \ - } -#else -#define SWALLOW_ERROR(expression) expression -#endif - -#endif // !common/AQUARIUM_ASSERT.h +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +#pragma once +#ifndef AQUARIUM_ASSERT_H +#define AQUARIUM_ASSERT_H 1 + +#include + +// TODO(yizhou) : replace this ASSERT by the code template of ANGLE or Chromium +#ifndef NDEBUG +#define ASSERT(expression) \ + { \ + if (!(expression)) \ + { \ + printf("Assertion(%s) failed: file \"%s\", line %d\n", #expression, __FILE__, \ + __LINE__); \ + abort(); \ + } \ + } +#else +#define ASSERT(expression) NULL; +#endif + +#ifndef NDEBUG +#define SWALLOW_ERROR(expression) \ + { \ + if (!(expression)) \ + { \ + printf("Assertion(%s) failed: file \"%s\", line %d\n", #expression, __FILE__, \ + __LINE__); \ + } \ + } +#else +#define SWALLOW_ERROR(expression) expression +#endif + +#endif // !common/AQUARIUM_ASSERT.h diff --git a/src/common/FPSTimer.cpp b/src/common/FPSTimer.cpp index d15095c..82f6c7f 100644 --- a/src/common/FPSTimer.cpp +++ b/src/common/FPSTimer.cpp @@ -1,44 +1,45 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FPSTimer.cpp: Implement fps timer. - -#include "FPSTimer.h" - -#include - -FPSTimer::FPSTimer() - : mTotalTime(static_cast(NUM_FRAMES_TO_AVERAGE)), - mTimeTable(NUM_FRAMES_TO_AVERAGE,1.0f), - mHistoryFPS(NUM_HISTORY_DATA, 1.0f), - mHistoryFrameTime(NUM_HISTORY_DATA, 100.0f), - mTimeTableCursor(0), - mInstantaneousFPS(0.0f), - mAverageFPS(0.0f) -{} - -void FPSTimer::update(float elapsedTime) -{ - mTotalTime += elapsedTime - mTimeTable[mTimeTableCursor]; - mTimeTable[mTimeTableCursor] = elapsedTime; - - ++mTimeTableCursor; - if (mTimeTableCursor == NUM_FRAMES_TO_AVERAGE) - { - mTimeTableCursor = 0; - } - - mInstantaneousFPS = floor(1.0f / elapsedTime + 0.5f); - mAverageFPS = floor((1.0f / (mTotalTime / static_cast(NUM_FRAMES_TO_AVERAGE))) + 0.5f); - - for (int i = 0; i < NUM_HISTORY_DATA; i++) - { - mHistoryFPS[i] = mHistoryFPS[i + 1]; - mHistoryFrameTime[i] = mHistoryFrameTime[i + 1]; - } - - mHistoryFPS[NUM_HISTORY_DATA - 1] = mAverageFPS; - mHistoryFrameTime[NUM_HISTORY_DATA - 1] = 1000.0f / mAverageFPS; -} +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FPSTimer.cpp: Implement fps timer. + +#include "FPSTimer.h" + +#include + +FPSTimer::FPSTimer() + : mTotalTime(static_cast(NUM_FRAMES_TO_AVERAGE)), + mTimeTable(NUM_FRAMES_TO_AVERAGE, 1.0f), + mHistoryFPS(NUM_HISTORY_DATA, 1.0f), + mHistoryFrameTime(NUM_HISTORY_DATA, 100.0f), + mTimeTableCursor(0), + mInstantaneousFPS(0.0f), + mAverageFPS(0.0f) +{ +} + +void FPSTimer::update(float elapsedTime) +{ + mTotalTime += elapsedTime - mTimeTable[mTimeTableCursor]; + mTimeTable[mTimeTableCursor] = elapsedTime; + + ++mTimeTableCursor; + if (mTimeTableCursor == NUM_FRAMES_TO_AVERAGE) + { + mTimeTableCursor = 0; + } + + mInstantaneousFPS = floor(1.0f / elapsedTime + 0.5f); + mAverageFPS = floor((1.0f / (mTotalTime / static_cast(NUM_FRAMES_TO_AVERAGE))) + 0.5f); + + for (int i = 0; i < NUM_HISTORY_DATA; i++) + { + mHistoryFPS[i] = mHistoryFPS[i + 1]; + mHistoryFrameTime[i] = mHistoryFrameTime[i + 1]; + } + + mHistoryFPS[NUM_HISTORY_DATA - 1] = mAverageFPS; + mHistoryFrameTime[NUM_HISTORY_DATA - 1] = 1000.0f / mAverageFPS; +} diff --git a/src/common/FPSTimer.h b/src/common/FPSTimer.h index 79570f7..6661e3a 100644 --- a/src/common/FPSTimer.h +++ b/src/common/FPSTimer.h @@ -1,38 +1,38 @@ -// -// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// FPSTimer.h: Define fps timer. - -#pragma once -#ifndef FPS_TIMER -#define FPS_TIMER 1 - -#include - -constexpr int NUM_FRAMES_TO_AVERAGE = 16; -constexpr int NUM_HISTORY_DATA = 100; - -class FPSTimer -{ -public: - FPSTimer(); - - void update(float elapsedTime); - float getAverageFPS() const { return mAverageFPS; } - float getInstantaneousFPS() const { return mInstantaneousFPS; } - const float *getHistoryFps() const { return mHistoryFPS.data(); } - const float *getHistoryFrameTime() const { return mHistoryFrameTime.data(); } - -private: - float mTotalTime; - std::vector mTimeTable; - std::vector mHistoryFPS; - std::vector mHistoryFrameTime; - int mTimeTableCursor; - float mInstantaneousFPS; - float mAverageFPS; -}; - -#endif +// +// Copyright (c) 2019 The Aquarium Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FPSTimer.h: Define fps timer. + +#pragma once +#ifndef FPS_TIMER +#define FPS_TIMER 1 + +#include + +constexpr int NUM_FRAMES_TO_AVERAGE = 16; +constexpr int NUM_HISTORY_DATA = 100; + +class FPSTimer +{ + public: + FPSTimer(); + + void update(float elapsedTime); + float getAverageFPS() const { return mAverageFPS; } + float getInstantaneousFPS() const { return mInstantaneousFPS; } + const float *getHistoryFps() const { return mHistoryFPS.data(); } + const float *getHistoryFrameTime() const { return mHistoryFrameTime.data(); } + + private: + float mTotalTime; + std::vector mTimeTable; + std::vector mHistoryFPS; + std::vector mHistoryFrameTime; + int mTimeTableCursor; + float mInstantaneousFPS; + float mAverageFPS; +}; + +#endif From 75a6640db59d4290fa4fbc07291ba559a0b0602f Mon Sep 17 00:00:00 2001 From: Yizhou Jiang Date: Mon, 29 Jul 2019 15:52:13 +0800 Subject: [PATCH 2/2] Make ANGLE compile successfully with the other backends in a same solution This patch makes ANGLE backend build with the other backends and removes standalone ANGLE build. First, solve conflict of ANGLE, dawn and d3d12 backend EGLWindow.h is from angle util, which causes microsoft namespace can't be find. However, EGLWindow isn't used at all by Aquarium, so the header should be removed. Second, solve conflict of ANGLE and OpenGL backend 1.Write own own gl header and gl functions 2.Load ANGLE dll on Windows by GetProcAddress 3.Load OpenGL dll by glfwGetProcAddress 4.Replace gl library of imgui by our own library 5.The egl headers of ANGLE isn't conflict with GL functions, so egl headers are maintained. Third, Update README.md and Build.gn --- .gn | 1 + BUILD.gn | 22 +- README.md | 585 ++- src/aquarium-optimized/opengl/BufferGL.h | 13 +- src/aquarium-optimized/opengl/ContextGL.cpp | 429 +- src/aquarium-optimized/opengl/ContextGL.h | 14 +- .../opengl/OpenGLFunctions.cpp | 1275 +++++ .../opengl/OpenGLFunctions.h | 796 ++++ .../opengl/OpenGLPlatforms.h | 4098 +++++++++++++++++ src/aquarium-optimized/opengl/ProgramGL.cpp | 13 +- src/aquarium-optimized/opengl/TextureGL.h | 13 +- .../opengl/imgui_impl_opengl3.cpp | 302 +- .../opengl/imgui_impl_opengl3.h | 5 +- 13 files changed, 6833 insertions(+), 733 deletions(-) create mode 100644 src/aquarium-optimized/opengl/OpenGLFunctions.cpp create mode 100644 src/aquarium-optimized/opengl/OpenGLFunctions.h create mode 100644 src/aquarium-optimized/opengl/OpenGLPlatforms.h diff --git a/.gn b/.gn index 8687f9c..f896c4c 100644 --- a/.gn +++ b/.gn @@ -17,3 +17,4 @@ check_targets = [ # Everything in third_party/BUILD.gn "//third_party/:*", ] + diff --git a/BUILD.gn b/BUILD.gn index 884a859..7df77e2 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -6,7 +6,7 @@ declare_args() { enable_dawn = is_win || is_linux || is_mac - enable_angle = false + enable_angle = is_win enable_d3d12 = is_win enable_opengl = is_win || is_linux || is_mac } @@ -72,35 +72,27 @@ executable("aquarium") { "src/aquarium-optimized/opengl/TextureGL.h", "src/aquarium-optimized/opengl/imgui_impl_opengl3.h", "src/aquarium-optimized/opengl/imgui_impl_opengl3.cpp", + "src/aquarium-optimized/opengl/OpenGLPlatforms.h", + "src/aquarium-optimized/opengl/OpenGLFunctions.h", + "src/aquarium-optimized/opengl/OpenGLFunctions.cpp", ] } defines = [] if (enable_angle) { - enable_dawn = false - enable_d3d12 = false - defines += [ "EGL_EGL_PROTOTYPES", "IMGUI_IMPL_OPENGL_LOADER_CUSTOM", "IMGUI_IMPL_OPENGL_ES3", ] include_dirs += [ "third_party/angle/include", - "third_party/angle/util", ] deps += [ - "third_party/angle:libANGLE", "third_party/angle:libGLESv2", "third_party/angle:libEGL", - "third_party/angle:angle_util_static", ] - } else { - deps += [ "third_party:glad" ] - - include_dirs += [ "third_party/glad/include" ] - defines += [ "IMGUI_IMPL_OPENGL_LOADER_GLAD", ] } if (enable_dawn) { @@ -223,13 +215,13 @@ executable("aquarium-direct-map") { "src/aquarium-direct-map/Uniform.h", "src/aquarium-direct-map/Uniform.cpp", ] - + deps = [ "third_party:stb", "third_party:glad", "third_party:glfw", ] - + include_dirs = [ "third_party/glad/include", "third_party/rapidjson/include", @@ -237,7 +229,7 @@ executable("aquarium-direct-map") { "third_party/glfw/include", "src", ] - + cflags_cc = [ "-Wno-string-conversion", "-Wno-unused-result", diff --git a/README.md b/README.md index 9f54b3c..9905e51 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,25 @@ -# Aquarium -Aquarium is a native implementation of [WebGL Aquarium](https://github.com/WebGLSamples/WebGLSamples.github.io). The goal of this project is to compare the performance of WebGL version to its native counterparts, such as OpenGL, D3D, Vulkan, Metal, ANGLE and Dawn. - -# Progress - - - - - - - - - - - - - - - - - - +# Aquarium +Aquarium is a native implementation of [WebGL Aquarium](https://github.com/WebGLSamples/WebGLSamples.github.io). The goal of this project is to compare the performance of WebGL version to its native counterparts, such as OpenGL, D3D, Vulkan, Metal, ANGLE and Dawn. + +# Progress +
OSBackendSupportedMSAADynamic Buffer OffsetInstanced DrawDynamically choose GPU
LinuxOpenGLYYNot supportedNNot supported
+ + + + + + + + + + + + + + + + + @@ -29,284 +29,263 @@ Aquarium is a native implementation of [WebGL Aquarium](https://github.com/WebGL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSBackendSupportedMSAADynamic Buffer OffsetInstanced DrawDynamically choose GPU
LinuxOpenGLYYNot supportedNNot supported
LinuxY Y Y
macOSOpenGLYYNot supportedNNot supported
macOSDawn/MetalYYYYY
WindowsOpenGLYYNot supportedNNot supported
WindowsANGLE/D3D11YNNot supportedNNot supported
WindowsDawn/D3D12YYNYY
WindowsDawn/VulkanYYYYY
WindowsD3D12YYYYY
LinuxANGLE/OpenGLNNNot supportedNNot supported
LinuxANGLE/VulkanNNNNN
LinuxVulkanNNNNN
macOSANGLE/OpenGLNNNot supportedNNot supported
macOSMetalNNNNN
WindowsANGLE/OpenGLNNNot supportedNNot supported
WindowsANGLE/VulkanNNNNN
WindowsD3D11NNNot supportedNNot supported
WindowsVulkanNNNNN
- -# Required Tools and Configurations -Configure [depot_tools](http://dev.chromium.org/developers/how-tos/install-depot-tools) on all platforms. - -## Windows Requirement -The OpenGL version is required to >= 4.5 on Windows. -Windows sdk version is required to be over -[10.0.17134.0](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk) to support D3D12 backend. -Visual Studio 2017 is recommand if you want to debug into the code. -## Linux Requirement -The OpenGL version is required to >= 4.5 on Linux. To run vulkan of Dawn, please install vulkan driver on ubuntu. -If you are using Mesa driver, you should install the following library: -```sh -sudo apt-get install mesa-vulkan-drivers -``` -If you are using Nvidia gpu, you should check if the driver support vulkan. -## macOS Requirement -The OpenGL version is required to >= 4.1 on macOS. To run Dawn/Metal backend, please check if your macOS support metal. -```sh -ps aux | grep -i "metal" -``` - -## Build OpenGL, D3D12 and Dawn backends - -Aquarium uses gn to build on Linux, macOS and Windows. - -```sh -# Aquarium contains two projects, aquarium-direct-map is a direct map version to WebGL repo, and only has OpenGL backend. The aquarium -# project contains many backends. - -# cd the repo -cd aquarium - -# Download thirdparty -gclient sync - -# Build on aquarium by ninja on Windows, Linux and macOS. -# On windows, opengl, d3d12 and dawn backends are enabled by default. -# On linux and macOS, opengl and dawn are enabled by default. -# Enable or disable a specific platform, you can add 'enable_opengl', 'enable_d3d12', and 'enable_dawn' to gn args. -# To build a release version, specify 'is_debug=false'. -gn gen out/Release --args="is_debug=false" -ninja -C out/Release aquarium -ninja -C out/Release aquarium-direct-map - -# Build on Windows by vs -gn gen out/build --ide=vs -open out/build/all.sln using visual studio. -build aquarium by vs - -# Build on macOS by xcode -gn gen out/build --ide=xcode -build aquarium by xcode -``` - -## Build ANGLE backend - -Because ANGLE headers have conflicts with other backends, it can only build individually. To build ANGLE version on Windows, please refer to the following steps (ANGLE backend is only supported on Windows now). -```sh -# cd the repo -cd aquarium - -# download thirdparty -gclient sync - -#Build aquarium ninja -gn gen out/Release --args="is_debug=false enable_angle=true" -ninja -C out/Release aquarium - -# Build on Windows by vs -gn gen out/Release --ide=vs --args="is_debug=false enable_angle=true" -open out/Release/all.sln using visual studio. -build aquarium by vs -``` - -# Run -```sh -# "--num-fish" : specifies how many fishes will be rendered -# "--backend" : specifies running a certain backend, 'opengl', 'dawn_d3d12', 'dawn_vulkan', 'dawn_metal', 'dawn_opengl', 'angle' -# "--enable-full-screen-mode" : specifies rendering a full screen mode - -# run on Windows -aquarium.exe --num-fish 10000 --backend dawn_d3d12 -aquarium.exe --num-fish 10000 --backend dawn_vulkan -aquarium.exe --num-fish 10000 --backend angle - -# run on Linux -./aquarium --num-fish 10000 --backend opengl -./aquarium.exe --num-fish 10000 --backend dawn_vulkan - -# run on macOS -./aquarium --num-fish 10000 --backend opengl -./aquarium.exe --num-fish 10000 --backend dawn_metal - -# "--enable-instanced-draws" : specifies rendering fishes by instanced draw. By default fishes -# are rendered by individual draw. Instanced rendering is only supported on dawn and d3d12 backend now. - -aquarium.exe --num-fish 10000 --backend dawn_d3d12 --enable-instanced-draws -aquarium.exe --num-fish 10000 --backend dawn_vulkan --enable-instanced-draws -aquarium.exe --num-fish 10000 --backend d3d12 --enable-instanced-draws - -# MSAA is disabled by default. To Enable MSAA, "--enable-msaa", 4 samples. -# MSAA of ANGLE is not supported now. - -aquarium.exe --num-fish 10000 --backend opengl --enable-msaa - - -# “--disable-dynamic-buffer-offset” :The path is to test individual draw by creating many binding groups on dawn backend. -# By default, dynamic buffer offset is enabled. This arg is only supported on dawn backend. - -aquarium.exe --num-fish 10000 --backend dawn_d3d12 --disable-dynamic-buffer-offset -aquarium.exe --num-fish 10000 --backend dawn_vulkan --disable-dynamic-buffer-offset - -# "--integrated-gpu", "--discrete-gpu": Specifies which gpu to render the application. The two args are exclusive. -# This is an optional arg. By default, a default adapter will be created. -# The option is only supported on dawn and d3d12 backend. -aquarium.exe --num-fish 10000 --backend dawn_d3d12 --integrated-gpu -aquarium.exe --num-fish 10000 --backend dawn_vulkan --discrete-gpu - -# aquarium-direct-map only has OpenGL backend -# Enable MSAA -./aquarium-direct-map --num-fish 10000 --backend opengl --enable-msaa - -``` - -# TODO -* Dawn Vulkan backend doesn't work now. We need to implement recreate swap chain in Dawn. -* Debug mode of Dawn Metal backend has some issues to be fixed. -* Extra semicolon in dawn/third_party/shaderc throws warning when build the project. This should be fixed in Dawn. -* Texture without VK_IMAGE_USAGE_TRANSFER_DST_BIT should not be cleared. This is a warning of Dawn Vulkan backend. -* Enable dynamic choosing backend for ANGLE backend. -* Enable MSAA mode for ANGLE backend. -* Support Imgui for Direct Map Aquarium. -* Check and create the highest OpenGL version supported on each of the platforms. -* Check if some feature is available for D3D12 backend. + + + macOS + OpenGL + Y + Y + Not supported + N + Not supported + + + macOS + Dawn/Metal + Y + Y + Y + Y + Y + + + Windows + OpenGL + Y + Y + Not supported + N + Not supported + + + Windows + ANGLE/D3D11 + Y + N + Not supported + N + Not supported + + + Windows + Dawn/D3D12 + Y + Y + N + Y + Y + + + Windows + Dawn/Vulkan + Y + Y + Y + Y + Y + + + Windows + D3D12 + Y + Y + Y + Y + Y + + + Linux + ANGLE/OpenGL + N + N + Not supported + N + Not supported + + + Linux + ANGLE/Vulkan + N + N + N + N + N + + + Linux + Vulkan + N + N + N + N + N + + + macOS + ANGLE/OpenGL + N + N + Not supported + N + Not supported + + + macOS + Metal + N + N + N + N + N + + + Windows + ANGLE/OpenGL + N + N + Not supported + N + Not supported + + + Windows + ANGLE/Vulkan + N + N + N + N + N + + + Windows + D3D11 + N + N + Not supported + N + Not supported + + + Windows + Vulkan + N + N + N + N + N + + + +# Required Tools and Configurations +Configure [depot_tools](http://dev.chromium.org/developers/how-tos/install-depot-tools) on all platforms. + +## Windows Requirement +The OpenGL version is required to >= 4.5 on Windows. +Windows sdk version is required to be over +[10.0.17134.0](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk) to support D3D12 backend. +Visual Studio 2017 is recommand if you want to debug into the code. +## Linux Requirement +The OpenGL version is required to >= 4.5 on Linux. To run vulkan of Dawn, please install vulkan driver on ubuntu. +If you are using Mesa driver, you should install the following library: +```sh +sudo apt-get install mesa-vulkan-drivers +``` +If you are using Nvidia gpu, you should check if the driver support vulkan. +## macOS Requirement +The OpenGL version is required to >= 4.1 on macOS. To run Dawn/Metal backend, please check if your macOS support metal. +```sh +ps aux | grep -i "metal" +``` + +## Build OpenGL, D3D12 and Dawn backends + +Aquarium uses gn to build on Linux, macOS and Windows. + +```sh +# Aquarium contains two projects, aquarium-direct-map is a direct map version to WebGL repo, and only has OpenGL backend. The aquarium +# project contains many backends. + +# cd the repo +cd aquarium + +# Download thirdparty +gclient sync + +# Build on aquarium by ninja on Windows, Linux and macOS. +# On Windows, OpenGL, D3D12,ANGLE and Dawn backends are enabled by default. +# On Linux and macOS, Opengl and Dawn are enabled by default. +# Enable or disable a specific platform, you can add 'enable_opengl', 'enable_d3d12', 'enable_angle', and 'enable_dawn' to gn args. +# To build a release version, specify 'is_debug=false'. +gn gen out/Release --args="is_debug=false" +ninja -C out/Release aquarium +ninja -C out/Release aquarium-direct-map + +# Build on Windows by vs +gn gen out/build --ide=vs +open out/build/all.sln using visual studio. +build aquarium by vs + +# Build on macOS by xcode +gn gen out/build --ide=xcode +build aquarium by xcode +``` + +# Run +```sh +# "--num-fish" : specifies how many fishes will be rendered +# "--backend" : specifies running a certain backend, 'opengl', 'dawn_d3d12', 'dawn_vulkan', 'dawn_metal', 'dawn_opengl', 'angle' +# "--enable-full-screen-mode" : specifies rendering a full screen mode + +# run on Windows +aquarium.exe --num-fish 10000 --backend dawn_d3d12 +aquarium.exe --num-fish 10000 --backend dawn_vulkan +aquarium.exe --num-fish 10000 --backend angle + +# run on Linux +./aquarium --num-fish 10000 --backend opengl +./aquarium.exe --num-fish 10000 --backend dawn_vulkan + +# run on macOS +./aquarium --num-fish 10000 --backend opengl +./aquarium.exe --num-fish 10000 --backend dawn_metal + +# "--enable-instanced-draws" : specifies rendering fishes by instanced draw. By default fishes +# are rendered by individual draw. Instanced rendering is only supported on dawn and d3d12 backend now. + +aquarium.exe --num-fish 10000 --backend dawn_d3d12 --enable-instanced-draws +aquarium.exe --num-fish 10000 --backend dawn_vulkan --enable-instanced-draws +aquarium.exe --num-fish 10000 --backend d3d12 --enable-instanced-draws + +# MSAA is disabled by default. To Enable MSAA, "--enable-msaa", 4 samples. +# MSAA of ANGLE is not supported now. + +aquarium.exe --num-fish 10000 --backend opengl --enable-msaa + + +# “--disable-dynamic-buffer-offset” :The path is to test individual draw by creating many binding groups on dawn backend. +# By default, dynamic buffer offset is enabled. This arg is only supported on dawn backend. + +aquarium.exe --num-fish 10000 --backend dawn_d3d12 --disable-dynamic-buffer-offset +aquarium.exe --num-fish 10000 --backend dawn_vulkan --disable-dynamic-buffer-offset + +# "--integrated-gpu", "--discrete-gpu": Specifies which gpu to render the application. The two args are exclusive. +# This is an optional arg. By default, a default adapter will be created. +# The option is only supported on dawn and d3d12 backend. +aquarium.exe --num-fish 10000 --backend dawn_d3d12 --integrated-gpu +aquarium.exe --num-fish 10000 --backend dawn_vulkan --discrete-gpu + +# aquarium-direct-map only has OpenGL backend +# Enable MSAA +./aquarium-direct-map --num-fish 10000 --backend opengl --enable-msaa + +``` + +# TODO +* Dawn Vulkan backend doesn't work now. We need to implement recreate swap chain in Dawn. +* Debug mode of Dawn Metal backend has some issues to be fixed. +* Texture without VK_IMAGE_USAGE_TRANSFER_DST_BIT should not be cleared. This is a warning of Dawn Vulkan backend. +* Enable dynamic choosing backend for ANGLE backend. +* Enable MSAA mode for ANGLE backend. +* Support Imgui for Direct Map Aquarium. +* Check and create the highest OpenGL version supported on each of the platforms. +* Check if some feature is available for D3D12 backend. diff --git a/src/aquarium-optimized/opengl/BufferGL.h b/src/aquarium-optimized/opengl/BufferGL.h index c531e8d..3074895 100644 --- a/src/aquarium-optimized/opengl/BufferGL.h +++ b/src/aquarium-optimized/opengl/BufferGL.h @@ -9,21 +9,10 @@ #ifndef BUFFERGL_H #define BUFFERGL_H 1 -#ifdef EGL_EGL_PROTOTYPES -#include -#include -#include "EGL/egl.h" -#include "EGL/eglext.h" -#include "EGL/eglext_angle.h" -#include "EGL/eglplatform.h" -#include "EGLWindow.h" -#else -#include "glad/glad.h" -#endif - #include #include "ContextGL.h" +#include "OpenGLPlatforms.h" #include "../Buffer.h" diff --git a/src/aquarium-optimized/opengl/ContextGL.cpp b/src/aquarium-optimized/opengl/ContextGL.cpp index fc5446d..388e333 100644 --- a/src/aquarium-optimized/opengl/ContextGL.cpp +++ b/src/aquarium-optimized/opengl/ContextGL.cpp @@ -30,7 +30,7 @@ #include #endif -ContextGL::ContextGL(BACKENDTYPE backendType) : mWindow(nullptr) +ContextGL::ContextGL(BACKENDTYPE backendType) : mWindow(nullptr), mBackendType(backendType) { initAvailableToggleBitset(backendType); } @@ -51,31 +51,34 @@ bool ContextGL::initialize(BACKENDTYPE backend, return false; } -#ifdef GL_GLEXT_PROTOTYPES - // TODO(yizhou) : Enable msaa in angle. Render into a multisample Texture and then blit to a - // none multisample texture. - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - mResourceHelper = new ResourceHelper("opengl", std::string("100")); -#else - if (toggleBitset.test(static_cast(TOGGLE::ENABLEMSAAx4))) + if (backend == BACKENDTYPE::BACKENDTYPEANGLE) { - glfwWindowHint(GLFW_SAMPLES, 4); + // TODO(yizhou) : Enable msaa in angle. Render into a multisample Texture and then blit to a + // none multisample texture. + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + mResourceHelper = new ResourceHelper("opengl", std::string("100")); } + else + { + if (toggleBitset.test(static_cast(TOGGLE::ENABLEMSAAx4))) + { + glfwWindowHint(GLFW_SAMPLES, 4); + } - mResourceHelper = new ResourceHelper("opengl", "450"); - + mResourceHelper = new ResourceHelper("opengl", "450"); #ifdef __APPLE__ - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); - mGLSLVersion = "#version 410"; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); + mGLSLVersion = "#version 410"; #elif _WIN32 || __linux__ - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); - mGLSLVersion = "#version 450"; -#endif - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); + mGLSLVersion = "#version 450"; #endif + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); + } GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); @@ -100,125 +103,120 @@ bool ContextGL::initialize(BACKENDTYPE backend, } setWindowTitle("Aquarium"); - glfwSetFramebufferSizeCallback(mWindow, framebufferResizeCallback); - glfwSetWindowUserPointer(mWindow, this); - -#ifndef GL_GLES_PROTOTYPES - glfwWindowHint(GLFW_DECORATED, GL_FALSE); - glfwMakeContextCurrent(mWindow); -#else - mGLSLVersion = "#version 300 es"; - - std::vector display_attribs; - - display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE); - // display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE); - display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE); - display_attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE); - display_attribs.push_back(-1); - display_attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE); - display_attribs.push_back(-1); - display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE); - display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); - display_attribs.push_back(EGL_NONE); - - HWND hwnd = glfwGetWin32Window(mWindow); - mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, - reinterpret_cast(GetDC(hwnd)), &display_attribs[0]); - if (mDisplay == EGL_NO_DISPLAY) + + if (backend != BACKENDTYPE::BACKENDTYPEANGLE) { - std::cout << "EGL display query failed with error " << std::endl; + glfwWindowHint(GLFW_DECORATED, GL_FALSE); + glfwMakeContextCurrent(mWindow); + gl.initialize(backend); } - GLint mEGLMajorVersion = 0; - GLint mEGLMinorVersion = 0; - if (eglInitialize(mDisplay, &mEGLMajorVersion, &mEGLMinorVersion) == EGL_FALSE) + else { - return false; - } + mGLSLVersion = "#version 300 es"; + std::vector display_attribs; + + display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE); + // display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE); + display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE); + display_attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE); + display_attribs.push_back(-1); + display_attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE); + display_attribs.push_back(-1); + display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE); + display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); + display_attribs.push_back(EGL_NONE); + + HWND hwnd = glfwGetWin32Window(mWindow); + mDisplay = eglGetPlatformDisplay( + EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast(GetDC(hwnd)), &display_attribs[0]); + if (mDisplay == EGL_NO_DISPLAY) + { + std::cout << "EGL display query failed with error " << std::endl; + } + GLint mEGLMajorVersion = 0; + GLint mEGLMinorVersion = 0; + if (eglInitialize(mDisplay, &mEGLMajorVersion, &mEGLMinorVersion) == EGL_FALSE) + { + return false; + } - const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS); + const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS); - std::vector configAttributes = { - EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, - EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, - EGL_SAMPLE_BUFFERS, 0, EGL_SAMPLES, EGL_DONT_CARE}; + std::vector configAttributes = { + EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, + EGL_SAMPLE_BUFFERS, 0, EGL_SAMPLES, EGL_DONT_CARE}; - // Add dynamic attributes - bool hasPixelFormatFloat = strstr(displayExtensions, "EGL_EXT_pixel_format_float") != nullptr; - if (!hasPixelFormatFloat) - { - return false; - } - if (hasPixelFormatFloat) - { - configAttributes.push_back(EGL_COLOR_COMPONENT_TYPE_EXT); - configAttributes.push_back(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT); - } + // Add dynamic attributes + bool hasPixelFormatFloat = + strstr(displayExtensions, "EGL_EXT_pixel_format_float") != nullptr; + if (!hasPixelFormatFloat) + { + return false; + } + if (hasPixelFormatFloat) + { + configAttributes.push_back(EGL_COLOR_COMPONENT_TYPE_EXT); + configAttributes.push_back(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT); + } - // Finish the attribute list - configAttributes.push_back(EGL_NONE); + // Finish the attribute list + configAttributes.push_back(EGL_NONE); - if (!FindEGLConfig(mDisplay, configAttributes.data(), &mConfig)) - { - std::cout << "Could not find a suitable EGL config!" << std::endl; - return false; - } + if (!FindEGLConfig(mDisplay, configAttributes.data(), &mConfig)) + { + std::cout << "Could not find a suitable EGL config!" << std::endl; + return false; + } - GLint mRedBits, mGreenBits, mBlueBits, mSamples, mAlphaBits, mDepthBits, mStencilBits; - eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mAlphaBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLES, &mSamples); - - std::vector surfaceAttributes; - if (strstr(displayExtensions, "EGL_NV_post_sub_buffer") != nullptr) - { - surfaceAttributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV); - surfaceAttributes.push_back(EGL_TRUE); - } + GLint mRedBits, mGreenBits, mBlueBits, mSamples, mAlphaBits, mDepthBits, mStencilBits; + eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mAlphaBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLES, &mSamples); + + std::vector surfaceAttributes; + if (strstr(displayExtensions, "EGL_NV_post_sub_buffer") != nullptr) + { + surfaceAttributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV); + surfaceAttributes.push_back(EGL_TRUE); + } - surfaceAttributes.push_back(EGL_NONE); + surfaceAttributes.push_back(EGL_NONE); - mSurface = eglCreateWindowSurface( - mDisplay, mConfig, reinterpret_cast(hwnd), &surfaceAttributes[0]); + mSurface = eglCreateWindowSurface( + mDisplay, mConfig, reinterpret_cast(hwnd), &surfaceAttributes[0]); - if (eglGetError() != EGL_SUCCESS) - { - return false; - } - ASSERT(mSurface != EGL_NO_SURFACE); + if (eglGetError() != EGL_SUCCESS) + { + return false; + } + ASSERT(mSurface != EGL_NO_SURFACE); - mContext = createContext(EGL_NO_CONTEXT); - if (mContext == EGL_NO_CONTEXT) - { - return false; - } + mContext = createContext(EGL_NO_CONTEXT); + if (mContext == EGL_NO_CONTEXT) + { + return false; + } - eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); - if (eglGetError() != EGL_SUCCESS) - { - return false; - } + eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); + if (eglGetError() != EGL_SUCCESS) + { + return false; + } - eglSwapInterval(mDisplay, 0); + eglSwapInterval(mDisplay, 0); -#endif + gl.initialize(backend); + } // Set the window full screen // glfwSetWindowPos(window, 0, 0); -#ifndef EGL_EGL_PROTOTYPES - if (!gladLoadGL()) - { - std::cout << "Something went wrong!" << std::endl; - exit(-1); - } -#endif - // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); @@ -226,9 +224,9 @@ bool ContextGL::initialize(BACKENDTYPE backend, // Setup Platform/Renderer bindings ImGui_ImplGlfw_InitForOpenGL(mWindow, true); - ImGui_ImplOpenGL3_Init(mGLSLVersion.c_str()); + ImGui_ImplOpenGL3_Init(mGLSLVersion.c_str(), gl); - std::string renderer((const char *)glGetString(GL_RENDERER)); + std::string renderer((const char *)gl.GetString(GL_RENDERER)); size_t index = renderer.find("/"); mRenderer = renderer.substr(0, index); std::cout << mRenderer << std::endl; @@ -236,7 +234,6 @@ bool ContextGL::initialize(BACKENDTYPE backend, return true; } -#ifdef GL_GLEXT_PROTOTYPES EGLContext ContextGL::createContext(EGLContext share) const { const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS); @@ -311,15 +308,6 @@ EGLBoolean ContextGL::FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, E return EGL_FALSE; } -#endif - -void ContextGL::framebufferResizeCallback(GLFWwindow *window, int width, int height) -{ - ContextGL *contextGL = reinterpret_cast(glfwGetWindowUserPointer(window)); - contextGL->mClientWidth = width; - contextGL->mClientHeight = height; - glViewport(0, 0, width, height); -} Texture *ContextGL::createTexture(const std::string &name, const std::string &url) { @@ -338,18 +326,18 @@ Texture *ContextGL::createTexture(const std::string &name, const std::vectorgetBackendName(); for (auto &c : backend) c = toupper(c); -#ifdef EGL_EGL_PROTOTYPES - rendererStream << mRenderer; -#else - rendererStream << mRenderer << " " << backend << " " << mResourceHelper->getShaderVersion(); -#endif + if (mBackendType == BACKENDTYPE::BACKENDTYPEANGLE) + { + rendererStream << mRenderer; + } + else + { + rendererStream << mRenderer << " " << backend << " " + << mResourceHelper->getShaderVersion(); + } std::string renderer = rendererStream.str(); ImGui::Text(renderer.c_str()); @@ -507,15 +502,15 @@ void ContextGL::destoryImgUI() int ContextGL::getUniformLocation(unsigned int programId, const std::string &name) const { - GLint index = glGetUniformLocation(programId, name.c_str()); + GLint index = gl.GetUniformLocation(programId, name.c_str()); ASSERT(glGetError() == GL_NO_ERROR); return index; } int ContextGL::getAttribLocation(unsigned int programId, const std::string &name) const { - GLint index = glGetAttribLocation(programId, name.c_str()); - ASSERT(glGetError() == GL_NO_ERROR); + GLint index = gl.GetAttribLocation(programId, name.c_str()); + ASSERT(gl.GetError() == GL_NO_ERROR); return index; } @@ -523,11 +518,11 @@ void ContextGL::enableBlend(bool flag) const { if (flag) { - glEnable(GL_BLEND); + gl.Enable(GL_BLEND); } else { - glDisable(GL_BLEND); + gl.Disable(GL_BLEND); } } @@ -535,9 +530,9 @@ void ContextGL::drawElements(const BufferGL &buffer) const { GLint totalComponents = buffer.getTotalComponents(); GLenum type = buffer.getType(); - glDrawElements(GL_TRIANGLES, totalComponents, type, 0); + gl.DrawElements(GL_TRIANGLES, totalComponents, type, 0); - ASSERT(glGetError() == GL_NO_ERROR); + ASSERT(gl.GetError() == GL_NO_ERROR); } Model *ContextGL::createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME name, bool blend) @@ -570,11 +565,11 @@ Model *ContextGL::createModel(Aquarium *aquarium, MODELGROUP type, MODELNAME nam void ContextGL::preFrame() { - glClearColor(0.0f, 1.0f, 0.0f, 1.0f); - glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + gl.ClearColor(0.0f, 1.0f, 0.0f, 1.0f); + gl.Enable(GL_DEPTH_TEST); + gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - ASSERT(glGetError() == GL_NO_ERROR); + ASSERT(gl.GetError() == GL_NO_ERROR); } void ContextGL::setUniform(int index, const float *v, int type) const @@ -584,27 +579,27 @@ void ContextGL::setUniform(int index, const float *v, int type) const { case GL_FLOAT: { - glUniform1f(index, *v); + gl.Uniform1f(index, *v); break; } case GL_FLOAT_VEC4: { - glUniform4fv(index, 1, v); + gl.Uniform4fv(index, 1, v); break; } case GL_FLOAT_VEC3: { - glUniform3fv(index, 1, v); + gl.Uniform3fv(index, 1, v); break; } case GL_FLOAT_VEC2: { - glUniform2fv(index, 1, v); + gl.Uniform2fv(index, 1, v); break; } case GL_FLOAT_MAT4: { - glUniformMatrix4fv(index, 1, false, v); + gl.UniformMatrix4fv(index, 1, false, v); break; } default: @@ -613,97 +608,97 @@ void ContextGL::setUniform(int index, const float *v, int type) const } } - ASSERT(glGetError() == GL_NO_ERROR); + ASSERT(gl.GetError() == GL_NO_ERROR); } void ContextGL::setTexture(const TextureGL &texture, int index, int unit) const { ASSERT(index != -1); - glUniform1i(index, unit); - glActiveTexture(GL_TEXTURE0 + unit); - glBindTexture(texture.getTarget(), texture.getTextureId()); + gl.Uniform1i(index, unit); + gl.ActiveTexture(GL_TEXTURE0 + unit); + gl.BindTexture(texture.getTarget(), texture.getTextureId()); - ASSERT(glGetError() == GL_NO_ERROR); + ASSERT(gl.GetError() == GL_NO_ERROR); } void ContextGL::setAttribs(const BufferGL &bufferGL, int index) const { ASSERT(index != -1); - glBindBuffer(bufferGL.getTarget(), bufferGL.getBuffer()); + gl.BindBuffer(bufferGL.getTarget(), bufferGL.getBuffer()); - glEnableVertexAttribArray(index); - glVertexAttribPointer(index, bufferGL.getNumComponents(), bufferGL.getType(), - bufferGL.getNormalize(), bufferGL.getStride(), bufferGL.getOffset()); + gl.EnableVertexAttribArray(index); + gl.VertexAttribPointer(index, bufferGL.getNumComponents(), bufferGL.getType(), + bufferGL.getNormalize(), bufferGL.getStride(), bufferGL.getOffset()); - ASSERT(glGetError() == GL_NO_ERROR); + ASSERT(gl.GetError() == GL_NO_ERROR); } void ContextGL::setIndices(const BufferGL &bufferGL) const { - glBindBuffer(bufferGL.getTarget(), bufferGL.getBuffer()); + gl.BindBuffer(bufferGL.getTarget(), bufferGL.getBuffer()); } unsigned int ContextGL::generateVAO() { unsigned int vao; - glGenVertexArrays(1, &vao); + gl.GenVertexArrays(1, &vao); return vao; } void ContextGL::bindVAO(unsigned int vao) const { - glBindVertexArray(vao); + gl.BindVertexArray(vao); } void ContextGL::deleteVAO(unsigned int mVAO) { - glDeleteVertexArrays(1, &mVAO); + gl.DeleteVertexArrays(1, &mVAO); } unsigned int ContextGL::generateBuffer() { unsigned int buf; - glGenBuffers(1, &buf); + gl.GenBuffers(1, &buf); return buf; } void ContextGL::deleteBuffer(unsigned int buf) { - glDeleteBuffers(1, &buf); + gl.DeleteBuffers(1, &buf); } void ContextGL::bindBuffer(unsigned int target, unsigned int buf) { - glBindBuffer(target, buf); + gl.BindBuffer(target, buf); } void ContextGL::uploadBuffer(unsigned int target, const std::vector &buf) { - glBufferData(target, sizeof(GLfloat) * buf.size(), buf.data(), GL_STATIC_DRAW); + gl.BufferData(target, sizeof(GLfloat) * buf.size(), buf.data(), GL_STATIC_DRAW); - ASSERT(glGetError() == GL_NO_ERROR); + ASSERT(gl.GetError() == GL_NO_ERROR); } void ContextGL::uploadBuffer(unsigned int target, const std::vector &buf) { - glBufferData(target, sizeof(GLushort) * buf.size(), buf.data(), GL_STATIC_DRAW); + gl.BufferData(target, sizeof(GLushort) * buf.size(), buf.data(), GL_STATIC_DRAW); - ASSERT(glGetError() == GL_NO_ERROR); + ASSERT(gl.GetError() == GL_NO_ERROR); } unsigned int ContextGL::generateProgram() { - return glCreateProgram(); + return gl.CreateProgram(); } void ContextGL::setProgram(unsigned int program) { - glUseProgram(program); + gl.UseProgram(program); } void ContextGL::deleteProgram(unsigned int program) { - glDeleteProgram(program); + gl.DeleteProgram(program); } bool ContextGL::compileProgram(unsigned int programId, @@ -711,59 +706,59 @@ bool ContextGL::compileProgram(unsigned int programId, const std::string &FragmentShaderCode) { // Create the shaders - GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); - GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + GLuint VertexShaderID = gl.CreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = gl.CreateShader(GL_FRAGMENT_SHADER); GLint Result = GL_FALSE; int InfoLogLength; // Compile Vertex Shader char const *VertexSourcePointer = VertexShaderCode.c_str(); - glShaderSource(VertexShaderID, 1, &VertexSourcePointer, nullptr); - glCompileShader(VertexShaderID); + gl.ShaderSource(VertexShaderID, 1, &VertexSourcePointer, nullptr); + gl.CompileShader(VertexShaderID); // Check Vertex Shader - glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + gl.GetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); if (!Result) { - glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + gl.GetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); std::vector VertexShaderErrorMessage(InfoLogLength); - glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]); + gl.GetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]); std::cout << stdout << &VertexShaderErrorMessage[0] << std::endl; } // Compile Fragment Shader char const *FragmentSourcePointer = FragmentShaderCode.c_str(); - glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, nullptr); - glCompileShader(FragmentShaderID); + gl.ShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, nullptr); + gl.CompileShader(FragmentShaderID); // Check Fragment Shader - glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + gl.GetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); if (!Result) { - glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + gl.GetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); std::vector FragmentShaderErrorMessage(InfoLogLength); - glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, - &FragmentShaderErrorMessage[0]); + gl.GetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, + &FragmentShaderErrorMessage[0]); std::cout << stdout << &FragmentShaderErrorMessage[0] << std::endl; } // Link the program - glAttachShader(programId, VertexShaderID); - glAttachShader(programId, FragmentShaderID); - glLinkProgram(programId); + gl.AttachShader(programId, VertexShaderID); + gl.AttachShader(programId, FragmentShaderID); + gl.LinkProgram(programId); // Check the program - glGetProgramiv(programId, GL_LINK_STATUS, &Result); + gl.GetProgramiv(programId, GL_LINK_STATUS, &Result); if (!Result) { - glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &InfoLogLength); + gl.GetProgramiv(programId, GL_INFO_LOG_LENGTH, &InfoLogLength); std::vector ProgramErrorMessage(std::max(InfoLogLength, int(1))); - glGetProgramInfoLog(programId, InfoLogLength, nullptr, &ProgramErrorMessage[0]); + gl.GetProgramInfoLog(programId, InfoLogLength, nullptr, &ProgramErrorMessage[0]); std::cout << stdout << &ProgramErrorMessage[0] << std::endl; } - glDeleteShader(VertexShaderID); - glDeleteShader(FragmentShaderID); + gl.DeleteShader(VertexShaderID); + gl.DeleteShader(FragmentShaderID); return true; } diff --git a/src/aquarium-optimized/opengl/ContextGL.h b/src/aquarium-optimized/opengl/ContextGL.h index 35da74c..64ef592 100644 --- a/src/aquarium-optimized/opengl/ContextGL.h +++ b/src/aquarium-optimized/opengl/ContextGL.h @@ -8,17 +8,11 @@ #ifndef ContextGL_H #define ContextGL_H 1 -#ifdef EGL_EGL_PROTOTYPES -#include -#include #include "EGL/egl.h" #include "EGL/eglext.h" #include "EGL/eglext_angle.h" -#include "EGL/eglplatform.h" -#include "EGLWindow.h" -#else -#include "glad/glad.h" -#endif +#include "OpenGLFunctions.h" +#include "OpenGLPlatforms.h" #include @@ -96,11 +90,13 @@ class ContextGL : public Context private: void initState(); void initAvailableToggleBitset(BACKENDTYPE backendType) override; - static void framebufferResizeCallback(GLFWwindow *window, int width, int height); GLFWwindow *mWindow; std::string mGLSLVersion; std::string mRenderer; + BACKENDTYPE mBackendType; + + aquarium::OpenGLFunctions gl; #ifdef EGL_EGL_PROTOTYPES EGLBoolean FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config); diff --git a/src/aquarium-optimized/opengl/OpenGLFunctions.cpp b/src/aquarium-optimized/opengl/OpenGLFunctions.cpp new file mode 100644 index 0000000..dac2fa0 --- /dev/null +++ b/src/aquarium-optimized/opengl/OpenGLFunctions.cpp @@ -0,0 +1,1275 @@ +#include "OpenGLFunctions.h" + +#include "GLFW/glfw3.h" +#include "common/AQUARIUM_ASSERT.h" + +namespace aquarium +{ + +bool OpenGLFunctions::initialize(BACKENDTYPE backend) +{ + backendType = backend; + + PFNGLGETSTRINGPROC getString; + + if (backendType == BACKENDTYPE::BACKENDTYPEANGLE) + { +#ifdef _WIN32 + hinstance = LoadLibraryA("libGLESv2.dll"); + + if (hinstance == nullptr) + { + std::cout << "Failed to load OpenGL[es] library" << std::endl; + return false; + } + + getString = reinterpret_cast(GetProcAddress(hinstance, "glGetString")); +#endif + } + else // OpenGL + { + getString = reinterpret_cast(glfwGetProcAddress("glGetString")); + } + + if (getString == nullptr) + { + return false; + } + + std::string version = reinterpret_cast(getString(GL_VERSION)); + + if (version.find("OpenGL ES") != std::string::npos) + { + uint32_t mMajorVersion = version[10] - '0'; + uint32_t mMinorVersion = version[12] - '0'; + + // The minor version shouldn't get to two digits. + ASSERT(version.size() <= 13 || !isdigit(version[13])); + + return LoadOpenGLESProcs(mMajorVersion, mMinorVersion); + } + else + { + uint32_t mMajorVersion = version[0] - '0'; + uint32_t mMinorVersion = version[2] - '0'; + + // The minor version shouldn't get to two digits. + ASSERT(version.size() <= 3 || !isdigit(version[3])); + + return LoadDesktopGLProcs(mMajorVersion, mMinorVersion); + } + + return false; +} + +template +bool OpenGLFunctions::LoadProc(T *memberProc, const char *name) +{ + if (backendType == BACKENDTYPE::BACKENDTYPEANGLE) + { +#ifdef _WIN32 + *memberProc = reinterpret_cast(GetProcAddress(hinstance, name)); +#endif + } + else // OpenGL + { + *memberProc = reinterpret_cast(glfwGetProcAddress(name)); + } + + ASSERT(memberProc != nullptr); + + if (memberProc == nullptr) + { + return false; + } + + return true; +} + +bool OpenGLFunctions::LoadOpenGLESProcs(int majorVersion, int minorVersion) +{ + // OpenGL ES 2.0 + if (majorVersion > 2 || (majorVersion == 2 && minorVersion >= 0)) + { + (LoadProc(&ActiveTexture, "glActiveTexture")); + (LoadProc(&AttachShader, "glAttachShader")); + (LoadProc(&BindAttribLocation, "glBindAttribLocation")); + (LoadProc(&BindBuffer, "glBindBuffer")); + (LoadProc(&BindFramebuffer, "glBindFramebuffer")); + (LoadProc(&BindRenderbuffer, "glBindRenderbuffer")); + (LoadProc(&BindTexture, "glBindTexture")); + (LoadProc(&BlendColor, "glBlendColor")); + (LoadProc(&BlendEquation, "glBlendEquation")); + (LoadProc(&BlendEquationSeparate, "glBlendEquationSeparate")); + (LoadProc(&BlendFunc, "glBlendFunc")); + (LoadProc(&BlendFuncSeparate, "glBlendFuncSeparate")); + (LoadProc(&BufferData, "glBufferData")); + (LoadProc(&BufferSubData, "glBufferSubData")); + (LoadProc(&CheckFramebufferStatus, "glCheckFramebufferStatus")); + (LoadProc(&Clear, "glClear")); + (LoadProc(&ClearColor, "glClearColor")); + (LoadProc(&ClearDepthf, "glClearDepthf")); + (LoadProc(&ClearStencil, "glClearStencil")); + (LoadProc(&ColorMask, "glColorMask")); + (LoadProc(&CompileShader, "glCompileShader")); + (LoadProc(&CompressedTexImage2D, "glCompressedTexImage2D")); + (LoadProc(&CompressedTexSubImage2D, "glCompressedTexSubImage2D")); + (LoadProc(&CopyTexImage2D, "glCopyTexImage2D")); + (LoadProc(&CopyTexSubImage2D, "glCopyTexSubImage2D")); + (LoadProc(&CreateProgram, "glCreateProgram")); + (LoadProc(&CreateShader, "glCreateShader")); + (LoadProc(&CullFace, "glCullFace")); + (LoadProc(&DeleteBuffers, "glDeleteBuffers")); + (LoadProc(&DeleteFramebuffers, "glDeleteFramebuffers")); + (LoadProc(&DeleteProgram, "glDeleteProgram")); + (LoadProc(&DeleteRenderbuffers, "glDeleteRenderbuffers")); + (LoadProc(&DeleteShader, "glDeleteShader")); + (LoadProc(&DeleteTextures, "glDeleteTextures")); + (LoadProc(&DepthFunc, "glDepthFunc")); + (LoadProc(&DepthMask, "glDepthMask")); + (LoadProc(&DepthRangef, "glDepthRangef")); + (LoadProc(&DetachShader, "glDetachShader")); + (LoadProc(&Disable, "glDisable")); + (LoadProc(&DisableVertexAttribArray, "glDisableVertexAttribArray")); + (LoadProc(&DrawArrays, "glDrawArrays")); + (LoadProc(&DrawElements, "glDrawElements")); + (LoadProc(&Enable, "glEnable")); + (LoadProc(&EnableVertexAttribArray, "glEnableVertexAttribArray")); + (LoadProc(&Finish, "glFinish")); + (LoadProc(&Flush, "glFlush")); + (LoadProc(&FramebufferRenderbuffer, "glFramebufferRenderbuffer")); + (LoadProc(&FramebufferTexture2D, "glFramebufferTexture2D")); + (LoadProc(&FrontFace, "glFrontFace")); + (LoadProc(&GenBuffers, "glGenBuffers")); + (LoadProc(&GenerateMipmap, "glGenerateMipmap")); + (LoadProc(&GenFramebuffers, "glGenFramebuffers")); + (LoadProc(&GenRenderbuffers, "glGenRenderbuffers")); + (LoadProc(&GenTextures, "glGenTextures")); + (LoadProc(&GetActiveAttrib, "glGetActiveAttrib")); + (LoadProc(&GetActiveUniform, "glGetActiveUniform")); + (LoadProc(&GetAttachedShaders, "glGetAttachedShaders")); + (LoadProc(&GetAttribLocation, "glGetAttribLocation")); + (LoadProc(&GetBooleanv, "glGetBooleanv")); + (LoadProc(&GetBufferParameteriv, "glGetBufferParameteriv")); + (LoadProc(&GetError, "glGetError")); + (LoadProc(&GetFloatv, "glGetFloatv")); + (LoadProc(&GetFramebufferAttachmentParameteriv, "glGetFramebufferAttachmentParameteriv")); + (LoadProc(&GetIntegerv, "glGetIntegerv")); + (LoadProc(&GetProgramiv, "glGetProgramiv")); + (LoadProc(&GetProgramInfoLog, "glGetProgramInfoLog")); + (LoadProc(&GetRenderbufferParameteriv, "glGetRenderbufferParameteriv")); + (LoadProc(&GetShaderiv, "glGetShaderiv")); + (LoadProc(&GetShaderInfoLog, "glGetShaderInfoLog")); + (LoadProc(&GetShaderPrecisionFormat, "glGetShaderPrecisionFormat")); + (LoadProc(&GetShaderSource, "glGetShaderSource")); + (LoadProc(&GetString, "glGetString")); + (LoadProc(&GetTexParameterfv, "glGetTexParameterfv")); + (LoadProc(&GetTexParameteriv, "glGetTexParameteriv")); + (LoadProc(&GetUniformfv, "glGetUniformfv")); + (LoadProc(&GetUniformiv, "glGetUniformiv")); + (LoadProc(&GetUniformLocation, "glGetUniformLocation")); + (LoadProc(&GetVertexAttribfv, "glGetVertexAttribfv")); + (LoadProc(&GetVertexAttribiv, "glGetVertexAttribiv")); + (LoadProc(&GetVertexAttribPointerv, "glGetVertexAttribPointerv")); + (LoadProc(&Hint, "glHint")); + (LoadProc(&IsBuffer, "glIsBuffer")); + (LoadProc(&IsEnabled, "glIsEnabled")); + (LoadProc(&IsFramebuffer, "glIsFramebuffer")); + (LoadProc(&IsProgram, "glIsProgram")); + (LoadProc(&IsRenderbuffer, "glIsRenderbuffer")); + (LoadProc(&IsShader, "glIsShader")); + (LoadProc(&IsTexture, "glIsTexture")); + (LoadProc(&LineWidth, "glLineWidth")); + (LoadProc(&LinkProgram, "glLinkProgram")); + (LoadProc(&PixelStorei, "glPixelStorei")); + (LoadProc(&PolygonOffset, "glPolygonOffset")); + (LoadProc(&ReadPixels, "glReadPixels")); + (LoadProc(&ReleaseShaderCompiler, "glReleaseShaderCompiler")); + (LoadProc(&RenderbufferStorage, "glRenderbufferStorage")); + (LoadProc(&SampleCoverage, "glSampleCoverage")); + (LoadProc(&Scissor, "glScissor")); + (LoadProc(&ShaderBinary, "glShaderBinary")); + (LoadProc(&ShaderSource, "glShaderSource")); + (LoadProc(&StencilFunc, "glStencilFunc")); + (LoadProc(&StencilFuncSeparate, "glStencilFuncSeparate")); + (LoadProc(&StencilMask, "glStencilMask")); + (LoadProc(&StencilMaskSeparate, "glStencilMaskSeparate")); + (LoadProc(&StencilOp, "glStencilOp")); + (LoadProc(&StencilOpSeparate, "glStencilOpSeparate")); + (LoadProc(&TexImage2D, "glTexImage2D")); + (LoadProc(&TexParameterf, "glTexParameterf")); + (LoadProc(&TexParameterfv, "glTexParameterfv")); + (LoadProc(&TexParameteri, "glTexParameteri")); + (LoadProc(&TexParameteriv, "glTexParameteriv")); + (LoadProc(&TexSubImage2D, "glTexSubImage2D")); + (LoadProc(&Uniform1f, "glUniform1f")); + (LoadProc(&Uniform1fv, "glUniform1fv")); + (LoadProc(&Uniform1i, "glUniform1i")); + (LoadProc(&Uniform1iv, "glUniform1iv")); + (LoadProc(&Uniform2f, "glUniform2f")); + (LoadProc(&Uniform2fv, "glUniform2fv")); + (LoadProc(&Uniform2i, "glUniform2i")); + (LoadProc(&Uniform2iv, "glUniform2iv")); + (LoadProc(&Uniform3f, "glUniform3f")); + (LoadProc(&Uniform3fv, "glUniform3fv")); + (LoadProc(&Uniform3i, "glUniform3i")); + (LoadProc(&Uniform3iv, "glUniform3iv")); + (LoadProc(&Uniform4f, "glUniform4f")); + (LoadProc(&Uniform4fv, "glUniform4fv")); + (LoadProc(&Uniform4i, "glUniform4i")); + (LoadProc(&Uniform4iv, "glUniform4iv")); + (LoadProc(&UniformMatrix2fv, "glUniformMatrix2fv")); + (LoadProc(&UniformMatrix3fv, "glUniformMatrix3fv")); + (LoadProc(&UniformMatrix4fv, "glUniformMatrix4fv")); + (LoadProc(&UseProgram, "glUseProgram")); + (LoadProc(&ValidateProgram, "glValidateProgram")); + (LoadProc(&VertexAttrib1f, "glVertexAttrib1f")); + (LoadProc(&VertexAttrib1fv, "glVertexAttrib1fv")); + (LoadProc(&VertexAttrib2f, "glVertexAttrib2f")); + (LoadProc(&VertexAttrib2fv, "glVertexAttrib2fv")); + (LoadProc(&VertexAttrib3f, "glVertexAttrib3f")); + (LoadProc(&VertexAttrib3fv, "glVertexAttrib3fv")); + (LoadProc(&VertexAttrib4f, "glVertexAttrib4f")); + (LoadProc(&VertexAttrib4fv, "glVertexAttrib4fv")); + (LoadProc(&VertexAttribPointer, "glVertexAttribPointer")); + (LoadProc(&Viewport, "glViewport")); + } + + // OpenGL ES 3.0 + if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 0)) + { + (LoadProc(&ReadBuffer, "glReadBuffer")); + (LoadProc(&DrawRangeElements, "glDrawRangeElements")); + (LoadProc(&TexImage3D, "glTexImage3D")); + (LoadProc(&TexSubImage3D, "glTexSubImage3D")); + (LoadProc(&CopyTexSubImage3D, "glCopyTexSubImage3D")); + (LoadProc(&CompressedTexImage3D, "glCompressedTexImage3D")); + (LoadProc(&CompressedTexSubImage3D, "glCompressedTexSubImage3D")); + (LoadProc(&GenQueries, "glGenQueries")); + (LoadProc(&DeleteQueries, "glDeleteQueries")); + (LoadProc(&IsQuery, "glIsQuery")); + (LoadProc(&BeginQuery, "glBeginQuery")); + (LoadProc(&EndQuery, "glEndQuery")); + (LoadProc(&GetQueryiv, "glGetQueryiv")); + (LoadProc(&GetQueryObjectuiv, "glGetQueryObjectuiv")); + (LoadProc(&UnmapBuffer, "glUnmapBuffer")); + (LoadProc(&GetBufferPointerv, "glGetBufferPointerv")); + (LoadProc(&DrawBuffers, "glDrawBuffers")); + (LoadProc(&UniformMatrix2x3fv, "glUniformMatrix2x3fv")); + (LoadProc(&UniformMatrix3x2fv, "glUniformMatrix3x2fv")); + (LoadProc(&UniformMatrix2x4fv, "glUniformMatrix2x4fv")); + (LoadProc(&UniformMatrix4x2fv, "glUniformMatrix4x2fv")); + (LoadProc(&UniformMatrix3x4fv, "glUniformMatrix3x4fv")); + (LoadProc(&UniformMatrix4x3fv, "glUniformMatrix4x3fv")); + (LoadProc(&BlitFramebuffer, "glBlitFramebuffer")); + (LoadProc(&RenderbufferStorageMultisample, "glRenderbufferStorageMultisample")); + (LoadProc(&FramebufferTextureLayer, "glFramebufferTextureLayer")); + (LoadProc(&MapBufferRange, "glMapBufferRange")); + (LoadProc(&FlushMappedBufferRange, "glFlushMappedBufferRange")); + (LoadProc(&BindVertexArray, "glBindVertexArray")); + (LoadProc(&DeleteVertexArrays, "glDeleteVertexArrays")); + (LoadProc(&GenVertexArrays, "glGenVertexArrays")); + (LoadProc(&IsVertexArray, "glIsVertexArray")); + (LoadProc(&GetIntegeri_v, "glGetIntegeri_v")); + (LoadProc(&BeginTransformFeedback, "glBeginTransformFeedback")); + (LoadProc(&EndTransformFeedback, "glEndTransformFeedback")); + (LoadProc(&BindBufferRange, "glBindBufferRange")); + (LoadProc(&BindBufferBase, "glBindBufferBase")); + (LoadProc(&TransformFeedbackVaryings, "glTransformFeedbackVaryings")); + (LoadProc(&GetTransformFeedbackVarying, "glGetTransformFeedbackVarying")); + (LoadProc(&VertexAttribIPointer, "glVertexAttribIPointer")); + (LoadProc(&GetVertexAttribIiv, "glGetVertexAttribIiv")); + (LoadProc(&GetVertexAttribIuiv, "glGetVertexAttribIuiv")); + (LoadProc(&VertexAttribI4i, "glVertexAttribI4i")); + (LoadProc(&VertexAttribI4ui, "glVertexAttribI4ui")); + (LoadProc(&VertexAttribI4iv, "glVertexAttribI4iv")); + (LoadProc(&VertexAttribI4uiv, "glVertexAttribI4uiv")); + (LoadProc(&GetUniformuiv, "glGetUniformuiv")); + (LoadProc(&GetFragDataLocation, "glGetFragDataLocation")); + (LoadProc(&Uniform1ui, "glUniform1ui")); + (LoadProc(&Uniform2ui, "glUniform2ui")); + (LoadProc(&Uniform3ui, "glUniform3ui")); + (LoadProc(&Uniform4ui, "glUniform4ui")); + (LoadProc(&Uniform1uiv, "glUniform1uiv")); + (LoadProc(&Uniform2uiv, "glUniform2uiv")); + (LoadProc(&Uniform3uiv, "glUniform3uiv")); + (LoadProc(&Uniform4uiv, "glUniform4uiv")); + (LoadProc(&ClearBufferiv, "glClearBufferiv")); + (LoadProc(&ClearBufferuiv, "glClearBufferuiv")); + (LoadProc(&ClearBufferfv, "glClearBufferfv")); + (LoadProc(&ClearBufferfi, "glClearBufferfi")); + (LoadProc(&GetStringi, "glGetStringi")); + (LoadProc(&CopyBufferSubData, "glCopyBufferSubData")); + (LoadProc(&GetUniformIndices, "glGetUniformIndices")); + (LoadProc(&GetActiveUniformsiv, "glGetActiveUniformsiv")); + (LoadProc(&GetUniformBlockIndex, "glGetUniformBlockIndex")); + (LoadProc(&GetActiveUniformBlockiv, "glGetActiveUniformBlockiv")); + (LoadProc(&GetActiveUniformBlockName, "glGetActiveUniformBlockName")); + (LoadProc(&UniformBlockBinding, "glUniformBlockBinding")); + (LoadProc(&DrawArraysInstanced, "glDrawArraysInstanced")); + (LoadProc(&DrawElementsInstanced, "glDrawElementsInstanced")); + (LoadProc(&FenceSync, "glFenceSync")); + (LoadProc(&IsSync, "glIsSync")); + (LoadProc(&DeleteSync, "glDeleteSync")); + (LoadProc(&ClientWaitSync, "glClientWaitSync")); + (LoadProc(&WaitSync, "glWaitSync")); + (LoadProc(&GetInteger64v, "glGetInteger64v")); + (LoadProc(&GetSynciv, "glGetSynciv")); + (LoadProc(&GetInteger64i_v, "glGetInteger64i_v")); + (LoadProc(&GetBufferParameteri64v, "glGetBufferParameteri64v")); + (LoadProc(&GenSamplers, "glGenSamplers")); + (LoadProc(&DeleteSamplers, "glDeleteSamplers")); + (LoadProc(&IsSampler, "glIsSampler")); + (LoadProc(&BindSampler, "glBindSampler")); + (LoadProc(&SamplerParameteri, "glSamplerParameteri")); + (LoadProc(&SamplerParameteriv, "glSamplerParameteriv")); + (LoadProc(&SamplerParameterf, "glSamplerParameterf")); + (LoadProc(&SamplerParameterfv, "glSamplerParameterfv")); + (LoadProc(&GetSamplerParameteriv, "glGetSamplerParameteriv")); + (LoadProc(&GetSamplerParameterfv, "glGetSamplerParameterfv")); + (LoadProc(&VertexAttribDivisor, "glVertexAttribDivisor")); + (LoadProc(&BindTransformFeedback, "glBindTransformFeedback")); + (LoadProc(&DeleteTransformFeedbacks, "glDeleteTransformFeedbacks")); + (LoadProc(&GenTransformFeedbacks, "glGenTransformFeedbacks")); + (LoadProc(&IsTransformFeedback, "glIsTransformFeedback")); + (LoadProc(&PauseTransformFeedback, "glPauseTransformFeedback")); + (LoadProc(&ResumeTransformFeedback, "glResumeTransformFeedback")); + (LoadProc(&GetProgramBinary, "glGetProgramBinary")); + (LoadProc(&ProgramBinary, "glProgramBinary")); + (LoadProc(&ProgramParameteri, "glProgramParameteri")); + (LoadProc(&InvalidateFramebuffer, "glInvalidateFramebuffer")); + (LoadProc(&InvalidateSubFramebuffer, "glInvalidateSubFramebuffer")); + (LoadProc(&TexStorage2D, "glTexStorage2D")); + (LoadProc(&TexStorage3D, "glTexStorage3D")); + (LoadProc(&GetInternalformativ, "glGetInternalformativ")); + } + + // OpenGL ES 3.1 + if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 1)) + { + (LoadProc(&DispatchCompute, "glDispatchCompute")); + (LoadProc(&DispatchComputeIndirect, "glDispatchComputeIndirect")); + (LoadProc(&DrawArraysIndirect, "glDrawArraysIndirect")); + (LoadProc(&DrawElementsIndirect, "glDrawElementsIndirect")); + (LoadProc(&FramebufferParameteri, "glFramebufferParameteri")); + (LoadProc(&GetFramebufferParameteriv, "glGetFramebufferParameteriv")); + (LoadProc(&GetProgramInterfaceiv, "glGetProgramInterfaceiv")); + (LoadProc(&GetProgramResourceIndex, "glGetProgramResourceIndex")); + (LoadProc(&GetProgramResourceName, "glGetProgramResourceName")); + (LoadProc(&GetProgramResourceiv, "glGetProgramResourceiv")); + (LoadProc(&GetProgramResourceLocation, "glGetProgramResourceLocation")); + (LoadProc(&UseProgramStages, "glUseProgramStages")); + (LoadProc(&ActiveShaderProgram, "glActiveShaderProgram")); + (LoadProc(&CreateShaderProgramv, "glCreateShaderProgramv")); + (LoadProc(&BindProgramPipeline, "glBindProgramPipeline")); + (LoadProc(&DeleteProgramPipelines, "glDeleteProgramPipelines")); + (LoadProc(&GenProgramPipelines, "glGenProgramPipelines")); + (LoadProc(&IsProgramPipeline, "glIsProgramPipeline")); + (LoadProc(&GetProgramPipelineiv, "glGetProgramPipelineiv")); + (LoadProc(&ProgramUniform1i, "glProgramUniform1i")); + (LoadProc(&ProgramUniform2i, "glProgramUniform2i")); + (LoadProc(&ProgramUniform3i, "glProgramUniform3i")); + (LoadProc(&ProgramUniform4i, "glProgramUniform4i")); + (LoadProc(&ProgramUniform1ui, "glProgramUniform1ui")); + (LoadProc(&ProgramUniform2ui, "glProgramUniform2ui")); + (LoadProc(&ProgramUniform3ui, "glProgramUniform3ui")); + (LoadProc(&ProgramUniform4ui, "glProgramUniform4ui")); + (LoadProc(&ProgramUniform1f, "glProgramUniform1f")); + (LoadProc(&ProgramUniform2f, "glProgramUniform2f")); + (LoadProc(&ProgramUniform3f, "glProgramUniform3f")); + (LoadProc(&ProgramUniform4f, "glProgramUniform4f")); + (LoadProc(&ProgramUniform1iv, "glProgramUniform1iv")); + (LoadProc(&ProgramUniform2iv, "glProgramUniform2iv")); + (LoadProc(&ProgramUniform3iv, "glProgramUniform3iv")); + (LoadProc(&ProgramUniform4iv, "glProgramUniform4iv")); + (LoadProc(&ProgramUniform1uiv, "glProgramUniform1uiv")); + (LoadProc(&ProgramUniform2uiv, "glProgramUniform2uiv")); + (LoadProc(&ProgramUniform3uiv, "glProgramUniform3uiv")); + (LoadProc(&ProgramUniform4uiv, "glProgramUniform4uiv")); + (LoadProc(&ProgramUniform1fv, "glProgramUniform1fv")); + (LoadProc(&ProgramUniform2fv, "glProgramUniform2fv")); + (LoadProc(&ProgramUniform3fv, "glProgramUniform3fv")); + (LoadProc(&ProgramUniform4fv, "glProgramUniform4fv")); + (LoadProc(&ProgramUniformMatrix2fv, "glProgramUniformMatrix2fv")); + (LoadProc(&ProgramUniformMatrix3fv, "glProgramUniformMatrix3fv")); + (LoadProc(&ProgramUniformMatrix4fv, "glProgramUniformMatrix4fv")); + (LoadProc(&ProgramUniformMatrix2x3fv, "glProgramUniformMatrix2x3fv")); + (LoadProc(&ProgramUniformMatrix3x2fv, "glProgramUniformMatrix3x2fv")); + (LoadProc(&ProgramUniformMatrix2x4fv, "glProgramUniformMatrix2x4fv")); + (LoadProc(&ProgramUniformMatrix4x2fv, "glProgramUniformMatrix4x2fv")); + (LoadProc(&ProgramUniformMatrix3x4fv, "glProgramUniformMatrix3x4fv")); + (LoadProc(&ProgramUniformMatrix4x3fv, "glProgramUniformMatrix4x3fv")); + (LoadProc(&ValidateProgramPipeline, "glValidateProgramPipeline")); + (LoadProc(&GetProgramPipelineInfoLog, "glGetProgramPipelineInfoLog")); + (LoadProc(&BindImageTexture, "glBindImageTexture")); + (LoadProc(&GetBooleani_v, "glGetBooleani_v")); + (LoadProc(&MemoryBarrier, "glMemoryBarrier")); + (LoadProc(&MemoryBarrierByRegion, "glMemoryBarrierByRegion")); + (LoadProc(&TexStorage2DMultisample, "glTexStorage2DMultisample")); + (LoadProc(&GetMultisamplefv, "glGetMultisamplefv")); + (LoadProc(&SampleMaski, "glSampleMaski")); + (LoadProc(&GetTexLevelParameteriv, "glGetTexLevelParameteriv")); + (LoadProc(&GetTexLevelParameterfv, "glGetTexLevelParameterfv")); + (LoadProc(&BindVertexBuffer, "glBindVertexBuffer")); + (LoadProc(&VertexAttribFormat, "glVertexAttribFormat")); + (LoadProc(&VertexAttribIFormat, "glVertexAttribIFormat")); + (LoadProc(&VertexAttribBinding, "glVertexAttribBinding")); + (LoadProc(&VertexBindingDivisor, "glVertexBindingDivisor")); + } + + // OpenGL ES 3.2 + if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) + { + (LoadProc(&BlendBarrier, "glBlendBarrier")); + (LoadProc(&CopyImageSubData, "glCopyImageSubData")); + (LoadProc(&DebugMessageControl, "glDebugMessageControl")); + (LoadProc(&DebugMessageInsert, "glDebugMessageInsert")); + (LoadProc(&DebugMessageCallback, "glDebugMessageCallback")); + (LoadProc(&GetDebugMessageLog, "glGetDebugMessageLog")); + (LoadProc(&PushDebugGroup, "glPushDebugGroup")); + (LoadProc(&PopDebugGroup, "glPopDebugGroup")); + (LoadProc(&ObjectLabel, "glObjectLabel")); + (LoadProc(&GetObjectLabel, "glGetObjectLabel")); + (LoadProc(&ObjectPtrLabel, "glObjectPtrLabel")); + (LoadProc(&GetObjectPtrLabel, "glGetObjectPtrLabel")); + (LoadProc(&GetPointerv, "glGetPointerv")); + (LoadProc(&Enablei, "glEnablei")); + (LoadProc(&Disablei, "glDisablei")); + (LoadProc(&BlendEquationi, "glBlendEquationi")); + (LoadProc(&BlendEquationSeparatei, "glBlendEquationSeparatei")); + (LoadProc(&BlendFunci, "glBlendFunci")); + (LoadProc(&BlendFuncSeparatei, "glBlendFuncSeparatei")); + (LoadProc(&ColorMaski, "glColorMaski")); + (LoadProc(&IsEnabledi, "glIsEnabledi")); + (LoadProc(&DrawElementsBaseVertex, "glDrawElementsBaseVertex")); + (LoadProc(&DrawRangeElementsBaseVertex, "glDrawRangeElementsBaseVertex")); + (LoadProc(&DrawElementsInstancedBaseVertex, "glDrawElementsInstancedBaseVertex")); + (LoadProc(&FramebufferTexture, "glFramebufferTexture")); + (LoadProc(&PrimitiveBoundingBox, "glPrimitiveBoundingBox")); + (LoadProc(&GetGraphicsResetStatus, "glGetGraphicsResetStatus")); + (LoadProc(&ReadnPixels, "glReadnPixels")); + (LoadProc(&GetnUniformfv, "glGetnUniformfv")); + (LoadProc(&GetnUniformiv, "glGetnUniformiv")); + (LoadProc(&GetnUniformuiv, "glGetnUniformuiv")); + (LoadProc(&MinSampleShading, "glMinSampleShading")); + (LoadProc(&PatchParameteri, "glPatchParameteri")); + (LoadProc(&TexParameterIiv, "glTexParameterIiv")); + (LoadProc(&TexParameterIuiv, "glTexParameterIuiv")); + (LoadProc(&GetTexParameterIiv, "glGetTexParameterIiv")); + (LoadProc(&GetTexParameterIuiv, "glGetTexParameterIuiv")); + (LoadProc(&SamplerParameterIiv, "glSamplerParameterIiv")); + (LoadProc(&SamplerParameterIuiv, "glSamplerParameterIuiv")); + (LoadProc(&GetSamplerParameterIiv, "glGetSamplerParameterIiv")); + (LoadProc(&GetSamplerParameterIuiv, "glGetSamplerParameterIuiv")); + (LoadProc(&TexBuffer, "glTexBuffer")); + (LoadProc(&TexBufferRange, "glTexBufferRange")); + (LoadProc(&TexStorage3DMultisample, "glTexStorage3DMultisample")); + } + + return true; +} + +bool OpenGLFunctions::LoadDesktopGLProcs(int majorVersion, int minorVersion) +{ + // Desktop OpenGL 1.0 + if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 0)) + { + (LoadProc(&CullFace, "glCullFace")); + (LoadProc(&FrontFace, "glFrontFace")); + (LoadProc(&Hint, "glHint")); + (LoadProc(&LineWidth, "glLineWidth")); + (LoadProc(&PointSize, "glPointSize")); + (LoadProc(&PolygonMode, "glPolygonMode")); + (LoadProc(&Scissor, "glScissor")); + (LoadProc(&TexParameterf, "glTexParameterf")); + (LoadProc(&TexParameterfv, "glTexParameterfv")); + (LoadProc(&TexParameteri, "glTexParameteri")); + (LoadProc(&TexParameteriv, "glTexParameteriv")); + (LoadProc(&TexImage1D, "glTexImage1D")); + (LoadProc(&TexImage2D, "glTexImage2D")); + (LoadProc(&DrawBuffer, "glDrawBuffer")); + (LoadProc(&Clear, "glClear")); + (LoadProc(&ClearColor, "glClearColor")); + (LoadProc(&ClearStencil, "glClearStencil")); + (LoadProc(&ClearDepth, "glClearDepth")); + (LoadProc(&StencilMask, "glStencilMask")); + (LoadProc(&ColorMask, "glColorMask")); + (LoadProc(&DepthMask, "glDepthMask")); + (LoadProc(&Disable, "glDisable")); + (LoadProc(&Enable, "glEnable")); + (LoadProc(&Finish, "glFinish")); + (LoadProc(&Flush, "glFlush")); + (LoadProc(&BlendFunc, "glBlendFunc")); + (LoadProc(&LogicOp, "glLogicOp")); + (LoadProc(&StencilFunc, "glStencilFunc")); + (LoadProc(&StencilOp, "glStencilOp")); + (LoadProc(&DepthFunc, "glDepthFunc")); + (LoadProc(&PixelStoref, "glPixelStoref")); + (LoadProc(&PixelStorei, "glPixelStorei")); + (LoadProc(&ReadBuffer, "glReadBuffer")); + (LoadProc(&ReadPixels, "glReadPixels")); + (LoadProc(&GetBooleanv, "glGetBooleanv")); + (LoadProc(&GetDoublev, "glGetDoublev")); + (LoadProc(&GetError, "glGetError")); + (LoadProc(&GetFloatv, "glGetFloatv")); + (LoadProc(&GetIntegerv, "glGetIntegerv")); + (LoadProc(&GetString, "glGetString")); + (LoadProc(&GetTexImage, "glGetTexImage")); + (LoadProc(&GetTexParameterfv, "glGetTexParameterfv")); + (LoadProc(&GetTexParameteriv, "glGetTexParameteriv")); + (LoadProc(&GetTexLevelParameterfv, "glGetTexLevelParameterfv")); + (LoadProc(&GetTexLevelParameteriv, "glGetTexLevelParameteriv")); + (LoadProc(&IsEnabled, "glIsEnabled")); + (LoadProc(&DepthRange, "glDepthRange")); + (LoadProc(&Viewport, "glViewport")); + } + + // Desktop OpenGL 1.1 + if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 1)) + { + (LoadProc(&DrawArrays, "glDrawArrays")); + (LoadProc(&DrawElements, "glDrawElements")); + (LoadProc(&PolygonOffset, "glPolygonOffset")); + (LoadProc(&CopyTexImage1D, "glCopyTexImage1D")); + (LoadProc(&CopyTexImage2D, "glCopyTexImage2D")); + (LoadProc(&CopyTexSubImage1D, "glCopyTexSubImage1D")); + (LoadProc(&CopyTexSubImage2D, "glCopyTexSubImage2D")); + (LoadProc(&TexSubImage1D, "glTexSubImage1D")); + (LoadProc(&TexSubImage2D, "glTexSubImage2D")); + (LoadProc(&BindTexture, "glBindTexture")); + (LoadProc(&DeleteTextures, "glDeleteTextures")); + (LoadProc(&GenTextures, "glGenTextures")); + (LoadProc(&IsTexture, "glIsTexture")); + } + + // Desktop OpenGL 1.2 + if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 2)) + { + (LoadProc(&DrawRangeElements, "glDrawRangeElements")); + (LoadProc(&TexImage3D, "glTexImage3D")); + (LoadProc(&TexSubImage3D, "glTexSubImage3D")); + (LoadProc(&CopyTexSubImage3D, "glCopyTexSubImage3D")); + } + + // Desktop OpenGL 1.3 + if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 3)) + { + (LoadProc(&ActiveTexture, "glActiveTexture")); + (LoadProc(&SampleCoverage, "glSampleCoverage")); + (LoadProc(&CompressedTexImage3D, "glCompressedTexImage3D")); + (LoadProc(&CompressedTexImage2D, "glCompressedTexImage2D")); + (LoadProc(&CompressedTexImage1D, "glCompressedTexImage1D")); + (LoadProc(&CompressedTexSubImage3D, "glCompressedTexSubImage3D")); + (LoadProc(&CompressedTexSubImage2D, "glCompressedTexSubImage2D")); + (LoadProc(&CompressedTexSubImage1D, "glCompressedTexSubImage1D")); + (LoadProc(&GetCompressedTexImage, "glGetCompressedTexImage")); + } + + // Desktop OpenGL 1.4 + if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 4)) + { + (LoadProc(&BlendFuncSeparate, "glBlendFuncSeparate")); + (LoadProc(&MultiDrawArrays, "glMultiDrawArrays")); + (LoadProc(&MultiDrawElements, "glMultiDrawElements")); + (LoadProc(&PointParameterf, "glPointParameterf")); + (LoadProc(&PointParameterfv, "glPointParameterfv")); + (LoadProc(&PointParameteri, "glPointParameteri")); + (LoadProc(&PointParameteriv, "glPointParameteriv")); + (LoadProc(&BlendColor, "glBlendColor")); + (LoadProc(&BlendEquation, "glBlendEquation")); + } + + // Desktop OpenGL 1.5 + if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 5)) + { + (LoadProc(&GenQueries, "glGenQueries")); + (LoadProc(&DeleteQueries, "glDeleteQueries")); + (LoadProc(&IsQuery, "glIsQuery")); + (LoadProc(&BeginQuery, "glBeginQuery")); + (LoadProc(&EndQuery, "glEndQuery")); + (LoadProc(&GetQueryiv, "glGetQueryiv")); + (LoadProc(&GetQueryObjectiv, "glGetQueryObjectiv")); + (LoadProc(&GetQueryObjectuiv, "glGetQueryObjectuiv")); + (LoadProc(&BindBuffer, "glBindBuffer")); + (LoadProc(&DeleteBuffers, "glDeleteBuffers")); + (LoadProc(&GenBuffers, "glGenBuffers")); + (LoadProc(&IsBuffer, "glIsBuffer")); + (LoadProc(&BufferData, "glBufferData")); + (LoadProc(&BufferSubData, "glBufferSubData")); + (LoadProc(&GetBufferSubData, "glGetBufferSubData")); + (LoadProc(&MapBuffer, "glMapBuffer")); + (LoadProc(&UnmapBuffer, "glUnmapBuffer")); + (LoadProc(&GetBufferParameteriv, "glGetBufferParameteriv")); + (LoadProc(&GetBufferPointerv, "glGetBufferPointerv")); + } + + // Desktop OpenGL 2.0 + if (majorVersion > 2 || (majorVersion == 2 && minorVersion >= 0)) + { + (LoadProc(&BlendEquationSeparate, "glBlendEquationSeparate")); + (LoadProc(&DrawBuffers, "glDrawBuffers")); + (LoadProc(&StencilOpSeparate, "glStencilOpSeparate")); + (LoadProc(&StencilFuncSeparate, "glStencilFuncSeparate")); + (LoadProc(&StencilMaskSeparate, "glStencilMaskSeparate")); + (LoadProc(&AttachShader, "glAttachShader")); + (LoadProc(&BindAttribLocation, "glBindAttribLocation")); + (LoadProc(&CompileShader, "glCompileShader")); + (LoadProc(&CreateProgram, "glCreateProgram")); + (LoadProc(&CreateShader, "glCreateShader")); + (LoadProc(&DeleteProgram, "glDeleteProgram")); + (LoadProc(&DeleteShader, "glDeleteShader")); + (LoadProc(&DetachShader, "glDetachShader")); + (LoadProc(&DisableVertexAttribArray, "glDisableVertexAttribArray")); + (LoadProc(&EnableVertexAttribArray, "glEnableVertexAttribArray")); + (LoadProc(&GetActiveAttrib, "glGetActiveAttrib")); + (LoadProc(&GetActiveUniform, "glGetActiveUniform")); + (LoadProc(&GetAttachedShaders, "glGetAttachedShaders")); + (LoadProc(&GetAttribLocation, "glGetAttribLocation")); + (LoadProc(&GetProgramiv, "glGetProgramiv")); + (LoadProc(&GetProgramInfoLog, "glGetProgramInfoLog")); + (LoadProc(&GetShaderiv, "glGetShaderiv")); + (LoadProc(&GetShaderInfoLog, "glGetShaderInfoLog")); + (LoadProc(&GetShaderSource, "glGetShaderSource")); + (LoadProc(&GetUniformLocation, "glGetUniformLocation")); + (LoadProc(&GetUniformfv, "glGetUniformfv")); + (LoadProc(&GetUniformiv, "glGetUniformiv")); + (LoadProc(&GetVertexAttribdv, "glGetVertexAttribdv")); + (LoadProc(&GetVertexAttribfv, "glGetVertexAttribfv")); + (LoadProc(&GetVertexAttribiv, "glGetVertexAttribiv")); + (LoadProc(&GetVertexAttribPointerv, "glGetVertexAttribPointerv")); + (LoadProc(&IsProgram, "glIsProgram")); + (LoadProc(&IsShader, "glIsShader")); + (LoadProc(&LinkProgram, "glLinkProgram")); + (LoadProc(&ShaderSource, "glShaderSource")); + (LoadProc(&UseProgram, "glUseProgram")); + (LoadProc(&Uniform1f, "glUniform1f")); + (LoadProc(&Uniform2f, "glUniform2f")); + (LoadProc(&Uniform3f, "glUniform3f")); + (LoadProc(&Uniform4f, "glUniform4f")); + (LoadProc(&Uniform1i, "glUniform1i")); + (LoadProc(&Uniform2i, "glUniform2i")); + (LoadProc(&Uniform3i, "glUniform3i")); + (LoadProc(&Uniform4i, "glUniform4i")); + (LoadProc(&Uniform1fv, "glUniform1fv")); + (LoadProc(&Uniform2fv, "glUniform2fv")); + (LoadProc(&Uniform3fv, "glUniform3fv")); + (LoadProc(&Uniform4fv, "glUniform4fv")); + (LoadProc(&Uniform1iv, "glUniform1iv")); + (LoadProc(&Uniform2iv, "glUniform2iv")); + (LoadProc(&Uniform3iv, "glUniform3iv")); + (LoadProc(&Uniform4iv, "glUniform4iv")); + (LoadProc(&UniformMatrix2fv, "glUniformMatrix2fv")); + (LoadProc(&UniformMatrix3fv, "glUniformMatrix3fv")); + (LoadProc(&UniformMatrix4fv, "glUniformMatrix4fv")); + (LoadProc(&ValidateProgram, "glValidateProgram")); + (LoadProc(&VertexAttrib1d, "glVertexAttrib1d")); + (LoadProc(&VertexAttrib1dv, "glVertexAttrib1dv")); + (LoadProc(&VertexAttrib1f, "glVertexAttrib1f")); + (LoadProc(&VertexAttrib1fv, "glVertexAttrib1fv")); + (LoadProc(&VertexAttrib1s, "glVertexAttrib1s")); + (LoadProc(&VertexAttrib1sv, "glVertexAttrib1sv")); + (LoadProc(&VertexAttrib2d, "glVertexAttrib2d")); + (LoadProc(&VertexAttrib2dv, "glVertexAttrib2dv")); + (LoadProc(&VertexAttrib2f, "glVertexAttrib2f")); + (LoadProc(&VertexAttrib2fv, "glVertexAttrib2fv")); + (LoadProc(&VertexAttrib2s, "glVertexAttrib2s")); + (LoadProc(&VertexAttrib2sv, "glVertexAttrib2sv")); + (LoadProc(&VertexAttrib3d, "glVertexAttrib3d")); + (LoadProc(&VertexAttrib3dv, "glVertexAttrib3dv")); + (LoadProc(&VertexAttrib3f, "glVertexAttrib3f")); + (LoadProc(&VertexAttrib3fv, "glVertexAttrib3fv")); + (LoadProc(&VertexAttrib3s, "glVertexAttrib3s")); + (LoadProc(&VertexAttrib3sv, "glVertexAttrib3sv")); + (LoadProc(&VertexAttrib4Nbv, "glVertexAttrib4Nbv")); + (LoadProc(&VertexAttrib4Niv, "glVertexAttrib4Niv")); + (LoadProc(&VertexAttrib4Nsv, "glVertexAttrib4Nsv")); + (LoadProc(&VertexAttrib4Nub, "glVertexAttrib4Nub")); + (LoadProc(&VertexAttrib4Nubv, "glVertexAttrib4Nubv")); + (LoadProc(&VertexAttrib4Nuiv, "glVertexAttrib4Nuiv")); + (LoadProc(&VertexAttrib4Nusv, "glVertexAttrib4Nusv")); + (LoadProc(&VertexAttrib4bv, "glVertexAttrib4bv")); + (LoadProc(&VertexAttrib4d, "glVertexAttrib4d")); + (LoadProc(&VertexAttrib4dv, "glVertexAttrib4dv")); + (LoadProc(&VertexAttrib4f, "glVertexAttrib4f")); + (LoadProc(&VertexAttrib4fv, "glVertexAttrib4fv")); + (LoadProc(&VertexAttrib4iv, "glVertexAttrib4iv")); + (LoadProc(&VertexAttrib4s, "glVertexAttrib4s")); + (LoadProc(&VertexAttrib4sv, "glVertexAttrib4sv")); + (LoadProc(&VertexAttrib4ubv, "glVertexAttrib4ubv")); + (LoadProc(&VertexAttrib4uiv, "glVertexAttrib4uiv")); + (LoadProc(&VertexAttrib4usv, "glVertexAttrib4usv")); + (LoadProc(&VertexAttribPointer, "glVertexAttribPointer")); + } + + // Desktop OpenGL 2.1 + if (majorVersion > 2 || (majorVersion == 2 && minorVersion >= 1)) + { + (LoadProc(&UniformMatrix2x3fv, "glUniformMatrix2x3fv")); + (LoadProc(&UniformMatrix3x2fv, "glUniformMatrix3x2fv")); + (LoadProc(&UniformMatrix2x4fv, "glUniformMatrix2x4fv")); + (LoadProc(&UniformMatrix4x2fv, "glUniformMatrix4x2fv")); + (LoadProc(&UniformMatrix3x4fv, "glUniformMatrix3x4fv")); + (LoadProc(&UniformMatrix4x3fv, "glUniformMatrix4x3fv")); + } + + // Desktop OpenGL 3.0 + if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 0)) + { + (LoadProc(&ColorMaski, "glColorMaski")); + (LoadProc(&GetBooleani_v, "glGetBooleani_v")); + (LoadProc(&GetIntegeri_v, "glGetIntegeri_v")); + (LoadProc(&Enablei, "glEnablei")); + (LoadProc(&Disablei, "glDisablei")); + (LoadProc(&IsEnabledi, "glIsEnabledi")); + (LoadProc(&BeginTransformFeedback, "glBeginTransformFeedback")); + (LoadProc(&EndTransformFeedback, "glEndTransformFeedback")); + (LoadProc(&BindBufferRange, "glBindBufferRange")); + (LoadProc(&BindBufferBase, "glBindBufferBase")); + (LoadProc(&TransformFeedbackVaryings, "glTransformFeedbackVaryings")); + (LoadProc(&GetTransformFeedbackVarying, "glGetTransformFeedbackVarying")); + (LoadProc(&ClampColor, "glClampColor")); + (LoadProc(&BeginConditionalRender, "glBeginConditionalRender")); + (LoadProc(&EndConditionalRender, "glEndConditionalRender")); + (LoadProc(&VertexAttribIPointer, "glVertexAttribIPointer")); + (LoadProc(&GetVertexAttribIiv, "glGetVertexAttribIiv")); + (LoadProc(&GetVertexAttribIuiv, "glGetVertexAttribIuiv")); + (LoadProc(&VertexAttribI1i, "glVertexAttribI1i")); + (LoadProc(&VertexAttribI2i, "glVertexAttribI2i")); + (LoadProc(&VertexAttribI3i, "glVertexAttribI3i")); + (LoadProc(&VertexAttribI4i, "glVertexAttribI4i")); + (LoadProc(&VertexAttribI1ui, "glVertexAttribI1ui")); + (LoadProc(&VertexAttribI2ui, "glVertexAttribI2ui")); + (LoadProc(&VertexAttribI3ui, "glVertexAttribI3ui")); + (LoadProc(&VertexAttribI4ui, "glVertexAttribI4ui")); + (LoadProc(&VertexAttribI1iv, "glVertexAttribI1iv")); + (LoadProc(&VertexAttribI2iv, "glVertexAttribI2iv")); + (LoadProc(&VertexAttribI3iv, "glVertexAttribI3iv")); + (LoadProc(&VertexAttribI4iv, "glVertexAttribI4iv")); + (LoadProc(&VertexAttribI1uiv, "glVertexAttribI1uiv")); + (LoadProc(&VertexAttribI2uiv, "glVertexAttribI2uiv")); + (LoadProc(&VertexAttribI3uiv, "glVertexAttribI3uiv")); + (LoadProc(&VertexAttribI4uiv, "glVertexAttribI4uiv")); + (LoadProc(&VertexAttribI4bv, "glVertexAttribI4bv")); + (LoadProc(&VertexAttribI4sv, "glVertexAttribI4sv")); + (LoadProc(&VertexAttribI4ubv, "glVertexAttribI4ubv")); + (LoadProc(&VertexAttribI4usv, "glVertexAttribI4usv")); + (LoadProc(&GetUniformuiv, "glGetUniformuiv")); + (LoadProc(&BindFragDataLocation, "glBindFragDataLocation")); + (LoadProc(&GetFragDataLocation, "glGetFragDataLocation")); + (LoadProc(&Uniform1ui, "glUniform1ui")); + (LoadProc(&Uniform2ui, "glUniform2ui")); + (LoadProc(&Uniform3ui, "glUniform3ui")); + (LoadProc(&Uniform4ui, "glUniform4ui")); + (LoadProc(&Uniform1uiv, "glUniform1uiv")); + (LoadProc(&Uniform2uiv, "glUniform2uiv")); + (LoadProc(&Uniform3uiv, "glUniform3uiv")); + (LoadProc(&Uniform4uiv, "glUniform4uiv")); + (LoadProc(&TexParameterIiv, "glTexParameterIiv")); + (LoadProc(&TexParameterIuiv, "glTexParameterIuiv")); + (LoadProc(&GetTexParameterIiv, "glGetTexParameterIiv")); + (LoadProc(&GetTexParameterIuiv, "glGetTexParameterIuiv")); + (LoadProc(&ClearBufferiv, "glClearBufferiv")); + (LoadProc(&ClearBufferuiv, "glClearBufferuiv")); + (LoadProc(&ClearBufferfv, "glClearBufferfv")); + (LoadProc(&ClearBufferfi, "glClearBufferfi")); + (LoadProc(&GetStringi, "glGetStringi")); + (LoadProc(&IsRenderbuffer, "glIsRenderbuffer")); + (LoadProc(&BindRenderbuffer, "glBindRenderbuffer")); + (LoadProc(&DeleteRenderbuffers, "glDeleteRenderbuffers")); + (LoadProc(&GenRenderbuffers, "glGenRenderbuffers")); + (LoadProc(&RenderbufferStorage, "glRenderbufferStorage")); + (LoadProc(&GetRenderbufferParameteriv, "glGetRenderbufferParameteriv")); + (LoadProc(&IsFramebuffer, "glIsFramebuffer")); + (LoadProc(&BindFramebuffer, "glBindFramebuffer")); + (LoadProc(&DeleteFramebuffers, "glDeleteFramebuffers")); + (LoadProc(&GenFramebuffers, "glGenFramebuffers")); + (LoadProc(&CheckFramebufferStatus, "glCheckFramebufferStatus")); + (LoadProc(&FramebufferTexture1D, "glFramebufferTexture1D")); + (LoadProc(&FramebufferTexture2D, "glFramebufferTexture2D")); + (LoadProc(&FramebufferTexture3D, "glFramebufferTexture3D")); + (LoadProc(&FramebufferRenderbuffer, "glFramebufferRenderbuffer")); + (LoadProc(&GetFramebufferAttachmentParameteriv, "glGetFramebufferAttachmentParameteriv")); + (LoadProc(&GenerateMipmap, "glGenerateMipmap")); + (LoadProc(&BlitFramebuffer, "glBlitFramebuffer")); + (LoadProc(&RenderbufferStorageMultisample, "glRenderbufferStorageMultisample")); + (LoadProc(&FramebufferTextureLayer, "glFramebufferTextureLayer")); + (LoadProc(&MapBufferRange, "glMapBufferRange")); + (LoadProc(&FlushMappedBufferRange, "glFlushMappedBufferRange")); + (LoadProc(&BindVertexArray, "glBindVertexArray")); + (LoadProc(&DeleteVertexArrays, "glDeleteVertexArrays")); + (LoadProc(&GenVertexArrays, "glGenVertexArrays")); + (LoadProc(&IsVertexArray, "glIsVertexArray")); + } + + // Desktop OpenGL 3.1 + if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 1)) + { + (LoadProc(&DrawArraysInstanced, "glDrawArraysInstanced")); + (LoadProc(&DrawElementsInstanced, "glDrawElementsInstanced")); + (LoadProc(&TexBuffer, "glTexBuffer")); + (LoadProc(&PrimitiveRestartIndex, "glPrimitiveRestartIndex")); + (LoadProc(&CopyBufferSubData, "glCopyBufferSubData")); + (LoadProc(&GetUniformIndices, "glGetUniformIndices")); + (LoadProc(&GetActiveUniformsiv, "glGetActiveUniformsiv")); + (LoadProc(&GetActiveUniformName, "glGetActiveUniformName")); + (LoadProc(&GetUniformBlockIndex, "glGetUniformBlockIndex")); + (LoadProc(&GetActiveUniformBlockiv, "glGetActiveUniformBlockiv")); + (LoadProc(&GetActiveUniformBlockName, "glGetActiveUniformBlockName")); + (LoadProc(&UniformBlockBinding, "glUniformBlockBinding")); + (LoadProc(&BindBufferRange, "glBindBufferRange")); + (LoadProc(&BindBufferBase, "glBindBufferBase")); + (LoadProc(&GetIntegeri_v, "glGetIntegeri_v")); + } + + // Desktop OpenGL 3.2 + if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) + { + (LoadProc(&DrawElementsBaseVertex, "glDrawElementsBaseVertex")); + (LoadProc(&DrawRangeElementsBaseVertex, "glDrawRangeElementsBaseVertex")); + (LoadProc(&DrawElementsInstancedBaseVertex, "glDrawElementsInstancedBaseVertex")); + (LoadProc(&MultiDrawElementsBaseVertex, "glMultiDrawElementsBaseVertex")); + (LoadProc(&ProvokingVertex, "glProvokingVertex")); + (LoadProc(&FenceSync, "glFenceSync")); + (LoadProc(&IsSync, "glIsSync")); + (LoadProc(&DeleteSync, "glDeleteSync")); + (LoadProc(&ClientWaitSync, "glClientWaitSync")); + (LoadProc(&WaitSync, "glWaitSync")); + (LoadProc(&GetInteger64v, "glGetInteger64v")); + (LoadProc(&GetSynciv, "glGetSynciv")); + (LoadProc(&GetInteger64i_v, "glGetInteger64i_v")); + (LoadProc(&GetBufferParameteri64v, "glGetBufferParameteri64v")); + (LoadProc(&FramebufferTexture, "glFramebufferTexture")); + (LoadProc(&TexImage2DMultisample, "glTexImage2DMultisample")); + (LoadProc(&TexImage3DMultisample, "glTexImage3DMultisample")); + (LoadProc(&GetMultisamplefv, "glGetMultisamplefv")); + (LoadProc(&SampleMaski, "glSampleMaski")); + } + + // Desktop OpenGL 3.3 + if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 3)) + { + (LoadProc(&BindFragDataLocationIndexed, "glBindFragDataLocationIndexed")); + (LoadProc(&GetFragDataIndex, "glGetFragDataIndex")); + (LoadProc(&GenSamplers, "glGenSamplers")); + (LoadProc(&DeleteSamplers, "glDeleteSamplers")); + (LoadProc(&IsSampler, "glIsSampler")); + (LoadProc(&BindSampler, "glBindSampler")); + (LoadProc(&SamplerParameteri, "glSamplerParameteri")); + (LoadProc(&SamplerParameteriv, "glSamplerParameteriv")); + (LoadProc(&SamplerParameterf, "glSamplerParameterf")); + (LoadProc(&SamplerParameterfv, "glSamplerParameterfv")); + (LoadProc(&SamplerParameterIiv, "glSamplerParameterIiv")); + (LoadProc(&SamplerParameterIuiv, "glSamplerParameterIuiv")); + (LoadProc(&GetSamplerParameteriv, "glGetSamplerParameteriv")); + (LoadProc(&GetSamplerParameterIiv, "glGetSamplerParameterIiv")); + (LoadProc(&GetSamplerParameterfv, "glGetSamplerParameterfv")); + (LoadProc(&GetSamplerParameterIuiv, "glGetSamplerParameterIuiv")); + (LoadProc(&QueryCounter, "glQueryCounter")); + (LoadProc(&GetQueryObjecti64v, "glGetQueryObjecti64v")); + (LoadProc(&GetQueryObjectui64v, "glGetQueryObjectui64v")); + (LoadProc(&VertexAttribDivisor, "glVertexAttribDivisor")); + (LoadProc(&VertexAttribP1ui, "glVertexAttribP1ui")); + (LoadProc(&VertexAttribP1uiv, "glVertexAttribP1uiv")); + (LoadProc(&VertexAttribP2ui, "glVertexAttribP2ui")); + (LoadProc(&VertexAttribP2uiv, "glVertexAttribP2uiv")); + (LoadProc(&VertexAttribP3ui, "glVertexAttribP3ui")); + (LoadProc(&VertexAttribP3uiv, "glVertexAttribP3uiv")); + (LoadProc(&VertexAttribP4ui, "glVertexAttribP4ui")); + (LoadProc(&VertexAttribP4uiv, "glVertexAttribP4uiv")); + (LoadProc(&VertexP2ui, "glVertexP2ui")); + (LoadProc(&VertexP2uiv, "glVertexP2uiv")); + (LoadProc(&VertexP3ui, "glVertexP3ui")); + (LoadProc(&VertexP3uiv, "glVertexP3uiv")); + (LoadProc(&VertexP4ui, "glVertexP4ui")); + (LoadProc(&VertexP4uiv, "glVertexP4uiv")); + (LoadProc(&TexCoordP1ui, "glTexCoordP1ui")); + (LoadProc(&TexCoordP1uiv, "glTexCoordP1uiv")); + (LoadProc(&TexCoordP2ui, "glTexCoordP2ui")); + (LoadProc(&TexCoordP2uiv, "glTexCoordP2uiv")); + (LoadProc(&TexCoordP3ui, "glTexCoordP3ui")); + (LoadProc(&TexCoordP3uiv, "glTexCoordP3uiv")); + (LoadProc(&TexCoordP4ui, "glTexCoordP4ui")); + (LoadProc(&TexCoordP4uiv, "glTexCoordP4uiv")); + (LoadProc(&MultiTexCoordP1ui, "glMultiTexCoordP1ui")); + (LoadProc(&MultiTexCoordP1uiv, "glMultiTexCoordP1uiv")); + (LoadProc(&MultiTexCoordP2ui, "glMultiTexCoordP2ui")); + (LoadProc(&MultiTexCoordP2uiv, "glMultiTexCoordP2uiv")); + (LoadProc(&MultiTexCoordP3ui, "glMultiTexCoordP3ui")); + (LoadProc(&MultiTexCoordP3uiv, "glMultiTexCoordP3uiv")); + (LoadProc(&MultiTexCoordP4ui, "glMultiTexCoordP4ui")); + (LoadProc(&MultiTexCoordP4uiv, "glMultiTexCoordP4uiv")); + (LoadProc(&NormalP3ui, "glNormalP3ui")); + (LoadProc(&NormalP3uiv, "glNormalP3uiv")); + (LoadProc(&ColorP3ui, "glColorP3ui")); + (LoadProc(&ColorP3uiv, "glColorP3uiv")); + (LoadProc(&ColorP4ui, "glColorP4ui")); + (LoadProc(&ColorP4uiv, "glColorP4uiv")); + (LoadProc(&SecondaryColorP3ui, "glSecondaryColorP3ui")); + (LoadProc(&SecondaryColorP3uiv, "glSecondaryColorP3uiv")); + } + + // Desktop OpenGL 4.0 + if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 0)) + { + (LoadProc(&MinSampleShading, "glMinSampleShading")); + (LoadProc(&BlendEquationi, "glBlendEquationi")); + (LoadProc(&BlendEquationSeparatei, "glBlendEquationSeparatei")); + (LoadProc(&BlendFunci, "glBlendFunci")); + (LoadProc(&BlendFuncSeparatei, "glBlendFuncSeparatei")); + (LoadProc(&DrawArraysIndirect, "glDrawArraysIndirect")); + (LoadProc(&DrawElementsIndirect, "glDrawElementsIndirect")); + (LoadProc(&Uniform1d, "glUniform1d")); + (LoadProc(&Uniform2d, "glUniform2d")); + (LoadProc(&Uniform3d, "glUniform3d")); + (LoadProc(&Uniform4d, "glUniform4d")); + (LoadProc(&Uniform1dv, "glUniform1dv")); + (LoadProc(&Uniform2dv, "glUniform2dv")); + (LoadProc(&Uniform3dv, "glUniform3dv")); + (LoadProc(&Uniform4dv, "glUniform4dv")); + (LoadProc(&UniformMatrix2dv, "glUniformMatrix2dv")); + (LoadProc(&UniformMatrix3dv, "glUniformMatrix3dv")); + (LoadProc(&UniformMatrix4dv, "glUniformMatrix4dv")); + (LoadProc(&UniformMatrix2x3dv, "glUniformMatrix2x3dv")); + (LoadProc(&UniformMatrix2x4dv, "glUniformMatrix2x4dv")); + (LoadProc(&UniformMatrix3x2dv, "glUniformMatrix3x2dv")); + (LoadProc(&UniformMatrix3x4dv, "glUniformMatrix3x4dv")); + (LoadProc(&UniformMatrix4x2dv, "glUniformMatrix4x2dv")); + (LoadProc(&UniformMatrix4x3dv, "glUniformMatrix4x3dv")); + (LoadProc(&GetUniformdv, "glGetUniformdv")); + (LoadProc(&GetSubroutineUniformLocation, "glGetSubroutineUniformLocation")); + (LoadProc(&GetSubroutineIndex, "glGetSubroutineIndex")); + (LoadProc(&GetActiveSubroutineUniformiv, "glGetActiveSubroutineUniformiv")); + (LoadProc(&GetActiveSubroutineUniformName, "glGetActiveSubroutineUniformName")); + (LoadProc(&GetActiveSubroutineName, "glGetActiveSubroutineName")); + (LoadProc(&UniformSubroutinesuiv, "glUniformSubroutinesuiv")); + (LoadProc(&GetUniformSubroutineuiv, "glGetUniformSubroutineuiv")); + (LoadProc(&GetProgramStageiv, "glGetProgramStageiv")); + (LoadProc(&PatchParameteri, "glPatchParameteri")); + (LoadProc(&PatchParameterfv, "glPatchParameterfv")); + (LoadProc(&BindTransformFeedback, "glBindTransformFeedback")); + (LoadProc(&DeleteTransformFeedbacks, "glDeleteTransformFeedbacks")); + (LoadProc(&GenTransformFeedbacks, "glGenTransformFeedbacks")); + (LoadProc(&IsTransformFeedback, "glIsTransformFeedback")); + (LoadProc(&PauseTransformFeedback, "glPauseTransformFeedback")); + (LoadProc(&ResumeTransformFeedback, "glResumeTransformFeedback")); + (LoadProc(&DrawTransformFeedback, "glDrawTransformFeedback")); + (LoadProc(&DrawTransformFeedbackStream, "glDrawTransformFeedbackStream")); + (LoadProc(&BeginQueryIndexed, "glBeginQueryIndexed")); + (LoadProc(&EndQueryIndexed, "glEndQueryIndexed")); + (LoadProc(&GetQueryIndexediv, "glGetQueryIndexediv")); + } + + // Desktop OpenGL 4.1 + if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 1)) + { + (LoadProc(&ReleaseShaderCompiler, "glReleaseShaderCompiler")); + (LoadProc(&ShaderBinary, "glShaderBinary")); + (LoadProc(&GetShaderPrecisionFormat, "glGetShaderPrecisionFormat")); + (LoadProc(&DepthRangef, "glDepthRangef")); + (LoadProc(&ClearDepthf, "glClearDepthf")); + (LoadProc(&GetProgramBinary, "glGetProgramBinary")); + (LoadProc(&ProgramBinary, "glProgramBinary")); + (LoadProc(&ProgramParameteri, "glProgramParameteri")); + (LoadProc(&UseProgramStages, "glUseProgramStages")); + (LoadProc(&ActiveShaderProgram, "glActiveShaderProgram")); + (LoadProc(&CreateShaderProgramv, "glCreateShaderProgramv")); + (LoadProc(&BindProgramPipeline, "glBindProgramPipeline")); + (LoadProc(&DeleteProgramPipelines, "glDeleteProgramPipelines")); + (LoadProc(&GenProgramPipelines, "glGenProgramPipelines")); + (LoadProc(&IsProgramPipeline, "glIsProgramPipeline")); + (LoadProc(&GetProgramPipelineiv, "glGetProgramPipelineiv")); + (LoadProc(&ProgramParameteri, "glProgramParameteri")); + (LoadProc(&ProgramUniform1i, "glProgramUniform1i")); + (LoadProc(&ProgramUniform1iv, "glProgramUniform1iv")); + (LoadProc(&ProgramUniform1f, "glProgramUniform1f")); + (LoadProc(&ProgramUniform1fv, "glProgramUniform1fv")); + (LoadProc(&ProgramUniform1d, "glProgramUniform1d")); + (LoadProc(&ProgramUniform1dv, "glProgramUniform1dv")); + (LoadProc(&ProgramUniform1ui, "glProgramUniform1ui")); + (LoadProc(&ProgramUniform1uiv, "glProgramUniform1uiv")); + (LoadProc(&ProgramUniform2i, "glProgramUniform2i")); + (LoadProc(&ProgramUniform2iv, "glProgramUniform2iv")); + (LoadProc(&ProgramUniform2f, "glProgramUniform2f")); + (LoadProc(&ProgramUniform2fv, "glProgramUniform2fv")); + (LoadProc(&ProgramUniform2d, "glProgramUniform2d")); + (LoadProc(&ProgramUniform2dv, "glProgramUniform2dv")); + (LoadProc(&ProgramUniform2ui, "glProgramUniform2ui")); + (LoadProc(&ProgramUniform2uiv, "glProgramUniform2uiv")); + (LoadProc(&ProgramUniform3i, "glProgramUniform3i")); + (LoadProc(&ProgramUniform3iv, "glProgramUniform3iv")); + (LoadProc(&ProgramUniform3f, "glProgramUniform3f")); + (LoadProc(&ProgramUniform3fv, "glProgramUniform3fv")); + (LoadProc(&ProgramUniform3d, "glProgramUniform3d")); + (LoadProc(&ProgramUniform3dv, "glProgramUniform3dv")); + (LoadProc(&ProgramUniform3ui, "glProgramUniform3ui")); + (LoadProc(&ProgramUniform3uiv, "glProgramUniform3uiv")); + (LoadProc(&ProgramUniform4i, "glProgramUniform4i")); + (LoadProc(&ProgramUniform4iv, "glProgramUniform4iv")); + (LoadProc(&ProgramUniform4f, "glProgramUniform4f")); + (LoadProc(&ProgramUniform4fv, "glProgramUniform4fv")); + (LoadProc(&ProgramUniform4d, "glProgramUniform4d")); + (LoadProc(&ProgramUniform4dv, "glProgramUniform4dv")); + (LoadProc(&ProgramUniform4ui, "glProgramUniform4ui")); + (LoadProc(&ProgramUniform4uiv, "glProgramUniform4uiv")); + (LoadProc(&ProgramUniformMatrix2fv, "glProgramUniformMatrix2fv")); + (LoadProc(&ProgramUniformMatrix3fv, "glProgramUniformMatrix3fv")); + (LoadProc(&ProgramUniformMatrix4fv, "glProgramUniformMatrix4fv")); + (LoadProc(&ProgramUniformMatrix2dv, "glProgramUniformMatrix2dv")); + (LoadProc(&ProgramUniformMatrix3dv, "glProgramUniformMatrix3dv")); + (LoadProc(&ProgramUniformMatrix4dv, "glProgramUniformMatrix4dv")); + (LoadProc(&ProgramUniformMatrix2x3fv, "glProgramUniformMatrix2x3fv")); + (LoadProc(&ProgramUniformMatrix3x2fv, "glProgramUniformMatrix3x2fv")); + (LoadProc(&ProgramUniformMatrix2x4fv, "glProgramUniformMatrix2x4fv")); + (LoadProc(&ProgramUniformMatrix4x2fv, "glProgramUniformMatrix4x2fv")); + (LoadProc(&ProgramUniformMatrix3x4fv, "glProgramUniformMatrix3x4fv")); + (LoadProc(&ProgramUniformMatrix4x3fv, "glProgramUniformMatrix4x3fv")); + (LoadProc(&ProgramUniformMatrix2x3dv, "glProgramUniformMatrix2x3dv")); + (LoadProc(&ProgramUniformMatrix3x2dv, "glProgramUniformMatrix3x2dv")); + (LoadProc(&ProgramUniformMatrix2x4dv, "glProgramUniformMatrix2x4dv")); + (LoadProc(&ProgramUniformMatrix4x2dv, "glProgramUniformMatrix4x2dv")); + (LoadProc(&ProgramUniformMatrix3x4dv, "glProgramUniformMatrix3x4dv")); + (LoadProc(&ProgramUniformMatrix4x3dv, "glProgramUniformMatrix4x3dv")); + (LoadProc(&ValidateProgramPipeline, "glValidateProgramPipeline")); + (LoadProc(&GetProgramPipelineInfoLog, "glGetProgramPipelineInfoLog")); + (LoadProc(&VertexAttribL1d, "glVertexAttribL1d")); + (LoadProc(&VertexAttribL2d, "glVertexAttribL2d")); + (LoadProc(&VertexAttribL3d, "glVertexAttribL3d")); + (LoadProc(&VertexAttribL4d, "glVertexAttribL4d")); + (LoadProc(&VertexAttribL1dv, "glVertexAttribL1dv")); + (LoadProc(&VertexAttribL2dv, "glVertexAttribL2dv")); + (LoadProc(&VertexAttribL3dv, "glVertexAttribL3dv")); + (LoadProc(&VertexAttribL4dv, "glVertexAttribL4dv")); + (LoadProc(&VertexAttribLPointer, "glVertexAttribLPointer")); + (LoadProc(&GetVertexAttribLdv, "glGetVertexAttribLdv")); + (LoadProc(&ViewportArrayv, "glViewportArrayv")); + (LoadProc(&ViewportIndexedf, "glViewportIndexedf")); + (LoadProc(&ViewportIndexedfv, "glViewportIndexedfv")); + (LoadProc(&ScissorArrayv, "glScissorArrayv")); + (LoadProc(&ScissorIndexed, "glScissorIndexed")); + (LoadProc(&ScissorIndexedv, "glScissorIndexedv")); + (LoadProc(&DepthRangeArrayv, "glDepthRangeArrayv")); + (LoadProc(&DepthRangeIndexed, "glDepthRangeIndexed")); + (LoadProc(&GetFloati_v, "glGetFloati_v")); + (LoadProc(&GetDoublei_v, "glGetDoublei_v")); + } + + // Desktop OpenGL 4.2 + if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 2)) + { + (LoadProc(&DrawArraysInstancedBaseInstance, "glDrawArraysInstancedBaseInstance")); + (LoadProc(&DrawElementsInstancedBaseInstance, "glDrawElementsInstancedBaseInstance")); + (LoadProc(&DrawElementsInstancedBaseVertexBaseInstance, + "glDrawElementsInstancedBaseVertexBaseInstance")); + (LoadProc(&GetInternalformativ, "glGetInternalformativ")); + (LoadProc(&GetActiveAtomicCounterBufferiv, "glGetActiveAtomicCounterBufferiv")); + (LoadProc(&BindImageTexture, "glBindImageTexture")); + (LoadProc(&MemoryBarrier, "glMemoryBarrier")); + (LoadProc(&TexStorage1D, "glTexStorage1D")); + (LoadProc(&TexStorage2D, "glTexStorage2D")); + (LoadProc(&TexStorage3D, "glTexStorage3D")); + (LoadProc(&DrawTransformFeedbackInstanced, "glDrawTransformFeedbackInstanced")); + (LoadProc(&DrawTransformFeedbackStreamInstanced, "glDrawTransformFeedbackStreamInstanced")); + } + + // Desktop OpenGL 4.3 + if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 3)) + { + (LoadProc(&ClearBufferData, "glClearBufferData")); + (LoadProc(&ClearBufferSubData, "glClearBufferSubData")); + (LoadProc(&DispatchCompute, "glDispatchCompute")); + (LoadProc(&DispatchComputeIndirect, "glDispatchComputeIndirect")); + (LoadProc(&CopyImageSubData, "glCopyImageSubData")); + (LoadProc(&FramebufferParameteri, "glFramebufferParameteri")); + (LoadProc(&GetFramebufferParameteriv, "glGetFramebufferParameteriv")); + (LoadProc(&GetInternalformati64v, "glGetInternalformati64v")); + (LoadProc(&InvalidateTexSubImage, "glInvalidateTexSubImage")); + (LoadProc(&InvalidateTexImage, "glInvalidateTexImage")); + (LoadProc(&InvalidateBufferSubData, "glInvalidateBufferSubData")); + (LoadProc(&InvalidateBufferData, "glInvalidateBufferData")); + (LoadProc(&InvalidateFramebuffer, "glInvalidateFramebuffer")); + (LoadProc(&InvalidateSubFramebuffer, "glInvalidateSubFramebuffer")); + (LoadProc(&MultiDrawArraysIndirect, "glMultiDrawArraysIndirect")); + (LoadProc(&MultiDrawElementsIndirect, "glMultiDrawElementsIndirect")); + (LoadProc(&GetProgramInterfaceiv, "glGetProgramInterfaceiv")); + (LoadProc(&GetProgramResourceIndex, "glGetProgramResourceIndex")); + (LoadProc(&GetProgramResourceName, "glGetProgramResourceName")); + (LoadProc(&GetProgramResourceiv, "glGetProgramResourceiv")); + (LoadProc(&GetProgramResourceLocation, "glGetProgramResourceLocation")); + (LoadProc(&GetProgramResourceLocationIndex, "glGetProgramResourceLocationIndex")); + (LoadProc(&ShaderStorageBlockBinding, "glShaderStorageBlockBinding")); + (LoadProc(&TexBufferRange, "glTexBufferRange")); + (LoadProc(&TexStorage2DMultisample, "glTexStorage2DMultisample")); + (LoadProc(&TexStorage3DMultisample, "glTexStorage3DMultisample")); + (LoadProc(&TextureView, "glTextureView")); + (LoadProc(&BindVertexBuffer, "glBindVertexBuffer")); + (LoadProc(&VertexAttribFormat, "glVertexAttribFormat")); + (LoadProc(&VertexAttribIFormat, "glVertexAttribIFormat")); + (LoadProc(&VertexAttribLFormat, "glVertexAttribLFormat")); + (LoadProc(&VertexAttribBinding, "glVertexAttribBinding")); + (LoadProc(&VertexBindingDivisor, "glVertexBindingDivisor")); + (LoadProc(&DebugMessageControl, "glDebugMessageControl")); + (LoadProc(&DebugMessageInsert, "glDebugMessageInsert")); + (LoadProc(&DebugMessageCallback, "glDebugMessageCallback")); + (LoadProc(&GetDebugMessageLog, "glGetDebugMessageLog")); + (LoadProc(&PushDebugGroup, "glPushDebugGroup")); + (LoadProc(&PopDebugGroup, "glPopDebugGroup")); + (LoadProc(&ObjectLabel, "glObjectLabel")); + (LoadProc(&GetObjectLabel, "glGetObjectLabel")); + (LoadProc(&ObjectPtrLabel, "glObjectPtrLabel")); + (LoadProc(&GetObjectPtrLabel, "glGetObjectPtrLabel")); + } + + // Desktop OpenGL 4.4 + if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 4)) + { + (LoadProc(&BufferStorage, "glBufferStorage")); + (LoadProc(&ClearTexImage, "glClearTexImage")); + (LoadProc(&ClearTexSubImage, "glClearTexSubImage")); + (LoadProc(&BindBuffersBase, "glBindBuffersBase")); + (LoadProc(&BindBuffersRange, "glBindBuffersRange")); + (LoadProc(&BindTextures, "glBindTextures")); + (LoadProc(&BindSamplers, "glBindSamplers")); + (LoadProc(&BindImageTextures, "glBindImageTextures")); + (LoadProc(&BindVertexBuffers, "glBindVertexBuffers")); + } + + // Desktop OpenGL 4.5 + if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 5)) + { + (LoadProc(&ClipControl, "glClipControl")); + (LoadProc(&CreateTransformFeedbacks, "glCreateTransformFeedbacks")); + (LoadProc(&TransformFeedbackBufferBase, "glTransformFeedbackBufferBase")); + (LoadProc(&TransformFeedbackBufferRange, "glTransformFeedbackBufferRange")); + (LoadProc(&GetTransformFeedbackiv, "glGetTransformFeedbackiv")); + (LoadProc(&GetTransformFeedbacki_v, "glGetTransformFeedbacki_v")); + (LoadProc(&GetTransformFeedbacki64_v, "glGetTransformFeedbacki64_v")); + (LoadProc(&CreateBuffers, "glCreateBuffers")); + (LoadProc(&NamedBufferStorage, "glNamedBufferStorage")); + (LoadProc(&NamedBufferData, "glNamedBufferData")); + (LoadProc(&NamedBufferSubData, "glNamedBufferSubData")); + (LoadProc(&CopyNamedBufferSubData, "glCopyNamedBufferSubData")); + (LoadProc(&ClearNamedBufferData, "glClearNamedBufferData")); + (LoadProc(&ClearNamedBufferSubData, "glClearNamedBufferSubData")); + (LoadProc(&MapNamedBuffer, "glMapNamedBuffer")); + (LoadProc(&MapNamedBufferRange, "glMapNamedBufferRange")); + (LoadProc(&UnmapNamedBuffer, "glUnmapNamedBuffer")); + (LoadProc(&FlushMappedNamedBufferRange, "glFlushMappedNamedBufferRange")); + (LoadProc(&GetNamedBufferParameteriv, "glGetNamedBufferParameteriv")); + (LoadProc(&GetNamedBufferParameteri64v, "glGetNamedBufferParameteri64v")); + (LoadProc(&GetNamedBufferPointerv, "glGetNamedBufferPointerv")); + (LoadProc(&GetNamedBufferSubData, "glGetNamedBufferSubData")); + (LoadProc(&CreateFramebuffers, "glCreateFramebuffers")); + (LoadProc(&NamedFramebufferRenderbuffer, "glNamedFramebufferRenderbuffer")); + (LoadProc(&NamedFramebufferParameteri, "glNamedFramebufferParameteri")); + (LoadProc(&NamedFramebufferTexture, "glNamedFramebufferTexture")); + (LoadProc(&NamedFramebufferTextureLayer, "glNamedFramebufferTextureLayer")); + (LoadProc(&NamedFramebufferDrawBuffer, "glNamedFramebufferDrawBuffer")); + (LoadProc(&NamedFramebufferDrawBuffers, "glNamedFramebufferDrawBuffers")); + (LoadProc(&NamedFramebufferReadBuffer, "glNamedFramebufferReadBuffer")); + (LoadProc(&InvalidateNamedFramebufferData, "glInvalidateNamedFramebufferData")); + (LoadProc(&InvalidateNamedFramebufferSubData, "glInvalidateNamedFramebufferSubData")); + (LoadProc(&ClearNamedFramebufferiv, "glClearNamedFramebufferiv")); + (LoadProc(&ClearNamedFramebufferuiv, "glClearNamedFramebufferuiv")); + (LoadProc(&ClearNamedFramebufferfv, "glClearNamedFramebufferfv")); + (LoadProc(&ClearNamedFramebufferfi, "glClearNamedFramebufferfi")); + (LoadProc(&BlitNamedFramebuffer, "glBlitNamedFramebuffer")); + (LoadProc(&CheckNamedFramebufferStatus, "glCheckNamedFramebufferStatus")); + (LoadProc(&GetNamedFramebufferParameteriv, "glGetNamedFramebufferParameteriv")); + (LoadProc(&GetNamedFramebufferAttachmentParameteriv, + "glGetNamedFramebufferAttachmentParameteriv")); + (LoadProc(&CreateRenderbuffers, "glCreateRenderbuffers")); + (LoadProc(&NamedRenderbufferStorage, "glNamedRenderbufferStorage")); + (LoadProc(&NamedRenderbufferStorageMultisample, "glNamedRenderbufferStorageMultisample")); + (LoadProc(&GetNamedRenderbufferParameteriv, "glGetNamedRenderbufferParameteriv")); + (LoadProc(&CreateTextures, "glCreateTextures")); + (LoadProc(&TextureBuffer, "glTextureBuffer")); + (LoadProc(&TextureBufferRange, "glTextureBufferRange")); + (LoadProc(&TextureStorage1D, "glTextureStorage1D")); + (LoadProc(&TextureStorage2D, "glTextureStorage2D")); + (LoadProc(&TextureStorage3D, "glTextureStorage3D")); + (LoadProc(&TextureStorage2DMultisample, "glTextureStorage2DMultisample")); + (LoadProc(&TextureStorage3DMultisample, "glTextureStorage3DMultisample")); + (LoadProc(&TextureSubImage1D, "glTextureSubImage1D")); + (LoadProc(&TextureSubImage2D, "glTextureSubImage2D")); + (LoadProc(&TextureSubImage3D, "glTextureSubImage3D")); + (LoadProc(&CompressedTextureSubImage1D, "glCompressedTextureSubImage1D")); + (LoadProc(&CompressedTextureSubImage2D, "glCompressedTextureSubImage2D")); + (LoadProc(&CompressedTextureSubImage3D, "glCompressedTextureSubImage3D")); + (LoadProc(&CopyTextureSubImage1D, "glCopyTextureSubImage1D")); + (LoadProc(&CopyTextureSubImage2D, "glCopyTextureSubImage2D")); + (LoadProc(&CopyTextureSubImage3D, "glCopyTextureSubImage3D")); + (LoadProc(&TextureParameterf, "glTextureParameterf")); + (LoadProc(&TextureParameterfv, "glTextureParameterfv")); + (LoadProc(&TextureParameteri, "glTextureParameteri")); + (LoadProc(&TextureParameterIiv, "glTextureParameterIiv")); + (LoadProc(&TextureParameterIuiv, "glTextureParameterIuiv")); + (LoadProc(&TextureParameteriv, "glTextureParameteriv")); + (LoadProc(&GenerateTextureMipmap, "glGenerateTextureMipmap")); + (LoadProc(&BindTextureUnit, "glBindTextureUnit")); + (LoadProc(&GetTextureImage, "glGetTextureImage")); + (LoadProc(&GetCompressedTextureImage, "glGetCompressedTextureImage")); + (LoadProc(&GetTextureLevelParameterfv, "glGetTextureLevelParameterfv")); + (LoadProc(&GetTextureLevelParameteriv, "glGetTextureLevelParameteriv")); + (LoadProc(&GetTextureParameterfv, "glGetTextureParameterfv")); + (LoadProc(&GetTextureParameterIiv, "glGetTextureParameterIiv")); + (LoadProc(&GetTextureParameterIuiv, "glGetTextureParameterIuiv")); + (LoadProc(&GetTextureParameteriv, "glGetTextureParameteriv")); + (LoadProc(&CreateVertexArrays, "glCreateVertexArrays")); + (LoadProc(&DisableVertexArrayAttrib, "glDisableVertexArrayAttrib")); + (LoadProc(&EnableVertexArrayAttrib, "glEnableVertexArrayAttrib")); + (LoadProc(&VertexArrayElementBuffer, "glVertexArrayElementBuffer")); + (LoadProc(&VertexArrayVertexBuffer, "glVertexArrayVertexBuffer")); + (LoadProc(&VertexArrayVertexBuffers, "glVertexArrayVertexBuffers")); + (LoadProc(&VertexArrayAttribBinding, "glVertexArrayAttribBinding")); + (LoadProc(&VertexArrayAttribFormat, "glVertexArrayAttribFormat")); + (LoadProc(&VertexArrayAttribIFormat, "glVertexArrayAttribIFormat")); + (LoadProc(&VertexArrayAttribLFormat, "glVertexArrayAttribLFormat")); + (LoadProc(&VertexArrayBindingDivisor, "glVertexArrayBindingDivisor")); + (LoadProc(&GetVertexArrayiv, "glGetVertexArrayiv")); + (LoadProc(&GetVertexArrayIndexediv, "glGetVertexArrayIndexediv")); + (LoadProc(&GetVertexArrayIndexed64iv, "glGetVertexArrayIndexed64iv")); + (LoadProc(&CreateSamplers, "glCreateSamplers")); + (LoadProc(&CreateProgramPipelines, "glCreateProgramPipelines")); + (LoadProc(&CreateQueries, "glCreateQueries")); + (LoadProc(&GetQueryBufferObjecti64v, "glGetQueryBufferObjecti64v")); + (LoadProc(&GetQueryBufferObjectiv, "glGetQueryBufferObjectiv")); + (LoadProc(&GetQueryBufferObjectui64v, "glGetQueryBufferObjectui64v")); + (LoadProc(&GetQueryBufferObjectuiv, "glGetQueryBufferObjectuiv")); + (LoadProc(&MemoryBarrierByRegion, "glMemoryBarrierByRegion")); + (LoadProc(&GetTextureSubImage, "glGetTextureSubImage")); + (LoadProc(&GetCompressedTextureSubImage, "glGetCompressedTextureSubImage")); + (LoadProc(&GetGraphicsResetStatus, "glGetGraphicsResetStatus")); + (LoadProc(&GetnCompressedTexImage, "glGetnCompressedTexImage")); + (LoadProc(&GetnTexImage, "glGetnTexImage")); + (LoadProc(&GetnUniformdv, "glGetnUniformdv")); + (LoadProc(&GetnUniformfv, "glGetnUniformfv")); + (LoadProc(&GetnUniformiv, "glGetnUniformiv")); + (LoadProc(&GetnUniformuiv, "glGetnUniformuiv")); + (LoadProc(&ReadnPixels, "glReadnPixels")); + (LoadProc(&GetnMapdv, "glGetnMapdv")); + (LoadProc(&GetnMapfv, "glGetnMapfv")); + (LoadProc(&GetnMapiv, "glGetnMapiv")); + (LoadProc(&GetnPixelMapfv, "glGetnPixelMapfv")); + (LoadProc(&GetnPixelMapuiv, "glGetnPixelMapuiv")); + (LoadProc(&GetnPixelMapusv, "glGetnPixelMapusv")); + (LoadProc(&GetnPolygonStipple, "glGetnPolygonStipple")); + (LoadProc(&GetnColorTable, "glGetnColorTable")); + (LoadProc(&GetnConvolutionFilter, "glGetnConvolutionFilter")); + (LoadProc(&GetnSeparableFilter, "glGetnSeparableFilter")); + (LoadProc(&GetnHistogram, "glGetnHistogram")); + (LoadProc(&GetnMinmax, "glGetnMinmax")); + (LoadProc(&TextureBarrier, "glTextureBarrier")); + } + + // Desktop OpenGL 4.6 + if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 6)) + { + (LoadProc(&SpecializeShader, "glSpecializeShader")); + (LoadProc(&MultiDrawArraysIndirectCount, "glMultiDrawArraysIndirectCount")); + (LoadProc(&MultiDrawElementsIndirectCount, "glMultiDrawElementsIndirectCount")); + (LoadProc(&PolygonOffsetClamp, "glPolygonOffsetClamp")); + } + + return true; +} +} // namespace aquarium \ No newline at end of file diff --git a/src/aquarium-optimized/opengl/OpenGLFunctions.h b/src/aquarium-optimized/opengl/OpenGLFunctions.h new file mode 100644 index 0000000..c8c9330 --- /dev/null +++ b/src/aquarium-optimized/opengl/OpenGLFunctions.h @@ -0,0 +1,796 @@ +#ifndef OPENGL_FUNCTIONS +#define OPENGL_FUNCTIONS + +#include "OpenGLPlatforms.h" + +#include "../Aquarium.h" + +#include + +#ifdef _WIN32 +#include +#include "Windows.h" +const std::string slash = "\\"; +#elif __APPLE__ +#include +const std::string slash = "/"; +#else +#include +const std::string slash = "/"; +#endif + +namespace aquarium +{ +class Aquarium; +// using GetProcAddress = void *(*)(const char *); + +struct OpenGLFunctions +{ + public: + // OpenGL ES 2.0 + PFNGLACTIVETEXTUREPROC ActiveTexture = nullptr; + PFNGLATTACHSHADERPROC AttachShader = nullptr; + PFNGLBINDATTRIBLOCATIONPROC BindAttribLocation = nullptr; + PFNGLBINDBUFFERPROC BindBuffer = nullptr; + PFNGLBINDFRAMEBUFFERPROC BindFramebuffer = nullptr; + PFNGLBINDRENDERBUFFERPROC BindRenderbuffer = nullptr; + PFNGLBINDTEXTUREPROC BindTexture = nullptr; + PFNGLBLENDCOLORPROC BlendColor = nullptr; + PFNGLBLENDEQUATIONPROC BlendEquation = nullptr; + PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate = nullptr; + PFNGLBLENDFUNCPROC BlendFunc = nullptr; + PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate = nullptr; + PFNGLBUFFERDATAPROC BufferData = nullptr; + PFNGLBUFFERSUBDATAPROC BufferSubData = nullptr; + PFNGLCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus = nullptr; + PFNGLCLEARPROC Clear = nullptr; + PFNGLCLEARCOLORPROC ClearColor = nullptr; + PFNGLCLEARDEPTHFPROC ClearDepthf = nullptr; + PFNGLCLEARSTENCILPROC ClearStencil = nullptr; + PFNGLCOLORMASKPROC ColorMask = nullptr; + PFNGLCOMPILESHADERPROC CompileShader = nullptr; + PFNGLCOMPRESSEDTEXIMAGE2DPROC CompressedTexImage2D = nullptr; + PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC CompressedTexSubImage2D = nullptr; + PFNGLCOPYTEXIMAGE2DPROC CopyTexImage2D = nullptr; + PFNGLCOPYTEXSUBIMAGE2DPROC CopyTexSubImage2D = nullptr; + PFNGLCREATEPROGRAMPROC CreateProgram = nullptr; + PFNGLCREATESHADERPROC CreateShader = nullptr; + PFNGLCULLFACEPROC CullFace = nullptr; + PFNGLDELETEBUFFERSPROC DeleteBuffers = nullptr; + PFNGLDELETEFRAMEBUFFERSPROC DeleteFramebuffers = nullptr; + PFNGLDELETEPROGRAMPROC DeleteProgram = nullptr; + PFNGLDELETERENDERBUFFERSPROC DeleteRenderbuffers = nullptr; + PFNGLDELETESHADERPROC DeleteShader = nullptr; + PFNGLDELETETEXTURESPROC DeleteTextures = nullptr; + PFNGLDEPTHFUNCPROC DepthFunc = nullptr; + PFNGLDEPTHMASKPROC DepthMask = nullptr; + PFNGLDEPTHRANGEFPROC DepthRangef = nullptr; + PFNGLDETACHSHADERPROC DetachShader = nullptr; + PFNGLDISABLEPROC Disable = nullptr; + PFNGLDISABLEVERTEXATTRIBARRAYPROC DisableVertexAttribArray = nullptr; + PFNGLDRAWARRAYSPROC DrawArrays = nullptr; + PFNGLDRAWELEMENTSPROC DrawElements = nullptr; + PFNGLENABLEPROC Enable = nullptr; + PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray = nullptr; + PFNGLFINISHPROC Finish = nullptr; + PFNGLFLUSHPROC Flush = nullptr; + PFNGLFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer = nullptr; + PFNGLFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D = nullptr; + PFNGLFRONTFACEPROC FrontFace = nullptr; + PFNGLGENBUFFERSPROC GenBuffers = nullptr; + PFNGLGENERATEMIPMAPPROC GenerateMipmap = nullptr; + PFNGLGENFRAMEBUFFERSPROC GenFramebuffers = nullptr; + PFNGLGENRENDERBUFFERSPROC GenRenderbuffers = nullptr; + PFNGLGENTEXTURESPROC GenTextures = nullptr; + PFNGLGETACTIVEATTRIBPROC GetActiveAttrib = nullptr; + PFNGLGETACTIVEUNIFORMPROC GetActiveUniform = nullptr; + PFNGLGETATTACHEDSHADERSPROC GetAttachedShaders = nullptr; + PFNGLGETATTRIBLOCATIONPROC GetAttribLocation = nullptr; + PFNGLGETBOOLEANVPROC GetBooleanv = nullptr; + PFNGLGETBUFFERPARAMETERIVPROC GetBufferParameteriv = nullptr; + PFNGLGETERRORPROC GetError = nullptr; + PFNGLGETFLOATVPROC GetFloatv = nullptr; + PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetFramebufferAttachmentParameteriv = nullptr; + PFNGLGETINTEGERVPROC GetIntegerv = nullptr; + PFNGLGETPROGRAMIVPROC GetProgramiv = nullptr; + PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog = nullptr; + PFNGLGETRENDERBUFFERPARAMETERIVPROC GetRenderbufferParameteriv = nullptr; + PFNGLGETSHADERIVPROC GetShaderiv = nullptr; + PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog = nullptr; + PFNGLGETSHADERPRECISIONFORMATPROC GetShaderPrecisionFormat = nullptr; + PFNGLGETSHADERSOURCEPROC GetShaderSource = nullptr; + PFNGLGETSTRINGPROC GetString = nullptr; + PFNGLGETTEXPARAMETERFVPROC GetTexParameterfv = nullptr; + PFNGLGETTEXPARAMETERIVPROC GetTexParameteriv = nullptr; + PFNGLGETUNIFORMFVPROC GetUniformfv = nullptr; + PFNGLGETUNIFORMIVPROC GetUniformiv = nullptr; + PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation = nullptr; + PFNGLGETVERTEXATTRIBFVPROC GetVertexAttribfv = nullptr; + PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv = nullptr; + PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv = nullptr; + PFNGLHINTPROC Hint = nullptr; + PFNGLISBUFFERPROC IsBuffer = nullptr; + PFNGLISENABLEDPROC IsEnabled = nullptr; + PFNGLISFRAMEBUFFERPROC IsFramebuffer = nullptr; + PFNGLISPROGRAMPROC IsProgram = nullptr; + PFNGLISRENDERBUFFERPROC IsRenderbuffer = nullptr; + PFNGLISSHADERPROC IsShader = nullptr; + PFNGLISTEXTUREPROC IsTexture = nullptr; + PFNGLLINEWIDTHPROC LineWidth = nullptr; + PFNGLLINKPROGRAMPROC LinkProgram = nullptr; + PFNGLPIXELSTOREIPROC PixelStorei = nullptr; + PFNGLPOLYGONOFFSETPROC PolygonOffset = nullptr; + PFNGLREADPIXELSPROC ReadPixels = nullptr; + PFNGLRELEASESHADERCOMPILERPROC ReleaseShaderCompiler = nullptr; + PFNGLRENDERBUFFERSTORAGEPROC RenderbufferStorage = nullptr; + PFNGLSAMPLECOVERAGEPROC SampleCoverage = nullptr; + PFNGLSCISSORPROC Scissor = nullptr; + PFNGLSHADERBINARYPROC ShaderBinary = nullptr; + PFNGLSHADERSOURCEPROC ShaderSource = nullptr; + PFNGLSTENCILFUNCPROC StencilFunc = nullptr; + PFNGLSTENCILFUNCSEPARATEPROC StencilFuncSeparate = nullptr; + PFNGLSTENCILMASKPROC StencilMask = nullptr; + PFNGLSTENCILMASKSEPARATEPROC StencilMaskSeparate = nullptr; + PFNGLSTENCILOPPROC StencilOp = nullptr; + PFNGLSTENCILOPSEPARATEPROC StencilOpSeparate = nullptr; + PFNGLTEXIMAGE2DPROC TexImage2D = nullptr; + PFNGLTEXPARAMETERFPROC TexParameterf = nullptr; + PFNGLTEXPARAMETERFVPROC TexParameterfv = nullptr; + PFNGLTEXPARAMETERIPROC TexParameteri = nullptr; + PFNGLTEXPARAMETERIVPROC TexParameteriv = nullptr; + PFNGLTEXSUBIMAGE2DPROC TexSubImage2D = nullptr; + PFNGLUNIFORM1FPROC Uniform1f = nullptr; + PFNGLUNIFORM1FVPROC Uniform1fv = nullptr; + PFNGLUNIFORM1IPROC Uniform1i = nullptr; + PFNGLUNIFORM1IVPROC Uniform1iv = nullptr; + PFNGLUNIFORM2FPROC Uniform2f = nullptr; + PFNGLUNIFORM2FVPROC Uniform2fv = nullptr; + PFNGLUNIFORM2IPROC Uniform2i = nullptr; + PFNGLUNIFORM2IVPROC Uniform2iv = nullptr; + PFNGLUNIFORM3FPROC Uniform3f = nullptr; + PFNGLUNIFORM3FVPROC Uniform3fv = nullptr; + PFNGLUNIFORM3IPROC Uniform3i = nullptr; + PFNGLUNIFORM3IVPROC Uniform3iv = nullptr; + PFNGLUNIFORM4FPROC Uniform4f = nullptr; + PFNGLUNIFORM4FVPROC Uniform4fv = nullptr; + PFNGLUNIFORM4IPROC Uniform4i = nullptr; + PFNGLUNIFORM4IVPROC Uniform4iv = nullptr; + PFNGLUNIFORMMATRIX2FVPROC UniformMatrix2fv = nullptr; + PFNGLUNIFORMMATRIX3FVPROC UniformMatrix3fv = nullptr; + PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv = nullptr; + PFNGLUSEPROGRAMPROC UseProgram = nullptr; + PFNGLVALIDATEPROGRAMPROC ValidateProgram = nullptr; + PFNGLVERTEXATTRIB1FPROC VertexAttrib1f = nullptr; + PFNGLVERTEXATTRIB1FVPROC VertexAttrib1fv = nullptr; + PFNGLVERTEXATTRIB2FPROC VertexAttrib2f = nullptr; + PFNGLVERTEXATTRIB2FVPROC VertexAttrib2fv = nullptr; + PFNGLVERTEXATTRIB3FPROC VertexAttrib3f = nullptr; + PFNGLVERTEXATTRIB3FVPROC VertexAttrib3fv = nullptr; + PFNGLVERTEXATTRIB4FPROC VertexAttrib4f = nullptr; + PFNGLVERTEXATTRIB4FVPROC VertexAttrib4fv = nullptr; + PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer = nullptr; + PFNGLVIEWPORTPROC Viewport = nullptr; + + // OpenGL ES 3.0 + PFNGLREADBUFFERPROC ReadBuffer = nullptr; + PFNGLDRAWRANGEELEMENTSPROC DrawRangeElements = nullptr; + PFNGLTEXIMAGE3DPROC TexImage3D = nullptr; + PFNGLTEXSUBIMAGE3DPROC TexSubImage3D = nullptr; + PFNGLCOPYTEXSUBIMAGE3DPROC CopyTexSubImage3D = nullptr; + PFNGLCOMPRESSEDTEXIMAGE3DPROC CompressedTexImage3D = nullptr; + PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC CompressedTexSubImage3D = nullptr; + PFNGLGENQUERIESPROC GenQueries = nullptr; + PFNGLDELETEQUERIESPROC DeleteQueries = nullptr; + PFNGLISQUERYPROC IsQuery = nullptr; + PFNGLBEGINQUERYPROC BeginQuery = nullptr; + PFNGLENDQUERYPROC EndQuery = nullptr; + PFNGLGETQUERYIVPROC GetQueryiv = nullptr; + PFNGLGETQUERYOBJECTUIVPROC GetQueryObjectuiv = nullptr; + PFNGLUNMAPBUFFERPROC UnmapBuffer = nullptr; + PFNGLGETBUFFERPOINTERVPROC GetBufferPointerv = nullptr; + PFNGLDRAWBUFFERSPROC DrawBuffers = nullptr; + PFNGLUNIFORMMATRIX2X3FVPROC UniformMatrix2x3fv = nullptr; + PFNGLUNIFORMMATRIX3X2FVPROC UniformMatrix3x2fv = nullptr; + PFNGLUNIFORMMATRIX2X4FVPROC UniformMatrix2x4fv = nullptr; + PFNGLUNIFORMMATRIX4X2FVPROC UniformMatrix4x2fv = nullptr; + PFNGLUNIFORMMATRIX3X4FVPROC UniformMatrix3x4fv = nullptr; + PFNGLUNIFORMMATRIX4X3FVPROC UniformMatrix4x3fv = nullptr; + PFNGLBLITFRAMEBUFFERPROC BlitFramebuffer = nullptr; + PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC RenderbufferStorageMultisample = nullptr; + PFNGLFRAMEBUFFERTEXTURELAYERPROC FramebufferTextureLayer = nullptr; + PFNGLMAPBUFFERRANGEPROC MapBufferRange = nullptr; + PFNGLFLUSHMAPPEDBUFFERRANGEPROC FlushMappedBufferRange = nullptr; + PFNGLBINDVERTEXARRAYPROC BindVertexArray = nullptr; + PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays = nullptr; + PFNGLGENVERTEXARRAYSPROC GenVertexArrays = nullptr; + PFNGLISVERTEXARRAYPROC IsVertexArray = nullptr; + PFNGLGETINTEGERI_VPROC GetIntegeri_v = nullptr; + PFNGLBEGINTRANSFORMFEEDBACKPROC BeginTransformFeedback = nullptr; + PFNGLENDTRANSFORMFEEDBACKPROC EndTransformFeedback = nullptr; + PFNGLBINDBUFFERRANGEPROC BindBufferRange = nullptr; + PFNGLBINDBUFFERBASEPROC BindBufferBase = nullptr; + PFNGLTRANSFORMFEEDBACKVARYINGSPROC TransformFeedbackVaryings = nullptr; + PFNGLGETTRANSFORMFEEDBACKVARYINGPROC GetTransformFeedbackVarying = nullptr; + PFNGLVERTEXATTRIBIPOINTERPROC VertexAttribIPointer = nullptr; + PFNGLGETVERTEXATTRIBIIVPROC GetVertexAttribIiv = nullptr; + PFNGLGETVERTEXATTRIBIUIVPROC GetVertexAttribIuiv = nullptr; + PFNGLVERTEXATTRIBI4IPROC VertexAttribI4i = nullptr; + PFNGLVERTEXATTRIBI4UIPROC VertexAttribI4ui = nullptr; + PFNGLVERTEXATTRIBI4IVPROC VertexAttribI4iv = nullptr; + PFNGLVERTEXATTRIBI4UIVPROC VertexAttribI4uiv = nullptr; + PFNGLGETUNIFORMUIVPROC GetUniformuiv = nullptr; + PFNGLGETFRAGDATALOCATIONPROC GetFragDataLocation = nullptr; + PFNGLUNIFORM1UIPROC Uniform1ui = nullptr; + PFNGLUNIFORM2UIPROC Uniform2ui = nullptr; + PFNGLUNIFORM3UIPROC Uniform3ui = nullptr; + PFNGLUNIFORM4UIPROC Uniform4ui = nullptr; + PFNGLUNIFORM1UIVPROC Uniform1uiv = nullptr; + PFNGLUNIFORM2UIVPROC Uniform2uiv = nullptr; + PFNGLUNIFORM3UIVPROC Uniform3uiv = nullptr; + PFNGLUNIFORM4UIVPROC Uniform4uiv = nullptr; + PFNGLCLEARBUFFERIVPROC ClearBufferiv = nullptr; + PFNGLCLEARBUFFERUIVPROC ClearBufferuiv = nullptr; + PFNGLCLEARBUFFERFVPROC ClearBufferfv = nullptr; + PFNGLCLEARBUFFERFIPROC ClearBufferfi = nullptr; + PFNGLGETSTRINGIPROC GetStringi = nullptr; + PFNGLCOPYBUFFERSUBDATAPROC CopyBufferSubData = nullptr; + PFNGLGETUNIFORMINDICESPROC GetUniformIndices = nullptr; + PFNGLGETACTIVEUNIFORMSIVPROC GetActiveUniformsiv = nullptr; + PFNGLGETUNIFORMBLOCKINDEXPROC GetUniformBlockIndex = nullptr; + PFNGLGETACTIVEUNIFORMBLOCKIVPROC GetActiveUniformBlockiv = nullptr; + PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC GetActiveUniformBlockName = nullptr; + PFNGLUNIFORMBLOCKBINDINGPROC UniformBlockBinding = nullptr; + PFNGLDRAWARRAYSINSTANCEDPROC DrawArraysInstanced = nullptr; + PFNGLDRAWELEMENTSINSTANCEDPROC DrawElementsInstanced = nullptr; + PFNGLFENCESYNCPROC FenceSync = nullptr; + PFNGLISSYNCPROC IsSync = nullptr; + PFNGLDELETESYNCPROC DeleteSync = nullptr; + PFNGLCLIENTWAITSYNCPROC ClientWaitSync = nullptr; + PFNGLWAITSYNCPROC WaitSync = nullptr; + PFNGLGETINTEGER64VPROC GetInteger64v = nullptr; + PFNGLGETSYNCIVPROC GetSynciv = nullptr; + PFNGLGETINTEGER64I_VPROC GetInteger64i_v = nullptr; + PFNGLGETBUFFERPARAMETERI64VPROC GetBufferParameteri64v = nullptr; + PFNGLGENSAMPLERSPROC GenSamplers = nullptr; + PFNGLDELETESAMPLERSPROC DeleteSamplers = nullptr; + PFNGLISSAMPLERPROC IsSampler = nullptr; + PFNGLBINDSAMPLERPROC BindSampler = nullptr; + PFNGLSAMPLERPARAMETERIPROC SamplerParameteri = nullptr; + PFNGLSAMPLERPARAMETERIVPROC SamplerParameteriv = nullptr; + PFNGLSAMPLERPARAMETERFPROC SamplerParameterf = nullptr; + PFNGLSAMPLERPARAMETERFVPROC SamplerParameterfv = nullptr; + PFNGLGETSAMPLERPARAMETERIVPROC GetSamplerParameteriv = nullptr; + PFNGLGETSAMPLERPARAMETERFVPROC GetSamplerParameterfv = nullptr; + PFNGLVERTEXATTRIBDIVISORPROC VertexAttribDivisor = nullptr; + PFNGLBINDTRANSFORMFEEDBACKPROC BindTransformFeedback = nullptr; + PFNGLDELETETRANSFORMFEEDBACKSPROC DeleteTransformFeedbacks = nullptr; + PFNGLGENTRANSFORMFEEDBACKSPROC GenTransformFeedbacks = nullptr; + PFNGLISTRANSFORMFEEDBACKPROC IsTransformFeedback = nullptr; + PFNGLPAUSETRANSFORMFEEDBACKPROC PauseTransformFeedback = nullptr; + PFNGLRESUMETRANSFORMFEEDBACKPROC ResumeTransformFeedback = nullptr; + PFNGLGETPROGRAMBINARYPROC GetProgramBinary = nullptr; + PFNGLPROGRAMBINARYPROC ProgramBinary = nullptr; + PFNGLPROGRAMPARAMETERIPROC ProgramParameteri = nullptr; + PFNGLINVALIDATEFRAMEBUFFERPROC InvalidateFramebuffer = nullptr; + PFNGLINVALIDATESUBFRAMEBUFFERPROC InvalidateSubFramebuffer = nullptr; + PFNGLTEXSTORAGE2DPROC TexStorage2D = nullptr; + PFNGLTEXSTORAGE3DPROC TexStorage3D = nullptr; + PFNGLGETINTERNALFORMATIVPROC GetInternalformativ = nullptr; + + // OpenGL ES 3.1 + PFNGLDISPATCHCOMPUTEPROC DispatchCompute = nullptr; + PFNGLDISPATCHCOMPUTEINDIRECTPROC DispatchComputeIndirect = nullptr; + PFNGLDRAWARRAYSINDIRECTPROC DrawArraysIndirect = nullptr; + PFNGLDRAWELEMENTSINDIRECTPROC DrawElementsIndirect = nullptr; + PFNGLFRAMEBUFFERPARAMETERIPROC FramebufferParameteri = nullptr; + PFNGLGETFRAMEBUFFERPARAMETERIVPROC GetFramebufferParameteriv = nullptr; + PFNGLGETPROGRAMINTERFACEIVPROC GetProgramInterfaceiv = nullptr; + PFNGLGETPROGRAMRESOURCEINDEXPROC GetProgramResourceIndex = nullptr; + PFNGLGETPROGRAMRESOURCENAMEPROC GetProgramResourceName = nullptr; + PFNGLGETPROGRAMRESOURCEIVPROC GetProgramResourceiv = nullptr; + PFNGLGETPROGRAMRESOURCELOCATIONPROC GetProgramResourceLocation = nullptr; + PFNGLUSEPROGRAMSTAGESPROC UseProgramStages = nullptr; + PFNGLACTIVESHADERPROGRAMPROC ActiveShaderProgram = nullptr; + PFNGLCREATESHADERPROGRAMVPROC CreateShaderProgramv = nullptr; + PFNGLBINDPROGRAMPIPELINEPROC BindProgramPipeline = nullptr; + PFNGLDELETEPROGRAMPIPELINESPROC DeleteProgramPipelines = nullptr; + PFNGLGENPROGRAMPIPELINESPROC GenProgramPipelines = nullptr; + PFNGLISPROGRAMPIPELINEPROC IsProgramPipeline = nullptr; + PFNGLGETPROGRAMPIPELINEIVPROC GetProgramPipelineiv = nullptr; + PFNGLPROGRAMUNIFORM1IPROC ProgramUniform1i = nullptr; + PFNGLPROGRAMUNIFORM2IPROC ProgramUniform2i = nullptr; + PFNGLPROGRAMUNIFORM3IPROC ProgramUniform3i = nullptr; + PFNGLPROGRAMUNIFORM4IPROC ProgramUniform4i = nullptr; + PFNGLPROGRAMUNIFORM1UIPROC ProgramUniform1ui = nullptr; + PFNGLPROGRAMUNIFORM2UIPROC ProgramUniform2ui = nullptr; + PFNGLPROGRAMUNIFORM3UIPROC ProgramUniform3ui = nullptr; + PFNGLPROGRAMUNIFORM4UIPROC ProgramUniform4ui = nullptr; + PFNGLPROGRAMUNIFORM1FPROC ProgramUniform1f = nullptr; + PFNGLPROGRAMUNIFORM2FPROC ProgramUniform2f = nullptr; + PFNGLPROGRAMUNIFORM3FPROC ProgramUniform3f = nullptr; + PFNGLPROGRAMUNIFORM4FPROC ProgramUniform4f = nullptr; + PFNGLPROGRAMUNIFORM1IVPROC ProgramUniform1iv = nullptr; + PFNGLPROGRAMUNIFORM2IVPROC ProgramUniform2iv = nullptr; + PFNGLPROGRAMUNIFORM3IVPROC ProgramUniform3iv = nullptr; + PFNGLPROGRAMUNIFORM4IVPROC ProgramUniform4iv = nullptr; + PFNGLPROGRAMUNIFORM1UIVPROC ProgramUniform1uiv = nullptr; + PFNGLPROGRAMUNIFORM2UIVPROC ProgramUniform2uiv = nullptr; + PFNGLPROGRAMUNIFORM3UIVPROC ProgramUniform3uiv = nullptr; + PFNGLPROGRAMUNIFORM4UIVPROC ProgramUniform4uiv = nullptr; + PFNGLPROGRAMUNIFORM1FVPROC ProgramUniform1fv = nullptr; + PFNGLPROGRAMUNIFORM2FVPROC ProgramUniform2fv = nullptr; + PFNGLPROGRAMUNIFORM3FVPROC ProgramUniform3fv = nullptr; + PFNGLPROGRAMUNIFORM4FVPROC ProgramUniform4fv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX2FVPROC ProgramUniformMatrix2fv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX3FVPROC ProgramUniformMatrix3fv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX4FVPROC ProgramUniformMatrix4fv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC ProgramUniformMatrix2x3fv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC ProgramUniformMatrix3x2fv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC ProgramUniformMatrix2x4fv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC ProgramUniformMatrix4x2fv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC ProgramUniformMatrix3x4fv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC ProgramUniformMatrix4x3fv = nullptr; + PFNGLVALIDATEPROGRAMPIPELINEPROC ValidateProgramPipeline = nullptr; + PFNGLGETPROGRAMPIPELINEINFOLOGPROC GetProgramPipelineInfoLog = nullptr; + PFNGLBINDIMAGETEXTUREPROC BindImageTexture = nullptr; + PFNGLGETBOOLEANI_VPROC GetBooleani_v = nullptr; + PFNGLMEMORYBARRIERPROC MemoryBarrier = nullptr; + PFNGLMEMORYBARRIERBYREGIONPROC MemoryBarrierByRegion = nullptr; + PFNGLTEXSTORAGE2DMULTISAMPLEPROC TexStorage2DMultisample = nullptr; + PFNGLGETMULTISAMPLEFVPROC GetMultisamplefv = nullptr; + PFNGLSAMPLEMASKIPROC SampleMaski = nullptr; + PFNGLGETTEXLEVELPARAMETERIVPROC GetTexLevelParameteriv = nullptr; + PFNGLGETTEXLEVELPARAMETERFVPROC GetTexLevelParameterfv = nullptr; + PFNGLBINDVERTEXBUFFERPROC BindVertexBuffer = nullptr; + PFNGLVERTEXATTRIBFORMATPROC VertexAttribFormat = nullptr; + PFNGLVERTEXATTRIBIFORMATPROC VertexAttribIFormat = nullptr; + PFNGLVERTEXATTRIBBINDINGPROC VertexAttribBinding = nullptr; + PFNGLVERTEXBINDINGDIVISORPROC VertexBindingDivisor = nullptr; + + // OpenGL ES 3.2 + PFNGLBLENDBARRIERPROC BlendBarrier = nullptr; + PFNGLCOPYIMAGESUBDATAPROC CopyImageSubData = nullptr; + PFNGLDEBUGMESSAGECONTROLPROC DebugMessageControl = nullptr; + PFNGLDEBUGMESSAGEINSERTPROC DebugMessageInsert = nullptr; + PFNGLDEBUGMESSAGECALLBACKPROC DebugMessageCallback = nullptr; + PFNGLGETDEBUGMESSAGELOGPROC GetDebugMessageLog = nullptr; + PFNGLPUSHDEBUGGROUPPROC PushDebugGroup = nullptr; + PFNGLPOPDEBUGGROUPPROC PopDebugGroup = nullptr; + PFNGLOBJECTLABELPROC ObjectLabel = nullptr; + PFNGLGETOBJECTLABELPROC GetObjectLabel = nullptr; + PFNGLOBJECTPTRLABELPROC ObjectPtrLabel = nullptr; + PFNGLGETOBJECTPTRLABELPROC GetObjectPtrLabel = nullptr; + PFNGLGETPOINTERVPROC GetPointerv = nullptr; + PFNGLENABLEIPROC Enablei = nullptr; + PFNGLDISABLEIPROC Disablei = nullptr; + PFNGLBLENDEQUATIONIPROC BlendEquationi = nullptr; + PFNGLBLENDEQUATIONSEPARATEIPROC BlendEquationSeparatei = nullptr; + PFNGLBLENDFUNCIPROC BlendFunci = nullptr; + PFNGLBLENDFUNCSEPARATEIPROC BlendFuncSeparatei = nullptr; + PFNGLCOLORMASKIPROC ColorMaski = nullptr; + PFNGLISENABLEDIPROC IsEnabledi = nullptr; + PFNGLDRAWELEMENTSBASEVERTEXPROC DrawElementsBaseVertex = nullptr; + PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC DrawRangeElementsBaseVertex = nullptr; + PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC DrawElementsInstancedBaseVertex = nullptr; + PFNGLFRAMEBUFFERTEXTUREPROC FramebufferTexture = nullptr; + PFNGLPRIMITIVEBOUNDINGBOXPROC PrimitiveBoundingBox = nullptr; + PFNGLGETGRAPHICSRESETSTATUSPROC GetGraphicsResetStatus = nullptr; + PFNGLREADNPIXELSPROC ReadnPixels = nullptr; + PFNGLGETNUNIFORMFVPROC GetnUniformfv = nullptr; + PFNGLGETNUNIFORMIVPROC GetnUniformiv = nullptr; + PFNGLGETNUNIFORMUIVPROC GetnUniformuiv = nullptr; + PFNGLMINSAMPLESHADINGPROC MinSampleShading = nullptr; + PFNGLPATCHPARAMETERIPROC PatchParameteri = nullptr; + PFNGLTEXPARAMETERIIVPROC TexParameterIiv = nullptr; + PFNGLTEXPARAMETERIUIVPROC TexParameterIuiv = nullptr; + PFNGLGETTEXPARAMETERIIVPROC GetTexParameterIiv = nullptr; + PFNGLGETTEXPARAMETERIUIVPROC GetTexParameterIuiv = nullptr; + PFNGLSAMPLERPARAMETERIIVPROC SamplerParameterIiv = nullptr; + PFNGLSAMPLERPARAMETERIUIVPROC SamplerParameterIuiv = nullptr; + PFNGLGETSAMPLERPARAMETERIIVPROC GetSamplerParameterIiv = nullptr; + PFNGLGETSAMPLERPARAMETERIUIVPROC GetSamplerParameterIuiv = nullptr; + PFNGLTEXBUFFERPROC TexBuffer = nullptr; + PFNGLTEXBUFFERRANGEPROC TexBufferRange = nullptr; + PFNGLTEXSTORAGE3DMULTISAMPLEPROC TexStorage3DMultisample = nullptr; + + // Desktop OpenGL 1.0 + PFNGLPOINTSIZEPROC PointSize = nullptr; + PFNGLPOLYGONMODEPROC PolygonMode = nullptr; + PFNGLTEXIMAGE1DPROC TexImage1D = nullptr; + PFNGLDRAWBUFFERPROC DrawBuffer = nullptr; + PFNGLCLEARDEPTHPROC ClearDepth = nullptr; + PFNGLLOGICOPPROC LogicOp = nullptr; + PFNGLPIXELSTOREFPROC PixelStoref = nullptr; + PFNGLGETDOUBLEVPROC GetDoublev = nullptr; + PFNGLGETTEXIMAGEPROC GetTexImage = nullptr; + PFNGLDEPTHRANGEPROC DepthRange = nullptr; + + // Desktop OpenGL 1.1 + PFNGLCOPYTEXIMAGE1DPROC CopyTexImage1D = nullptr; + PFNGLCOPYTEXSUBIMAGE1DPROC CopyTexSubImage1D = nullptr; + PFNGLTEXSUBIMAGE1DPROC TexSubImage1D = nullptr; + + // Desktop OpenGL 1.2 + + // Desktop OpenGL 1.3 + PFNGLCOMPRESSEDTEXIMAGE1DPROC CompressedTexImage1D = nullptr; + PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC CompressedTexSubImage1D = nullptr; + PFNGLGETCOMPRESSEDTEXIMAGEPROC GetCompressedTexImage = nullptr; + + // Desktop OpenGL 1.4 + PFNGLMULTIDRAWARRAYSPROC MultiDrawArrays = nullptr; + PFNGLMULTIDRAWELEMENTSPROC MultiDrawElements = nullptr; + PFNGLPOINTPARAMETERFPROC PointParameterf = nullptr; + PFNGLPOINTPARAMETERFVPROC PointParameterfv = nullptr; + PFNGLPOINTPARAMETERIPROC PointParameteri = nullptr; + PFNGLPOINTPARAMETERIVPROC PointParameteriv = nullptr; + + // Desktop OpenGL 1.5 + PFNGLGETQUERYOBJECTIVPROC GetQueryObjectiv = nullptr; + PFNGLGETBUFFERSUBDATAPROC GetBufferSubData = nullptr; + PFNGLMAPBUFFERPROC MapBuffer = nullptr; + + // Desktop OpenGL 2.0 + PFNGLGETVERTEXATTRIBDVPROC GetVertexAttribdv = nullptr; + PFNGLVERTEXATTRIB1DPROC VertexAttrib1d = nullptr; + PFNGLVERTEXATTRIB1DVPROC VertexAttrib1dv = nullptr; + PFNGLVERTEXATTRIB1SPROC VertexAttrib1s = nullptr; + PFNGLVERTEXATTRIB1SVPROC VertexAttrib1sv = nullptr; + PFNGLVERTEXATTRIB2DPROC VertexAttrib2d = nullptr; + PFNGLVERTEXATTRIB2DVPROC VertexAttrib2dv = nullptr; + PFNGLVERTEXATTRIB2SPROC VertexAttrib2s = nullptr; + PFNGLVERTEXATTRIB2SVPROC VertexAttrib2sv = nullptr; + PFNGLVERTEXATTRIB3DPROC VertexAttrib3d = nullptr; + PFNGLVERTEXATTRIB3DVPROC VertexAttrib3dv = nullptr; + PFNGLVERTEXATTRIB3SPROC VertexAttrib3s = nullptr; + PFNGLVERTEXATTRIB3SVPROC VertexAttrib3sv = nullptr; + PFNGLVERTEXATTRIB4NBVPROC VertexAttrib4Nbv = nullptr; + PFNGLVERTEXATTRIB4NIVPROC VertexAttrib4Niv = nullptr; + PFNGLVERTEXATTRIB4NSVPROC VertexAttrib4Nsv = nullptr; + PFNGLVERTEXATTRIB4NUBPROC VertexAttrib4Nub = nullptr; + PFNGLVERTEXATTRIB4NUBVPROC VertexAttrib4Nubv = nullptr; + PFNGLVERTEXATTRIB4NUIVPROC VertexAttrib4Nuiv = nullptr; + PFNGLVERTEXATTRIB4NUSVPROC VertexAttrib4Nusv = nullptr; + PFNGLVERTEXATTRIB4BVPROC VertexAttrib4bv = nullptr; + PFNGLVERTEXATTRIB4DPROC VertexAttrib4d = nullptr; + PFNGLVERTEXATTRIB4DVPROC VertexAttrib4dv = nullptr; + PFNGLVERTEXATTRIB4IVPROC VertexAttrib4iv = nullptr; + PFNGLVERTEXATTRIB4SPROC VertexAttrib4s = nullptr; + PFNGLVERTEXATTRIB4SVPROC VertexAttrib4sv = nullptr; + PFNGLVERTEXATTRIB4UBVPROC VertexAttrib4ubv = nullptr; + PFNGLVERTEXATTRIB4UIVPROC VertexAttrib4uiv = nullptr; + PFNGLVERTEXATTRIB4USVPROC VertexAttrib4usv = nullptr; + + // Desktop OpenGL 2.1 + + // Desktop OpenGL 3.0 + PFNGLCLAMPCOLORPROC ClampColor = nullptr; + PFNGLBEGINCONDITIONALRENDERPROC BeginConditionalRender = nullptr; + PFNGLENDCONDITIONALRENDERPROC EndConditionalRender = nullptr; + PFNGLVERTEXATTRIBI1IPROC VertexAttribI1i = nullptr; + PFNGLVERTEXATTRIBI2IPROC VertexAttribI2i = nullptr; + PFNGLVERTEXATTRIBI3IPROC VertexAttribI3i = nullptr; + PFNGLVERTEXATTRIBI1UIPROC VertexAttribI1ui = nullptr; + PFNGLVERTEXATTRIBI2UIPROC VertexAttribI2ui = nullptr; + PFNGLVERTEXATTRIBI3UIPROC VertexAttribI3ui = nullptr; + PFNGLVERTEXATTRIBI1IVPROC VertexAttribI1iv = nullptr; + PFNGLVERTEXATTRIBI2IVPROC VertexAttribI2iv = nullptr; + PFNGLVERTEXATTRIBI3IVPROC VertexAttribI3iv = nullptr; + PFNGLVERTEXATTRIBI1UIVPROC VertexAttribI1uiv = nullptr; + PFNGLVERTEXATTRIBI2UIVPROC VertexAttribI2uiv = nullptr; + PFNGLVERTEXATTRIBI3UIVPROC VertexAttribI3uiv = nullptr; + PFNGLVERTEXATTRIBI4BVPROC VertexAttribI4bv = nullptr; + PFNGLVERTEXATTRIBI4SVPROC VertexAttribI4sv = nullptr; + PFNGLVERTEXATTRIBI4UBVPROC VertexAttribI4ubv = nullptr; + PFNGLVERTEXATTRIBI4USVPROC VertexAttribI4usv = nullptr; + PFNGLBINDFRAGDATALOCATIONPROC BindFragDataLocation = nullptr; + PFNGLFRAMEBUFFERTEXTURE1DPROC FramebufferTexture1D = nullptr; + PFNGLFRAMEBUFFERTEXTURE3DPROC FramebufferTexture3D = nullptr; + + // Desktop OpenGL 3.1 + PFNGLPRIMITIVERESTARTINDEXPROC PrimitiveRestartIndex = nullptr; + PFNGLGETACTIVEUNIFORMNAMEPROC GetActiveUniformName = nullptr; + + // Desktop OpenGL 3.2 + PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC MultiDrawElementsBaseVertex = nullptr; + PFNGLPROVOKINGVERTEXPROC ProvokingVertex = nullptr; + PFNGLTEXIMAGE2DMULTISAMPLEPROC TexImage2DMultisample = nullptr; + PFNGLTEXIMAGE3DMULTISAMPLEPROC TexImage3DMultisample = nullptr; + + // Desktop OpenGL 3.3 + PFNGLBINDFRAGDATALOCATIONINDEXEDPROC BindFragDataLocationIndexed = nullptr; + PFNGLGETFRAGDATAINDEXPROC GetFragDataIndex = nullptr; + PFNGLQUERYCOUNTERPROC QueryCounter = nullptr; + PFNGLGETQUERYOBJECTI64VPROC GetQueryObjecti64v = nullptr; + PFNGLGETQUERYOBJECTUI64VPROC GetQueryObjectui64v = nullptr; + PFNGLVERTEXATTRIBP1UIPROC VertexAttribP1ui = nullptr; + PFNGLVERTEXATTRIBP1UIVPROC VertexAttribP1uiv = nullptr; + PFNGLVERTEXATTRIBP2UIPROC VertexAttribP2ui = nullptr; + PFNGLVERTEXATTRIBP2UIVPROC VertexAttribP2uiv = nullptr; + PFNGLVERTEXATTRIBP3UIPROC VertexAttribP3ui = nullptr; + PFNGLVERTEXATTRIBP3UIVPROC VertexAttribP3uiv = nullptr; + PFNGLVERTEXATTRIBP4UIPROC VertexAttribP4ui = nullptr; + PFNGLVERTEXATTRIBP4UIVPROC VertexAttribP4uiv = nullptr; + PFNGLVERTEXP2UIPROC VertexP2ui = nullptr; + PFNGLVERTEXP2UIVPROC VertexP2uiv = nullptr; + PFNGLVERTEXP3UIPROC VertexP3ui = nullptr; + PFNGLVERTEXP3UIVPROC VertexP3uiv = nullptr; + PFNGLVERTEXP4UIPROC VertexP4ui = nullptr; + PFNGLVERTEXP4UIVPROC VertexP4uiv = nullptr; + PFNGLTEXCOORDP1UIPROC TexCoordP1ui = nullptr; + PFNGLTEXCOORDP1UIVPROC TexCoordP1uiv = nullptr; + PFNGLTEXCOORDP2UIPROC TexCoordP2ui = nullptr; + PFNGLTEXCOORDP2UIVPROC TexCoordP2uiv = nullptr; + PFNGLTEXCOORDP3UIPROC TexCoordP3ui = nullptr; + PFNGLTEXCOORDP3UIVPROC TexCoordP3uiv = nullptr; + PFNGLTEXCOORDP4UIPROC TexCoordP4ui = nullptr; + PFNGLTEXCOORDP4UIVPROC TexCoordP4uiv = nullptr; + PFNGLMULTITEXCOORDP1UIPROC MultiTexCoordP1ui = nullptr; + PFNGLMULTITEXCOORDP1UIVPROC MultiTexCoordP1uiv = nullptr; + PFNGLMULTITEXCOORDP2UIPROC MultiTexCoordP2ui = nullptr; + PFNGLMULTITEXCOORDP2UIVPROC MultiTexCoordP2uiv = nullptr; + PFNGLMULTITEXCOORDP3UIPROC MultiTexCoordP3ui = nullptr; + PFNGLMULTITEXCOORDP3UIVPROC MultiTexCoordP3uiv = nullptr; + PFNGLMULTITEXCOORDP4UIPROC MultiTexCoordP4ui = nullptr; + PFNGLMULTITEXCOORDP4UIVPROC MultiTexCoordP4uiv = nullptr; + PFNGLNORMALP3UIPROC NormalP3ui = nullptr; + PFNGLNORMALP3UIVPROC NormalP3uiv = nullptr; + PFNGLCOLORP3UIPROC ColorP3ui = nullptr; + PFNGLCOLORP3UIVPROC ColorP3uiv = nullptr; + PFNGLCOLORP4UIPROC ColorP4ui = nullptr; + PFNGLCOLORP4UIVPROC ColorP4uiv = nullptr; + PFNGLSECONDARYCOLORP3UIPROC SecondaryColorP3ui = nullptr; + PFNGLSECONDARYCOLORP3UIVPROC SecondaryColorP3uiv = nullptr; + + // Desktop OpenGL 4.0 + PFNGLUNIFORM1DPROC Uniform1d = nullptr; + PFNGLUNIFORM2DPROC Uniform2d = nullptr; + PFNGLUNIFORM3DPROC Uniform3d = nullptr; + PFNGLUNIFORM4DPROC Uniform4d = nullptr; + PFNGLUNIFORM1DVPROC Uniform1dv = nullptr; + PFNGLUNIFORM2DVPROC Uniform2dv = nullptr; + PFNGLUNIFORM3DVPROC Uniform3dv = nullptr; + PFNGLUNIFORM4DVPROC Uniform4dv = nullptr; + PFNGLUNIFORMMATRIX2DVPROC UniformMatrix2dv = nullptr; + PFNGLUNIFORMMATRIX3DVPROC UniformMatrix3dv = nullptr; + PFNGLUNIFORMMATRIX4DVPROC UniformMatrix4dv = nullptr; + PFNGLUNIFORMMATRIX2X3DVPROC UniformMatrix2x3dv = nullptr; + PFNGLUNIFORMMATRIX2X4DVPROC UniformMatrix2x4dv = nullptr; + PFNGLUNIFORMMATRIX3X2DVPROC UniformMatrix3x2dv = nullptr; + PFNGLUNIFORMMATRIX3X4DVPROC UniformMatrix3x4dv = nullptr; + PFNGLUNIFORMMATRIX4X2DVPROC UniformMatrix4x2dv = nullptr; + PFNGLUNIFORMMATRIX4X3DVPROC UniformMatrix4x3dv = nullptr; + PFNGLGETUNIFORMDVPROC GetUniformdv = nullptr; + PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC GetSubroutineUniformLocation = nullptr; + PFNGLGETSUBROUTINEINDEXPROC GetSubroutineIndex = nullptr; + PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC GetActiveSubroutineUniformiv = nullptr; + PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC GetActiveSubroutineUniformName = nullptr; + PFNGLGETACTIVESUBROUTINENAMEPROC GetActiveSubroutineName = nullptr; + PFNGLUNIFORMSUBROUTINESUIVPROC UniformSubroutinesuiv = nullptr; + PFNGLGETUNIFORMSUBROUTINEUIVPROC GetUniformSubroutineuiv = nullptr; + PFNGLGETPROGRAMSTAGEIVPROC GetProgramStageiv = nullptr; + PFNGLPATCHPARAMETERFVPROC PatchParameterfv = nullptr; + PFNGLDRAWTRANSFORMFEEDBACKPROC DrawTransformFeedback = nullptr; + PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC DrawTransformFeedbackStream = nullptr; + PFNGLBEGINQUERYINDEXEDPROC BeginQueryIndexed = nullptr; + PFNGLENDQUERYINDEXEDPROC EndQueryIndexed = nullptr; + PFNGLGETQUERYINDEXEDIVPROC GetQueryIndexediv = nullptr; + + // Desktop OpenGL 4.1 + PFNGLPROGRAMUNIFORM1DPROC ProgramUniform1d = nullptr; + PFNGLPROGRAMUNIFORM1DVPROC ProgramUniform1dv = nullptr; + PFNGLPROGRAMUNIFORM2DPROC ProgramUniform2d = nullptr; + PFNGLPROGRAMUNIFORM2DVPROC ProgramUniform2dv = nullptr; + PFNGLPROGRAMUNIFORM3DPROC ProgramUniform3d = nullptr; + PFNGLPROGRAMUNIFORM3DVPROC ProgramUniform3dv = nullptr; + PFNGLPROGRAMUNIFORM4DPROC ProgramUniform4d = nullptr; + PFNGLPROGRAMUNIFORM4DVPROC ProgramUniform4dv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX2DVPROC ProgramUniformMatrix2dv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX3DVPROC ProgramUniformMatrix3dv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX4DVPROC ProgramUniformMatrix4dv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC ProgramUniformMatrix2x3dv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC ProgramUniformMatrix3x2dv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC ProgramUniformMatrix2x4dv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC ProgramUniformMatrix4x2dv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC ProgramUniformMatrix3x4dv = nullptr; + PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC ProgramUniformMatrix4x3dv = nullptr; + PFNGLVERTEXATTRIBL1DPROC VertexAttribL1d = nullptr; + PFNGLVERTEXATTRIBL2DPROC VertexAttribL2d = nullptr; + PFNGLVERTEXATTRIBL3DPROC VertexAttribL3d = nullptr; + PFNGLVERTEXATTRIBL4DPROC VertexAttribL4d = nullptr; + PFNGLVERTEXATTRIBL1DVPROC VertexAttribL1dv = nullptr; + PFNGLVERTEXATTRIBL2DVPROC VertexAttribL2dv = nullptr; + PFNGLVERTEXATTRIBL3DVPROC VertexAttribL3dv = nullptr; + PFNGLVERTEXATTRIBL4DVPROC VertexAttribL4dv = nullptr; + PFNGLVERTEXATTRIBLPOINTERPROC VertexAttribLPointer = nullptr; + PFNGLGETVERTEXATTRIBLDVPROC GetVertexAttribLdv = nullptr; + PFNGLVIEWPORTARRAYVPROC ViewportArrayv = nullptr; + PFNGLVIEWPORTINDEXEDFPROC ViewportIndexedf = nullptr; + PFNGLVIEWPORTINDEXEDFVPROC ViewportIndexedfv = nullptr; + PFNGLSCISSORARRAYVPROC ScissorArrayv = nullptr; + PFNGLSCISSORINDEXEDPROC ScissorIndexed = nullptr; + PFNGLSCISSORINDEXEDVPROC ScissorIndexedv = nullptr; + PFNGLDEPTHRANGEARRAYVPROC DepthRangeArrayv = nullptr; + PFNGLDEPTHRANGEINDEXEDPROC DepthRangeIndexed = nullptr; + PFNGLGETFLOATI_VPROC GetFloati_v = nullptr; + PFNGLGETDOUBLEI_VPROC GetDoublei_v = nullptr; + + // Desktop OpenGL 4.2 + PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC DrawArraysInstancedBaseInstance = nullptr; + PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC DrawElementsInstancedBaseInstance = nullptr; + PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC + DrawElementsInstancedBaseVertexBaseInstance = nullptr; + PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC GetActiveAtomicCounterBufferiv = nullptr; + PFNGLTEXSTORAGE1DPROC TexStorage1D = nullptr; + PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC DrawTransformFeedbackInstanced = nullptr; + PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC DrawTransformFeedbackStreamInstanced = nullptr; + + // Desktop OpenGL 4.3 + PFNGLCLEARBUFFERDATAPROC ClearBufferData = nullptr; + PFNGLCLEARBUFFERSUBDATAPROC ClearBufferSubData = nullptr; + PFNGLGETINTERNALFORMATI64VPROC GetInternalformati64v = nullptr; + PFNGLINVALIDATETEXSUBIMAGEPROC InvalidateTexSubImage = nullptr; + PFNGLINVALIDATETEXIMAGEPROC InvalidateTexImage = nullptr; + PFNGLINVALIDATEBUFFERSUBDATAPROC InvalidateBufferSubData = nullptr; + PFNGLINVALIDATEBUFFERDATAPROC InvalidateBufferData = nullptr; + PFNGLMULTIDRAWARRAYSINDIRECTPROC MultiDrawArraysIndirect = nullptr; + PFNGLMULTIDRAWELEMENTSINDIRECTPROC MultiDrawElementsIndirect = nullptr; + PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC GetProgramResourceLocationIndex = nullptr; + PFNGLSHADERSTORAGEBLOCKBINDINGPROC ShaderStorageBlockBinding = nullptr; + PFNGLTEXTUREVIEWPROC TextureView = nullptr; + PFNGLVERTEXATTRIBLFORMATPROC VertexAttribLFormat = nullptr; + + // Desktop OpenGL 4.4 + PFNGLBUFFERSTORAGEPROC BufferStorage = nullptr; + PFNGLCLEARTEXIMAGEPROC ClearTexImage = nullptr; + PFNGLCLEARTEXSUBIMAGEPROC ClearTexSubImage = nullptr; + PFNGLBINDBUFFERSBASEPROC BindBuffersBase = nullptr; + PFNGLBINDBUFFERSRANGEPROC BindBuffersRange = nullptr; + PFNGLBINDTEXTURESPROC BindTextures = nullptr; + PFNGLBINDSAMPLERSPROC BindSamplers = nullptr; + PFNGLBINDIMAGETEXTURESPROC BindImageTextures = nullptr; + PFNGLBINDVERTEXBUFFERSPROC BindVertexBuffers = nullptr; + + // Desktop OpenGL 4.5 + PFNGLCLIPCONTROLPROC ClipControl = nullptr; + PFNGLCREATETRANSFORMFEEDBACKSPROC CreateTransformFeedbacks = nullptr; + PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC TransformFeedbackBufferBase = nullptr; + PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC TransformFeedbackBufferRange = nullptr; + PFNGLGETTRANSFORMFEEDBACKIVPROC GetTransformFeedbackiv = nullptr; + PFNGLGETTRANSFORMFEEDBACKI_VPROC GetTransformFeedbacki_v = nullptr; + PFNGLGETTRANSFORMFEEDBACKI64_VPROC GetTransformFeedbacki64_v = nullptr; + PFNGLCREATEBUFFERSPROC CreateBuffers = nullptr; + PFNGLNAMEDBUFFERSTORAGEPROC NamedBufferStorage = nullptr; + PFNGLNAMEDBUFFERDATAPROC NamedBufferData = nullptr; + PFNGLNAMEDBUFFERSUBDATAPROC NamedBufferSubData = nullptr; + PFNGLCOPYNAMEDBUFFERSUBDATAPROC CopyNamedBufferSubData = nullptr; + PFNGLCLEARNAMEDBUFFERDATAPROC ClearNamedBufferData = nullptr; + PFNGLCLEARNAMEDBUFFERSUBDATAPROC ClearNamedBufferSubData = nullptr; + PFNGLMAPNAMEDBUFFERPROC MapNamedBuffer = nullptr; + PFNGLMAPNAMEDBUFFERRANGEPROC MapNamedBufferRange = nullptr; + PFNGLUNMAPNAMEDBUFFERPROC UnmapNamedBuffer = nullptr; + PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC FlushMappedNamedBufferRange = nullptr; + PFNGLGETNAMEDBUFFERPARAMETERIVPROC GetNamedBufferParameteriv = nullptr; + PFNGLGETNAMEDBUFFERPARAMETERI64VPROC GetNamedBufferParameteri64v = nullptr; + PFNGLGETNAMEDBUFFERPOINTERVPROC GetNamedBufferPointerv = nullptr; + PFNGLGETNAMEDBUFFERSUBDATAPROC GetNamedBufferSubData = nullptr; + PFNGLCREATEFRAMEBUFFERSPROC CreateFramebuffers = nullptr; + PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC NamedFramebufferRenderbuffer = nullptr; + PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC NamedFramebufferParameteri = nullptr; + PFNGLNAMEDFRAMEBUFFERTEXTUREPROC NamedFramebufferTexture = nullptr; + PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC NamedFramebufferTextureLayer = nullptr; + PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC NamedFramebufferDrawBuffer = nullptr; + PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC NamedFramebufferDrawBuffers = nullptr; + PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC NamedFramebufferReadBuffer = nullptr; + PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC InvalidateNamedFramebufferData = nullptr; + PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC InvalidateNamedFramebufferSubData = nullptr; + PFNGLCLEARNAMEDFRAMEBUFFERIVPROC ClearNamedFramebufferiv = nullptr; + PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC ClearNamedFramebufferuiv = nullptr; + PFNGLCLEARNAMEDFRAMEBUFFERFVPROC ClearNamedFramebufferfv = nullptr; + PFNGLCLEARNAMEDFRAMEBUFFERFIPROC ClearNamedFramebufferfi = nullptr; + PFNGLBLITNAMEDFRAMEBUFFERPROC BlitNamedFramebuffer = nullptr; + PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC CheckNamedFramebufferStatus = nullptr; + PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC GetNamedFramebufferParameteriv = nullptr; + PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetNamedFramebufferAttachmentParameteriv = + nullptr; + PFNGLCREATERENDERBUFFERSPROC CreateRenderbuffers = nullptr; + PFNGLNAMEDRENDERBUFFERSTORAGEPROC NamedRenderbufferStorage = nullptr; + PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC NamedRenderbufferStorageMultisample = nullptr; + PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC GetNamedRenderbufferParameteriv = nullptr; + PFNGLCREATETEXTURESPROC CreateTextures = nullptr; + PFNGLTEXTUREBUFFERPROC TextureBuffer = nullptr; + PFNGLTEXTUREBUFFERRANGEPROC TextureBufferRange = nullptr; + PFNGLTEXTURESTORAGE1DPROC TextureStorage1D = nullptr; + PFNGLTEXTURESTORAGE2DPROC TextureStorage2D = nullptr; + PFNGLTEXTURESTORAGE3DPROC TextureStorage3D = nullptr; + PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC TextureStorage2DMultisample = nullptr; + PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC TextureStorage3DMultisample = nullptr; + PFNGLTEXTURESUBIMAGE1DPROC TextureSubImage1D = nullptr; + PFNGLTEXTURESUBIMAGE2DPROC TextureSubImage2D = nullptr; + PFNGLTEXTURESUBIMAGE3DPROC TextureSubImage3D = nullptr; + PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC CompressedTextureSubImage1D = nullptr; + PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC CompressedTextureSubImage2D = nullptr; + PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC CompressedTextureSubImage3D = nullptr; + PFNGLCOPYTEXTURESUBIMAGE1DPROC CopyTextureSubImage1D = nullptr; + PFNGLCOPYTEXTURESUBIMAGE2DPROC CopyTextureSubImage2D = nullptr; + PFNGLCOPYTEXTURESUBIMAGE3DPROC CopyTextureSubImage3D = nullptr; + PFNGLTEXTUREPARAMETERFPROC TextureParameterf = nullptr; + PFNGLTEXTUREPARAMETERFVPROC TextureParameterfv = nullptr; + PFNGLTEXTUREPARAMETERIPROC TextureParameteri = nullptr; + PFNGLTEXTUREPARAMETERIIVPROC TextureParameterIiv = nullptr; + PFNGLTEXTUREPARAMETERIUIVPROC TextureParameterIuiv = nullptr; + PFNGLTEXTUREPARAMETERIVPROC TextureParameteriv = nullptr; + PFNGLGENERATETEXTUREMIPMAPPROC GenerateTextureMipmap = nullptr; + PFNGLBINDTEXTUREUNITPROC BindTextureUnit = nullptr; + PFNGLGETTEXTUREIMAGEPROC GetTextureImage = nullptr; + PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC GetCompressedTextureImage = nullptr; + PFNGLGETTEXTURELEVELPARAMETERFVPROC GetTextureLevelParameterfv = nullptr; + PFNGLGETTEXTURELEVELPARAMETERIVPROC GetTextureLevelParameteriv = nullptr; + PFNGLGETTEXTUREPARAMETERFVPROC GetTextureParameterfv = nullptr; + PFNGLGETTEXTUREPARAMETERIIVPROC GetTextureParameterIiv = nullptr; + PFNGLGETTEXTUREPARAMETERIUIVPROC GetTextureParameterIuiv = nullptr; + PFNGLGETTEXTUREPARAMETERIVPROC GetTextureParameteriv = nullptr; + PFNGLCREATEVERTEXARRAYSPROC CreateVertexArrays = nullptr; + PFNGLDISABLEVERTEXARRAYATTRIBPROC DisableVertexArrayAttrib = nullptr; + PFNGLENABLEVERTEXARRAYATTRIBPROC EnableVertexArrayAttrib = nullptr; + PFNGLVERTEXARRAYELEMENTBUFFERPROC VertexArrayElementBuffer = nullptr; + PFNGLVERTEXARRAYVERTEXBUFFERPROC VertexArrayVertexBuffer = nullptr; + PFNGLVERTEXARRAYVERTEXBUFFERSPROC VertexArrayVertexBuffers = nullptr; + PFNGLVERTEXARRAYATTRIBBINDINGPROC VertexArrayAttribBinding = nullptr; + PFNGLVERTEXARRAYATTRIBFORMATPROC VertexArrayAttribFormat = nullptr; + PFNGLVERTEXARRAYATTRIBIFORMATPROC VertexArrayAttribIFormat = nullptr; + PFNGLVERTEXARRAYATTRIBLFORMATPROC VertexArrayAttribLFormat = nullptr; + PFNGLVERTEXARRAYBINDINGDIVISORPROC VertexArrayBindingDivisor = nullptr; + PFNGLGETVERTEXARRAYIVPROC GetVertexArrayiv = nullptr; + PFNGLGETVERTEXARRAYINDEXEDIVPROC GetVertexArrayIndexediv = nullptr; + PFNGLGETVERTEXARRAYINDEXED64IVPROC GetVertexArrayIndexed64iv = nullptr; + PFNGLCREATESAMPLERSPROC CreateSamplers = nullptr; + PFNGLCREATEPROGRAMPIPELINESPROC CreateProgramPipelines = nullptr; + PFNGLCREATEQUERIESPROC CreateQueries = nullptr; + PFNGLGETQUERYBUFFEROBJECTI64VPROC GetQueryBufferObjecti64v = nullptr; + PFNGLGETQUERYBUFFEROBJECTIVPROC GetQueryBufferObjectiv = nullptr; + PFNGLGETQUERYBUFFEROBJECTUI64VPROC GetQueryBufferObjectui64v = nullptr; + PFNGLGETQUERYBUFFEROBJECTUIVPROC GetQueryBufferObjectuiv = nullptr; + PFNGLGETTEXTURESUBIMAGEPROC GetTextureSubImage = nullptr; + PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC GetCompressedTextureSubImage = nullptr; + PFNGLGETNCOMPRESSEDTEXIMAGEPROC GetnCompressedTexImage = nullptr; + PFNGLGETNTEXIMAGEPROC GetnTexImage = nullptr; + PFNGLGETNUNIFORMDVPROC GetnUniformdv = nullptr; + PFNGLGETNMAPDVPROC GetnMapdv = nullptr; + PFNGLGETNMAPFVPROC GetnMapfv = nullptr; + PFNGLGETNMAPIVPROC GetnMapiv = nullptr; + PFNGLGETNPIXELMAPFVPROC GetnPixelMapfv = nullptr; + PFNGLGETNPIXELMAPUIVPROC GetnPixelMapuiv = nullptr; + PFNGLGETNPIXELMAPUSVPROC GetnPixelMapusv = nullptr; + PFNGLGETNPOLYGONSTIPPLEPROC GetnPolygonStipple = nullptr; + PFNGLGETNCOLORTABLEPROC GetnColorTable = nullptr; + PFNGLGETNCONVOLUTIONFILTERPROC GetnConvolutionFilter = nullptr; + PFNGLGETNSEPARABLEFILTERPROC GetnSeparableFilter = nullptr; + PFNGLGETNHISTOGRAMPROC GetnHistogram = nullptr; + PFNGLGETNMINMAXPROC GetnMinmax = nullptr; + PFNGLTEXTUREBARRIERPROC TextureBarrier = nullptr; + + // Desktop OpenGL 4.6 + PFNGLSPECIALIZESHADERPROC SpecializeShader = nullptr; + PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC MultiDrawArraysIndirectCount = nullptr; + PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC MultiDrawElementsIndirectCount = nullptr; + PFNGLPOLYGONOFFSETCLAMPPROC PolygonOffsetClamp = nullptr; + + public: + bool initialize(BACKENDTYPE backend); + bool LoadDesktopGLProcs(int majorVersion, int minorVersion); + bool LoadOpenGLESProcs(int majorVersion, int minorVersion); + + private: + template + bool LoadProc(T *memberProc, const char *name); + +#ifdef _WIN32 + HINSTANCE hinstance; +#endif + + BACKENDTYPE backendType; +}; +} // namespace aquarium + +#endif // !OPENGL_FUNCTIONS diff --git a/src/aquarium-optimized/opengl/OpenGLPlatforms.h b/src/aquarium-optimized/opengl/OpenGLPlatforms.h new file mode 100644 index 0000000..73edb89 --- /dev/null +++ b/src/aquarium-optimized/opengl/OpenGLPlatforms.h @@ -0,0 +1,4098 @@ +#ifndef OPENGL_PLATFORMS +#define OPENGL_PLATFORMS + +#include + +using GLvoid = void; +using GLchar = char; +using GLenum = unsigned int; +using GLboolean = unsigned char; +using GLbitfield = unsigned int; +using GLbyte = khronos_int8_t; +using GLshort = short; +using GLint = int; +using GLsizei = int; +using GLubyte = khronos_uint8_t; +using GLushort = unsigned short; +using GLuint = unsigned int; +using GLfloat = khronos_float_t; +using GLclampf = khronos_float_t; +using GLdouble = double; +using GLclampd = double; +using GLfixed = khronos_int32_t; +using GLintptr = khronos_intptr_t; +using GLsizeiptr = khronos_ssize_t; +using GLhalf = unsigned short; +using GLint64 = khronos_int64_t; +using GLuint64 = khronos_uint64_t; +using GLsync = struct __GLsync *; +using GLDEBUGPROC = void(KHRONOS_APIENTRY *)(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *message, + const void *userParam); +using GLDEBUGPROCARB = GLDEBUGPROC; +using GLDEBUGPROCKHR = GLDEBUGPROC; +using GLDEBUGPROCAMD = void(KHRONOS_APIENTRY *)(GLuint id, + GLenum category, + GLenum severity, + GLsizei length, + const GLchar *message, + void *userParam); + +// OpenGL ES 2.0 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_NONE 0 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 + +using PFNGLACTIVETEXTUREPROC = void(KHRONOS_APIENTRY *)(GLenum texture); +using PFNGLATTACHSHADERPROC = void(KHRONOS_APIENTRY *)(GLuint program, GLuint shader); +using PFNGLBINDATTRIBLOCATIONPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint index, + const GLchar *name); +using PFNGLBINDBUFFERPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint buffer); +using PFNGLBINDFRAMEBUFFERPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint framebuffer); +using PFNGLBINDRENDERBUFFERPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint renderbuffer); +using PFNGLBINDTEXTUREPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint texture); +using PFNGLBLENDCOLORPROC = void(KHRONOS_APIENTRY *)(GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha); +using PFNGLBLENDEQUATIONPROC = void(KHRONOS_APIENTRY *)(GLenum mode); +using PFNGLBLENDEQUATIONSEPARATEPROC = void(KHRONOS_APIENTRY *)(GLenum modeRGB, GLenum modeAlpha); +using PFNGLBLENDFUNCPROC = void(KHRONOS_APIENTRY *)(GLenum sfactor, GLenum dfactor); +using PFNGLBLENDFUNCSEPARATEPROC = void(KHRONOS_APIENTRY *)(GLenum sfactorRGB, + GLenum dfactorRGB, + GLenum sfactorAlpha, + GLenum dfactorAlpha); +using PFNGLBUFFERDATAPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizeiptr size, + const void *data, + GLenum usage); +using PFNGLBUFFERSUBDATAPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLintptr offset, + GLsizeiptr size, + const void *data); +using PFNGLCHECKFRAMEBUFFERSTATUSPROC = GLenum(KHRONOS_APIENTRY *)(GLenum target); +using PFNGLCLEARPROC = void(KHRONOS_APIENTRY *)(GLbitfield mask); +using PFNGLCLEARCOLORPROC = void(KHRONOS_APIENTRY *)(GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha); +using PFNGLCLEARDEPTHFPROC = void(KHRONOS_APIENTRY *)(GLfloat d); +using PFNGLCLEARSTENCILPROC = void(KHRONOS_APIENTRY *)(GLint s); +using PFNGLCOLORMASKPROC = void(KHRONOS_APIENTRY *)(GLboolean red, + GLboolean green, + GLboolean blue, + GLboolean alpha); +using PFNGLCOMPILESHADERPROC = void(KHRONOS_APIENTRY *)(GLuint shader); +using PFNGLCOMPRESSEDTEXIMAGE2DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data); +using PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data); +using PFNGLCOPYTEXIMAGE2DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); +using PFNGLCOPYTEXSUBIMAGE2DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +using PFNGLCREATEPROGRAMPROC = GLuint(KHRONOS_APIENTRY *)(); +using PFNGLCREATESHADERPROC = GLuint(KHRONOS_APIENTRY *)(GLenum type); +using PFNGLCULLFACEPROC = void(KHRONOS_APIENTRY *)(GLenum mode); +using PFNGLDELETEBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, const GLuint *buffers); +using PFNGLDELETEFRAMEBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, const GLuint *framebuffers); +using PFNGLDELETEPROGRAMPROC = void(KHRONOS_APIENTRY *)(GLuint program); +using PFNGLDELETERENDERBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, + const GLuint *renderbuffers); +using PFNGLDELETESHADERPROC = void(KHRONOS_APIENTRY *)(GLuint shader); +using PFNGLDELETETEXTURESPROC = void(KHRONOS_APIENTRY *)(GLsizei n, const GLuint *textures); +using PFNGLDEPTHFUNCPROC = void(KHRONOS_APIENTRY *)(GLenum func); +using PFNGLDEPTHMASKPROC = void(KHRONOS_APIENTRY *)(GLboolean flag); +using PFNGLDEPTHRANGEFPROC = void(KHRONOS_APIENTRY *)(GLfloat n, GLfloat f); +using PFNGLDETACHSHADERPROC = void(KHRONOS_APIENTRY *)(GLuint program, GLuint shader); +using PFNGLDISABLEPROC = void(KHRONOS_APIENTRY *)(GLenum cap); +using PFNGLDISABLEVERTEXATTRIBARRAYPROC = void(KHRONOS_APIENTRY *)(GLuint index); +using PFNGLDRAWARRAYSPROC = void(KHRONOS_APIENTRY *)(GLenum mode, GLint first, GLsizei count); +using PFNGLDRAWELEMENTSPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLsizei count, + GLenum type, + const void *indices); +using PFNGLENABLEPROC = void(KHRONOS_APIENTRY *)(GLenum cap); +using PFNGLENABLEVERTEXATTRIBARRAYPROC = void(KHRONOS_APIENTRY *)(GLuint index); +using PFNGLFINISHPROC = void(KHRONOS_APIENTRY *)(); +using PFNGLFLUSHPROC = void(KHRONOS_APIENTRY *)(); +using PFNGLFRAMEBUFFERRENDERBUFFERPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer); +using PFNGLFRAMEBUFFERTEXTURE2DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level); +using PFNGLFRONTFACEPROC = void(KHRONOS_APIENTRY *)(GLenum mode); +using PFNGLGENBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *buffers); +using PFNGLGENERATEMIPMAPPROC = void(KHRONOS_APIENTRY *)(GLenum target); +using PFNGLGENFRAMEBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *framebuffers); +using PFNGLGENRENDERBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *renderbuffers); +using PFNGLGENTEXTURESPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *textures); +using PFNGLGETACTIVEATTRIBPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name); +using PFNGLGETACTIVEUNIFORMPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name); +using PFNGLGETATTACHEDSHADERSPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLsizei maxCount, + GLsizei *count, + GLuint *shaders); +using PFNGLGETATTRIBLOCATIONPROC = GLint(KHRONOS_APIENTRY *)(GLuint program, const GLchar *name); +using PFNGLGETBOOLEANVPROC = void(KHRONOS_APIENTRY *)(GLenum pname, GLboolean *data); +using PFNGLGETBUFFERPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + GLint *params); +using PFNGLGETERRORPROC = GLenum(KHRONOS_APIENTRY *)(); +using PFNGLGETFLOATVPROC = void(KHRONOS_APIENTRY *)(GLenum pname, GLfloat *data); +using PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum attachment, + GLenum pname, + GLint *params); +using PFNGLGETINTEGERVPROC = void(KHRONOS_APIENTRY *)(GLenum pname, GLint *data); +using PFNGLGETPROGRAMIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, GLenum pname, GLint *params); +using PFNGLGETPROGRAMINFOLOGPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); +using PFNGLGETRENDERBUFFERPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + GLint *params); +using PFNGLGETSHADERIVPROC = void(KHRONOS_APIENTRY *)(GLuint shader, GLenum pname, GLint *params); +using PFNGLGETSHADERINFOLOGPROC = void(KHRONOS_APIENTRY *)(GLuint shader, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); +using PFNGLGETSHADERPRECISIONFORMATPROC = void(KHRONOS_APIENTRY *)(GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision); +using PFNGLGETSHADERSOURCEPROC = void(KHRONOS_APIENTRY *)(GLuint shader, + GLsizei bufSize, + GLsizei *length, + GLchar *source); +using PFNGLGETSTRINGPROC = const GLubyte *(KHRONOS_APIENTRY *)(GLenum name); +using PFNGLGETTEXPARAMETERFVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + GLfloat *params); +using PFNGLGETTEXPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + GLint *params); +using PFNGLGETUNIFORMFVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLfloat *params); +using PFNGLGETUNIFORMIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLint *params); +using PFNGLGETUNIFORMLOCATIONPROC = GLint(KHRONOS_APIENTRY *)(GLuint program, const GLchar *name); +using PFNGLGETVERTEXATTRIBFVPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum pname, + GLfloat *params); +using PFNGLGETVERTEXATTRIBIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum pname, + GLint *params); +using PFNGLGETVERTEXATTRIBPOINTERVPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum pname, + void **pointer); +using PFNGLHINTPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLenum mode); +using PFNGLISBUFFERPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint buffer); +using PFNGLISENABLEDPROC = GLboolean(KHRONOS_APIENTRY *)(GLenum cap); +using PFNGLISFRAMEBUFFERPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint framebuffer); +using PFNGLISPROGRAMPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint program); +using PFNGLISRENDERBUFFERPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint renderbuffer); +using PFNGLISSHADERPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint shader); +using PFNGLISTEXTUREPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint texture); +using PFNGLLINEWIDTHPROC = void(KHRONOS_APIENTRY *)(GLfloat width); +using PFNGLLINKPROGRAMPROC = void(KHRONOS_APIENTRY *)(GLuint program); +using PFNGLPIXELSTOREIPROC = void(KHRONOS_APIENTRY *)(GLenum pname, GLint param); +using PFNGLPOLYGONOFFSETPROC = void(KHRONOS_APIENTRY *)(GLfloat factor, GLfloat units); +using PFNGLREADPIXELSPROC = void(KHRONOS_APIENTRY *)(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void *pixels); +using PFNGLRELEASESHADERCOMPILERPROC = void(KHRONOS_APIENTRY *)(); +using PFNGLRENDERBUFFERSTORAGEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height); +using PFNGLSAMPLECOVERAGEPROC = void(KHRONOS_APIENTRY *)(GLfloat value, GLboolean invert); +using PFNGLSCISSORPROC = void(KHRONOS_APIENTRY *)(GLint x, GLint y, GLsizei width, GLsizei height); +using PFNGLSHADERBINARYPROC = void(KHRONOS_APIENTRY *)(GLsizei count, + const GLuint *shaders, + GLenum binaryformat, + const void *binary, + GLsizei length); +using PFNGLSHADERSOURCEPROC = void(KHRONOS_APIENTRY *)(GLuint shader, + GLsizei count, + const GLchar *const *string, + const GLint *length); +using PFNGLSTENCILFUNCPROC = void(KHRONOS_APIENTRY *)(GLenum func, GLint ref, GLuint mask); +using PFNGLSTENCILFUNCSEPARATEPROC = void(KHRONOS_APIENTRY *)(GLenum face, + GLenum func, + GLint ref, + GLuint mask); +using PFNGLSTENCILMASKPROC = void(KHRONOS_APIENTRY *)(GLuint mask); +using PFNGLSTENCILMASKSEPARATEPROC = void(KHRONOS_APIENTRY *)(GLenum face, GLuint mask); +using PFNGLSTENCILOPPROC = void(KHRONOS_APIENTRY *)(GLenum fail, GLenum zfail, GLenum zpass); +using PFNGLSTENCILOPSEPARATEPROC = void(KHRONOS_APIENTRY *)(GLenum face, + GLenum sfail, + GLenum dpfail, + GLenum dppass); +using PFNGLTEXIMAGE2DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +using PFNGLTEXPARAMETERFPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLenum pname, GLfloat param); +using PFNGLTEXPARAMETERFVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + const GLfloat *params); +using PFNGLTEXPARAMETERIPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLenum pname, GLint param); +using PFNGLTEXPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + const GLint *params); +using PFNGLTEXSUBIMAGE2DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); +using PFNGLUNIFORM1FPROC = void(KHRONOS_APIENTRY *)(GLint location, GLfloat v0); +using PFNGLUNIFORM1FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLfloat *value); +using PFNGLUNIFORM1IPROC = void(KHRONOS_APIENTRY *)(GLint location, GLint v0); +using PFNGLUNIFORM1IVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLint *value); +using PFNGLUNIFORM2FPROC = void(KHRONOS_APIENTRY *)(GLint location, GLfloat v0, GLfloat v1); +using PFNGLUNIFORM2FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLfloat *value); +using PFNGLUNIFORM2IPROC = void(KHRONOS_APIENTRY *)(GLint location, GLint v0, GLint v1); +using PFNGLUNIFORM2IVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLint *value); +using PFNGLUNIFORM3FPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLfloat v0, + GLfloat v1, + GLfloat v2); +using PFNGLUNIFORM3FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLfloat *value); +using PFNGLUNIFORM3IPROC = void(KHRONOS_APIENTRY *)(GLint location, GLint v0, GLint v1, GLint v2); +using PFNGLUNIFORM3IVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLint *value); +using PFNGLUNIFORM4FPROC = + void(KHRONOS_APIENTRY *)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +using PFNGLUNIFORM4FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLfloat *value); +using PFNGLUNIFORM4IPROC = + void(KHRONOS_APIENTRY *)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +using PFNGLUNIFORM4IVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLint *value); +using PFNGLUNIFORMMATRIX2FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLUNIFORMMATRIX3FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLUNIFORMMATRIX4FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLUSEPROGRAMPROC = void(KHRONOS_APIENTRY *)(GLuint program); +using PFNGLVALIDATEPROGRAMPROC = void(KHRONOS_APIENTRY *)(GLuint program); +using PFNGLVERTEXATTRIB1FPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLfloat x); +using PFNGLVERTEXATTRIB1FVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLfloat *v); +using PFNGLVERTEXATTRIB2FPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLfloat x, GLfloat y); +using PFNGLVERTEXATTRIB2FVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLfloat *v); +using PFNGLVERTEXATTRIB3FPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLfloat x, + GLfloat y, + GLfloat z); +using PFNGLVERTEXATTRIB3FVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLfloat *v); +using PFNGLVERTEXATTRIB4FPROC = + void(KHRONOS_APIENTRY *)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +using PFNGLVERTEXATTRIB4FVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLfloat *v); +using PFNGLVERTEXATTRIBPOINTERPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const void *pointer); +using PFNGLVIEWPORTPROC = void(KHRONOS_APIENTRY *)(GLint x, GLint y, GLsizei width, GLsizei height); + +// OpenGL ES 3.0 +#define GL_READ_BUFFER 0x0C02 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_RED 0x1903 +#define GL_RGB8 0x8051 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_RG8 0x822B +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFF +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF + +using PFNGLREADBUFFERPROC = void(KHRONOS_APIENTRY *)(GLenum src); +using PFNGLDRAWRANGEELEMENTSPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices); +using PFNGLTEXIMAGE3DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +using PFNGLTEXSUBIMAGE3DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels); +using PFNGLCOPYTEXSUBIMAGE3DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +using PFNGLCOMPRESSEDTEXIMAGE3DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data); +using PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data); +using PFNGLGENQUERIESPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *ids); +using PFNGLDELETEQUERIESPROC = void(KHRONOS_APIENTRY *)(GLsizei n, const GLuint *ids); +using PFNGLISQUERYPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint id); +using PFNGLBEGINQUERYPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint id); +using PFNGLENDQUERYPROC = void(KHRONOS_APIENTRY *)(GLenum target); +using PFNGLGETQUERYIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLenum pname, GLint *params); +using PFNGLGETQUERYOBJECTUIVPROC = void(KHRONOS_APIENTRY *)(GLuint id, + GLenum pname, + GLuint *params); +using PFNGLUNMAPBUFFERPROC = GLboolean(KHRONOS_APIENTRY *)(GLenum target); +using PFNGLGETBUFFERPOINTERVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + void **params); +using PFNGLDRAWBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, const GLenum *bufs); +using PFNGLUNIFORMMATRIX2X3FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLUNIFORMMATRIX3X2FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLUNIFORMMATRIX2X4FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLUNIFORMMATRIX4X2FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLUNIFORMMATRIX3X4FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLUNIFORMMATRIX4X3FVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLBLITFRAMEBUFFERPROC = void(KHRONOS_APIENTRY *)(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); +using PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); +using PFNGLFRAMEBUFFERTEXTURELAYERPROC = void( + KHRONOS_APIENTRY *)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +using PFNGLMAPBUFFERRANGEPROC = void *(KHRONOS_APIENTRY *)(GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +using PFNGLFLUSHMAPPEDBUFFERRANGEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLintptr offset, + GLsizeiptr length); +using PFNGLBINDVERTEXARRAYPROC = void(KHRONOS_APIENTRY *)(GLuint array); +using PFNGLDELETEVERTEXARRAYSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, const GLuint *arrays); +using PFNGLGENVERTEXARRAYSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *arrays); +using PFNGLISVERTEXARRAYPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint array); +using PFNGLGETINTEGERI_VPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint index, GLint *data); +using PFNGLBEGINTRANSFORMFEEDBACKPROC = void(KHRONOS_APIENTRY *)(GLenum primitiveMode); +using PFNGLENDTRANSFORMFEEDBACKPROC = void(KHRONOS_APIENTRY *)(); +using PFNGLBINDBUFFERRANGEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size); +using PFNGLBINDBUFFERBASEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLuint index, + GLuint buffer); +using PFNGLTRANSFORMFEEDBACKVARYINGSPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode); +using PFNGLGETTRANSFORMFEEDBACKVARYINGPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name); +using PFNGLVERTEXATTRIBIPOINTERPROC = void( + KHRONOS_APIENTRY *)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +using PFNGLGETVERTEXATTRIBIIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum pname, + GLint *params); +using PFNGLGETVERTEXATTRIBIUIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum pname, + GLuint *params); +using PFNGLVERTEXATTRIBI4IPROC = + void(KHRONOS_APIENTRY *)(GLuint index, GLint x, GLint y, GLint z, GLint w); +using PFNGLVERTEXATTRIBI4UIPROC = + void(KHRONOS_APIENTRY *)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +using PFNGLVERTEXATTRIBI4IVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLint *v); +using PFNGLVERTEXATTRIBI4UIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLuint *v); +using PFNGLGETUNIFORMUIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLuint *params); +using PFNGLGETFRAGDATALOCATIONPROC = GLint(KHRONOS_APIENTRY *)(GLuint program, const GLchar *name); +using PFNGLUNIFORM1UIPROC = void(KHRONOS_APIENTRY *)(GLint location, GLuint v0); +using PFNGLUNIFORM2UIPROC = void(KHRONOS_APIENTRY *)(GLint location, GLuint v0, GLuint v1); +using PFNGLUNIFORM3UIPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLuint v0, + GLuint v1, + GLuint v2); +using PFNGLUNIFORM4UIPROC = + void(KHRONOS_APIENTRY *)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +using PFNGLUNIFORM1UIVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLuint *value); +using PFNGLUNIFORM2UIVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLuint *value); +using PFNGLUNIFORM3UIVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLuint *value); +using PFNGLUNIFORM4UIVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLuint *value); +using PFNGLCLEARBUFFERIVPROC = void(KHRONOS_APIENTRY *)(GLenum buffer, + GLint drawbuffer, + const GLint *value); +using PFNGLCLEARBUFFERUIVPROC = void(KHRONOS_APIENTRY *)(GLenum buffer, + GLint drawbuffer, + const GLuint *value); +using PFNGLCLEARBUFFERFVPROC = void(KHRONOS_APIENTRY *)(GLenum buffer, + GLint drawbuffer, + const GLfloat *value); +using PFNGLCLEARBUFFERFIPROC = void(KHRONOS_APIENTRY *)(GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil); +using PFNGLGETSTRINGIPROC = const GLubyte *(KHRONOS_APIENTRY *)(GLenum name, GLuint index); +using PFNGLCOPYBUFFERSUBDATAPROC = void(KHRONOS_APIENTRY *)(GLenum readTarget, + GLenum writeTarget, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size); +using PFNGLGETUNIFORMINDICESPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices); +using PFNGLGETACTIVEUNIFORMSIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params); +using PFNGLGETUNIFORMBLOCKINDEXPROC = GLuint(KHRONOS_APIENTRY *)(GLuint program, + const GLchar *uniformBlockName); +using PFNGLGETACTIVEUNIFORMBLOCKIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params); +using PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint uniformBlockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName); +using PFNGLUNIFORMBLOCKBINDINGPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding); +using PFNGLDRAWARRAYSINSTANCEDPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLint first, + GLsizei count, + GLsizei instancecount); +using PFNGLDRAWELEMENTSINSTANCEDPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instancecount); +using PFNGLFENCESYNCPROC = GLsync(KHRONOS_APIENTRY *)(GLenum condition, GLbitfield flags); +using PFNGLISSYNCPROC = GLboolean(KHRONOS_APIENTRY *)(GLsync sync); +using PFNGLDELETESYNCPROC = void(KHRONOS_APIENTRY *)(GLsync sync); +using PFNGLCLIENTWAITSYNCPROC = GLenum(KHRONOS_APIENTRY *)(GLsync sync, + GLbitfield flags, + GLuint64 timeout); +using PFNGLWAITSYNCPROC = void(KHRONOS_APIENTRY *)(GLsync sync, GLbitfield flags, GLuint64 timeout); +using PFNGLGETINTEGER64VPROC = void(KHRONOS_APIENTRY *)(GLenum pname, GLint64 *data); +using PFNGLGETSYNCIVPROC = void( + KHRONOS_APIENTRY *)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +using PFNGLGETINTEGER64I_VPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLuint index, + GLint64 *data); +using PFNGLGETBUFFERPARAMETERI64VPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + GLint64 *params); +using PFNGLGENSAMPLERSPROC = void(KHRONOS_APIENTRY *)(GLsizei count, GLuint *samplers); +using PFNGLDELETESAMPLERSPROC = void(KHRONOS_APIENTRY *)(GLsizei count, const GLuint *samplers); +using PFNGLISSAMPLERPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint sampler); +using PFNGLBINDSAMPLERPROC = void(KHRONOS_APIENTRY *)(GLuint unit, GLuint sampler); +using PFNGLSAMPLERPARAMETERIPROC = void(KHRONOS_APIENTRY *)(GLuint sampler, + GLenum pname, + GLint param); +using PFNGLSAMPLERPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLuint sampler, + GLenum pname, + const GLint *param); +using PFNGLSAMPLERPARAMETERFPROC = void(KHRONOS_APIENTRY *)(GLuint sampler, + GLenum pname, + GLfloat param); +using PFNGLSAMPLERPARAMETERFVPROC = void(KHRONOS_APIENTRY *)(GLuint sampler, + GLenum pname, + const GLfloat *param); +using PFNGLGETSAMPLERPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLuint sampler, + GLenum pname, + GLint *params); +using PFNGLGETSAMPLERPARAMETERFVPROC = void(KHRONOS_APIENTRY *)(GLuint sampler, + GLenum pname, + GLfloat *params); +using PFNGLVERTEXATTRIBDIVISORPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLuint divisor); +using PFNGLBINDTRANSFORMFEEDBACKPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint id); +using PFNGLDELETETRANSFORMFEEDBACKSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, const GLuint *ids); +using PFNGLGENTRANSFORMFEEDBACKSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *ids); +using PFNGLISTRANSFORMFEEDBACKPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint id); +using PFNGLPAUSETRANSFORMFEEDBACKPROC = void(KHRONOS_APIENTRY *)(); +using PFNGLRESUMETRANSFORMFEEDBACKPROC = void(KHRONOS_APIENTRY *)(); +using PFNGLGETPROGRAMBINARYPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary); +using PFNGLPROGRAMBINARYPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLenum binaryFormat, + const void *binary, + GLsizei length); +using PFNGLPROGRAMPARAMETERIPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLenum pname, + GLint value); +using PFNGLINVALIDATEFRAMEBUFFERPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizei numAttachments, + const GLenum *attachments); +using PFNGLINVALIDATESUBFRAMEBUFFERPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +using PFNGLTEXSTORAGE2DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); +using PFNGLTEXSTORAGE3DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); +using PFNGLGETINTERNALFORMATIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLint *params); + +// OpenGL ES 3.1 +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_NAME_LENGTH 0x92F9 +#define GL_TYPE 0x92FA +#define GL_ARRAY_SIZE 0x92FB +#define GL_OFFSET 0x92FC +#define GL_BLOCK_INDEX 0x92FD +#define GL_ARRAY_STRIDE 0x92FE +#define GL_MATRIX_STRIDE 0x92FF +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_LOCATION 0x930E +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_STENCIL_INDEX 0x1901 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 + +using PFNGLDISPATCHCOMPUTEPROC = void(KHRONOS_APIENTRY *)(GLuint num_groups_x, + GLuint num_groups_y, + GLuint num_groups_z); +using PFNGLDISPATCHCOMPUTEINDIRECTPROC = void(KHRONOS_APIENTRY *)(GLintptr indirect); +using PFNGLDRAWARRAYSINDIRECTPROC = void(KHRONOS_APIENTRY *)(GLenum mode, const void *indirect); +using PFNGLDRAWELEMENTSINDIRECTPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLenum type, + const void *indirect); +using PFNGLFRAMEBUFFERPARAMETERIPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + GLint param); +using PFNGLGETFRAMEBUFFERPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + GLint *params); +using PFNGLGETPROGRAMINTERFACEIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLenum programInterface, + GLenum pname, + GLint *params); +using PFNGLGETPROGRAMRESOURCEINDEXPROC = GLuint(KHRONOS_APIENTRY *)(GLuint program, + GLenum programInterface, + const GLchar *name); +using PFNGLGETPROGRAMRESOURCENAMEPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name); +using PFNGLGETPROGRAMRESOURCEIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params); +using PFNGLGETPROGRAMRESOURCELOCATIONPROC = GLint(KHRONOS_APIENTRY *)(GLuint program, + GLenum programInterface, + const GLchar *name); +using PFNGLUSEPROGRAMSTAGESPROC = void(KHRONOS_APIENTRY *)(GLuint pipeline, + GLbitfield stages, + GLuint program); +using PFNGLACTIVESHADERPROGRAMPROC = void(KHRONOS_APIENTRY *)(GLuint pipeline, GLuint program); +using PFNGLCREATESHADERPROGRAMVPROC = GLuint(KHRONOS_APIENTRY *)(GLenum type, + GLsizei count, + const GLchar *const *strings); +using PFNGLBINDPROGRAMPIPELINEPROC = void(KHRONOS_APIENTRY *)(GLuint pipeline); +using PFNGLDELETEPROGRAMPIPELINESPROC = void(KHRONOS_APIENTRY *)(GLsizei n, + const GLuint *pipelines); +using PFNGLGENPROGRAMPIPELINESPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *pipelines); +using PFNGLISPROGRAMPIPELINEPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint pipeline); +using PFNGLGETPROGRAMPIPELINEIVPROC = void(KHRONOS_APIENTRY *)(GLuint pipeline, + GLenum pname, + GLint *params); +using PFNGLPROGRAMUNIFORM1IPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLint v0); +using PFNGLPROGRAMUNIFORM2IPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLint v0, + GLint v1); +using PFNGLPROGRAMUNIFORM3IPROC = + void(KHRONOS_APIENTRY *)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +using PFNGLPROGRAMUNIFORM4IPROC = void( + KHRONOS_APIENTRY *)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +using PFNGLPROGRAMUNIFORM1UIPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLuint v0); +using PFNGLPROGRAMUNIFORM2UIPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLuint v0, + GLuint v1); +using PFNGLPROGRAMUNIFORM3UIPROC = + void(KHRONOS_APIENTRY *)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +using PFNGLPROGRAMUNIFORM4UIPROC = void( + KHRONOS_APIENTRY *)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +using PFNGLPROGRAMUNIFORM1FPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLfloat v0); +using PFNGLPROGRAMUNIFORM2FPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLfloat v0, + GLfloat v1); +using PFNGLPROGRAMUNIFORM3FPROC = + void(KHRONOS_APIENTRY *)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +using PFNGLPROGRAMUNIFORM4FPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3); +using PFNGLPROGRAMUNIFORM1IVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +using PFNGLPROGRAMUNIFORM2IVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +using PFNGLPROGRAMUNIFORM3IVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +using PFNGLPROGRAMUNIFORM4IVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +using PFNGLPROGRAMUNIFORM1UIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +using PFNGLPROGRAMUNIFORM2UIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +using PFNGLPROGRAMUNIFORM3UIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +using PFNGLPROGRAMUNIFORM4UIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +using PFNGLPROGRAMUNIFORM1FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +using PFNGLPROGRAMUNIFORM2FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +using PFNGLPROGRAMUNIFORM3FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +using PFNGLPROGRAMUNIFORM4FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +using PFNGLPROGRAMUNIFORMMATRIX2FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLPROGRAMUNIFORMMATRIX3FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLPROGRAMUNIFORMMATRIX4FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +using PFNGLVALIDATEPROGRAMPIPELINEPROC = void(KHRONOS_APIENTRY *)(GLuint pipeline); +using PFNGLGETPROGRAMPIPELINEINFOLOGPROC = void(KHRONOS_APIENTRY *)(GLuint pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); +using PFNGLBINDIMAGETEXTUREPROC = void(KHRONOS_APIENTRY *)(GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format); +using PFNGLGETBOOLEANI_VPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLuint index, + GLboolean *data); +using PFNGLMEMORYBARRIERPROC = void(KHRONOS_APIENTRY *)(GLbitfield barriers); +using PFNGLMEMORYBARRIERBYREGIONPROC = void(KHRONOS_APIENTRY *)(GLbitfield barriers); +using PFNGLTEXSTORAGE2DMULTISAMPLEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +using PFNGLGETMULTISAMPLEFVPROC = void(KHRONOS_APIENTRY *)(GLenum pname, + GLuint index, + GLfloat *val); +using PFNGLSAMPLEMASKIPROC = void(KHRONOS_APIENTRY *)(GLuint maskNumber, GLbitfield mask); +using PFNGLGETTEXLEVELPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLenum pname, + GLint *params); +using PFNGLGETTEXLEVELPARAMETERFVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLenum pname, + GLfloat *params); +using PFNGLBINDVERTEXBUFFERPROC = void(KHRONOS_APIENTRY *)(GLuint bindingindex, + GLuint buffer, + GLintptr offset, + GLsizei stride); +using PFNGLVERTEXATTRIBFORMATPROC = void(KHRONOS_APIENTRY *)(GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset); +using PFNGLVERTEXATTRIBIFORMATPROC = void(KHRONOS_APIENTRY *)(GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); +using PFNGLVERTEXATTRIBBINDINGPROC = void(KHRONOS_APIENTRY *)(GLuint attribindex, + GLuint bindingindex); +using PFNGLVERTEXBINDINGDIVISORPROC = void(KHRONOS_APIENTRY *)(GLuint bindingindex, GLuint divisor); + +// OpenGL ES 3.2 +#define GL_MULTISAMPLE_LINE_WIDTH_RANGE 0x9381 +#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY 0x9382 +#define GL_MULTIPLY 0x9294 +#define GL_SCREEN 0x9295 +#define GL_OVERLAY 0x9296 +#define GL_DARKEN 0x9297 +#define GL_LIGHTEN 0x9298 +#define GL_COLORDODGE 0x9299 +#define GL_COLORBURN 0x929A +#define GL_HARDLIGHT 0x929B +#define GL_SOFTLIGHT 0x929C +#define GL_DIFFERENCE 0x929E +#define GL_EXCLUSION 0x92A0 +#define GL_HSL_HUE 0x92AD +#define GL_HSL_SATURATION 0x92AE +#define GL_HSL_COLOR 0x92AF +#define GL_HSL_LUMINOSITY 0x92B0 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_BUFFER 0x82E0 +#define GL_SHADER 0x82E1 +#define GL_PROGRAM 0x82E2 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_QUERY 0x82E3 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_SAMPLER 0x82E6 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_UNDEFINED_VERTEX 0x8260 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_PRIMITIVE_BOUNDING_BOX 0x92BE +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 +#define GL_CONTEXT_FLAGS 0x821E +#define GL_LOSE_CONTEXT_ON_RESET 0x8252 +#define GL_GUILTY_CONTEXT_RESET 0x8253 +#define GL_INNOCENT_CONTEXT_RESET 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 +#define GL_NO_RESET_NOTIFICATION 0x8261 +#define GL_CONTEXT_LOST 0x0507 +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_PATCHES 0x000E +#define GL_PATCH_VERTICES 0x8E72 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_ISOLINES 0x8E7A +#define GL_QUADS 0x0007 +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_IS_PER_PATCH 0x92E7 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_IMAGE_BUFFER 0x9051 +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_COMPRESSED_RGBA_ASTC_4x4 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12 0x93DD +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D + +using PFNGLBLENDBARRIERPROC = void(KHRONOS_APIENTRY *)(); +using PFNGLCOPYIMAGESUBDATAPROC = void(KHRONOS_APIENTRY *)(GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth); +using PFNGLDEBUGMESSAGECONTROLPROC = void(KHRONOS_APIENTRY *)(GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled); +using PFNGLDEBUGMESSAGEINSERTPROC = void(KHRONOS_APIENTRY *)(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf); +using PFNGLDEBUGMESSAGECALLBACKPROC = void(KHRONOS_APIENTRY *)(GLDEBUGPROC callback, + const void *userParam); +using PFNGLGETDEBUGMESSAGELOGPROC = GLuint(KHRONOS_APIENTRY *)(GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog); +using PFNGLPUSHDEBUGGROUPPROC = void(KHRONOS_APIENTRY *)(GLenum source, + GLuint id, + GLsizei length, + const GLchar *message); +using PFNGLPOPDEBUGGROUPPROC = void(KHRONOS_APIENTRY *)(); +using PFNGLOBJECTLABELPROC = void(KHRONOS_APIENTRY *)(GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label); +using PFNGLGETOBJECTLABELPROC = void(KHRONOS_APIENTRY *)(GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label); +using PFNGLOBJECTPTRLABELPROC = void(KHRONOS_APIENTRY *)(const void *ptr, + GLsizei length, + const GLchar *label); +using PFNGLGETOBJECTPTRLABELPROC = void(KHRONOS_APIENTRY *)(const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label); +using PFNGLGETPOINTERVPROC = void(KHRONOS_APIENTRY *)(GLenum pname, void **params); +using PFNGLENABLEIPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint index); +using PFNGLDISABLEIPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint index); +using PFNGLBLENDEQUATIONIPROC = void(KHRONOS_APIENTRY *)(GLuint buf, GLenum mode); +using PFNGLBLENDEQUATIONSEPARATEIPROC = void(KHRONOS_APIENTRY *)(GLuint buf, + GLenum modeRGB, + GLenum modeAlpha); +using PFNGLBLENDFUNCIPROC = void(KHRONOS_APIENTRY *)(GLuint buf, GLenum src, GLenum dst); +using PFNGLBLENDFUNCSEPARATEIPROC = void( + KHRONOS_APIENTRY *)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +using PFNGLCOLORMASKIPROC = + void(KHRONOS_APIENTRY *)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +using PFNGLISENABLEDIPROC = GLboolean(KHRONOS_APIENTRY *)(GLenum target, GLuint index); +using PFNGLDRAWELEMENTSBASEVERTEXPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLint basevertex); +using PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices, + GLint basevertex); +using PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instancecount, + GLint basevertex); +using PFNGLFRAMEBUFFERTEXTUREPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum attachment, + GLuint texture, + GLint level); +using PFNGLPRIMITIVEBOUNDINGBOXPROC = void(KHRONOS_APIENTRY *)(GLfloat minX, + GLfloat minY, + GLfloat minZ, + GLfloat minW, + GLfloat maxX, + GLfloat maxY, + GLfloat maxZ, + GLfloat maxW); +using PFNGLGETGRAPHICSRESETSTATUSPROC = GLenum(KHRONOS_APIENTRY *)(); +using PFNGLREADNPIXELSPROC = void(KHRONOS_APIENTRY *)(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + void *data); +using PFNGLGETNUNIFORMFVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei bufSize, + GLfloat *params); +using PFNGLGETNUNIFORMIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei bufSize, + GLint *params); +using PFNGLGETNUNIFORMUIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei bufSize, + GLuint *params); +using PFNGLMINSAMPLESHADINGPROC = void(KHRONOS_APIENTRY *)(GLfloat value); +using PFNGLPATCHPARAMETERIPROC = void(KHRONOS_APIENTRY *)(GLenum pname, GLint value); +using PFNGLTEXPARAMETERIIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + const GLint *params); +using PFNGLTEXPARAMETERIUIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + const GLuint *params); +using PFNGLGETTEXPARAMETERIIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + GLint *params); +using PFNGLGETTEXPARAMETERIUIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum pname, + GLuint *params); +using PFNGLSAMPLERPARAMETERIIVPROC = void(KHRONOS_APIENTRY *)(GLuint sampler, + GLenum pname, + const GLint *param); +using PFNGLSAMPLERPARAMETERIUIVPROC = void(KHRONOS_APIENTRY *)(GLuint sampler, + GLenum pname, + const GLuint *param); +using PFNGLGETSAMPLERPARAMETERIIVPROC = void(KHRONOS_APIENTRY *)(GLuint sampler, + GLenum pname, + GLint *params); +using PFNGLGETSAMPLERPARAMETERIUIVPROC = void(KHRONOS_APIENTRY *)(GLuint sampler, + GLenum pname, + GLuint *params); +using PFNGLTEXBUFFERPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum internalformat, + GLuint buffer); +using PFNGLTEXBUFFERRANGEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum internalformat, + GLuint buffer, + GLintptr offset, + GLsizeiptr size); +using PFNGLTEXSTORAGE3DMULTISAMPLEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + +// Desktop OpenGL 1.0 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 +#define GL_ACCUM 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LIST_MODE 0x0B30 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_SHADE_MODEL 0x0B54 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_FOG 0x0B60 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_COLOR 0x0B66 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_NORMALIZE 0x0BA1 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_LOGIC_OP 0x0BF1 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_INDEX_MODE 0x0C30 +#define GL_RGBA_MODE 0x0C31 +#define GL_RENDER_MODE 0x0C40 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_FOG_HINT 0x0C54 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_INDEX_BITS 0x0D51 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_EMISSION 0x1600 +#define GL_SHININESS 0x1601 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_COLOR_INDEX 0x1900 +#define GL_BITMAP 0x1A00 +#define GL_RENDER 0x1C00 +#define GL_FEEDBACK 0x1C01 +#define GL_SELECT 0x1C02 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV 0x2300 +#define GL_EYE_LINEAR 0x2400 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_SPHERE_MAP 0x2402 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_PLANE 0x2502 +#define GL_CLAMP 0x2900 +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 + +using PFNGLPOINTSIZEPROC = void(KHRONOS_APIENTRY *)(GLfloat size); +using PFNGLPOLYGONMODEPROC = void(KHRONOS_APIENTRY *)(GLenum face, GLenum mode); +using PFNGLTEXIMAGE1DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +using PFNGLDRAWBUFFERPROC = void(KHRONOS_APIENTRY *)(GLenum buf); +using PFNGLCLEARDEPTHPROC = void(KHRONOS_APIENTRY *)(GLdouble depth); +using PFNGLLOGICOPPROC = void(KHRONOS_APIENTRY *)(GLenum opcode); +using PFNGLPIXELSTOREFPROC = void(KHRONOS_APIENTRY *)(GLenum pname, GLfloat param); +using PFNGLGETDOUBLEVPROC = void(KHRONOS_APIENTRY *)(GLenum pname, GLdouble *data); +using PFNGLGETTEXIMAGEPROC = + void(KHRONOS_APIENTRY *)(GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +using PFNGLDEPTHRANGEPROC = void(KHRONOS_APIENTRY *)(GLdouble n, GLdouble f); + +// Desktop OpenGL 1.1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_DOUBLE 0x140A +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D + +using PFNGLCOPYTEXIMAGE1DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLint border); +using PFNGLCOPYTEXSUBIMAGE1DPROC = void( + KHRONOS_APIENTRY *)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +using PFNGLTEXSUBIMAGE1DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels); + +// Desktop OpenGL 1.2 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_RESCALE_NORMAL 0x803A +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA + +// Desktop OpenGL 1.3 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF + +using PFNGLCOMPRESSEDTEXIMAGE1DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLint border, + GLsizei imageSize, + const void *data); +using PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data); +using PFNGLGETCOMPRESSEDTEXIMAGEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + void *img); + +// Desktop OpenGL 1.4 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_COMPARE_R_TO_TEXTURE 0x884E + +using PFNGLMULTIDRAWARRAYSPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + const GLint *first, + const GLsizei *count, + GLsizei drawcount); +using PFNGLMULTIDRAWELEMENTSPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + const GLsizei *count, + GLenum type, + const void *const *indices, + GLsizei drawcount); +using PFNGLPOINTPARAMETERFPROC = void(KHRONOS_APIENTRY *)(GLenum pname, GLfloat param); +using PFNGLPOINTPARAMETERFVPROC = void(KHRONOS_APIENTRY *)(GLenum pname, const GLfloat *params); +using PFNGLPOINTPARAMETERIPROC = void(KHRONOS_APIENTRY *)(GLenum pname, GLint param); +using PFNGLPOINTPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLenum pname, const GLint *params); + +// Desktop OpenGL 1.5 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_BUFFER_ACCESS 0x88BB +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SRC1_ALPHA 0x8589 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_FOG_COORD_SRC 0x8450 +#define GL_FOG_COORD 0x8451 +#define GL_CURRENT_FOG_COORD 0x8453 +#define GL_FOG_COORD_ARRAY_TYPE 0x8454 +#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORD_ARRAY_POINTER 0x8456 +#define GL_FOG_COORD_ARRAY 0x8457 +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D +#define GL_SRC0_RGB 0x8580 +#define GL_SRC1_RGB 0x8581 +#define GL_SRC2_RGB 0x8582 +#define GL_SRC0_ALPHA 0x8588 +#define GL_SRC2_ALPHA 0x858A + +using PFNGLGETQUERYOBJECTIVPROC = void(KHRONOS_APIENTRY *)(GLuint id, GLenum pname, GLint *params); +using PFNGLGETBUFFERSUBDATAPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLintptr offset, + GLsizeiptr size, + void *data); +using PFNGLMAPBUFFERPROC = void *(KHRONOS_APIENTRY *)(GLenum target, GLenum access); + +// Desktop OpenGL 2.0 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_TEXTURE_COORDS 0x8871 + +using PFNGLGETVERTEXATTRIBDVPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum pname, + GLdouble *params); +using PFNGLVERTEXATTRIB1DPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLdouble x); +using PFNGLVERTEXATTRIB1DVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLdouble *v); +using PFNGLVERTEXATTRIB1SPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLshort x); +using PFNGLVERTEXATTRIB1SVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLshort *v); +using PFNGLVERTEXATTRIB2DPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLdouble x, GLdouble y); +using PFNGLVERTEXATTRIB2DVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLdouble *v); +using PFNGLVERTEXATTRIB2SPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLshort x, GLshort y); +using PFNGLVERTEXATTRIB2SVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLshort *v); +using PFNGLVERTEXATTRIB3DPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLdouble x, + GLdouble y, + GLdouble z); +using PFNGLVERTEXATTRIB3DVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLdouble *v); +using PFNGLVERTEXATTRIB3SPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLshort x, + GLshort y, + GLshort z); +using PFNGLVERTEXATTRIB3SVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLshort *v); +using PFNGLVERTEXATTRIB4NBVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLbyte *v); +using PFNGLVERTEXATTRIB4NIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLint *v); +using PFNGLVERTEXATTRIB4NSVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLshort *v); +using PFNGLVERTEXATTRIB4NUBPROC = + void(KHRONOS_APIENTRY *)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +using PFNGLVERTEXATTRIB4NUBVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLubyte *v); +using PFNGLVERTEXATTRIB4NUIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLuint *v); +using PFNGLVERTEXATTRIB4NUSVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLushort *v); +using PFNGLVERTEXATTRIB4BVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLbyte *v); +using PFNGLVERTEXATTRIB4DPROC = + void(KHRONOS_APIENTRY *)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +using PFNGLVERTEXATTRIB4DVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLdouble *v); +using PFNGLVERTEXATTRIB4IVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLint *v); +using PFNGLVERTEXATTRIB4SPROC = + void(KHRONOS_APIENTRY *)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +using PFNGLVERTEXATTRIB4SVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLshort *v); +using PFNGLVERTEXATTRIB4UBVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLubyte *v); +using PFNGLVERTEXATTRIB4UIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLuint *v); +using PFNGLVERTEXATTRIB4USVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLushort *v); + +// Desktop OpenGL 2.1 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B + +// Desktop OpenGL 3.0 +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_INDEX 0x8222 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_R16 0x822A +#define GL_RG16 0x822C +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_ALPHA_INTEGER 0x8D97 + +using PFNGLCLAMPCOLORPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLenum clamp); +using PFNGLBEGINCONDITIONALRENDERPROC = void(KHRONOS_APIENTRY *)(GLuint id, GLenum mode); +using PFNGLENDCONDITIONALRENDERPROC = void(KHRONOS_APIENTRY *)(); +using PFNGLVERTEXATTRIBI1IPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLint x); +using PFNGLVERTEXATTRIBI2IPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLint x, GLint y); +using PFNGLVERTEXATTRIBI3IPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLint x, GLint y, GLint z); +using PFNGLVERTEXATTRIBI1UIPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLuint x); +using PFNGLVERTEXATTRIBI2UIPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLuint x, GLuint y); +using PFNGLVERTEXATTRIBI3UIPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLuint x, + GLuint y, + GLuint z); +using PFNGLVERTEXATTRIBI1IVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLint *v); +using PFNGLVERTEXATTRIBI2IVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLint *v); +using PFNGLVERTEXATTRIBI3IVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLint *v); +using PFNGLVERTEXATTRIBI1UIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLuint *v); +using PFNGLVERTEXATTRIBI2UIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLuint *v); +using PFNGLVERTEXATTRIBI3UIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLuint *v); +using PFNGLVERTEXATTRIBI4BVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLbyte *v); +using PFNGLVERTEXATTRIBI4SVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLshort *v); +using PFNGLVERTEXATTRIBI4UBVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLubyte *v); +using PFNGLVERTEXATTRIBI4USVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLushort *v); +using PFNGLBINDFRAGDATALOCATIONPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint color, + const GLchar *name); +using PFNGLFRAMEBUFFERTEXTURE1DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level); +using PFNGLFRAMEBUFFERTEXTURE3DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level, + GLint zoffset); + +// Desktop OpenGL 3.1 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 + +using PFNGLPRIMITIVERESTARTINDEXPROC = void(KHRONOS_APIENTRY *)(GLuint index); +using PFNGLGETACTIVEUNIFORMNAMEPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint uniformIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformName); + +// Desktop OpenGL 3.2 +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_DEPTH_CLAMP 0x864F +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 + +using PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + const GLsizei *count, + GLenum type, + const void *const *indices, + GLsizei drawcount, + const GLint *basevertex); +using PFNGLPROVOKINGVERTEXPROC = void(KHRONOS_APIENTRY *)(GLenum mode); +using PFNGLTEXIMAGE2DMULTISAMPLEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +using PFNGLTEXIMAGE3DMULTISAMPLEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + +// Desktop OpenGL 3.3 +#define GL_SRC1_COLOR 0x88F9 +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 + +using PFNGLBINDFRAGDATALOCATIONINDEXEDPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint colorNumber, + GLuint index, + const GLchar *name); +using PFNGLGETFRAGDATAINDEXPROC = GLint(KHRONOS_APIENTRY *)(GLuint program, const GLchar *name); +using PFNGLQUERYCOUNTERPROC = void(KHRONOS_APIENTRY *)(GLuint id, GLenum target); +using PFNGLGETQUERYOBJECTI64VPROC = void(KHRONOS_APIENTRY *)(GLuint id, + GLenum pname, + GLint64 *params); +using PFNGLGETQUERYOBJECTUI64VPROC = void(KHRONOS_APIENTRY *)(GLuint id, + GLenum pname, + GLuint64 *params); +using PFNGLVERTEXATTRIBP1UIPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +using PFNGLVERTEXATTRIBP1UIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +using PFNGLVERTEXATTRIBP2UIPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +using PFNGLVERTEXATTRIBP2UIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +using PFNGLVERTEXATTRIBP3UIPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +using PFNGLVERTEXATTRIBP3UIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +using PFNGLVERTEXATTRIBP4UIPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum type, + GLboolean normalized, + GLuint value); +using PFNGLVERTEXATTRIBP4UIVPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum type, + GLboolean normalized, + const GLuint *value); +using PFNGLVERTEXP2UIPROC = void(KHRONOS_APIENTRY *)(GLenum type, GLuint value); +using PFNGLVERTEXP2UIVPROC = void(KHRONOS_APIENTRY *)(GLenum type, const GLuint *value); +using PFNGLVERTEXP3UIPROC = void(KHRONOS_APIENTRY *)(GLenum type, GLuint value); +using PFNGLVERTEXP3UIVPROC = void(KHRONOS_APIENTRY *)(GLenum type, const GLuint *value); +using PFNGLVERTEXP4UIPROC = void(KHRONOS_APIENTRY *)(GLenum type, GLuint value); +using PFNGLVERTEXP4UIVPROC = void(KHRONOS_APIENTRY *)(GLenum type, const GLuint *value); +using PFNGLTEXCOORDP1UIPROC = void(KHRONOS_APIENTRY *)(GLenum type, GLuint coords); +using PFNGLTEXCOORDP1UIVPROC = void(KHRONOS_APIENTRY *)(GLenum type, const GLuint *coords); +using PFNGLTEXCOORDP2UIPROC = void(KHRONOS_APIENTRY *)(GLenum type, GLuint coords); +using PFNGLTEXCOORDP2UIVPROC = void(KHRONOS_APIENTRY *)(GLenum type, const GLuint *coords); +using PFNGLTEXCOORDP3UIPROC = void(KHRONOS_APIENTRY *)(GLenum type, GLuint coords); +using PFNGLTEXCOORDP3UIVPROC = void(KHRONOS_APIENTRY *)(GLenum type, const GLuint *coords); +using PFNGLTEXCOORDP4UIPROC = void(KHRONOS_APIENTRY *)(GLenum type, GLuint coords); +using PFNGLTEXCOORDP4UIVPROC = void(KHRONOS_APIENTRY *)(GLenum type, const GLuint *coords); +using PFNGLMULTITEXCOORDP1UIPROC = void(KHRONOS_APIENTRY *)(GLenum texture, + GLenum type, + GLuint coords); +using PFNGLMULTITEXCOORDP1UIVPROC = void(KHRONOS_APIENTRY *)(GLenum texture, + GLenum type, + const GLuint *coords); +using PFNGLMULTITEXCOORDP2UIPROC = void(KHRONOS_APIENTRY *)(GLenum texture, + GLenum type, + GLuint coords); +using PFNGLMULTITEXCOORDP2UIVPROC = void(KHRONOS_APIENTRY *)(GLenum texture, + GLenum type, + const GLuint *coords); +using PFNGLMULTITEXCOORDP3UIPROC = void(KHRONOS_APIENTRY *)(GLenum texture, + GLenum type, + GLuint coords); +using PFNGLMULTITEXCOORDP3UIVPROC = void(KHRONOS_APIENTRY *)(GLenum texture, + GLenum type, + const GLuint *coords); +using PFNGLMULTITEXCOORDP4UIPROC = void(KHRONOS_APIENTRY *)(GLenum texture, + GLenum type, + GLuint coords); +using PFNGLMULTITEXCOORDP4UIVPROC = void(KHRONOS_APIENTRY *)(GLenum texture, + GLenum type, + const GLuint *coords); +using PFNGLNORMALP3UIPROC = void(KHRONOS_APIENTRY *)(GLenum type, GLuint coords); +using PFNGLNORMALP3UIVPROC = void(KHRONOS_APIENTRY *)(GLenum type, const GLuint *coords); +using PFNGLCOLORP3UIPROC = void(KHRONOS_APIENTRY *)(GLenum type, GLuint color); +using PFNGLCOLORP3UIVPROC = void(KHRONOS_APIENTRY *)(GLenum type, const GLuint *color); +using PFNGLCOLORP4UIPROC = void(KHRONOS_APIENTRY *)(GLenum type, GLuint color); +using PFNGLCOLORP4UIVPROC = void(KHRONOS_APIENTRY *)(GLenum type, const GLuint *color); +using PFNGLSECONDARYCOLORP3UIPROC = void(KHRONOS_APIENTRY *)(GLenum type, GLuint color); +using PFNGLSECONDARYCOLORP3UIVPROC = void(KHRONOS_APIENTRY *)(GLenum type, const GLuint *color); + +// Desktop OpenGL 4.0 +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 + +using PFNGLUNIFORM1DPROC = void(KHRONOS_APIENTRY *)(GLint location, GLdouble x); +using PFNGLUNIFORM2DPROC = void(KHRONOS_APIENTRY *)(GLint location, GLdouble x, GLdouble y); +using PFNGLUNIFORM3DPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLdouble x, + GLdouble y, + GLdouble z); +using PFNGLUNIFORM4DPROC = + void(KHRONOS_APIENTRY *)(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +using PFNGLUNIFORM1DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLdouble *value); +using PFNGLUNIFORM2DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLdouble *value); +using PFNGLUNIFORM3DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLdouble *value); +using PFNGLUNIFORM4DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + const GLdouble *value); +using PFNGLUNIFORMMATRIX2DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLUNIFORMMATRIX3DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLUNIFORMMATRIX4DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLUNIFORMMATRIX2X3DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLUNIFORMMATRIX2X4DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLUNIFORMMATRIX3X2DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLUNIFORMMATRIX3X4DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLUNIFORMMATRIX4X2DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLUNIFORMMATRIX4X3DVPROC = void(KHRONOS_APIENTRY *)(GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLGETUNIFORMDVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLdouble *params); +using PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC = GLint(KHRONOS_APIENTRY *)(GLuint program, + GLenum shadertype, + const GLchar *name); +using PFNGLGETSUBROUTINEINDEXPROC = GLuint(KHRONOS_APIENTRY *)(GLuint program, + GLenum shadertype, + const GLchar *name); +using PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLenum shadertype, + GLuint index, + GLenum pname, + GLint *values); +using PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLenum shadertype, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLchar *name); +using PFNGLGETACTIVESUBROUTINENAMEPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLenum shadertype, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLchar *name); +using PFNGLUNIFORMSUBROUTINESUIVPROC = void(KHRONOS_APIENTRY *)(GLenum shadertype, + GLsizei count, + const GLuint *indices); +using PFNGLGETUNIFORMSUBROUTINEUIVPROC = void(KHRONOS_APIENTRY *)(GLenum shadertype, + GLint location, + GLuint *params); +using PFNGLGETPROGRAMSTAGEIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLenum shadertype, + GLenum pname, + GLint *values); +using PFNGLPATCHPARAMETERFVPROC = void(KHRONOS_APIENTRY *)(GLenum pname, const GLfloat *values); +using PFNGLDRAWTRANSFORMFEEDBACKPROC = void(KHRONOS_APIENTRY *)(GLenum mode, GLuint id); +using PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLuint id, + GLuint stream); +using PFNGLBEGINQUERYINDEXEDPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint index, GLuint id); +using PFNGLENDQUERYINDEXEDPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint index); +using PFNGLGETQUERYINDEXEDIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLuint index, + GLenum pname, + GLint *params); + +// Desktop OpenGL 4.1 +#define GL_MAX_VIEWPORTS 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F + +using PFNGLPROGRAMUNIFORM1DPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLdouble v0); +using PFNGLPROGRAMUNIFORM1DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLdouble *value); +using PFNGLPROGRAMUNIFORM2DPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLdouble v0, + GLdouble v1); +using PFNGLPROGRAMUNIFORM2DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLdouble *value); +using PFNGLPROGRAMUNIFORM3DPROC = + void(KHRONOS_APIENTRY *)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +using PFNGLPROGRAMUNIFORM3DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLdouble *value); +using PFNGLPROGRAMUNIFORM4DPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLdouble v0, + GLdouble v1, + GLdouble v2, + GLdouble v3); +using PFNGLPROGRAMUNIFORM4DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + const GLdouble *value); +using PFNGLPROGRAMUNIFORMMATRIX2DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLPROGRAMUNIFORMMATRIX3DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLPROGRAMUNIFORMMATRIX4DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLdouble *value); +using PFNGLVERTEXATTRIBL1DPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLdouble x); +using PFNGLVERTEXATTRIBL2DPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLdouble x, GLdouble y); +using PFNGLVERTEXATTRIBL3DPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLdouble x, + GLdouble y, + GLdouble z); +using PFNGLVERTEXATTRIBL4DPROC = + void(KHRONOS_APIENTRY *)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +using PFNGLVERTEXATTRIBL1DVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLdouble *v); +using PFNGLVERTEXATTRIBL2DVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLdouble *v); +using PFNGLVERTEXATTRIBL3DVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLdouble *v); +using PFNGLVERTEXATTRIBL4DVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLdouble *v); +using PFNGLVERTEXATTRIBLPOINTERPROC = void( + KHRONOS_APIENTRY *)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +using PFNGLGETVERTEXATTRIBLDVPROC = void(KHRONOS_APIENTRY *)(GLuint index, + GLenum pname, + GLdouble *params); +using PFNGLVIEWPORTARRAYVPROC = void(KHRONOS_APIENTRY *)(GLuint first, + GLsizei count, + const GLfloat *v); +using PFNGLVIEWPORTINDEXEDFPROC = + void(KHRONOS_APIENTRY *)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +using PFNGLVIEWPORTINDEXEDFVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLfloat *v); +using PFNGLSCISSORARRAYVPROC = void(KHRONOS_APIENTRY *)(GLuint first, + GLsizei count, + const GLint *v); +using PFNGLSCISSORINDEXEDPROC = + void(KHRONOS_APIENTRY *)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +using PFNGLSCISSORINDEXEDVPROC = void(KHRONOS_APIENTRY *)(GLuint index, const GLint *v); +using PFNGLDEPTHRANGEARRAYVPROC = void(KHRONOS_APIENTRY *)(GLuint first, + GLsizei count, + const GLdouble *v); +using PFNGLDEPTHRANGEINDEXEDPROC = void(KHRONOS_APIENTRY *)(GLuint index, GLdouble n, GLdouble f); +using PFNGLGETFLOATI_VPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint index, GLfloat *data); +using PFNGLGETDOUBLEI_VPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLuint index, GLdouble *data); + +// Desktop OpenGL 4.2 +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F + +using PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLint first, + GLsizei count, + GLsizei instancecount, + GLuint baseinstance); +using PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instancecount, + GLuint baseinstance); +using PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC = + void(KHRONOS_APIENTRY *)(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instancecount, + GLint basevertex, + GLuint baseinstance); +using PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint bufferIndex, + GLenum pname, + GLint *params); +using PFNGLTEXSTORAGE1DPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width); +using PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLuint id, + GLsizei instancecount); +using PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC = + void(KHRONOS_APIENTRY *)(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); + +// Desktop OpenGL 4.3 +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_MAX_WIDTH 0x827E +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_MIPMAP 0x8293 +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_COLOR_ENCODING 0x8296 +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_FILTER 0x829A +#define GL_VERTEX_TEXTURE 0x829B +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_FULL_SUPPORT 0x82B7 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_LOCATION_INDEX 0x930F +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_DISPLAY_LIST 0x82E7 + +using PFNGLCLEARBUFFERDATAPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data); +using PFNGLCLEARBUFFERSUBDATAPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data); +using PFNGLGETINTERNALFORMATI64VPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLint64 *params); +using PFNGLINVALIDATETEXSUBIMAGEPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth); +using PFNGLINVALIDATETEXIMAGEPROC = void(KHRONOS_APIENTRY *)(GLuint texture, GLint level); +using PFNGLINVALIDATEBUFFERSUBDATAPROC = void(KHRONOS_APIENTRY *)(GLuint buffer, + GLintptr offset, + GLsizeiptr length); +using PFNGLINVALIDATEBUFFERDATAPROC = void(KHRONOS_APIENTRY *)(GLuint buffer); +using PFNGLMULTIDRAWARRAYSINDIRECTPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + const void *indirect, + GLsizei drawcount, + GLsizei stride); +using PFNGLMULTIDRAWELEMENTSINDIRECTPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLenum type, + const void *indirect, + GLsizei drawcount, + GLsizei stride); +using PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC = GLint(KHRONOS_APIENTRY *)(GLuint program, + GLenum programInterface, + const GLchar *name); +using PFNGLSHADERSTORAGEBLOCKBINDINGPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLuint storageBlockIndex, + GLuint storageBlockBinding); +using PFNGLTEXTUREVIEWPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum target, + GLuint origtexture, + GLenum internalformat, + GLuint minlevel, + GLuint numlevels, + GLuint minlayer, + GLuint numlayers); +using PFNGLVERTEXATTRIBLFORMATPROC = void(KHRONOS_APIENTRY *)(GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); + +// Desktop OpenGL 4.4 +#define GL_MAP_PERSISTENT_BIT 0x0040 +#define GL_MAP_COHERENT_BIT 0x0080 +#define GL_DYNAMIC_STORAGE_BIT 0x0100 +#define GL_CLIENT_STORAGE_BIT 0x0200 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F +#define GL_BUFFER_STORAGE_FLAGS 0x8220 +#define GL_CLEAR_TEXTURE 0x9365 +#define GL_LOCATION_COMPONENT 0x934A +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C +#define GL_QUERY_BUFFER 0x9192 +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER_BINDING 0x9193 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 + +using PFNGLBUFFERSTORAGEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizeiptr size, + const void *data, + GLbitfield flags); +using PFNGLCLEARTEXIMAGEPROC = void( + KHRONOS_APIENTRY *)(GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +using PFNGLCLEARTEXSUBIMAGEPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *data); +using PFNGLBINDBUFFERSBASEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLuint first, + GLsizei count, + const GLuint *buffers); +using PFNGLBINDBUFFERSRANGEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLuint first, + GLsizei count, + const GLuint *buffers, + const GLintptr *offsets, + const GLsizeiptr *sizes); +using PFNGLBINDTEXTURESPROC = void(KHRONOS_APIENTRY *)(GLuint first, + GLsizei count, + const GLuint *textures); +using PFNGLBINDSAMPLERSPROC = void(KHRONOS_APIENTRY *)(GLuint first, + GLsizei count, + const GLuint *samplers); +using PFNGLBINDIMAGETEXTURESPROC = void(KHRONOS_APIENTRY *)(GLuint first, + GLsizei count, + const GLuint *textures); +using PFNGLBINDVERTEXBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLuint first, + GLsizei count, + const GLuint *buffers, + const GLintptr *offsets, + const GLsizei *strides); + +// Desktop OpenGL 4.5 +#define GL_NEGATIVE_ONE_TO_ONE 0x935E +#define GL_ZERO_TO_ONE 0x935F +#define GL_CLIP_ORIGIN 0x935C +#define GL_CLIP_DEPTH_MODE 0x935D +#define GL_QUERY_WAIT_INVERTED 0x8E17 +#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 +#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 +#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A +#define GL_MAX_CULL_DISTANCES 0x82F9 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA +#define GL_TEXTURE_TARGET 0x1006 +#define GL_QUERY_TARGET 0x82EA +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC + +using PFNGLCLIPCONTROLPROC = void(KHRONOS_APIENTRY *)(GLenum origin, GLenum depth); +using PFNGLCREATETRANSFORMFEEDBACKSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *ids); +using PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC = void(KHRONOS_APIENTRY *)(GLuint xfb, + GLuint index, + GLuint buffer); +using PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC = void( + KHRONOS_APIENTRY *)(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +using PFNGLGETTRANSFORMFEEDBACKIVPROC = void(KHRONOS_APIENTRY *)(GLuint xfb, + GLenum pname, + GLint *param); +using PFNGLGETTRANSFORMFEEDBACKI_VPROC = void(KHRONOS_APIENTRY *)(GLuint xfb, + GLenum pname, + GLuint index, + GLint *param); +using PFNGLGETTRANSFORMFEEDBACKI64_VPROC = void(KHRONOS_APIENTRY *)(GLuint xfb, + GLenum pname, + GLuint index, + GLint64 *param); +using PFNGLCREATEBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *buffers); +using PFNGLNAMEDBUFFERSTORAGEPROC = void(KHRONOS_APIENTRY *)(GLuint buffer, + GLsizeiptr size, + const void *data, + GLbitfield flags); +using PFNGLNAMEDBUFFERDATAPROC = void(KHRONOS_APIENTRY *)(GLuint buffer, + GLsizeiptr size, + const void *data, + GLenum usage); +using PFNGLNAMEDBUFFERSUBDATAPROC = void(KHRONOS_APIENTRY *)(GLuint buffer, + GLintptr offset, + GLsizeiptr size, + const void *data); +using PFNGLCOPYNAMEDBUFFERSUBDATAPROC = void(KHRONOS_APIENTRY *)(GLuint readBuffer, + GLuint writeBuffer, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size); +using PFNGLCLEARNAMEDBUFFERDATAPROC = void(KHRONOS_APIENTRY *)(GLuint buffer, + GLenum internalformat, + GLenum format, + GLenum type, + const void *data); +using PFNGLCLEARNAMEDBUFFERSUBDATAPROC = void(KHRONOS_APIENTRY *)(GLuint buffer, + GLenum internalformat, + GLintptr offset, + GLsizeiptr size, + GLenum format, + GLenum type, + const void *data); +using PFNGLMAPNAMEDBUFFERPROC = void *(KHRONOS_APIENTRY *)(GLuint buffer, GLenum access); +using PFNGLMAPNAMEDBUFFERRANGEPROC = void *(KHRONOS_APIENTRY *)(GLuint buffer, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +using PFNGLUNMAPNAMEDBUFFERPROC = GLboolean(KHRONOS_APIENTRY *)(GLuint buffer); +using PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC = void(KHRONOS_APIENTRY *)(GLuint buffer, + GLintptr offset, + GLsizeiptr length); +using PFNGLGETNAMEDBUFFERPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLuint buffer, + GLenum pname, + GLint *params); +using PFNGLGETNAMEDBUFFERPARAMETERI64VPROC = void(KHRONOS_APIENTRY *)(GLuint buffer, + GLenum pname, + GLint64 *params); +using PFNGLGETNAMEDBUFFERPOINTERVPROC = void(KHRONOS_APIENTRY *)(GLuint buffer, + GLenum pname, + void **params); +using PFNGLGETNAMEDBUFFERSUBDATAPROC = void(KHRONOS_APIENTRY *)(GLuint buffer, + GLintptr offset, + GLsizeiptr size, + void *data); +using PFNGLCREATEFRAMEBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *framebuffers); +using PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer); +using PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum pname, + GLint param); +using PFNGLNAMEDFRAMEBUFFERTEXTUREPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum attachment, + GLuint texture, + GLint level); +using PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer); +using PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum buf); +using PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLsizei n, + const GLenum *bufs); +using PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum src); +using PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLsizei numAttachments, + const GLenum *attachments); +using PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC = + void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +using PFNGLCLEARNAMEDFRAMEBUFFERIVPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum buffer, + GLint drawbuffer, + const GLint *value); +using PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum buffer, + GLint drawbuffer, + const GLuint *value); +using PFNGLCLEARNAMEDFRAMEBUFFERFVPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value); +using PFNGLCLEARNAMEDFRAMEBUFFERFIPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil); +using PFNGLBLITNAMEDFRAMEBUFFERPROC = void(KHRONOS_APIENTRY *)(GLuint readFramebuffer, + GLuint drawFramebuffer, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); +using PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC = GLenum(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum target); +using PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLuint framebuffer, + GLenum pname, + GLint *param); +using PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC = + void(KHRONOS_APIENTRY *)(GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); +using PFNGLCREATERENDERBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *renderbuffers); +using PFNGLNAMEDRENDERBUFFERSTORAGEPROC = void(KHRONOS_APIENTRY *)(GLuint renderbuffer, + GLenum internalformat, + GLsizei width, + GLsizei height); +using PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC = void(KHRONOS_APIENTRY *)(GLuint renderbuffer, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); +using PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLuint renderbuffer, + GLenum pname, + GLint *params); +using PFNGLCREATETEXTURESPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLsizei n, + GLuint *textures); +using PFNGLTEXTUREBUFFERPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum internalformat, + GLuint buffer); +using PFNGLTEXTUREBUFFERRANGEPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum internalformat, + GLuint buffer, + GLintptr offset, + GLsizeiptr size); +using PFNGLTEXTURESTORAGE1DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLsizei levels, + GLenum internalformat, + GLsizei width); +using PFNGLTEXTURESTORAGE2DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); +using PFNGLTEXTURESTORAGE3DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); +using PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC = + void(KHRONOS_APIENTRY *)(GLuint texture, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +using PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC = + void(KHRONOS_APIENTRY *)(GLuint texture, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); +using PFNGLTEXTURESUBIMAGE1DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void *pixels); +using PFNGLTEXTURESUBIMAGE2DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); +using PFNGLTEXTURESUBIMAGE3DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels); +using PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void *data); +using PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data); +using PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data); +using PFNGLCOPYTEXTURESUBIMAGE1DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLint x, + GLint y, + GLsizei width); +using PFNGLCOPYTEXTURESUBIMAGE2DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +using PFNGLCOPYTEXTURESUBIMAGE3DPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +using PFNGLTEXTUREPARAMETERFPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum pname, + GLfloat param); +using PFNGLTEXTUREPARAMETERFVPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum pname, + const GLfloat *param); +using PFNGLTEXTUREPARAMETERIPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum pname, + GLint param); +using PFNGLTEXTUREPARAMETERIIVPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum pname, + const GLint *params); +using PFNGLTEXTUREPARAMETERIUIVPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum pname, + const GLuint *params); +using PFNGLTEXTUREPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum pname, + const GLint *param); +using PFNGLGENERATETEXTUREMIPMAPPROC = void(KHRONOS_APIENTRY *)(GLuint texture); +using PFNGLBINDTEXTUREUNITPROC = void(KHRONOS_APIENTRY *)(GLuint unit, GLuint texture); +using PFNGLGETTEXTUREIMAGEPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels); +using PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLsizei bufSize, + void *pixels); +using PFNGLGETTEXTURELEVELPARAMETERFVPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLenum pname, + GLfloat *params); +using PFNGLGETTEXTURELEVELPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLenum pname, + GLint *params); +using PFNGLGETTEXTUREPARAMETERFVPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum pname, + GLfloat *params); +using PFNGLGETTEXTUREPARAMETERIIVPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum pname, + GLint *params); +using PFNGLGETTEXTUREPARAMETERIUIVPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum pname, + GLuint *params); +using PFNGLGETTEXTUREPARAMETERIVPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLenum pname, + GLint *params); +using PFNGLCREATEVERTEXARRAYSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *arrays); +using PFNGLDISABLEVERTEXARRAYATTRIBPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, GLuint index); +using PFNGLENABLEVERTEXARRAYATTRIBPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, GLuint index); +using PFNGLVERTEXARRAYELEMENTBUFFERPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, GLuint buffer); +using PFNGLVERTEXARRAYVERTEXBUFFERPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, + GLuint bindingindex, + GLuint buffer, + GLintptr offset, + GLsizei stride); +using PFNGLVERTEXARRAYVERTEXBUFFERSPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, + GLuint first, + GLsizei count, + const GLuint *buffers, + const GLintptr *offsets, + const GLsizei *strides); +using PFNGLVERTEXARRAYATTRIBBINDINGPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, + GLuint attribindex, + GLuint bindingindex); +using PFNGLVERTEXARRAYATTRIBFORMATPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, + GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset); +using PFNGLVERTEXARRAYATTRIBIFORMATPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); +using PFNGLVERTEXARRAYATTRIBLFORMATPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); +using PFNGLVERTEXARRAYBINDINGDIVISORPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, + GLuint bindingindex, + GLuint divisor); +using PFNGLGETVERTEXARRAYIVPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, + GLenum pname, + GLint *param); +using PFNGLGETVERTEXARRAYINDEXEDIVPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, + GLuint index, + GLenum pname, + GLint *param); +using PFNGLGETVERTEXARRAYINDEXED64IVPROC = void(KHRONOS_APIENTRY *)(GLuint vaobj, + GLuint index, + GLenum pname, + GLint64 *param); +using PFNGLCREATESAMPLERSPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *samplers); +using PFNGLCREATEPROGRAMPIPELINESPROC = void(KHRONOS_APIENTRY *)(GLsizei n, GLuint *pipelines); +using PFNGLCREATEQUERIESPROC = void(KHRONOS_APIENTRY *)(GLenum target, GLsizei n, GLuint *ids); +using PFNGLGETQUERYBUFFEROBJECTI64VPROC = void(KHRONOS_APIENTRY *)(GLuint id, + GLuint buffer, + GLenum pname, + GLintptr offset); +using PFNGLGETQUERYBUFFEROBJECTIVPROC = void(KHRONOS_APIENTRY *)(GLuint id, + GLuint buffer, + GLenum pname, + GLintptr offset); +using PFNGLGETQUERYBUFFEROBJECTUI64VPROC = void(KHRONOS_APIENTRY *)(GLuint id, + GLuint buffer, + GLenum pname, + GLintptr offset); +using PFNGLGETQUERYBUFFEROBJECTUIVPROC = void(KHRONOS_APIENTRY *)(GLuint id, + GLuint buffer, + GLenum pname, + GLintptr offset); +using PFNGLGETTEXTURESUBIMAGEPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels); +using PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC = void(KHRONOS_APIENTRY *)(GLuint texture, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei bufSize, + void *pixels); +using PFNGLGETNCOMPRESSEDTEXIMAGEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint lod, + GLsizei bufSize, + void *pixels); +using PFNGLGETNTEXIMAGEPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLint level, + GLenum format, + GLenum type, + GLsizei bufSize, + void *pixels); +using PFNGLGETNUNIFORMDVPROC = void(KHRONOS_APIENTRY *)(GLuint program, + GLint location, + GLsizei bufSize, + GLdouble *params); +using PFNGLGETNMAPDVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum query, + GLsizei bufSize, + GLdouble *v); +using PFNGLGETNMAPFVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum query, + GLsizei bufSize, + GLfloat *v); +using PFNGLGETNMAPIVPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum query, + GLsizei bufSize, + GLint *v); +using PFNGLGETNPIXELMAPFVPROC = void(KHRONOS_APIENTRY *)(GLenum map, + GLsizei bufSize, + GLfloat *values); +using PFNGLGETNPIXELMAPUIVPROC = void(KHRONOS_APIENTRY *)(GLenum map, + GLsizei bufSize, + GLuint *values); +using PFNGLGETNPIXELMAPUSVPROC = void(KHRONOS_APIENTRY *)(GLenum map, + GLsizei bufSize, + GLushort *values); +using PFNGLGETNPOLYGONSTIPPLEPROC = void(KHRONOS_APIENTRY *)(GLsizei bufSize, GLubyte *pattern); +using PFNGLGETNCOLORTABLEPROC = void( + KHRONOS_APIENTRY *)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); +using PFNGLGETNCONVOLUTIONFILTERPROC = void( + KHRONOS_APIENTRY *)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); +using PFNGLGETNSEPARABLEFILTERPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLenum format, + GLenum type, + GLsizei rowBufSize, + void *row, + GLsizei columnBufSize, + void *column, + void *span); +using PFNGLGETNHISTOGRAMPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + void *values); +using PFNGLGETNMINMAXPROC = void(KHRONOS_APIENTRY *)(GLenum target, + GLboolean reset, + GLenum format, + GLenum type, + GLsizei bufSize, + void *values); +using PFNGLTEXTUREBARRIERPROC = void(KHRONOS_APIENTRY *)(); + +// Desktop OpenGL 4.6 +#define GL_SHADER_BINARY_FORMAT_SPIR_V 0x9551 +#define GL_SPIR_V_BINARY 0x9552 +#define GL_PARAMETER_BUFFER 0x80EE +#define GL_PARAMETER_BUFFER_BINDING 0x80EF +#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008 +#define GL_VERTICES_SUBMITTED 0x82EE +#define GL_PRIMITIVES_SUBMITTED 0x82EF +#define GL_VERTEX_SHADER_INVOCATIONS 0x82F0 +#define GL_TESS_CONTROL_SHADER_PATCHES 0x82F1 +#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2 +#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3 +#define GL_FRAGMENT_SHADER_INVOCATIONS 0x82F4 +#define GL_COMPUTE_SHADER_INVOCATIONS 0x82F5 +#define GL_CLIPPING_INPUT_PRIMITIVES 0x82F6 +#define GL_CLIPPING_OUTPUT_PRIMITIVES 0x82F7 +#define GL_POLYGON_OFFSET_CLAMP 0x8E1B +#define GL_SPIR_V_EXTENSIONS 0x9553 +#define GL_NUM_SPIR_V_EXTENSIONS 0x9554 +#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF +#define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC +#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED + +using PFNGLSPECIALIZESHADERPROC = void(KHRONOS_APIENTRY *)(GLuint shader, + const GLchar *pEntryPoint, + GLuint numSpecializationConstants, + const GLuint *pConstantIndex, + const GLuint *pConstantValue); +using PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride); +using PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC = void(KHRONOS_APIENTRY *)(GLenum mode, + GLenum type, + const void *indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride); +using PFNGLPOLYGONOFFSETCLAMPPROC = void(KHRONOS_APIENTRY *)(GLfloat factor, + GLfloat units, + GLfloat clamp); + +#endif diff --git a/src/aquarium-optimized/opengl/ProgramGL.cpp b/src/aquarium-optimized/opengl/ProgramGL.cpp index 61fd6b3..ad05698 100644 --- a/src/aquarium-optimized/opengl/ProgramGL.cpp +++ b/src/aquarium-optimized/opengl/ProgramGL.cpp @@ -8,18 +8,6 @@ // Compiles OpenGL shaders and check if compiled success. // Apply Buffers, Textures and Uniforms to program. -#ifdef EGL_EGL_PROTOTYPES -#include -#include -#include "EGL/egl.h" -#include "EGL/eglext.h" -#include "EGL/eglext_angle.h" -#include "EGL/eglplatform.h" -#include "EGLWindow.h" -#else -#include "glad/glad.h" -#endif - #include #include #include @@ -27,6 +15,7 @@ #include #include +#include "OpenGLPlatforms.h" #include "ProgramGL.h" #include "common/AQUARIUM_ASSERT.h" diff --git a/src/aquarium-optimized/opengl/TextureGL.h b/src/aquarium-optimized/opengl/TextureGL.h index 6f3337c..9218509 100644 --- a/src/aquarium-optimized/opengl/TextureGL.h +++ b/src/aquarium-optimized/opengl/TextureGL.h @@ -13,19 +13,8 @@ #include #include -#ifdef EGL_EGL_PROTOTYPES -#include -#include -#include "EGL/egl.h" -#include "EGL/eglext.h" -#include "EGL/eglext_angle.h" -#include "EGL/eglplatform.h" -#include "EGLWindow.h" -#else -#include "glad/glad.h" -#endif - #include "ContextGL.h" +#include "OpenGLPlatforms.h" #include "../Texture.h" diff --git a/src/aquarium-optimized/opengl/imgui_impl_opengl3.cpp b/src/aquarium-optimized/opengl/imgui_impl_opengl3.cpp index ee96ca8..4c35a7c 100644 --- a/src/aquarium-optimized/opengl/imgui_impl_opengl3.cpp +++ b/src/aquarium-optimized/opengl/imgui_impl_opengl3.cpp @@ -92,12 +92,12 @@ #endif #if defined(IMGUI_IMPL_OPENGL_ES2) -#include +//#include #elif defined(IMGUI_IMPL_OPENGL_ES3) #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) -#include // Use GL ES 3 +//#include // Use GL ES 3 #else -#include // Use GL ES 3 +#include "OpenGLPlatforms.h" #endif #else // About Desktop OpenGL function loaders: @@ -112,15 +112,11 @@ #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #include // Needs to be initialized with gladLoadGL() in user's code #else -#include -#include "EGL/egl.h" -#include "EGL/eglext.h" -#include "EGL/eglext_angle.h" -#include "EGL/eglplatform.h" -#include "GLES3/gl32.h" #endif #endif +aquarium::OpenGLFunctions gl; + // Desktop GL has glDrawElementsBaseVertex() which GL ES and WebGL don't have. #if defined(IMGUI_IMPL_OPENGL_ES2) || defined(IMGUI_IMPL_OPENGL_ES3) #define IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX 0 @@ -138,8 +134,11 @@ static int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, static unsigned int g_VboHandle = 0, g_ElementsHandle = 0; // Functions -bool ImGui_ImplOpenGL3_Init(const char *glsl_version) +bool ImGui_ImplOpenGL3_Init(const char *glsl_version, + const aquarium::OpenGLFunctions &openglFunctions) { + gl = openglFunctions; + // Setup back-end capabilities flags ImGuiIO &io = ImGui::GetIO(); io.BackendRendererName = "imgui_impl_opengl3"; @@ -170,7 +169,7 @@ bool ImGui_ImplOpenGL3_Init(const char *glsl_version) // loader used by this code. Desktop OpenGL 3/4 need a function loader. See the // IMGUI_IMPL_OPENGL_LOADER_xxx explanation above. GLint current_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); + gl.GetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); return true; } @@ -193,21 +192,21 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData *draw_data, { // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor // enabled, polygon fill - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); -#ifdef GL_POLYGON_MODE - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -#endif + gl.Enable(GL_BLEND); + gl.BlendEquation(GL_FUNC_ADD); + gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl.Disable(GL_CULL_FACE); + gl.Disable(GL_DEPTH_TEST); + gl.Enable(GL_SCISSOR_TEST); + //#ifdef GL_POLYGON_MODE + // gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL); + //#endif // Setup viewport, orthographic projection matrix // Our visible imgui space lies from draw_data->DisplayPos (top left) to // draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single // viewport apps. - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + gl.Viewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); float L = draw_data->DisplayPos.x; float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; float T = draw_data->DisplayPos.y; @@ -218,31 +217,31 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData *draw_data, {0.0f, 0.0f, -1.0f, 0.0f}, {(R + L) / (L - R), (T + B) / (B - T), 0.0f, 1.0f}, }; - glUseProgram(g_ShaderHandle); - glUniform1i(g_AttribLocationTex, 0); - glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + gl.UseProgram(g_ShaderHandle); + gl.Uniform1i(g_AttribLocationTex, 0); + gl.UniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); #ifdef GL_SAMPLER_BINDING - glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may - // set that otherwise. + gl.BindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may + // set that otherwise. #endif (void)vertex_array_object; #ifndef IMGUI_IMPL_OPENGL_ES2 - glBindVertexArray(vertex_array_object); + gl.BindVertexArray(vertex_array_object); #endif // Bind vertex/index buffers and setup attributes for ImDrawVert - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); - glEnableVertexAttribArray(g_AttribLocationVtxPos); - glEnableVertexAttribArray(g_AttribLocationVtxUV); - glEnableVertexAttribArray(g_AttribLocationVtxColor); - glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), - (GLvoid *)IM_OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), - (GLvoid *)IM_OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, - sizeof(ImDrawVert), (GLvoid *)IM_OFFSETOF(ImDrawVert, col)); + gl.BindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); + gl.EnableVertexAttribArray(g_AttribLocationVtxPos); + gl.EnableVertexAttribArray(g_AttribLocationVtxUV); + gl.EnableVertexAttribArray(g_AttribLocationVtxColor); + gl.VertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), + (GLvoid *)IM_OFFSETOF(ImDrawVert, pos)); + gl.VertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), + (GLvoid *)IM_OFFSETOF(ImDrawVert, uv)); + gl.VertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, + sizeof(ImDrawVert), (GLvoid *)IM_OFFSETOF(ImDrawVert, col)); } // OpenGL3 Render function. @@ -261,54 +260,53 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data) // Backup GL state GLenum last_active_texture; - glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&last_active_texture); - glActiveTexture(GL_TEXTURE0); + gl.GetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&last_active_texture); + gl.ActiveTexture(GL_TEXTURE0); GLint last_program; - glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + gl.GetIntegerv(GL_CURRENT_PROGRAM, &last_program); GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + gl.GetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); #ifdef GL_SAMPLER_BINDING GLint last_sampler; - glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); + gl.GetIntegerv(GL_SAMPLER_BINDING, &last_sampler); #endif GLint last_array_buffer; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); + gl.GetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); #ifndef IMGUI_IMPL_OPENGL_ES2 GLint last_vertex_array_object; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object); -#endif -#ifdef GL_POLYGON_MODE - GLint last_polygon_mode[2]; - glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); + gl.GetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object); #endif + //#ifdef GL_POLYGON_MODE + // GLint last_polygon_mode[2]; + // gl.GetIntegerv(GL_POLYGON_MODE, last_polygon_mode); + //#endif GLint last_viewport[4]; - glGetIntegerv(GL_VIEWPORT, last_viewport); + gl.GetIntegerv(GL_VIEWPORT, last_viewport); GLint last_scissor_box[4]; - glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); + gl.GetIntegerv(GL_SCISSOR_BOX, last_scissor_box); GLenum last_blend_src_rgb; - glGetIntegerv(GL_BLEND_SRC_RGB, (GLint *)&last_blend_src_rgb); + gl.GetIntegerv(GL_BLEND_SRC_RGB, (GLint *)&last_blend_src_rgb); GLenum last_blend_dst_rgb; - glGetIntegerv(GL_BLEND_DST_RGB, (GLint *)&last_blend_dst_rgb); + gl.GetIntegerv(GL_BLEND_DST_RGB, (GLint *)&last_blend_dst_rgb); GLenum last_blend_src_alpha; - glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint *)&last_blend_src_alpha); + gl.GetIntegerv(GL_BLEND_SRC_ALPHA, (GLint *)&last_blend_src_alpha); GLenum last_blend_dst_alpha; - glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint *)&last_blend_dst_alpha); + gl.GetIntegerv(GL_BLEND_DST_ALPHA, (GLint *)&last_blend_dst_alpha); GLenum last_blend_equation_rgb; - glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint *)&last_blend_equation_rgb); + gl.GetIntegerv(GL_BLEND_EQUATION_RGB, (GLint *)&last_blend_equation_rgb); GLenum last_blend_equation_alpha; - glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint *)&last_blend_equation_alpha); - GLboolean last_enable_blend = glIsEnabled(GL_BLEND); - GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); - GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); - GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); + gl.GetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint *)&last_blend_equation_alpha); + GLboolean last_enable_blend = gl.IsEnabled(GL_BLEND); + GLboolean last_enable_cull_face = gl.IsEnabled(GL_CULL_FACE); + GLboolean last_enable_depth_test = gl.IsEnabled(GL_DEPTH_TEST); + GLboolean last_enable_scissor_test = gl.IsEnabled(GL_SCISSOR_TEST); bool clip_origin_lower_left = true; -#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) - GLenum last_clip_origin = 0; - glGetIntegerv(GL_CLIP_ORIGIN, - (GLint *)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) - if (last_clip_origin == GL_UPPER_LEFT) - clip_origin_lower_left = false; -#endif + /*#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) + GLenum last_clip_origin = 0; + gl.GetIntegerv(GL_CLIP_ORIGIN, + (GLint *)&last_clip_origin); // Support for GL 4.5's + glClipControl(GL_UPPER_LEFT) if (last_clip_origin == GL_UPPER_LEFT) clip_origin_lower_left = + false; #endif*/ // Setup desired GL state // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. @@ -316,7 +314,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data) // but then our VertexAttrib calls would overwrite the default one currently bound. GLuint vertex_array_object = 0; #ifndef IMGUI_IMPL_OPENGL_ES2 - glGenVertexArrays(1, &vertex_array_object); + gl.GenVertexArrays(1, &vertex_array_object); #endif ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); @@ -331,11 +329,11 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data) const ImDrawList *cmd_list = draw_data->CmdLists[n]; // Upload vertex/index buffers - glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), - (const GLvoid *)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), - (const GLvoid *)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); + gl.BufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), + (const GLvoid *)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); + gl.BufferData(GL_ELEMENT_ARRAY_BUFFER, + (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), + (const GLvoid *)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { @@ -365,17 +363,17 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data) { // Apply scissor/clipping rectangle if (clip_origin_lower_left) - glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), - (int)(clip_rect.z - clip_rect.x), - (int)(clip_rect.w - clip_rect.y)); + gl.Scissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), + (int)(clip_rect.z - clip_rect.x), + (int)(clip_rect.w - clip_rect.y)); else - glScissor( + gl.Scissor( (int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect .w); // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) // Bind texture, Draw - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + gl.BindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); #if IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX glDrawElementsBaseVertex( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, @@ -383,9 +381,9 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data) (void *)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset); #else - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, - sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, - (void *)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))); + gl.DrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, + sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, + (void *)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))); #endif } } @@ -394,46 +392,46 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data) // Destroy the temporary VAO #ifndef IMGUI_IMPL_OPENGL_ES2 - glDeleteVertexArrays(1, &vertex_array_object); + gl.DeleteVertexArrays(1, &vertex_array_object); #endif // Restore modified GL state - glUseProgram(last_program); - glBindTexture(GL_TEXTURE_2D, last_texture); + gl.UseProgram(last_program); + gl.BindTexture(GL_TEXTURE_2D, last_texture); #ifdef GL_SAMPLER_BINDING - glBindSampler(0, last_sampler); + gl.BindSampler(0, last_sampler); #endif - glActiveTexture(last_active_texture); + gl.ActiveTexture(last_active_texture); #ifndef IMGUI_IMPL_OPENGL_ES2 - glBindVertexArray(last_vertex_array_object); + gl.BindVertexArray(last_vertex_array_object); #endif - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); - glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); - glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, - last_blend_dst_alpha); + gl.BindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + gl.BlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); + gl.BlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, + last_blend_dst_alpha); if (last_enable_blend) - glEnable(GL_BLEND); + gl.Enable(GL_BLEND); else - glDisable(GL_BLEND); + gl.Disable(GL_BLEND); if (last_enable_cull_face) - glEnable(GL_CULL_FACE); + gl.Enable(GL_CULL_FACE); else - glDisable(GL_CULL_FACE); + gl.Disable(GL_CULL_FACE); if (last_enable_depth_test) - glEnable(GL_DEPTH_TEST); + gl.Enable(GL_DEPTH_TEST); else - glDisable(GL_DEPTH_TEST); + gl.Disable(GL_DEPTH_TEST); if (last_enable_scissor_test) - glEnable(GL_SCISSOR_TEST); + gl.Enable(GL_SCISSOR_TEST); else - glDisable(GL_SCISSOR_TEST); -#ifdef GL_POLYGON_MODE - glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); -#endif - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], - (GLsizei)last_viewport[3]); - glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], - (GLsizei)last_scissor_box[3]); + gl.Disable(GL_SCISSOR_TEST); + //#ifdef GL_POLYGON_MODE + // gl.PolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); + //#endif + gl.Viewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], + (GLsizei)last_viewport[3]); + gl.Scissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], + (GLsizei)last_scissor_box[3]); } bool ImGui_ImplOpenGL3_CreateFontsTexture() @@ -452,21 +450,21 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture() // Upload texture to graphics system GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl.GetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + gl.GenTextures(1, &g_FontTexture); + gl.BindTexture(GL_TEXTURE_2D, g_FontTexture); + gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); #ifdef GL_UNPACK_ROW_LENGTH - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0); #endif - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + gl.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); // Store our identifier io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture; // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); + gl.BindTexture(GL_TEXTURE_2D, last_texture); return true; } @@ -476,7 +474,7 @@ void ImGui_ImplOpenGL3_DestroyFontsTexture() if (g_FontTexture) { ImGuiIO &io = ImGui::GetIO(); - glDeleteTextures(1, &g_FontTexture); + gl.DeleteTextures(1, &g_FontTexture); io.Fonts->TexID = 0; g_FontTexture = 0; } @@ -487,8 +485,8 @@ void ImGui_ImplOpenGL3_DestroyFontsTexture() static bool CheckShader(GLuint handle, const char *desc) { GLint status = 0, log_length = 0; - glGetShaderiv(handle, GL_COMPILE_STATUS, &status); - glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); + gl.GetShaderiv(handle, GL_COMPILE_STATUS, &status); + gl.GetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); if ((GLboolean)status == GL_FALSE) fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", desc); @@ -496,7 +494,7 @@ static bool CheckShader(GLuint handle, const char *desc) { ImVector buf; buf.resize((int)(log_length + 1)); - glGetShaderInfoLog(handle, log_length, NULL, (GLchar *)buf.begin()); + gl.GetShaderInfoLog(handle, log_length, NULL, (GLchar *)buf.begin()); fprintf(stderr, "%s\n", buf.begin()); } return (GLboolean)status == GL_TRUE; @@ -507,8 +505,8 @@ static bool CheckShader(GLuint handle, const char *desc) static bool CheckProgram(GLuint handle, const char *desc) { GLint status = 0, log_length = 0; - glGetProgramiv(handle, GL_LINK_STATUS, &status); - glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); + gl.GetProgramiv(handle, GL_LINK_STATUS, &status); + gl.GetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); if ((GLboolean)status == GL_FALSE) fprintf( stderr, @@ -518,7 +516,7 @@ static bool CheckProgram(GLuint handle, const char *desc) { ImVector buf; buf.resize((int)(log_length + 1)); - glGetProgramInfoLog(handle, log_length, NULL, (GLchar *)buf.begin()); + gl.GetProgramInfoLog(handle, log_length, NULL, (GLchar *)buf.begin()); fprintf(stderr, "%s\n", buf.begin()); } return (GLboolean)status == GL_TRUE; @@ -528,11 +526,11 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects() { // Backup GL state GLint last_texture, last_array_buffer; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); + gl.GetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + gl.GetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); #ifndef IMGUI_IMPL_OPENGL_ES2 GLint last_vertex_array; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); + gl.GetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); #endif // Parse GLSL version string @@ -665,40 +663,40 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects() // Create shaders const GLchar *vertex_shader_with_version[2] = {g_GlslVersionString, vertex_shader}; - g_VertHandle = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL); - glCompileShader(g_VertHandle); + g_VertHandle = gl.CreateShader(GL_VERTEX_SHADER); + gl.ShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL); + gl.CompileShader(g_VertHandle); CheckShader(g_VertHandle, "vertex shader"); const GLchar *fragment_shader_with_version[2] = {g_GlslVersionString, fragment_shader}; - g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL); - glCompileShader(g_FragHandle); + g_FragHandle = gl.CreateShader(GL_FRAGMENT_SHADER); + gl.ShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL); + gl.CompileShader(g_FragHandle); CheckShader(g_FragHandle, "fragment shader"); - g_ShaderHandle = glCreateProgram(); - glAttachShader(g_ShaderHandle, g_VertHandle); - glAttachShader(g_ShaderHandle, g_FragHandle); - glLinkProgram(g_ShaderHandle); + g_ShaderHandle = gl.CreateProgram(); + gl.AttachShader(g_ShaderHandle, g_VertHandle); + gl.AttachShader(g_ShaderHandle, g_FragHandle); + gl.LinkProgram(g_ShaderHandle); CheckProgram(g_ShaderHandle, "shader program"); - g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); - g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); - g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position"); - g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV"); - g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color"); + g_AttribLocationTex = gl.GetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = gl.GetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationVtxPos = gl.GetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationVtxUV = gl.GetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationVtxColor = gl.GetAttribLocation(g_ShaderHandle, "Color"); // Create buffers - glGenBuffers(1, &g_VboHandle); - glGenBuffers(1, &g_ElementsHandle); + gl.GenBuffers(1, &g_VboHandle); + gl.GenBuffers(1, &g_ElementsHandle); ImGui_ImplOpenGL3_CreateFontsTexture(); // Restore modified GL state - glBindTexture(GL_TEXTURE_2D, last_texture); - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + gl.BindTexture(GL_TEXTURE_2D, last_texture); + gl.BindBuffer(GL_ARRAY_BUFFER, last_array_buffer); #ifndef IMGUI_IMPL_OPENGL_ES2 - glBindVertexArray(last_vertex_array); + gl.BindVertexArray(last_vertex_array); #endif return true; @@ -707,25 +705,25 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects() void ImGui_ImplOpenGL3_DestroyDeviceObjects() { if (g_VboHandle) - glDeleteBuffers(1, &g_VboHandle); + gl.DeleteBuffers(1, &g_VboHandle); if (g_ElementsHandle) - glDeleteBuffers(1, &g_ElementsHandle); + gl.DeleteBuffers(1, &g_ElementsHandle); g_VboHandle = g_ElementsHandle = 0; if (g_ShaderHandle && g_VertHandle) - glDetachShader(g_ShaderHandle, g_VertHandle); + gl.DetachShader(g_ShaderHandle, g_VertHandle); if (g_VertHandle) - glDeleteShader(g_VertHandle); + gl.DeleteShader(g_VertHandle); g_VertHandle = 0; if (g_ShaderHandle && g_FragHandle) - glDetachShader(g_ShaderHandle, g_FragHandle); + gl.DetachShader(g_ShaderHandle, g_FragHandle); if (g_FragHandle) - glDeleteShader(g_FragHandle); + gl.DeleteShader(g_FragHandle); g_FragHandle = 0; if (g_ShaderHandle) - glDeleteProgram(g_ShaderHandle); + gl.DeleteProgram(g_ShaderHandle); g_ShaderHandle = 0; ImGui_ImplOpenGL3_DestroyFontsTexture(); diff --git a/src/aquarium-optimized/opengl/imgui_impl_opengl3.h b/src/aquarium-optimized/opengl/imgui_impl_opengl3.h index a0e0da1..45b6a55 100644 --- a/src/aquarium-optimized/opengl/imgui_impl_opengl3.h +++ b/src/aquarium-optimized/opengl/imgui_impl_opengl3.h @@ -32,13 +32,16 @@ #include "imgui.h" +#include "OpenGLFunctions.h" + // Set default OpenGL3 loader to be gl3w #if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) && !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) && \ !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) #define IMGUI_IMPL_OPENGL_LOADER_GL3W #endif -IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char *glsl_version = NULL); +IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char *glsl_version, + const aquarium::OpenGLFunctions &openglFunctions); IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown(); IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame(); IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data);