Beispiel #1
0
 /// <summary>
 /// Queries for all potentially visible RenderChunk instances given a RenderPassDesc descriptor.
 /// </summary>
 /// <param name="desc">A descriptor for the current rendering pass.</param>
 public void QueryForChunks(ref RenderPassDesc desc)
 {
     foreach (BaseEntity entity in this.entities.Values)
     {
         entity.QueryForRenderChunks(ref desc);
     }
 }
Beispiel #2
0
        /// <summary>
        /// This is called by the <seealso cref="GraphicsSystem"/> to query the WaterComponent for information
        /// needed to render the water plane.
        /// </summary>
        /// <param name="desc"></param>
        public override void QueryForChunks(ref RenderPassDesc desc)
        {
            // We don't render water on geometry render passes
            if (desc.GeometryChunksOnlyThisPass)
            {
                return;
            }

            // Check to see if the water plane is in the view frustum
            if (!desc.ViewFrustum.Intersects(this.boundingBox))
            {
                return;
            }

            WaterChunk chunk = this.parentEntity.Game.Graphics.AllocateWaterChunk();

            chunk.Vertices          = this.waterVertices;
            chunk.VertexDeclaration = vertexDeclaration;
            chunk.Material          = this.material;
            chunk.Type            = PrimitiveType.TriangleList;
            chunk.PrimitiveCount  = 2;  // The water plane is only two triangles.
            chunk.Elevation       = this.WaterElevation;
            chunk.Reflectivity    = this.reflectivity;
            chunk.WaterColorLight = this.waterColorLight;
            chunk.WaterColorDark  = this.waterColorDark;
        }
Beispiel #3
0
        public override void QueryForChunks(ref RenderPassDesc desc)
        {
            // Restore the vertex buffer contents if the graphics device was lost.
            if (this.vertexBuffer.IsContentLost)
            {
                this.vertexBuffer.SetData(this.particles);
            }

            // If there are any particles waiting in the newly added queue, we'd better upload them to the GPU ready for drawing.
            if (this.firstNewParticle != this.firstFreeParticle)
            {
                AddNewParticlesToVertexBuffer();
            }

            // If there are any active particles, draw them now!
            if (this.firstActiveParticle != this.firstFreeParticle)
            {
                ParticleChunk chunk = this.parentEntity.Game.Graphics.AllocateParticleChunk();
                chunk.vertices         = this.vertexBuffer;
                chunk.indices          = this.indexBuffer;
                chunk.Material         = this.material;
                chunk.Type             = PrimitiveType.TriangleList;
                chunk.ParticleSettings = this.settings;
                chunk.CurrentTime      = this.currentTime;

                chunk.StartVertexIndex = this.firstActiveParticle * 4;
                chunk.StartIndex       = this.firstActiveParticle * 6;

                if (this.firstActiveParticle < this.firstFreeParticle)
                {
                    // If the active particles are all in one consecutive range, we can draw them all in a single call.
                    chunk.NumVerts       = (this.firstFreeParticle - this.firstActiveParticle) * 4;
                    chunk.PrimitiveCount = (this.firstFreeParticle - this.firstActiveParticle) * 2;
                }
                else
                {
                    // If the active particle range wraps past the end of the queue
                    // back to the start, we must split them over two draw calls.
                    chunk.NumVerts       = (this.settings.MaxParticles - this.firstActiveParticle) * 4;
                    chunk.PrimitiveCount = (this.settings.MaxParticles - this.firstActiveParticle) * 2;

                    if (this.firstFreeParticle > 0)
                    {
                        ParticleChunk chunkTwo = this.parentEntity.Game.Graphics.AllocateParticleChunk();
                        chunkTwo.vertices         = this.vertexBuffer;
                        chunkTwo.indices          = this.indexBuffer;
                        chunkTwo.StartVertexIndex = 0;
                        chunkTwo.NumVerts         = this.firstFreeParticle * 4;
                        chunkTwo.StartIndex       = 0;
                        chunkTwo.PrimitiveCount   = this.firstFreeParticle * 2;
                        chunkTwo.Material         = this.material;
                        chunkTwo.Type             = PrimitiveType.TriangleList;
                        chunkTwo.ParticleSettings = this.settings;
                        chunkTwo.CurrentTime      = this.currentTime;
                    }
                }
            }

            ++drawCounter;
        }
Beispiel #4
0
        public unsafe bool Init(RenderPassDesc desc, RenderTexture2D[] renderTextures)
        {
            ValidateMSAARenderTextures(renderTextures);
            int length = renderTextures.Length;

            InitBase(ref desc, length);
            using (var descNative = new RenderPassDesc_NativeInterop(ref desc))
            {
                var renderTextureHandles = stackalloc IntPtr[length];
                var usages             = stackalloc RenderTextureUsage[length];
                var depthStencilHandle = IntPtr.Zero;
                var stencilUsage       = StencilUsage.Discard;
                if (renderTextures[0].depthStencil != null)
                {
                    depthStencilHandle = renderTextures[0].depthStencil.handle;
                    stencilUsage       = renderTextures[0].depthStencil.stencilUsage;
                }
                for (int i = 0; i != length; ++i)
                {
                    renderTextureHandles[i] = renderTextures[i].handle;
                    usages[i] = renderTextures[i].usage;
                }
                return(Orbital_Video_D3D12_RenderPass_Init_WithRenderTextures(handle, &descNative, renderTextureHandles, usages, (uint)length, depthStencilHandle, stencilUsage) != 0);
            }
        }
 public unsafe bool Init(RenderPassDesc desc)
 {
     using (var descNative = new RenderPassDesc_NativeInterop(ref desc))
     {
         return(Orbital_Video_Vulkan_RenderPass_Init(handle, &descNative) != 0);
     }
 }
