From 344accea6050e380bfe52bbe7f020f7c0b2e448f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Mon, 9 Aug 2021 18:03:47 +0200 Subject: [PATCH] Implemented Materials - Shaders get Textureslots via reflection - added Textureslots to Effect --- .../DX11/Renderer/Dx11GraphicsContext.bf | 50 +++++- .../src/Platform/DX11/Renderer/Dx11Shader.bf | 59 +++---- GlitchyEngine/src/Renderer/BufferVariable.bf | 40 ++++- GlitchyEngine/src/Renderer/Effect.bf | 135 +++++++++++++--- GlitchyEngine/src/Renderer/Material.bf | 147 +++++++++++++++++- GlitchyEngine/src/Renderer/Renderer.bf | 11 ++ GlitchyEngine/src/Renderer/Shader.bf | 5 + .../src/Renderer/ShaderTextureCollection.bf | 65 ++++++++ Sandbox/content/Shaders/textureShader.hlsl | 2 +- Sandbox/src/SandboxApp.bf | 24 ++- 10 files changed, 463 insertions(+), 75 deletions(-) create mode 100644 GlitchyEngine/src/Renderer/ShaderTextureCollection.bf diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11GraphicsContext.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11GraphicsContext.bf index b19cbc5..8d20ce2 100644 --- a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11GraphicsContext.bf +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11GraphicsContext.bf @@ -174,19 +174,61 @@ namespace GlitchyEngine.Renderer public override void SetVertexShader(VertexShader vertexShader) { - //Todo: nativeContext.VertexShader.SetSamplers(); + uint32 _firstTexture = D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; + uint32 _textureCount = 0; + + ID3D11ShaderResourceView*[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] _textures = .(); + ID3D11SamplerState*[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] _samplers = .(); + + for(let entry in vertexShader.Textures) + { + _textures[entry.Index] = entry.Texture?.nativeView; + _samplers[entry.Index] = entry.Texture?.SamplerState?.nativeSamplerState; + + if(entry.Index >= _textureCount) + _textureCount = entry.Index + 1; + if(entry.Index < _firstTexture) + _firstTexture = entry.Index; + } + + if(_textureCount > 0) + { + nativeContext.VertexShader.SetShaderResources(_firstTexture, _textureCount, &_textures[_firstTexture]); + nativeContext.VertexShader.SetSamplers(_firstTexture, _textureCount, &_samplers[_firstTexture]); + } + vertexShader.Buffers.PlatformFetchNativeBuffers(); nativeContext.VertexShader.SetConstantBuffers(0, vertexShader.Buffers.nativeBuffers.Count, &vertexShader.Buffers.nativeBuffers); - //Todo: nativeContext.VertexShader.SetShaderResources(); nativeContext.VertexShader.SetShader(vertexShader.nativeShader); } public override void SetPixelShader(PixelShader pixelShader) { - //Todo: nativeContext.PixelShader.SetSamplers(); + uint32 _firstTexture = D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; + uint32 _textureCount = 0; + + ID3D11ShaderResourceView*[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] _textures = .(); + ID3D11SamplerState*[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] _samplers = .(); + + for(let entry in pixelShader.Textures) + { + _textures[entry.Index] = entry.Texture?.nativeView; + _samplers[entry.Index] = entry.Texture?.SamplerState?.nativeSamplerState; + + if(entry.Index >= _textureCount) + _textureCount = entry.Index + 1; + if(entry.Index < _firstTexture) + _firstTexture = entry.Index; + } + + if(_textureCount > 0) + { + nativeContext.PixelShader.SetShaderResources(_firstTexture, _textureCount, &_textures[_firstTexture]); + nativeContext.PixelShader.SetSamplers(_firstTexture, _textureCount, &_samplers[_firstTexture]); + } + pixelShader.Buffers.PlatformFetchNativeBuffers(); nativeContext.PixelShader.SetConstantBuffers(0, pixelShader.Buffers.nativeBuffers.Count, &pixelShader.Buffers.nativeBuffers); - //Todo: nativeContext.PixelShader.SetShaderResources(); nativeContext.PixelShader.SetShader(pixelShader.nativeShader); } } diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11Shader.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11Shader.bf index 066c689..df35d23 100644 --- a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11Shader.bf +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11Shader.bf @@ -16,7 +16,7 @@ namespace GlitchyEngine.Renderer */ internal ID3DBlob* nativeCode ~ _?.Release(); - protected const ShaderCompileFlags DefaultCompileFlags = + protected const ShaderCompileFlags DefaultCompileFlags = .EnableStrictness | #if DEBUG .Debug; #else @@ -57,56 +57,43 @@ namespace GlitchyEngine.Renderer } reflection.GetDescription(let desc); - uint32 cBufferCount = desc.ConstantBuffers; - for(uint32 i < cBufferCount) + uint32 resourceCount = desc.BoundResources; + for (uint32 i < resourceCount) { - reflection.GetResourceBindingDescription(i, let bindDesc); + var res = reflection.GetResourceBindingDescription(i, let bindDesc); - var bufferReflection = reflection.GetConstantBufferByIndex(i); - - bufferReflection.GetDescription(let bufferDesc); - - // ConstantBuffer - if(bufferDesc.Type == .D3D11_CT_CBUFFER) + if (res.Failed) { - let buffer = new ConstantBuffer(_context, bufferReflection); - - _buffers.Add(bindDesc.BindPoint, buffer.Name, buffer); - - buffer.ReleaseRef(); + Log.EngineLogger.Error($"Error({(int)res}) {res}: Failed to get resource binding desc for resource {i}"); + continue; } - /* - bufferReflection.GetDescription(let bufferDesc); - // ConstantBuffer - if(bufferDesc.Type == .D3D11_CT_CBUFFER) + switch(bindDesc.Type) { - GlitchyEngine.Renderer.BufferDescription cBufferDesc = .(bufferDesc.Size, .Constant, .Dynamic, .Write); + case .ConstantBuffer: + var bufferReflection = reflection.GetConstantBufferByName(bindDesc.Name); - let buffer = new Buffer(_context, cBufferDesc); + bufferReflection.GetDescription(let bufferDesc); - _buffers.Add(bindDesc.BindPoint, StringView(bufferDesc.Name), buffer);//, true - buffer.ReleaseRef(); - - // Buffer for default values - uint8* rawData = new:ScopedAlloc! uint8[bufferDesc.Size]*; - - // Get default values - for(uint32 variable < bufferDesc.Variables) + // ConstantBuffer + if(bufferDesc.Type == .D3D11_CT_CBUFFER) { - let variableReflection = bufferReflection.GetVariableByIndex(variable); + let buffer = new ConstantBuffer(_context, bufferReflection); - variableReflection.GetDescription(let varDesc); + _buffers.Add(bindDesc.BindPoint, buffer.Name, buffer); - if(varDesc.DefaultValue != null) - Internal.MemCpy(rawData + varDesc.StartOffset, varDesc.DefaultValue, varDesc.Size); + buffer.ReleaseRef(); } - - buffer.SetData(Span(rawData, bufferDesc.Size)); + case .Texture: + _textures.Add(scope String(bindDesc.Name), bindDesc.BindPoint, null); + case .Sampler: + // TODO: do we have to do something for samplers? + default: + Log.EngineLogger.Warning($"Unhandled shader resource type: \"{bindDesc.Type}\""); } - */ } + reflection.Release(); } } diff --git a/GlitchyEngine/src/Renderer/BufferVariable.bf b/GlitchyEngine/src/Renderer/BufferVariable.bf index f75d693..e3e7199 100644 --- a/GlitchyEngine/src/Renderer/BufferVariable.bf +++ b/GlitchyEngine/src/Renderer/BufferVariable.bf @@ -12,10 +12,10 @@ namespace GlitchyEngine.Renderer private ShaderVariableType _type; - private uint32 _columns; - private uint32 _rows; + internal uint32 _columns; + internal uint32 _rows; private uint32 _offset; - private uint32 _sizeInBytes; + internal uint32 _sizeInBytes; private bool _isUsed; @@ -25,6 +25,8 @@ namespace GlitchyEngine.Renderer public String Name => _name; + public bool IsUsed => _isUsed; + /** * Gets a pointer to the start of the variable in the constant buffers backing data. */ @@ -58,6 +60,38 @@ namespace GlitchyEngine.Renderer Log.EngineLogger.Warning($"The types do not match: Expected \"{_type}\" but Received \"{type}\" instead. Variable: \"{_name}\" of buffer: \"{_constantBuffer.Name}\""); #endif } + + public void EnsureTypeMatch() + { + switch(typeof(T)) + { + case typeof(bool): + EnsureTypeMatch(1, 1, .Bool); + + case typeof(float): + EnsureTypeMatch(1, 1, .Float); + case typeof(Vector2): + EnsureTypeMatch(1, 2, .Float); + case typeof(Vector3): + EnsureTypeMatch(1, 3, .Float); + case typeof(Vector4): + EnsureTypeMatch(1, 4, .Float); + + case typeof(Matrix4x3): + EnsureTypeMatch(4, 3, .Float); + case typeof(Matrix3x3): + EnsureTypeMatch(3, 3, .Float); + case typeof(Matrix): + EnsureTypeMatch(4, 4, .Float); + + case typeof(ColorRGB): + EnsureTypeMatch(1, 3, .Float); + case typeof(ColorRGBA): + EnsureTypeMatch(1, 4, .Float); + case typeof(Color): + EnsureTypeMatch(1, 4, .Float); + } + } public void SetData(bool value) { diff --git a/GlitchyEngine/src/Renderer/Effect.bf b/GlitchyEngine/src/Renderer/Effect.bf index 989a4a7..85940cf 100644 --- a/GlitchyEngine/src/Renderer/Effect.bf +++ b/GlitchyEngine/src/Renderer/Effect.bf @@ -99,9 +99,14 @@ namespace GlitchyEngine.Renderer BufferCollection _bufferCollection ~ delete _; BufferVariableCollection _variables ~ delete _; + + typealias TextureEntry = (Texture Texture, ShaderTextureCollection.ResourceEntry* VsSlot, ShaderTextureCollection.ResourceEntry* PsSlot); + Dictionary _textures ~ delete _; public GraphicsContext Context => _context; + public Dictionary Textures => _textures; + public VertexShader VertexShader { get => _vs; @@ -129,25 +134,6 @@ namespace GlitchyEngine.Renderer public String Name => _name; - public void ApplyChanges() - { - for(let buffer in _bufferCollection) - { - if(let cbuffer = buffer.Buffer as ConstantBuffer) - { - cbuffer.Update(); - } - } - } - - public void Bind(GraphicsContext context) - { - ApplyChanges(); - - context.SetVertexShader(_vs); - context.SetPixelShader(_ps); - } - [Obsolete("Will be removed in the future", false)] public this() { @@ -178,6 +164,12 @@ namespace GlitchyEngine.Renderer String psName = scope String(); ProcessFile(filename, fileContent, vsName, psName); + + if(filename.EndsWith("textureShader.hlsl")) + { + NOP!(); + } + Compile(fileContent, vsName, psName); MergeResources(); @@ -199,7 +191,60 @@ namespace GlitchyEngine.Renderer _name = new String(shaderName); } - + + public ~this() + { + for(let entry in _textures) + { + entry.value.Texture?.ReleaseRef(); + } + } + + public void SetTexture(String name, Texture texture) + { + ref TextureEntry entry = ref _textures[name]; + + entry.Texture?.ReleaseRef(); + entry.Texture = texture; + entry.Texture?.AddRef(); + } + + private void ApplyTextures() + { + for(let (name, entry) in _textures) + { + entry.VsSlot?.Texture?.ReleaseRef(); + entry.VsSlot?.Texture = entry.Texture; + entry.VsSlot?.Texture?.AddRef(); + + entry.PsSlot?.Texture?.ReleaseRef(); + entry.PsSlot?.Texture = entry.Texture; + entry.PsSlot?.Texture?.AddRef(); + } + } + + private void ApplyChanges() + { + for(let buffer in _bufferCollection) + { + if(let cbuffer = buffer.Buffer as ConstantBuffer) + { + cbuffer.Update(); + } + } + } + + public void Bind(GraphicsContext context) + { + ApplyTextures(); + ApplyChanges(); + + context.SetVertexShader(_vs); + context.SetPixelShader(_ps); + } + + + private void CompileFromFile(String filename, String vsEntry, String psEntry) { let vs = Shader.FromFile!(_context, filename, vsEntry); @@ -293,6 +338,7 @@ namespace GlitchyEngine.Renderer { MergeConstantBuffers(); MergeBufferVariables(); + MergeTextures(); } private void MergeConstantBuffers() @@ -364,5 +410,54 @@ namespace GlitchyEngine.Renderer } } } + + /// Merges the texture slots of all shaders into one dictionary. + private void MergeTextures() + { + delete _textures; + _textures = new .(); + + EnumerateShaderTextures(_vs); + EnumerateShaderTextures(_ps); + } + + /** @brief Merges all textures of the given shader into the _textures dictionary. + * @param shader The shader whose textures will be merged into the dictionary. + */ + private void EnumerateShaderTextures(T shader) where T : Shader + { + //for(var (name, index, texture) in shader.Resources) + for(var shaderEntry in ref shader.Textures) + { + TextureEntry entry; + + // Get existing entry or create new + if(!_textures.TryGetValue(shaderEntry.Name, out entry)) + { + entry = (shaderEntry.Texture, null, null); + entry.Texture?.AddRef(); + } + + // Set the corresponding shader resource slot + if(typeof(T) == typeof(VertexShader)) + { + entry.VsSlot = &shaderEntry; + } + else if(typeof(T) == typeof(PixelShader)) + { + entry.PsSlot = &shaderEntry; + } + + // If the entry has no texture but the shader has one -> set texture + if(entry.Texture == null && shaderEntry.Texture != null) + { + entry.Texture = shaderEntry.Texture; + entry.Texture?.AddRef(); + } + + // save entry + _textures[shaderEntry.Name] = entry; + } + } } } diff --git a/GlitchyEngine/src/Renderer/Material.bf b/GlitchyEngine/src/Renderer/Material.bf index 06a938b..54cdbff 100644 --- a/GlitchyEngine/src/Renderer/Material.bf +++ b/GlitchyEngine/src/Renderer/Material.bf @@ -1,15 +1,159 @@ using System; +using System.Collections; using GlitchyEngine.Math; +using internal GlitchyEngine.Renderer; + namespace GlitchyEngine.Renderer { public class Material : RefCounted { private Effect _effect ~ _?.ReleaseRef(); + private uint8[] _rawVariables ~ delete _; + + private Dictionary _textures = new .(); + + private Dictionary _variables = new .() ~ delete _; + + public Effect Effect => _effect; + public this(Effect effect) { _effect = effect..AddRef(); + + // TODO: get variables from effect + + for(let (name, entry) in _effect.Textures) + { + var texture = entry.Texture; + texture?.AddRef(); + + _textures.Add(name, texture); + } + + InitRawData(); + } + + public ~this() + { + for(let (name, texture) in _textures) + { + texture?.ReleaseRef(); + } + + delete _textures; + } + + /** @brief Initializes the raw data array for the variables. + */ + private void InitRawData() + { + uint32 bufferSize = 0; + + for(let variable in _effect.Variables) + { + _variables.Add(variable.Name, (bufferSize, variable)); + + bufferSize += variable._sizeInBytes; + } + + _rawVariables = new uint8[bufferSize]; + } + + /** + * Binds the materials Shaders and Parameters to the given context. + */ + public void Bind(GraphicsContext context) + { + for(let (name, texture) in _textures) + { + _effect.SetTexture(name, texture); + } + + for(let (name, variable) in _variables) + { + variable.Variable.SetRawData(&RawPointer!(variable.Offset)); + } + + _effect.Bind(context); + } + + /** @brief Sets a texture of the material. + * @param name The name of the texture to set. + * @param texture The texture to bind to the effect. + */ + public void SetTexture(String name, Texture texture) + { + if(_textures.TryGetValue(name, var entry)) + { + entry?.ReleaseRef(); + _textures[name] = texture; + texture?.AddRef(); + } + else + { + Log.EngineLogger.Assert(false); + } + } + + private mixin RawPointer(uint32 offset) + { + *(T*)(&_rawVariables[offset]) + } + + public void SetVariable(String name, float value) + { + if(_variables.TryGetValue(name, let entry)) + { + entry.Variable.EnsureTypeMatch(1, 1, .Float); + + RawPointer!(entry.Offset) = value; + } + else + { + Log.EngineLogger.Assert(false, scope $"The effect doesn't contain a variable named \"{name}\""); + } + } + + public void SetVariable(String name, Color value) + { + if(_variables.TryGetValue(name, let entry)) + { + entry.Variable.EnsureTypeMatch(); + + RawPointer!(entry.Offset) = (ColorRGBA)value; + } + else + { + Log.EngineLogger.Assert(false, scope $"The effect doesn't contain a variable named \"{name}\""); + } + } + + public void SetVariable(String name, Matrix value) + { + if(_variables.TryGetValue(name, let entry)) + { + entry.Variable.EnsureTypeMatch(); + + RawPointer!(entry.Offset) = value; + } + else + { + Log.EngineLogger.Assert(false, scope $"The effect doesn't contain a variable named \"{name}\""); + } + } + + /** + * Sets the raw data of the variable. + * @param rawData The pointer to the raw data. If rawData is null the raw data will be set to zero. + */ + internal void SetRawData(uint32 offset, void* rawData, uint32 byteCount) + { + if(rawData != null) + Internal.MemCpy(&_rawVariables + offset, rawData, byteCount); + else + Internal.MemSet(&_rawVariables + offset, 0, byteCount); } // public void Set(String name, VALUE)... @@ -22,8 +166,5 @@ namespace GlitchyEngine.Renderer // Bool, Bool2, Bool3, Bool4 // Half, Half2, Half3, Half4 // Byte, Byte2, Byte3, Byte4 - - // Texture - // Sampler } } diff --git a/GlitchyEngine/src/Renderer/Renderer.bf b/GlitchyEngine/src/Renderer/Renderer.bf index 2734908..5f1e4ca 100644 --- a/GlitchyEngine/src/Renderer/Renderer.bf +++ b/GlitchyEngine/src/Renderer/Renderer.bf @@ -77,5 +77,16 @@ namespace GlitchyEngine.Renderer geometry.Bind(); RenderCommand.DrawIndexed(geometry); } + + public static void Submit(GeometryBinding geometry, Material material, Matrix transform = .Identity) + { + material.SetVariable("ViewProjection", _sceneConstants.ViewProjection); + material.SetVariable("Transform", transform); + + material.Bind(_context); + + geometry.Bind(); + RenderCommand.DrawIndexed(geometry); + } } } diff --git a/GlitchyEngine/src/Renderer/Shader.bf b/GlitchyEngine/src/Renderer/Shader.bf index 1e80832..bd66024 100644 --- a/GlitchyEngine/src/Renderer/Shader.bf +++ b/GlitchyEngine/src/Renderer/Shader.bf @@ -23,17 +23,22 @@ namespace GlitchyEngine.Renderer protected GraphicsContext _context ~ _?.ReleaseRef(); protected BufferCollection _buffers ~ delete _;//:append _; + + protected ShaderTextureCollection _textures ~ delete _; public GraphicsContext Context => _context; public BufferCollection Buffers => _buffers; + public ShaderTextureCollection Textures => _textures; + [AllowAppend] public this(GraphicsContext context, String source, String entryPoint, ShaderDefine[] macros = null) { // Todo: append as soon as it's fixed. //let buffers = new BufferCollection(); _buffers = new BufferCollection(); + _textures = new ShaderTextureCollection(); _context = context..AddRef(); CompileFromSource(source, entryPoint); diff --git a/GlitchyEngine/src/Renderer/ShaderTextureCollection.bf b/GlitchyEngine/src/Renderer/ShaderTextureCollection.bf new file mode 100644 index 0000000..345e01f --- /dev/null +++ b/GlitchyEngine/src/Renderer/ShaderTextureCollection.bf @@ -0,0 +1,65 @@ +using System; +using System.Collections; + +namespace GlitchyEngine.Renderer +{ + public class ShaderTextureCollection : IEnumerable<(String Name, uint32 Index, Texture Texture)> + { + public typealias ResourceEntry = (String Name, uint32 Index, Texture Texture); + + List _textures ~ DeleteTextureEntries!(_); + + Dictionary _strToBuf ~ delete _; + Dictionary _idxToBuf ~ delete _; + + public this() + { + let textures = new List(); + let strToBuf = new Dictionary(); + let idxToBuf = new Dictionary(); + + _textures = textures; + _strToBuf = strToBuf; + _idxToBuf = idxToBuf; + } + + mixin DeleteTextureEntries(List entries) + { + if(entries == null) + return; + + for(let entry in entries) + { + delete entry.Name; + entry.Texture?.ReleaseRef(); + } + + delete entries; + } + + // TODO: finish implementation (like BufferCollection) + + public void Add(String name, uint32 index, Texture texture) + { + Add((name, index, texture)); + } + + public void Add(ResourceEntry entry) + { + ResourceEntry copy = (new String(entry.Name), entry.Index, entry.Texture); + entry.Texture?.AddRef(); + + _textures.Add(copy); + + ResourceEntry* copyRef = &_textures.Back; + + _strToBuf.Add(copy.Name, copyRef); + _idxToBuf.Add(copy.Index, copyRef); + } + + public List.Enumerator GetEnumerator() + { + return _textures.GetEnumerator(); + } + } +} diff --git a/Sandbox/content/Shaders/textureShader.hlsl b/Sandbox/content/Shaders/textureShader.hlsl index d471cba..de1c023 100644 --- a/Sandbox/content/Shaders/textureShader.hlsl +++ b/Sandbox/content/Shaders/textureShader.hlsl @@ -49,7 +49,7 @@ PS_IN VS(VS_IN input) float4 PS(PS_IN input) : SV_TARGET { - return input.Color * ColorTexture.Sample(TextureSampler, input.TexCoord); + return input.Color * BaseColor * ColorTexture.Sample(TextureSampler, input.TexCoord); } #effect[VS=VS,PS=PS] diff --git a/Sandbox/src/SandboxApp.bf b/Sandbox/src/SandboxApp.bf index 58554a9..b6a7965 100644 --- a/Sandbox/src/SandboxApp.bf +++ b/Sandbox/src/SandboxApp.bf @@ -61,7 +61,9 @@ namespace Sandbox GraphicsContext _context ~ _?.ReleaseRef(); DepthStencilTarget _depthTarget ~ _?.ReleaseRef(); - + + Material _checkerMaterial ~ _?.ReleaseRef(); + Material _logoMaterial ~ _?.ReleaseRef(); Texture2D _texture ~ _?.ReleaseRef(); Texture2D _ge_logo ~ _?.ReleaseRef(); @@ -188,6 +190,12 @@ namespace Sandbox sampler.ReleaseRef(); + _logoMaterial = new Material(textureEffect); + _logoMaterial.SetTexture("ColorTexture", _ge_logo); + + _checkerMaterial = new Material(textureEffect); + _checkerMaterial.SetTexture("ColorTexture", _texture); + BlendStateDescription blendDesc = .(); blendDesc.RenderTarget[0] = .(true, .SourceAlpha, .InvertedSourceAlpha, .Add, .SourceAlpha, .InvertedSourceAlpha, .Add, .All); _alphaBlendState = new BlendState(_context, blendDesc); @@ -289,7 +297,6 @@ namespace Sandbox _opaqueBlendState.Bind(); var basicEffect = _effectLibrary.Get("basicShader"); - var textureEffect = _effectLibrary.Get("textureShader"); // Model test { @@ -314,7 +321,7 @@ namespace Sandbox var transform = _world.GetComponent(entity); transform.Update(); } - + int i = 0; for(var entity in _world.Enumerate(typeof(TransformComponent), typeof(MeshComponent))) { @@ -332,19 +339,20 @@ namespace Sandbox } basicEffect.Variables["BaseColor"].SetData(_squareColor1); + + _checkerMaterial.SetVariable("BaseColor", Color.White); - _texture.Bind(); - Renderer.Submit(_quadGeometryBinding, textureEffect, .Scaling(1.5f)); + Renderer.Submit(_quadGeometryBinding, _checkerMaterial, .Scaling(1.5f)); _alphaBlendState.Bind(); + + _logoMaterial.SetVariable("BaseColor", Color.Pink); - _ge_logo.Bind(); - Renderer.Submit(_quadGeometryBinding, textureEffect, .Scaling(1.5f)); + Renderer.Submit(_quadGeometryBinding, _logoMaterial, .Scaling(2f)); Renderer.EndScene(); basicEffect.ReleaseRef(); - textureEffect.ReleaseRef(); } ColorRGBA _squareColor0 = ColorRGBA.CornflowerBlue;