Beispiel #1
0
        public Material Create(AssetDatabase ad, RenderContext rc, Dictionary <string, ConstantBufferDataProvider> providers = null)
        {
            Material ret;

            if (!CreatedResourceCache.TryGetCachedItem(this, out ret))
            {
                MaterialTextureInputElement[] texElements = TextureInputs.Select(ta => ta.Create(ad)).ToArray();
                var allTextures           = texElements.Concat(ContextTextures).ToArray();
                var materialTextureInputs = new MaterialTextureInputs(allTextures);
                MaterialInputs <MaterialGlobalInputElement> globalInputs;
                if (providers != null)
                {
                    globalInputs =
                        new MaterialInputs <MaterialGlobalInputElement>(GlobalInputs.Select(mgid => mgid.Create(providers)).ToArray());
                }
                else
                {
                    globalInputs =
                        new MaterialInputs <MaterialGlobalInputElement>(GlobalInputs.Select(mgid => mgid.Create()).ToArray());
                }
                MaterialInputs <MaterialPerObjectInputElement> perObjectInputs = new MaterialInputs <MaterialPerObjectInputElement>(PerObjectInputs);
                ret = rc.ResourceFactory.CreateMaterial(rc, VertexShader, FragmentShader, VertexInputs, globalInputs, perObjectInputs, materialTextureInputs);

                CreatedResourceCache.CacheItem(this, ret);
            }

            return(ret);
        }
Beispiel #2
0
 public override ShaderConstantBindings CreateShaderConstantBindings(
     RenderContext rc,
     ShaderSet shaderSet,
     MaterialInputs <MaterialGlobalInputElement> globalInputs,
     MaterialInputs <MaterialPerObjectInputElement> perObjectInputs)
 {
     return(new D3DShaderConstantBindings(rc, _device, shaderSet, globalInputs, perObjectInputs));
 }
Beispiel #3
0
        private void InitializeContextObjects(RenderContext context)
        {
            s_currentContext = context;
            ResourceFactory factory = context.ResourceFactory;

            s_vb0 = factory.CreateVertexBuffer(12 * s_cubeVertices.Length, false);
            VertexDescriptor desc = new VertexDescriptor(12, 1, 0, IntPtr.Zero);

            s_vb0.SetVertexData(s_cubeVertices.Select(vpc => vpc.Position).ToArray(), desc);

            s_vb1 = factory.CreateVertexBuffer(16 * s_cubeVertices.Length, false);
            VertexDescriptor desc2 = new VertexDescriptor(16, 1, 0, IntPtr.Zero);

            s_vb1.SetVertexData(s_cubeVertices.Select(vpc => vpc.Color).ToArray(), desc2);

            s_ib = factory.CreateIndexBuffer(sizeof(int) * s_cubeIndices.Length, false);
            s_ib.SetIndices(s_cubeIndices);

            MaterialVertexInput materialInputs0 = new MaterialVertexInput(
                12,
                new MaterialVertexInputElement[]
            {
                new MaterialVertexInputElement("in_position", VertexSemanticType.Position, VertexElementFormat.Float3),
            });

            MaterialVertexInput materialInputs1 = new MaterialVertexInput(
                16,
                new MaterialVertexInputElement[]
            {
                new MaterialVertexInputElement("in_color", VertexSemanticType.Color, VertexElementFormat.Float4)
            });

            MaterialInputs <MaterialGlobalInputElement> globalInputs = new MaterialInputs <MaterialGlobalInputElement>(
                new MaterialGlobalInputElement[]
            {
                new MaterialGlobalInputElement("ProjectionMatrixBuffer", MaterialInputType.Matrix4x4, "ProjectionMatrix")
            });

            MaterialInputs <MaterialPerObjectInputElement> perObjectInputs = new MaterialInputs <MaterialPerObjectInputElement>(
                new MaterialPerObjectInputElement[]
            {
                new MaterialPerObjectInputElement("ModelViewMatrixBuffer", MaterialInputType.Matrix4x4, _modelViewProvider.DataSizeInBytes)
            });

            s_material = factory.CreateMaterial(
                context,
                VertexShaderSource,
                FragmentShaderSource,
                materialInputs0,
                materialInputs1,
                globalInputs,
                perObjectInputs,
                MaterialTextureInputs.Empty);
        }