Beispiel #6
0
 /// <summary>
 /// Gives each component a change to give render information.
 /// Generally only the <see cref="RenderComponent"/> does this, but occasionally we may want others to
 /// have the chance to do it, just like the PhysicsComponent can when it is displaying physics meshes.
 /// </summary>
 /// <param name="desc">Descriptor reference from the renderer</param>
 public virtual void QueryForRenderChunks(ref RenderPassDesc desc)
 {
     foreach (KeyValuePair <ComponentType, BaseComponent> pair in this.componentList)
     {
         (pair.Value).QueryForChunks(ref desc);
     }
 }
Beispiel #7
0
        public override void QueryForChunks(ref RenderPassDesc desc)
        {
            if (desc.GeometryChunksExcludedThisPass)
            {
                return;
            }

            switch (desc.Type)
            {
            case RenderPassType.ShadowMapCreate:
            case RenderPassType.SemiTransparentOnly:
            case RenderPassType.SkyOnly:
            {
                return;
            }
            }

            var msgGetWaterElev = ObjectPool.Aquire <MsgGetGraphicsWaterElevation>();

            this.parentEntity.Game.SendInterfaceMessage(msgGetWaterElev, InterfaceType.Graphics);

            desc.WaterElevation = msgGetWaterElev.Elevation;

            this.rootQuadTree.QueryForRenderChunks(desc.ViewFrustum, ref desc.ClippingPlane, desc.RequestedLOD, ref desc);
        }
Beispiel #8
0
 public RenderPassDesc_NativeInterop(ref RenderPassDesc desc)
 {
     clearColor        = (byte)(desc.clearColor ? 1 : 0);
     clearDepthStencil = (byte)(desc.clearDepthStencil ? 1 : 0);
     clearColorValue   = desc.clearColorValue;
     depthValue        = desc.depthValue;
     stencilValue      = desc.stencilValue;
 }
Beispiel #9
0
 public unsafe bool Init(RenderPassDesc desc, SwapChain swapChain, DepthStencil depthStencil)
 {
     InitBase(ref desc, 1);
     using (var descNative = new RenderPassDesc_NativeInterop(ref desc))
     {
         return(Orbital_Video_D3D12_RenderPass_Init_WithSwapChain(handle, &descNative, swapChain.handle, depthStencil.handle, depthStencil.stencilUsage) != 0);
     }
 }
Beispiel #10
0
 public unsafe bool Init(RenderPassDesc desc, RenderTexture2D renderTexture, DepthStencil depthStencil)
 {
     InitBase(ref desc, 1);
     using (var descNative = new RenderPassDesc_NativeInterop(ref desc))
     {
         var renderTextureHandle = renderTexture.handle;
         var usage = renderTexture.usage;
         return(Orbital_Video_D3D12_RenderPass_Init_WithRenderTextures(handle, &descNative, &renderTextureHandle, &usage, 1, depthStencil.handle, depthStencil.stencilUsage) != 0);
     }
 }
        public RenderPassDesc_NativeInterop(ref RenderPassDesc desc)
        {
            renderTargetDescCount = desc.renderTargetDescs.Length;
            renderTargetDescs     = (RenderPassRenderTargetDesc_NativeInterop *)Marshal.AllocHGlobal(Marshal.SizeOf <RenderPassRenderTargetDesc_NativeInterop>() * desc.renderTargetDescs.Length);
            for (int i = 0; i != desc.renderTargetDescs.Length; ++i)
            {
                renderTargetDescs[i] = new RenderPassRenderTargetDesc_NativeInterop(ref desc.renderTargetDescs[i]);
            }

            depthStencilDesc = new RenderPassDepthStencilDesc_NativeInterop(ref desc.depthStencilDesc);
        }
        public override RenderPassBase CreateRenderPass(RenderPassDesc desc)
        {
            var abstraction = new RenderPass(this);

            if (!abstraction.Init(desc))
            {
                abstraction.Dispose();
                throw new Exception("Failed to create RenderPass");
            }
            return(abstraction);
        }
Beispiel #13
0
        public override RenderPassBase CreateRenderPass(RenderPassDesc desc, Texture2DBase[] renderTextures)
        {
            var abstraction = new RenderPass(this);

            /*if (!abstraction.Init(desc, (RenderTexture2D[])renderTextures))
             * {
             *      abstraction.Dispose();
             *      throw new Exception("Failed to create RenderState");
             * }*/
            return(abstraction);
        }
Beispiel #14
0
        public override RenderPassBase CreateRenderPass(RenderPassDesc desc, DepthStencilBase depthStencil)
        {
            var abstraction = new RenderPass(deviceD3D12);

            if (!abstraction.Init(desc, this, (DepthStencil)depthStencil))
            {
                abstraction.Dispose();
                throw new Exception("Failed to create RenderPass");
            }
            return(abstraction);
        }
Beispiel #15
0
        public override RenderPassBase CreateRenderPass(RenderPassDesc desc, Texture2DBase[] renderTextures, DepthStencilBase depthStencil)
        {
            var abstraction = new RenderPass(this);

            if (!abstraction.Init(desc, (RenderTexture2D[])renderTextures, (DepthStencil)depthStencil))
            {
                abstraction.Dispose();
                throw new Exception("Failed to create RenderState");
            }
            return(abstraction);
        }
Beispiel #16
0
        /// <summary>
        /// Allows the renderer to query this component for render information.
        /// </summary>
        /// <param name="desc">Descriptor reference from the renderer</param>
        /// <remarks>This is used to render physics information. Only meant for debug use.</remarks>
        public override void QueryForChunks(ref RenderPassDesc desc)
        {
#if WINDOWS
            if (this.parentEntity.Game.PhysicsRenderer.Enabled)
            {
                // Do not render this physics mesh's verts if it isn't in view.
                if (!desc.RenderCamera.ViewFrustum.Intersects(this.actor.GetBoundingBox()))
                {
                    return;
                }
            }
#endif //WINDOWS
        }
