aboutsummaryrefslogtreecommitdiffstatsci
path: root/vke/src/model/PbrModelTexArray.cs
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2019-05-22 10:09:50 +0200
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2019-05-22 10:09:50 +0200
commit884e2a9dba1c0f7b9305520f35aa86764bbffc4b (patch)
tree75a3f8ff39fc00f44655fe7085b1ac328dd9ca49 /vke/src/model/PbrModelTexArray.cs
parenta0330071543a504f765f5c438bec7e4363398fa7 (diff)
shadow mapping with instance rendering ok
Diffstat (limited to 'vke/src/model/PbrModelTexArray.cs')
-rw-r--r--vke/src/model/PbrModelTexArray.cs169
1 files changed, 169 insertions, 0 deletions
diff --git a/vke/src/model/PbrModelTexArray.cs b/vke/src/model/PbrModelTexArray.cs
new file mode 100644
index 0000000..99c6f76
--- /dev/null
+++ b/vke/src/model/PbrModelTexArray.cs
@@ -0,0 +1,169 @@
+//
+// PbrModel.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// Copyright (c) 2019 jp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Diagnostics;
+using System.Numerics;
+using System.Runtime.InteropServices;
+
+using VK;
+using System.Collections.Generic;
+
+namespace CVKL {
+ using static VK.Utils;
+
+ /// <summary>
+ /// Indexed pbr model whith one descriptorSet per material with separate textures attachments
+ /// </summary>
+ public class PbrModelTexArray : PbrModel {
+ public static uint TEXTURE_DIM = 512;
+
+ /// <summary>
+ /// Material structure for ubo containing texture indices in tex array
+ /// </summary>
+ public new struct Material {
+ public Vector4 baseColorFactor;
+ public Vector4 emissiveFactor;
+ public Vector4 diffuseFactor;
+ public Vector4 specularFactor;
+
+ public float workflow;
+ public AttachmentType TexCoord0;
+ public AttachmentType TexCoord1;
+ public int baseColorTextureSet;
+
+ public int phyDescTex;
+ public int normalTex;
+ public int aoTex;
+ public int emissiveTex;
+
+ public float metallicFactor;
+ public float roughnessFactor;
+ public float alphaMask;
+ public float alphaMaskCutoff;
+ }
+
+ public Image texArray;
+ public Material[] materials;
+
+ public PbrModelTexArray (Queue transferQ, string path) {
+ dev = transferQ.Dev;
+ using (CommandPool cmdPool = new CommandPool (dev, transferQ.index)) {
+ using (glTFLoader ctx = new glTFLoader (path, transferQ, cmdPool)) {
+ ulong vertexCount, indexCount;
+
+ ctx.GetVertexCount (out vertexCount, out indexCount, out IndexBufferType);
+ ulong vertSize = vertexCount * (ulong)Marshal.SizeOf<Vertex> ();
+ ulong idxSize = indexCount * (IndexBufferType == VkIndexType.Uint16 ? 2ul : 4ul);
+ ulong size = vertSize + idxSize;
+
+ vbo = new GPUBuffer (dev, VkBufferUsageFlags.VertexBuffer | VkBufferUsageFlags.TransferDst, vertSize);
+ ibo = new GPUBuffer (dev, VkBufferUsageFlags.IndexBuffer | VkBufferUsageFlags.TransferDst, idxSize);
+
+ vbo.SetName ("vbo gltf");
+ ibo.SetName ("ibo gltf");
+
+ Meshes = new List<Mesh> (ctx.LoadMeshes<Vertex> (IndexBufferType, vbo, 0, ibo, 0));
+
+ if (ctx.ImageCount > 0) {
+ texArray = new Image (dev, Image.DefaultTextureFormat, VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferDst | VkImageUsageFlags.TransferSrc,
+ VkMemoryPropertyFlags.DeviceLocal, TEXTURE_DIM, TEXTURE_DIM, VkImageType.Image2D,
+ VkSampleCountFlags.SampleCount1, VkImageTiling.Optimal, Image.ComputeMipLevels (TEXTURE_DIM), ctx.ImageCount);
+
+ ctx.BuildTexArray (ref texArray, 0);
+
+ texArray.CreateView (VkImageViewType.ImageView2DArray, VkImageAspectFlags.Color, texArray.CreateInfo.arrayLayers);
+ texArray.CreateSampler ();
+ texArray.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
+ texArray.SetName ("model texArray");
+ }
+
+ loadMaterials (ctx);
+
+ materialUBO = new HostBuffer<Material> (dev, VkBufferUsageFlags.UniformBuffer, materials);
+
+ Scenes = new List<Scene> (ctx.LoadScenes (out defaultSceneIndex));
+ }
+ }
+ }
+
+ void loadMaterials (glTFLoader ctx) {
+ Model.Material[] mats = ctx.LoadMaterial ();
+ materials = new Material[mats.Length];
+
+ for (int i = 0; i < mats.Length; i++) {
+ materials[i] = new Material {
+ workflow = (float)mats[i].workflow,
+ baseColorFactor = mats[i].baseColorFactor,
+ emissiveFactor = mats[i].emissiveFactor,
+ metallicFactor = mats[i].metallicFactor,
+ roughnessFactor = mats[i].roughnessFactor,
+
+ baseColorTextureSet = mats[i].baseColorTexture,
+ phyDescTex = mats[i].metallicRoughnessTexture,
+ normalTex = mats[i].normalTexture,
+ aoTex = mats[i].occlusionTexture,
+ emissiveTex = mats[i].emissiveTexture,
+
+ TexCoord0 = mats[i].availableAttachments,
+ TexCoord1 = mats[i].availableAttachments1,
+
+ alphaMask = 0f,
+ alphaMaskCutoff = 0.0f,
+ diffuseFactor = new Vector4 (0),
+ specularFactor = new Vector4 (0)
+ };
+ }
+ }
+
+ public override void RenderNode (CommandBuffer cmd, PipelineLayout pipelineLayout, Node node, Matrix4x4 currentTransform, bool shadowPass = false) {
+ Matrix4x4 localMat = node.localMatrix * currentTransform;
+
+ cmd.PushConstant (pipelineLayout, VkShaderStageFlags.Vertex, localMat);
+
+ if (node.Mesh != null) {
+ foreach (Primitive p in node.Mesh.Primitives) {
+ if (!shadowPass)
+ cmd.PushConstant (pipelineLayout, VkShaderStageFlags.Fragment, (int)p.material, (uint)Marshal.SizeOf<Matrix4x4> ());
+ cmd.DrawIndexed (p.indexCount, 1, p.indexBase, p.vertexBase, 0);
+ }
+ }
+ if (node.Children == null)
+ return;
+ foreach (Node child in node.Children)
+ RenderNode (cmd, pipelineLayout, child, localMat, shadowPass);
+ }
+
+ protected override void Dispose (bool disposing) {
+ if (!isDisposed) {
+ if (disposing) {
+ texArray?.Dispose ();
+ } else
+ Debug.WriteLine ("model was not disposed");
+ }
+ base.Dispose (disposing);
+ }
+ }
+}