Beispiel #4
0
 public Material GetMaterial(
     RenderContext rc,
     string vertexShaderName,
     string pixelShaderName,
     MaterialVertexInput vertexInputs,
     MaterialInputs <MaterialGlobalInputElement> globalInputs,
     MaterialInputs <MaterialPerObjectInputElement> perObjectInputs,
     MaterialTextureInputs textureInputs)
 {
     return(GetMaterial(rc, vertexShaderName, null, pixelShaderName, vertexInputs, globalInputs, perObjectInputs, textureInputs));
 }
        private void InitializeContextObjects(RenderContext context)
        {
            _currentContext = context;
            ResourceFactory factory = context.ResourceFactory;

            s_vb = factory.CreateVertexBuffer(VertexPositionNormalTexture.SizeInBytes * _vertices.Length, false);
            VertexDescriptor desc = new VertexDescriptor(VertexPositionNormalTexture.SizeInBytes, VertexPositionNormalTexture.ElementCount, 0, IntPtr.Zero);

            s_vb.SetVertexData(_vertices, desc);

            s_ib = factory.CreateIndexBuffer(sizeof(int) * _indices.Length, false);
            s_ib.SetIndices(_indices);

            MaterialVertexInput materialInputs = new MaterialVertexInput(
                VertexPositionNormalTexture.SizeInBytes,
                new MaterialVertexInputElement[]
            {
                new MaterialVertexInputElement("in_position", VertexSemanticType.Position, VertexElementFormat.Float3),
                new MaterialVertexInputElement("in_normal", VertexSemanticType.Normal, VertexElementFormat.Float3),
                new MaterialVertexInputElement("in_texCoord", VertexSemanticType.TextureCoordinate, VertexElementFormat.Float2)
            });

            MaterialInputs <MaterialGlobalInputElement> globalInputs = new MaterialInputs <MaterialGlobalInputElement>(
                new MaterialGlobalInputElement[]
            {
                new MaterialGlobalInputElement("ProjectionMatrixBuffer", MaterialInputType.Matrix4x4, "ProjectionMatrix"),
                new MaterialGlobalInputElement("ViewMatrixBuffer", MaterialInputType.Matrix4x4, "ViewMatrix"),
                new MaterialGlobalInputElement("LightBuffer", MaterialInputType.Custom, "LightBuffer"),
            });

            MaterialInputs <MaterialPerObjectInputElement> perObjectInputs = new MaterialInputs <MaterialPerObjectInputElement>(
                new MaterialPerObjectInputElement[]
            {
                new MaterialPerObjectInputElement("WorldMatrixBuffer", MaterialInputType.Matrix4x4, _worldProvider.DataSizeInBytes),
                new MaterialPerObjectInputElement("InverseTransposeWorldMatrixBuffer", MaterialInputType.Matrix4x4, _inverseTransposeWorldProvider.DataSizeInBytes),
            });

            MaterialTextureInputs textureInputs = new MaterialTextureInputs(
                new MaterialTextureInputElement[]
            {
                new TextureDataInputElement("surfaceTexture", _texture)
            });

            s_material = factory.CreateMaterial(
                context,
                VertexShaderSource,
                FragmentShaderSource,
                materialInputs,
                globalInputs,
                perObjectInputs,
                textureInputs);

            s_wireframeRasterizerState = factory.CreateRasterizerState(FaceCullingMode.None, TriangleFillMode.Wireframe, true, true);
        }