Beispiel #17
0
 public unsafe bool Init(RenderPassDesc desc, SwapChain swapChain)
 {
     InitBase(ref desc, 1);
     using (var descNative = new RenderPassDesc_NativeInterop(ref desc))
     {
         var depthStencilHandle = IntPtr.Zero;
         var stencilUsage       = StencilUsage.Discard;
         if (swapChain.depthStencil != null)
         {
             depthStencilHandle = swapChain.depthStencilD3D12.handle;
             stencilUsage       = swapChain.depthStencilD3D12.stencilUsage;
         }
         return(Orbital_Video_D3D12_RenderPass_Init_WithSwapChain(handle, &descNative, swapChain.handle, depthStencilHandle, stencilUsage) != 0);
     }
 }
Beispiel #18
0
 public unsafe bool Init(RenderPassDesc desc, RenderTexture2D renderTexture)
 {
     InitBase(ref desc, 1);
     using (var descNative = new RenderPassDesc_NativeInterop(ref desc))
     {
         var renderTextureHandle = renderTexture.handle;
         var usage = renderTexture.usage;
         var depthStencilHandle = IntPtr.Zero;
         var stencilUsage       = StencilUsage.Discard;
         if (renderTexture.depthStencil != null)
         {
             depthStencilHandle = renderTexture.depthStencil.handle;
             stencilUsage       = renderTexture.depthStencil.stencilUsage;
         }
         return(Orbital_Video_D3D12_RenderPass_Init_WithRenderTextures(handle, &descNative, &renderTextureHandle, &usage, 1, depthStencilHandle, stencilUsage) != 0);
     }
 }
Beispiel #19
0
        /// <summary>
        /// Allows the renderer to query this component for light information
        /// </summary>
        /// <param name="desc">Descriptor reference from the renderer</param>
        public override void QueryForChunks(ref RenderPassDesc desc)
        {
            if (desc.GeometryChunksOnlyThisPass)
            {
                return;
            }

            LightChunk chunk;

            chunk               = this.parentEntity.Game.Graphics.AllocateLightChunk();
            chunk.position      = this.parentEntity.Position;
            chunk.direction     = this.parentEntity.Rotation.Forward;
            chunk.directional   = (this.type == LightType.Directional);
            chunk.ambientColor  = this.ambientColor;
            chunk.diffuseColor  = this.diffuseColor;
            chunk.specularColor = this.specularColor;
            chunk.specularPower = this.specularPower;
        }
Beispiel #20
0
        public override void QueryForRenderChunks(ref RenderPassDesc desc)
        {
            if (displayBoundingBoxes)
            {
                foreach (NavMeshChunk chunk in meshChunks.Values)
                {
                    chunk.BoundingBoxDrawnThisFrame = false;
                }

                foreach (NavMeshChunk chunk in meshChunks.Values)
                {
                    if (!chunk.BoundingBoxDrawnThisFrame)
                    {
                        chunk.QueryForRenderChunks(ref desc);
                    }
                }
            }
        }
Beispiel #21
0
        public void QueryForRenderChunks(ref RenderPassDesc desc)
        {
            boundingBoxDrawnThisFrame = true;

            if (!desc.RenderCamera.ViewFrustum.Intersects(boundingBox))
            {
                return;
            }

            // Draw bounding boxes
            GeometryChunk boxChunk = this.parent.Game.Graphics.AllocateGeometryChunk();

            boxChunk.Indices = boundingBoxIndexBuffer;
            boxChunk.VertexStreams.Add(this.boundingBoxVertBuffer);
            boxChunk.WorldTransform      = Matrix.Identity;
            boxChunk.VertexCount         = this.boundingBoxMesh.Length;
            boxChunk.StartIndex          = 0;
            boxChunk.VertexStreamOffset  = 0;
            boxChunk.PrimitiveCount      = 12; // Number of trianges that are required to render a cube.
            boxChunk.Material            = boundingBoxMaterial;
            boxChunk.RenderTechniqueName = boundingBoxMaterial.CurrentTechnique;
            boxChunk.Type = PrimitiveType.TriangleList;
        }
 public override RenderPassBase CreateRenderPass(RenderPassDesc desc)
 {
     return(swapChain.CreateRenderPass(desc));
 }