Beispiel #6
0
 public Task <Material> GetMaterialAsync(
     RenderContext rc,
     string vertexShaderName,
     string pixelShaderName,
     MaterialVertexInput vertexInputs,
     MaterialInputs <MaterialGlobalInputElement> globalInputs,
     MaterialInputs <MaterialPerObjectInputElement> perObjectInputs,
     MaterialTextureInputs textureInputs)
 {
     return(_gs.ExecuteOnMainThread(
                () => GetMaterial(rc, vertexShaderName, pixelShaderName, vertexInputs, globalInputs, perObjectInputs, textureInputs)));
 }
Beispiel #7
0
        public Material GetMaterial(
            RenderContext rc,
            string vertexShaderName,
            string geometryShaderName,
            string fragmentShaderName,
            MaterialVertexInput vertexInputs,
            MaterialInputs <MaterialGlobalInputElement> globalInputs,
            MaterialInputs <MaterialPerObjectInputElement> perObjectInputs,
            MaterialTextureInputs textureInputs)
        {
            MaterialKey key = new MaterialKey()
            {
                VertexShaderName   = vertexShaderName,
                FragmentShaderName = fragmentShaderName,
                GeometryShaderName = geometryShaderName,
                VertexInputs       = vertexInputs,
                GlobalInputs       = globalInputs
            };

            Material m;

            if (!_materials.TryGetValue(key, out m))
            {
                Shader            vs          = _factory.CreateShader(ShaderType.Vertex, vertexShaderName);
                Shader            fs          = _factory.CreateShader(ShaderType.Fragment, fragmentShaderName);
                VertexInputLayout inputLayout = _factory.CreateInputLayout(vs, vertexInputs);

                ShaderSet shaderSet;
                if (geometryShaderName != null)
                {
                    Shader gs = _factory.CreateShader(ShaderType.Geometry, geometryShaderName);
                    shaderSet = _factory.CreateShaderSet(inputLayout, vs, gs, fs);
                }
                else
                {
                    shaderSet = _factory.CreateShaderSet(inputLayout, vs, fs);
                }

                ShaderConstantBindings    constantBindings = _factory.CreateShaderConstantBindings(rc, shaderSet, globalInputs, perObjectInputs);
                ShaderTextureBindingSlots textureSlots     = _factory.CreateShaderTextureBindingSlots(shaderSet, textureInputs);
                m = new Material(rc, shaderSet, constantBindings, textureSlots, _factory.CreateDefaultTextureBindingInfos(rc, textureInputs));

                if (!_materials.TryAdd(key, m))
                {
                    return(_materials[key]);
                }
            }

            return(m);
        }
Beispiel #8
0
        private void InitializeContextObjects(RenderContext rc)
        {
            var factory = rc.ResourceFactory;
            var mesh    = LoadTeapotMesh();

            _vertexBuffer = factory.CreateVertexBuffer(mesh.Vertices.Length * VertexPositionNormalTexture.SizeInBytes, false);
            _vertexBuffer.SetVertexData(mesh.Vertices, new VertexDescriptor(VertexPositionNormalTexture.SizeInBytes, 3, 0, IntPtr.Zero));

            _indexBuffer = factory.CreateIndexBuffer(mesh.Indices.Length * sizeof(int), false);
            _indexBuffer.SetIndices(mesh.Indices);

            MaterialVertexInput materialInputs = new MaterialVertexInput(
                VertexPositionNormalTexture.SizeInBytes,
                new MaterialVertexInputElement[]
            {
                new MaterialVertexInputElement("in_position", VertexSemanticType.Position, VertexElementFormat.Float3),
                new MaterialVertexInputElement("in_normal", VertexSemanticType.Normal, VertexElementFormat.Float3),
                new MaterialVertexInputElement("in_texCoord", VertexSemanticType.TextureCoordinate, VertexElementFormat.Float2)
            });

            MaterialInputs <MaterialGlobalInputElement> globalInputs = new MaterialInputs <MaterialGlobalInputElement>(
                new MaterialGlobalInputElement[]
            {
                new MaterialGlobalInputElement("ProjectionMatrixBuffer", MaterialInputType.Matrix4x4, "ProjectionMatrix"),
                new MaterialGlobalInputElement("ViewMatrixBuffer", MaterialInputType.Matrix4x4, "ViewMatrix"),
                new MaterialGlobalInputElement("LightBuffer", MaterialInputType.Custom, "LightBuffer"),
            });

            MaterialInputs <MaterialPerObjectInputElement> perObjectInputs = new MaterialInputs <MaterialPerObjectInputElement>(
                new MaterialPerObjectInputElement[]
            {
                new MaterialPerObjectInputElement("WorldMatrixBuffer", MaterialInputType.Matrix4x4, _worldProvider.DataSizeInBytes),
                new MaterialPerObjectInputElement("InverseTransposeWorldMatrixBuffer", MaterialInputType.Matrix4x4, _inverseTransposeWorldProvider.DataSizeInBytes),
            });

            MaterialTextureInputs textureInputs = new MaterialTextureInputs(
                new TextureDataInputElement("surfaceTexture", s_cubeTexture));

            _material = factory.CreateMaterial(
                rc,
                "textured-vertex",
                "lit-frag",
                materialInputs,
                globalInputs,
                perObjectInputs,
                textureInputs);
        }