Beispiel #23
0
        public void Init(string platformPath, string folder64Bit, string folder32Bit)
        {
            // pre-load native libs
            string libFolderBit;

            if (IntPtr.Size == 8)
            {
                libFolderBit = folder64Bit;
            }
            else if (IntPtr.Size == 4)
            {
                libFolderBit = folder32Bit;
            }
            else
            {
                throw new NotSupportedException("Unsupported bit size: " + IntPtr.Size.ToString());
            }

                        #if RELEASE
            const string config = "Release";
                        #else
            const string config = "Debug";
                        #endif

            // load api abstraction (api-instance and hardware-device)
            var abstractionDesc = new AbstractionDesc(true);
            abstractionDesc.supportedAPIs = new AbstractionAPI[] { AbstractionAPI.D3D12 };

            abstractionDesc.deviceDescD3D12.window = window;
            abstractionDesc.nativeLibPathD3D12     = Path.Combine(platformPath, @"Shared\Orbital.Video.D3D12.Native\bin", libFolderBit, config);

            abstractionDesc.deviceDescVulkan.window = window;
            abstractionDesc.nativeLibPathVulkan     = Path.Combine(platformPath, @"Shared\Orbital.Video.Vulkan.Native\bin", libFolderBit, config);

            if (!Abstraction.InitFirstAvaliable(abstractionDesc, out instance, out device))
            {
                throw new Exception("Failed to init abstraction");
            }

            // create command list
            commandList = device.CreateCommandList();

            // create render pass
            var renderPassDesc = new RenderPassDesc()
            {
                clearColor      = true,
                clearColorValue = new Vec4(0, .2f, .4f, 1)
            };
            renderPass = device.CreateRenderPass(renderPassDesc);

            // create texture
            int textureWidth = 256, textureHeight = 256;
            var textureData = new byte[textureWidth * textureHeight * 4];
            for (int y = 0; y != textureHeight; ++y)
            {
                for (int x = 0; x != textureWidth; ++x)
                {
                    int i = (x * 4) + (y * textureWidth * 4);
                    if (x % 16 <= 7 && y % 16 <= 7)
                    {
                        textureData[i + 0] = 0;
                        textureData[i + 1] = 0;
                        textureData[i + 2] = 0;
                        textureData[i + 3] = 0;
                    }
                    else
                    {
                        textureData[i + 0] = 255;
                        textureData[i + 1] = 255;
                        textureData[i + 2] = 255;
                        textureData[i + 3] = 255;
                    }
                }
            }
            texture = device.CreateTexture2D(TextureFormat.B8G8R8A8, textureWidth, textureHeight, textureData, TextureMode.GPUOptimized);

            // create texture 2
            textureWidth  = 100;
            textureHeight = 100;
            textureData   = new byte[textureWidth * textureHeight * 4];
            for (int y = 0; y != textureHeight; ++y)
            {
                for (int x = 0; x != textureWidth; ++x)
                {
                    int i = (x * 4) + (y * textureWidth * 4);
                    if (x % 16 <= 7 && y % 16 <= 7)
                    {
                        textureData[i + 0] = 0;
                        textureData[i + 1] = 0;
                        textureData[i + 2] = 0;
                        textureData[i + 3] = 0;
                    }
                    else
                    {
                        textureData[i + 0] = 255;
                        textureData[i + 1] = 255;
                        textureData[i + 2] = 255;
                        textureData[i + 3] = 255;
                    }
                }
            }
            texture2 = device.CreateTexture2D(TextureFormat.B8G8R8A8, textureWidth, textureHeight, textureData, TextureMode.GPUOptimized);

            // create constant buffer
            constantBufferObject = new ConstantBufferObject()
            {
                offset    = .5f,
                constrast = .5f
            };
            constantBuffer = device.CreateConstantBuffer <ConstantBufferObject>(constantBufferObject, ConstantBufferMode.Write);

            // load shaders
            // TODO: load CS2X compiled ShaderEffect

            /*using (var stream = new FileStream("Shader.se", FileMode.Open, FileAccess.Read, FileShare.Read))
             * {
             *      shaderEffect = device.CreateShaderEffect(stream, ShaderEffectSamplerAnisotropy.Default);
             * }*/

            using (var vsStream = new FileStream("Shaders\\Shader_D3D12.vs", FileMode.Open, FileAccess.Read, FileShare.Read))
                using (var psStream = new FileStream("Shaders\\Shader_D3D12.ps", FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var vs = new Video.D3D12.Shader((Video.D3D12.Device)device, ShaderType.VS);
                    var ps = new Video.D3D12.Shader((Video.D3D12.Device)device, ShaderType.PS);
                    if (!vs.Init(vsStream))
                    {
                        throw new Exception("Failed to init VS shader");
                    }
                    if (!ps.Init(psStream))
                    {
                        throw new Exception("Failed to init PS shader");
                    }
                    var desc = new ShaderEffectDesc();
                    desc.constantBuffers    = new ShaderEffectConstantBuffer[1];
                    desc.constantBuffers[0] = new ShaderEffectConstantBuffer()
                    {
                        registerIndex = 0,
                        usage         = ShaderEffectResourceUsage.VS
                    };
                    desc.textures    = new ShaderEffectTexture[2];
                    desc.textures[0] = new ShaderEffectTexture()
                    {
                        registerIndex = 0,
                        usage         = ShaderEffectResourceUsage.PS
                    };
                    desc.textures[1] = new ShaderEffectTexture()
                    {
                        registerIndex = 1,
                        usage         = ShaderEffectResourceUsage.PS
                    };
                    desc.samplers    = new ShaderEffectSampler[1];
                    desc.samplers[0] = new ShaderEffectSampler()
                    {
                        registerIndex = 0,
                        filter        = ShaderEffectSamplerFilter.Default,
                        anisotropy    = ShaderEffectSamplerAnisotropy.Default,
                        addressU      = ShaderEffectSamplerAddress.Wrap,
                        addressV      = ShaderEffectSamplerAddress.Wrap,
                        addressW      = ShaderEffectSamplerAddress.Wrap
                    };
                    shaderEffect = device.CreateShaderEffect(vs, ps, null, null, null, desc, true);
                }

            // create vertex buffer
            var vertexBufferLayout = new VertexBufferLayout();
            vertexBufferLayout.elements    = new VertexBufferLayoutElement[3];
            vertexBufferLayout.elements[0] = new VertexBufferLayoutElement()
            {
                type        = VertexBufferLayoutElementType.Float3,
                usage       = VertexBufferLayoutElementUsage.Position,
                streamIndex = 0, usageIndex = 0, byteOffset = 0
            };
            vertexBufferLayout.elements[1] = new VertexBufferLayoutElement()
            {
                type        = VertexBufferLayoutElementType.RGBAx8,
                usage       = VertexBufferLayoutElementUsage.Color,
                streamIndex = 0, usageIndex = 0, byteOffset = (sizeof(float) * 3)
            };
            vertexBufferLayout.elements[2] = new VertexBufferLayoutElement()
            {
                type        = VertexBufferLayoutElementType.Float2,
                usage       = VertexBufferLayoutElementUsage.UV,
                streamIndex = 0, usageIndex = 0, byteOffset = (sizeof(float) * 3) + 4
            };

            var vertices = new Vertex[]
            {
                new Vertex(new Vec3(-1, -1, 0), Color4.red, new Vec2(0, 0)),
                new Vertex(new Vec3(0, 1, 0), Color4.green, new Vec2(.5f, 1)),
                new Vertex(new Vec3(1, -1, 0), Color4.blue, new Vec2(1, 0))
            };
            vertexBuffer = device.CreateVertexBuffer <Vertex>(vertices, vertexBufferLayout, VertexBufferMode.GPUOptimized);

            // create render state
            var renderStateDesc = new RenderStateDesc()
            {
                renderPass           = renderPass,
                shaderEffect         = shaderEffect,
                constantBuffers      = new ConstantBufferBase[1],
                textures             = new TextureBase[2],
                vertexBuffer         = vertexBuffer,
                vertexBufferTopology = VertexBufferTopology.Triangle
            };
            renderStateDesc.constantBuffers[0] = constantBuffer;
            renderStateDesc.textures[0]        = texture;
            renderStateDesc.textures[1]        = texture2;
            renderState = device.CreateRenderState(renderStateDesc, 0);

            // print all GPUs this abstraction supports
            if (!instance.QuerySupportedAdapters(false, out var adapters))
            {
                throw new Exception("Failed: QuerySupportedAdapters");
            }
            foreach (var adapter in adapters)
            {
                Debug.WriteLine(adapter.name);
            }
        }
        public RenderTextureTest(DeviceBase device)
        {
            // create render texture
            const int size = 256;

            renderTexture = device.CreateRenderTexture2D(size, size, TextureFormat.Default, RenderTextureUsage.Discard, TextureMode.GPUOptimized, MSAALevel.Disabled, true, MultiGPUNodeResourceVisibility.Self);

            // load shader effect
            using (var vsStream = new FileStream("Shaders\\Triangle_D3D12.vs", FileMode.Open, FileAccess.Read, FileShare.Read))
                using (var psStream = new FileStream("Shaders\\Triangle_D3D12.ps", FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var vs = new Video.D3D12.Shader((Video.D3D12.Device)device, ShaderType.VS);
                    var ps = new Video.D3D12.Shader((Video.D3D12.Device)device, ShaderType.PS);
                    if (!vs.Init(vsStream))
                    {
                        throw new Exception("Failed to init VS shader");
                    }
                    if (!ps.Init(psStream))
                    {
                        throw new Exception("Failed to init PS shader");
                    }
                    var desc = new ShaderEffectDesc();
                    shaderEffect = device.CreateShaderEffect(vs, ps, null, null, null, desc, true);
                }

            // create vertex buffer
            var vertices = new Vec3[3]
            {
                new Vec3(-1, -1, 0),
                new Vec3(0, 1, 0),
                new Vec3(1, -1, 0)
            };

            vertexBuffer = device.CreateVertexBuffer <Vec3>(vertices, VertexBufferMode.GPUOptimized);

            // create vertex buffer streamer
            var vertexBufferStreamLayout = new VertexBufferStreamLayout()
            {
                descs    = new VertexBufferStreamDesc[1],
                elements = new VertexBufferStreamElement[1]
            };

            vertexBufferStreamLayout.descs[0] = new VertexBufferStreamDesc()
            {
                vertexBuffer = vertexBuffer,
                type         = VertexBufferStreamType.VertexData
            };
            vertexBufferStreamLayout.elements[0] = new VertexBufferStreamElement()
            {
                type   = VertexBufferStreamElementType.Float3,
                usage  = VertexBufferStreamElementUsage.Position,
                offset = 0
            };
            vertexBufferStreamer = device.CreateVertexBufferStreamer(vertexBufferStreamLayout);

            // create render pass
            var renderPassDesc = RenderPassDesc.CreateDefault(new Color4F(0, 0, 0, 0), 1);

            renderPass = renderTexture.CreateRenderPass(renderPassDesc);

            // create render state
            var renderStateDesc = new RenderStateDesc()
            {
                renderPass           = renderPass,
                shaderEffect         = shaderEffect,
                vertexBufferTopology = VertexBufferTopology.Triangle,
                vertexBufferStreamer = vertexBufferStreamer,
                triangleCulling      = TriangleCulling.Back,
                triangleFillMode     = TriangleFillMode.Solid
            };

            renderState = device.CreateRenderState(renderStateDesc);
        }
        public void Init(string platformPath, string folder64Bit, string folder32Bit)
        {
            // pre-load native libs
            string libFolderBit;

            if (IntPtr.Size == 8)
            {
                libFolderBit = folder64Bit;
            }
            else if (IntPtr.Size == 4)
            {
                libFolderBit = folder32Bit;
            }
            else
            {
                throw new NotSupportedException("Unsupported bit size: " + IntPtr.Size.ToString());
            }

                        #if RELEASE
            const string config = "Release";
                        #else
            const string config = "Debug";
                        #endif

            // load api abstraction (api-instance and hardware-device)
            var abstractionDesc = new AbstractionDesc(AbstractionInitType.DefaultSingleGPU);
            abstractionDesc.supportedAPIs = new AbstractionAPI[] { AbstractionAPI.D3D12 };

            abstractionDesc.deviceDescD3D12.window = window;
            //abstractionDesc.deviceDescD3D12.adapterIndex = 1;
            //abstractionDesc.deviceDescD3D12.vSyncMode = SwapChainVSyncMode.VSyncOff;
            abstractionDesc.nativeLibPathD3D12 = Path.Combine(platformPath, @"Shared\Orbital.Video.D3D12.Native\bin", libFolderBit, config);

            abstractionDesc.deviceDescVulkan.window = window;
            abstractionDesc.nativeLibPathVulkan     = Path.Combine(platformPath, @"Shared\Orbital.Video.Vulkan.Native\bin", libFolderBit, config);

            if (!Abstraction.InitFirstAvaliable(abstractionDesc, out instance, out device))
            {
                throw new Exception("Failed to init abstraction");
            }

            // create render texture test objects
            renderTextureTest = new RenderTextureTest(device);

            // create msaa render texture
            if (!device.GetMaxMSAALevel(TextureFormat.Default, out var msaaLevel))
            {
                throw new Exception("Failed to get MSAA level");
            }
            msaaLevel = MSAALevel.Disabled;
            var windowSize = window.GetSize(WindowSizeType.WorkingArea);
            renderTextureMSAA = device.CreateRenderTexture2D(windowSize.width, windowSize.height, TextureFormat.Default, RenderTextureUsage.Discard, TextureMode.GPUOptimized, StencilUsage.Discard, DepthStencilFormat.DefaultDepth, DepthStencilMode.GPUOptimized, msaaLevel, false, MultiGPUNodeResourceVisibility.All);

            // create command list
            commandList         = device.CreateRasterizeCommandList();
            commandList_Compute = device.CreateComputeCommandList();

            // create render pass
            var renderPassDesc = RenderPassDesc.CreateDefault(new Color4F(0, .2f, .4f, 1), 1);
            //renderPass = device.CreateRenderPass(renderPassDesc, device.swapChain.depthStencil);
            renderPass = renderTextureMSAA.CreateRenderPass(renderPassDesc, renderTextureMSAA.GetDepthStencil());

            // create texture
            int textureWidth = 256, textureHeight = 256;
            var textureData = new byte[textureWidth * textureHeight * 4];
            for (int y = 0; y != textureHeight; ++y)
            {
                for (int x = 0; x != textureWidth; ++x)
                {
                    int i = (x * 4) + (y * textureWidth * 4);
                    if (x % 16 <= 7 && y % 16 <= 7)
                    {
                        textureData[i + 0] = 0;
                        textureData[i + 1] = 0;
                        textureData[i + 2] = 0;
                        textureData[i + 3] = 0;
                    }
                    else
                    {
                        textureData[i + 0] = 255;
                        textureData[i + 1] = 255;
                        textureData[i + 2] = 255;
                        textureData[i + 3] = 255;
                    }
                }
            }
            texture = device.CreateTexture2D(textureWidth, textureHeight, TextureFormat.B8G8R8A8, textureData, TextureMode.GPUOptimized, MultiGPUNodeResourceVisibility.Self);

            // create texture 2
            textureWidth  = 100;
            textureHeight = 100;
            textureData   = new byte[textureWidth * textureHeight * 4];
            for (int y = 0; y != textureHeight; ++y)
            {
                for (int x = 0; x != textureWidth; ++x)
                {
                    int i = (x * 4) + (y * textureWidth * 4);
                    if (x % 16 <= 7 && y % 16 <= 7)
                    {
                        textureData[i + 0] = 0;
                        textureData[i + 1] = 0;
                        textureData[i + 2] = 0;
                        textureData[i + 3] = 0;
                    }
                    else
                    {
                        textureData[i + 0] = 255;
                        textureData[i + 1] = 255;
                        textureData[i + 2] = 255;
                        textureData[i + 3] = 255;
                    }
                }
            }
            texture2 = device.CreateTexture2D(textureWidth, textureHeight, TextureFormat.B8G8R8A8, textureData, TextureMode.GPUOptimized, MultiGPUNodeResourceVisibility.Self);

            // load shaders
            // TODO: load CS2X compiled ShaderEffect

            /*using (var stream = new FileStream("Shader.se", FileMode.Open, FileAccess.Read, FileShare.Read))
             * {
             *      shaderEffect = device.CreateShaderEffect(stream, ShaderEffectSamplerAnisotropy.Default);
             * }*/

            using (var vsStream = new FileStream("Shaders\\Shader_D3D12.vs", FileMode.Open, FileAccess.Read, FileShare.Read))
                using (var psStream = new FileStream("Shaders\\Shader_D3D12.ps", FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var vs = new Video.D3D12.Shader((Video.D3D12.Device)device, ShaderType.VS);
                    var ps = new Video.D3D12.Shader((Video.D3D12.Device)device, ShaderType.PS);
                    if (!vs.Init(vsStream))
                    {
                        throw new Exception("Failed to init VS shader");
                    }
                    if (!ps.Init(psStream))
                    {
                        throw new Exception("Failed to init PS shader");
                    }
                    var desc = new ShaderEffectDesc();
                    desc.constantBuffers    = new ShaderEffectConstantBuffer[1];
                    desc.constantBuffers[0] = new ShaderEffectConstantBuffer()
                    {
                        registerIndex = 0,
                        usage         = ShaderEffectResourceUsage.VS,
                        variables     = new ShaderVariable[2]
                    };
                    desc.constantBuffers[0].variables[0] = new ShaderVariable()
                    {
                        name = "constrast",
                        type = ShaderVariableType.Float
                    };
                    desc.constantBuffers[0].variables[1] = new ShaderVariable()
                    {
                        name = "camera",
                        type = ShaderVariableType.Float4x4
                    };
                    desc.textures    = new ShaderEffectTexture[3];
                    desc.textures[0] = new ShaderEffectTexture()
                    {
                        registerIndex = 0,
                        usage         = ShaderEffectResourceUsage.PS
                    };
                    desc.textures[1] = new ShaderEffectTexture()
                    {
                        registerIndex = 1,
                        usage         = ShaderEffectResourceUsage.PS
                    };
                    desc.textures[2] = new ShaderEffectTexture()
                    {
                        registerIndex = 2,
                        usage         = ShaderEffectResourceUsage.PS
                    };
                    desc.samplers    = new ShaderEffectSampler[1];
                    desc.samplers[0] = new ShaderEffectSampler()
                    {
                        registerIndex = 0,
                        filter        = ShaderSamplerFilter.Default,
                        anisotropy    = ShaderSamplerAnisotropy.Default,
                        addressU      = ShaderSamplerAddress.Wrap,
                        addressV      = ShaderSamplerAddress.Wrap,
                        addressW      = ShaderSamplerAddress.Wrap,
                        usage         = ShaderEffectResourceUsage.PS
                    };
                    shaderEffect = device.CreateShaderEffect(vs, ps, null, null, null, desc, true);
                }

            if (!shaderEffect.FindVariable("constrast", out shaderEffectVar_Constrast))
            {
                throw new Exception("Failed to find shader effect variable");
            }
            if (!shaderEffect.FindVariable("camera", out shaderEffectVar_Camera))
            {
                throw new Exception("Failed to find shader effect variable");
            }

            // create constant buffer
            constantBuffer = device.CreateConstantBuffer(shaderEffect.constantBufferMappings[0].size, ConstantBufferMode.Write);

            // create vertex buffer
            const float size            = 1 / 2f;
            var         rotUpAxisMat    = Mat3.FromEuler(0, MathTools.DegToRad(90), 0);
            var         rotRightAxisMat = Mat3.FromEuler(MathTools.DegToRad(90), 0, 0);
            var         vertices        = new Vertex[4 * 6]; // 4 vertices per face
            var         indices         = new ushort[6 * 6]; // 6 indices per face
            var         colorKey        = new Color4[4]
            {
                Color4.blue,
                Color4.red,
                Color4.white,
                Color4.white
            };
            for (int v = 0, i = 0, r = 0; v < (4 * 4); v += 4, i += 6, ++r)            // caluclate front, right, back, left faces
            {
                vertices[v + 0] = new Vertex(new Vec3(-size, -size, size), colorKey[r], new Vec2(0, 0)).Transform(rotUpAxisMat, r);
                vertices[v + 1] = new Vertex(new Vec3(-size, size, size), colorKey[r], new Vec2(0, 1)).Transform(rotUpAxisMat, r);
                vertices[v + 2] = new Vertex(new Vec3(size, size, size), colorKey[r], new Vec2(1, 1)).Transform(rotUpAxisMat, r);
                vertices[v + 3] = new Vertex(new Vec3(size, -size, size), colorKey[r], new Vec2(1, 0)).Transform(rotUpAxisMat, r);
                indices[i + 0]  = (ushort)(v + 0);
                indices[i + 1]  = (ushort)(v + 1);
                indices[i + 2]  = (ushort)(v + 2);
                indices[i + 3]  = (ushort)(v + 0);
                indices[i + 4]  = (ushort)(v + 2);
                indices[i + 5]  = (ushort)(v + 3);
            }
            colorKey = new Color4[2]
            {
                Color4.green,
                Color4.white
            };
            for (int v = (4 * 4), i = (6 * 4), r = 1; v < (4 * 6); v += 4, i += 6, r = 3)            // caluclate top, bottom faces
            {
                vertices[v + 0] = new Vertex(new Vec3(-size, -size, size), colorKey[r / 3], new Vec2(0, 0)).Transform(rotRightAxisMat, r);
                vertices[v + 1] = new Vertex(new Vec3(-size, size, size), colorKey[r / 3], new Vec2(0, 1)).Transform(rotRightAxisMat, r);
                vertices[v + 2] = new Vertex(new Vec3(size, size, size), colorKey[r / 3], new Vec2(1, 1)).Transform(rotRightAxisMat, r);
                vertices[v + 3] = new Vertex(new Vec3(size, -size, size), colorKey[r / 3], new Vec2(1, 0)).Transform(rotRightAxisMat, r);
                indices[i + 0]  = (ushort)(v + 0);
                indices[i + 1]  = (ushort)(v + 1);
                indices[i + 2]  = (ushort)(v + 2);
                indices[i + 3]  = (ushort)(v + 0);
                indices[i + 4]  = (ushort)(v + 2);
                indices[i + 5]  = (ushort)(v + 3);
            }
            vertexBuffer = device.CreateVertexBuffer <Vertex>(vertices, indices, VertexBufferMode.GPUOptimized);

            // create vertex buffer streamer
            var vertexBufferStreamLayout = new VertexBufferStreamLayout()
            {
                descs    = new VertexBufferStreamDesc[1],
                elements = new VertexBufferStreamElement[3]
            };
            vertexBufferStreamLayout.descs[0] = new VertexBufferStreamDesc()
            {
                vertexBuffer = vertexBuffer,
                type         = VertexBufferStreamType.VertexData
            };
            vertexBufferStreamLayout.elements[0] = new VertexBufferStreamElement()
            {
                type   = VertexBufferStreamElementType.Float3,
                usage  = VertexBufferStreamElementUsage.Position,
                offset = 0
            };
            vertexBufferStreamLayout.elements[1] = new VertexBufferStreamElement()
            {
                type   = VertexBufferStreamElementType.RGBAx8,
                usage  = VertexBufferStreamElementUsage.Color,
                offset = (sizeof(float) * 3)
            };
            vertexBufferStreamLayout.elements[2] = new VertexBufferStreamElement()
            {
                type   = VertexBufferStreamElementType.Float2,
                usage  = VertexBufferStreamElementUsage.UV,
                offset = (sizeof(float) * 3) + 4
            };
            vertexBufferStreamer = device.CreateVertexBufferStreamer(vertexBufferStreamLayout);

            // create render state
            var renderStateDesc = new RenderStateDesc()
            {
                renderPass           = renderPass,
                shaderEffect         = shaderEffect,
                constantBuffers      = new ConstantBufferBase[1],
                textures             = new TextureBase[3],
                vertexBufferTopology = VertexBufferTopology.Triangle,
                vertexBufferStreamer = vertexBufferStreamer,
                triangleCulling      = TriangleCulling.Back,
                triangleFillMode     = TriangleFillMode.Solid,
                depthStencilDesc     = DepthStencilDesc.StandardDepthTesting()
            };
            //renderStateDesc.blendDesc.renderTargetBlendDescs = new RenderTargetBlendDesc[1] {RenderTargetBlendDesc.AlphaBlending()};
            renderStateDesc.constantBuffers[0] = constantBuffer;
            renderStateDesc.textures[0]        = texture;
            renderStateDesc.textures[1]        = texture2;
            renderStateDesc.textures[2]        = renderTextureTest.renderTexture;
            renderState = device.CreateRenderState(renderStateDesc);

            // create compute shader
            using (var csStream = new FileStream("Shaders\\Compute_D3D12.cs", FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                var csDesc = new ComputeShaderDesc()
                {
                    randomAccessBuffers = new ComputeShaderRandomAccessBuffer[1]
                };
                csDesc.randomAccessBuffers[0] = new ComputeShaderRandomAccessBuffer()
                {
                    registerIndex = 0
                };
                computeShader = device.CreateComputeShader(csStream, csDesc);
            }

            // create compute state
            var computeStateDesc = new ComputeStateDesc()
            {
                computeShader       = computeShader,
                randomAccessBuffers = new object[1]
            };
            computeStateDesc.randomAccessBuffers[0] = renderTextureTest.renderTexture;
            computeState = device.CreateComputeState(computeStateDesc);

            // print all GPUs this abstraction supports
            if (!instance.QuerySupportedAdapters(false, out var adapters))
            {
                throw new Exception("Failed: QuerySupportedAdapters");
            }
            foreach (var adapter in adapters)
            {
                Debug.WriteLine(adapter.name);
            }

            // setup camera
            camera = new Camera();
        }
Beispiel #26
0
        public void QueryForRenderChunks(BoundingFrustum bFrustum, ref Plane clippingPlane, LOD DetailLevel, ref RenderPassDesc desc)
        {
            // If a clipping plane exists, check which side the box is on
            if (null != clippingPlane)
            {
                PlaneIntersectionType intersection = clippingPlane.Intersects(this.boundingBox);

                // If all geometry is on the back side of the plane, then no need to render it
                if (intersection == PlaneIntersectionType.Back)
                {
                    return;
                }
            }

            // Check if QuadTree bounding box intersection the current view frustum
            if (!bFrustum.Intersects(this.boundingBox))
            {
                return;
            }

            // Only draw leaves on the tree, never the main tree branches themselves.
            if (isLeaf)
            {
                GeometryChunk chunk = this.Game.Graphics.AllocateGeometryChunk();
                chunk.Indices = this.leafPatch.indexBuffers[(int)DetailLevel];
                chunk.VertexStreams.Add(terrain.VertexBuffer);
                chunk.WorldTransform     = Matrix.Identity;
                chunk.VertexCount        = this.width * this.width;
                chunk.StartIndex         = 0;
                chunk.VertexStreamOffset = this.vertexBufferOffset;
                chunk.PrimitiveCount     = this.leafPatch.numTris[(int)DetailLevel];
                chunk.Material           = this.terrain.Material;

                if (this.Game.Settings.GraphicsLevel > GraphicsLevel.Low && DetailLevel == LOD.High)
                {
                    float distanceToBoundingBox = GetDistanceBetweenCameraNearPlaneAndBoundingBox(bFrustum, this.boundingBox);

                    // If the entire terrain patch is far enough from the camera then we lower the shader quality.
                    if (distanceToBoundingBox < QSConstants.MinQuadTreeCubeCenterDistance / 2)
                    {
                        chunk.RenderTechniqueName = "MultiTexturedNormaled";
                    }
                    else
                    {
                        chunk.RenderTechniqueName = "MultiTextured";
                    }
                }
                else
                {
                    chunk.RenderTechniqueName = "MultiTextured";
                }

                chunk.CanCreateShadows  = false; // Terrain does not cast shadows, it would be very expensive
                chunk.CanReceiveShadows = true;
                chunk.Type = PrimitiveType.TriangleList;

                if (this.terrain.DisplayBoundingBoxes)
                {
                    // Draw bounding boxes
                    GeometryChunk boxChunk = this.Game.Graphics.AllocateGeometryChunk();
                    boxChunk.Indices = boundingBoxIndexBuffer;
                    boxChunk.VertexStreams.Add(this.boundingBoxVertBuffer);
                    boxChunk.WorldTransform      = Matrix.Identity;
                    boxChunk.VertexCount         = this.BoundingBoxMesh.Length;
                    boxChunk.StartIndex          = 0;
                    boxChunk.VertexStreamOffset  = 0;
                    boxChunk.PrimitiveCount      = 12; // Number of trianges that are required to render a cube.
                    boxChunk.Material            = boundingBoxMaterial;
                    boxChunk.RenderTechniqueName = boundingBoxMaterial.CurrentTechnique;
                    boxChunk.CanCreateShadows    = false;
                    boxChunk.CanReceiveShadows   = true;
                    boxChunk.Type = PrimitiveType.TriangleList;
                }
            }
            // If there are branches on this node, move down through them recursively
            else if (childQuadTrees.Length > 0)
            {
                for (int i = 0; i < childQuadTrees.Length; ++i)
                {
                    childQuadTrees[i].QueryForRenderChunks(bFrustum, ref clippingPlane, DetailLevel, ref desc);
                }
            }
        }
 public override RenderPassBase CreateRenderPass(RenderPassDesc desc, DepthStencilBase swapChain)
 {
     throw new NotImplementedException();
 }
Beispiel #28
0
        public unsafe bool Init(RenderPassDesc desc)
        {
            var descNative = new RenderPassDesc_NativeInterop(ref desc);

            return(Orbital_Video_D3D12_RenderPass_Init(handle, &descNative) != 0);
        }
Beispiel #29
0
 public override RenderPassBase CreateRenderPass(RenderPassDesc desc, DepthStencilBase depthStencil)
 {
     return(swapChainD3D12.CreateRenderPass(desc, depthStencil));
 }
 public override RenderPassBase CreateRenderPass(RenderPassDesc desc, Texture2DBase[] renderTextures, DepthStencilBase depthStencil)
 {
     throw new NotImplementedException();
 }