Beispiel #9
0
        private async void InitializeContextObjects(RenderContext context, MaterialCache materialCache, BufferCache bufferCache)
        {
            ResourceFactory factory = context.ResourceFactory;

            Debug.Assert(_vb == null);
            Debug.Assert(_ib == null);
            Debug.Assert(_deviceTexture == null);
            Debug.Assert(_textureBinding == null);

            _vb = bufferCache.GetVertexBuffer(_mesh);
            CreateIndexBuffer(wasTransparent: false);

            if (s_regularGlobalInputs == null)
            {
                s_regularGlobalInputs = new MaterialInputs <MaterialGlobalInputElement>(
                    new MaterialGlobalInputElement[]
                {
                    new MaterialGlobalInputElement("ProjectionMatrixBuffer", MaterialInputType.Matrix4x4, "ProjectionMatrix"),
                    new MaterialGlobalInputElement("ViewMatrixBuffer", MaterialInputType.Matrix4x4, "ViewMatrix"),
                    new MaterialGlobalInputElement("LightProjectionMatrixBuffer", MaterialInputType.Matrix4x4, "LightProjMatrix"),
                    new MaterialGlobalInputElement("LightViewMatrixBuffer", MaterialInputType.Matrix4x4, "LightViewMatrix"),
                    new MaterialGlobalInputElement("LightInfoBuffer", MaterialInputType.Custom, "LightBuffer"),
                    new MaterialGlobalInputElement("CameraInfoBuffer", MaterialInputType.Custom, "CameraInfo"),
                    new MaterialGlobalInputElement("PointLightsBuffer", MaterialInputType.Custom, "PointLights")
                });
            }

            _regularPassMaterial = materialCache.GetMaterial(
                context,
                RegularPassVertexShaderSource,
                RegularPassFragmentShaderSource,
                s_vertexInputs,
                s_regularGlobalInputs,
                s_perObjectInputs,
                s_textureInputs);

            _regularPassTransparentMaterial = materialCache.GetMaterial(
                context,
                RegularPassTransparentVertexShaderSource,
                RegularPassTransparentFragmentShaderSource,
                s_vertexInputs,
                s_regularGlobalInputs,
                s_transparentPerObjectInputs,
                s_transparentTextureInputs);

            if (_texture == null)
            {
                _texture = RawTextureDataArray <RgbaFloat> .FromSingleColor(RgbaFloat.Pink);
            }

            _deviceTexture = await _gs.ExecuteOnMainThread(() => _texture.CreateDeviceTexture(factory));

            _textureBinding = await _gs.ExecuteOnMainThread(() => factory.CreateShaderTextureBinding(_deviceTexture));

            if (s_shadowmapGlobalInputs == null)
            {
                s_shadowmapGlobalInputs = new MaterialInputs <MaterialGlobalInputElement>(
                    new MaterialGlobalInputElement[]
                {
                    new MaterialGlobalInputElement("ProjectionMatrixBuffer", MaterialInputType.Matrix4x4, "LightProjMatrix"),
                    new MaterialGlobalInputElement("ViewMatrixBuffer", MaterialInputType.Matrix4x4, "LightViewMatrix")
                });
            }

            _shadowPassMaterial = materialCache.GetMaterial(
                context,
                ShadowMapPassVertexShaderSource,
                ShadowMapPassFragmentShaderSource,
                s_vertexInputs,
                s_shadowmapGlobalInputs,
                s_shadowmapPerObjectInputs,
                MaterialTextureInputs.Empty);

            if (s_wireframeRS == null)
            {
                s_wireframeRS = factory.CreateRasterizerState(FaceCullingMode.None, TriangleFillMode.Wireframe, true, true);
            }
            if (s_noCullRS == null)
            {
                s_noCullRS = factory.CreateRasterizerState(FaceCullingMode.None, TriangleFillMode.Solid, true, true);
            }

            _initialized = true;
        }
        public D3DShaderConstantBindings(
            RenderContext rc,
            Device device,
            ShaderSet shaderSet,
            MaterialInputs <MaterialGlobalInputElement> globalInputs,
            MaterialInputs <MaterialPerObjectInputElement> perObjectInputs)
        {
            _device = device;

            ShaderReflection vsReflection = new ShaderReflection(((D3DVertexShader)shaderSet.VertexShader).Bytecode.Data);
            ShaderReflection psReflection = new ShaderReflection(((D3DFragmentShader)shaderSet.FragmentShader).Bytecode.Data);
            ShaderReflection gsReflection = null;

            if (shaderSet.GeometryShader != null)
            {
                gsReflection = new ShaderReflection(((D3DGeometryShader)shaderSet.GeometryShader).Bytecode.Data);
            }

            int numGlobalElements = globalInputs.Elements.Length;

            _constantBufferBindings =
                (numGlobalElements > 0)
                ? new GlobalConstantBufferBinding[numGlobalElements]
                : Array.Empty <GlobalConstantBufferBinding>();
            for (int i = 0; i < numGlobalElements; i++)
            {
                var genericElement = globalInputs.Elements[i];
                BufferProviderPair          pair;
                GlobalConstantBufferBinding cbb;
                bool isVsBuffer = DoesConstantBufferExist(vsReflection, i, genericElement.Name);
                bool isPsBuffer = DoesConstantBufferExist(psReflection, i, genericElement.Name);
                bool isGsBuffer = false;
                if (gsReflection != null)
                {
                    isGsBuffer = DoesConstantBufferExist(gsReflection, i, genericElement.Name);
                }

                if (genericElement.UseGlobalNamedBuffer)
                {
                    pair = rc.GetNamedGlobalBufferProviderPair(genericElement.GlobalProviderName);
                    cbb  = new GlobalConstantBufferBinding(i, pair, false, isVsBuffer, isGsBuffer, isPsBuffer);
                }
                else
                {
                    D3DConstantBuffer constantBuffer = new D3DConstantBuffer(device, genericElement.DataProvider.DataSizeInBytes);
                    pair = new BufferProviderPair(constantBuffer, genericElement.DataProvider);
                    cbb  = new GlobalConstantBufferBinding(i, pair, true, isVsBuffer, isGsBuffer, isPsBuffer);
                }

                _constantBufferBindings[i] = cbb;
            }

            int numPerObjectInputs = perObjectInputs.Elements.Length;

            _perObjectBufferBindings =
                (numPerObjectInputs > 0)
                ? new PerObjectConstantBufferBinding[numPerObjectInputs]
                : Array.Empty <PerObjectConstantBufferBinding>();
            for (int i = 0; i < numPerObjectInputs; i++)
            {
                var  genericElement = perObjectInputs.Elements[i];
                int  bufferSlot     = i + numGlobalElements;
                bool isVsBuffer     = DoesConstantBufferExist(vsReflection, bufferSlot, genericElement.Name);
                bool isPsBuffer     = DoesConstantBufferExist(psReflection, bufferSlot, genericElement.Name);
                bool isGsBuffer     = false;
                if (gsReflection != null)
                {
                    isGsBuffer = DoesConstantBufferExist(gsReflection, bufferSlot, genericElement.Name);
                }
                D3DConstantBuffer constantBuffer     = new D3DConstantBuffer(device, genericElement.BufferSizeInBytes);
                PerObjectConstantBufferBinding pocbb = new PerObjectConstantBufferBinding(bufferSlot, constantBuffer, isVsBuffer, isGsBuffer, isPsBuffer);
                _perObjectBufferBindings[i] = pocbb;
            }
        }
Beispiel #11
0
        public OpenGLShaderConstantBindings(
            RenderContext rc,
            ShaderSet shaderSet,
            MaterialInputs <MaterialGlobalInputElement> globalInputs,
            MaterialInputs <MaterialPerObjectInputElement> perObjectInputs)
        {
            var programID         = ((OpenGLShaderSet)shaderSet).ProgramID;
            int globalInputsCount = globalInputs.Elements.Length;
            int bindingIndex      = 0;

            _globalUniformBindings = new GlobalBindingPair[globalInputsCount];
            for (int i = 0; i < globalInputsCount; i++)
            {
                var element = globalInputs.Elements[i];

                ConstantBufferDataProvider dataProvider = element.UseGlobalNamedBuffer
                    ? rc.GetNamedGlobalBufferProviderPair(element.GlobalProviderName).DataProvider
                    : element.DataProvider;
                int blockIndex = GL.GetUniformBlockIndex(programID, element.Name);
                if (blockIndex != -1)
                {
                    ValidateBlockSize(programID, blockIndex, dataProvider.DataSizeInBytes, element.Name);
                    _globalUniformBindings[i] = new GlobalBindingPair(
                        new UniformBlockBinding(
                            programID,
                            blockIndex,
                            bindingIndex,
                            new OpenGLConstantBuffer(dataProvider),
                            dataProvider.DataSizeInBytes),
                        dataProvider);
                    bindingIndex += 1;
                }
                else
                {
                    int uniformLocation = GL.GetUniformLocation(programID, element.Name);
                    if (uniformLocation == -1)
                    {
                        throw new InvalidOperationException($"No uniform or uniform block with name {element.Name} was found.");
                    }

                    _globalUniformBindings[i] = new GlobalBindingPair(
                        new UniformLocationBinding(
                            programID,
                            uniformLocation),
                        dataProvider);
                }
            }

            int perObjectInputsCount = perObjectInputs.Elements.Length;

            _perObjectBindings = new UniformBinding[perObjectInputsCount];
            for (int i = 0; i < perObjectInputsCount; i++)
            {
                var element = perObjectInputs.Elements[i];

                int blockIndex = GL.GetUniformBlockIndex(programID, element.Name);
                if (blockIndex != -1)
                {
                    _perObjectBindings[i] = new UniformBlockBinding(
                        programID,
                        blockIndex,
                        bindingIndex,
                        new OpenGLConstantBuffer(),
                        element.BufferSizeInBytes);
                    bindingIndex += 1;
                }
                else
                {
                    int uniformLocation = GL.GetUniformLocation(programID, element.Name);
                    if (uniformLocation == -1)
                    {
                        throw new InvalidOperationException($"No uniform or uniform block with name {element.Name} was found.");
                    }

                    _perObjectBindings[i] = new UniformLocationBinding(
                        programID,
                        uniformLocation);
                }
            }
        }