internal void Initialize() { PlatformInitialize(); // Clear the texture and sampler collections forcing // the state to be reapplied. VertexTextures.Clear(); VertexSamplerStates.Clear(); Textures.Clear(); SamplerStates.Clear(); // Clear constant buffers _vertexConstantBuffers.Clear(); _pixelConstantBuffers.Clear(); // Force set the buffers and shaders on next ApplyState() call _vertexBuffers = new VertexBufferBindings(_maxVertexBufferSlots); // _vertexBuffersDirty = true; _indexBufferDirty = true; _vertexShaderDirty = true; _pixelShaderDirty = true; // Set the default scissor rect. _scissorRectangleDirty = true; ScissorRectangle = _viewport.Bounds; // Set the default render target. ApplyRenderTargets(null); }
/// <summary> /// Gets or create the DirectX input layout for the specified vertex buffers. /// </summary> /// <param name="vertexBuffers">The vertex buffers.</param> /// <returns>The DirectX input layout.</returns> public InputLayout GetOrCreate(VertexBufferBindings vertexBuffers) { InputLayout inputLayout; if (_cache.TryGetValue(vertexBuffers, out inputLayout)) return inputLayout; var vertexInputLayout = vertexBuffers.ToImmutable(); var inputElements = vertexInputLayout.GetInputElements(); try { inputLayout = new InputLayout(_graphicsDevice._d3dDevice, _shaderByteCode, inputElements); } catch (SharpDXException ex) { if (ex.Descriptor != Result.InvalidArg) throw; // If InputLayout ctor fails with InvalidArg then it's most likely because the // vertex declaration doesn't match the vertex shader. // Shader probably used the semantic "SV_Position" in the vertex shader input. // Background information: // "SV_Position" is a "system-value semantic" which is interpreted by the // rasterizer stage. This means it needs to be used in the vertex shader output // or the pixel shader input. (See // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647.aspx) // // However, some effects (notably the original XNA stock effects) use // "SV_Position" for the vertex shader input. This is technically allowed, but // rather uncommon and causes problems: // - XNA/MonoGame only has VertexElementUsage.Position, so there is no way to // distinguish between "POSITION" and "SV_Position". // - "SV_Position" cannot be used with any index other than 0, i.e. the DirectX // FX compiler does not accept "SV_Position1", "SV_Position2", ... // This is a problem when using multiple vertex streams, e.g. for blend shape // animations. It makes it impossible to correctly match the vertex // declaration with the vertex shader signature. // // Conclusion: // - MonoGame needs to translate VertexElementUsage.Position to "POSITION". // - MonoGame effects should always use "POSITION" for vertex shader inputs. // Here is a workaround ("hack") for old vertex shaders which haven't been // updated: Rename "POSITION0" to "SV_Position" and try again. bool retry = false; for (int i = 0; i < inputElements.Length; i++) { if (inputElements[i].SemanticIndex == 0 && inputElements[i].SemanticName.Equals("POSITION", StringComparison.OrdinalIgnoreCase)) { inputElements[i].SemanticName = "SV_Position"; retry = true; break; } } if (!retry) throw new InvalidOperationException(GetInvalidArgMessage(inputElements), ex); try { inputLayout = new InputLayout(_graphicsDevice._d3dDevice, _shaderByteCode, inputElements); // Workaround succeeded? This means that there is a vertex shader that needs // to be updated. #if DEBUG if (_printWarning) { Debug.WriteLine( "Warning: Vertex shader uses semantic 'SV_Position' for input register. " + "Please update the shader and use the semantic 'POSITION0' instead. The " + "semantic 'SV_Position' should only be used for the vertex shader output or " + "pixel shader input!"); _printWarning = false; } #endif } catch (SharpDXException) { // Workaround failed. throw new InvalidOperationException(GetInvalidArgMessage(inputElements), ex); } } _cache.Add(vertexInputLayout, inputLayout); return inputLayout; }
/// <summary> /// Gets or create the DirectX input layout for the specified vertex buffers. /// </summary> /// <param name="vertexBuffers">The vertex buffers.</param> /// <returns>The DirectX input layout.</returns> public InputLayout GetOrCreate(VertexBufferBindings vertexBuffers) { InputLayout inputLayout; if (_cache.TryGetValue(vertexBuffers, out inputLayout)) { return(inputLayout); } var vertexInputLayout = vertexBuffers.ToImmutable(); var inputElements = vertexInputLayout.GetInputElements(); try { inputLayout = new InputLayout(_graphicsDevice._d3dDevice, _shaderByteCode, inputElements); } catch (SharpDXException ex) { if (ex.Descriptor != Result.InvalidArg) { throw; } // If InputLayout ctor fails with InvalidArg then it's most likely because the // vertex declaration doesn't match the vertex shader. // Shader probably used the semantic "SV_Position" in the vertex shader input. // Background information: // "SV_Position" is a "system-value semantic" which is interpreted by the // rasterizer stage. This means it needs to be used in the vertex shader output // or the pixel shader input. (See // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647.aspx) // // However, some effects (notably the original XNA stock effects) use // "SV_Position" for the vertex shader input. This is technically allowed, but // rather uncommon and causes problems: // - XNA/MonoGame only has VertexElementUsage.Position, so there is no way to // distinguish between "POSITION" and "SV_Position". // - "SV_Position" cannot be used with any index other than 0, i.e. the DirectX // FX compiler does not accept "SV_Position1", "SV_Position2", ... // This is a problem when using multiple vertex streams, e.g. for blend shape // animations. It makes it impossible to correctly match the vertex // declaration with the vertex shader signature. // // Conclusion: // - MonoGame needs to translate VertexElementUsage.Position to "POSITION". // - MonoGame effects should always use "POSITION" for vertex shader inputs. // Here is a workaround ("hack") for old vertex shaders which haven't been // updated: Rename "POSITION0" to "SV_Position" and try again. bool retry = false; for (int i = 0; i < inputElements.Length; i++) { if (inputElements[i].SemanticIndex == 0 && inputElements[i].SemanticName.Equals("POSITION", StringComparison.OrdinalIgnoreCase)) { inputElements[i].SemanticName = "SV_Position"; retry = true; break; } } if (!retry) { throw new InvalidOperationException(GetInvalidArgMessage(inputElements), ex); } try { inputLayout = new InputLayout(_graphicsDevice._d3dDevice, _shaderByteCode, inputElements); // Workaround succeeded? This means that there is a vertex shader that needs // to be updated. #if DEBUG if (_printWarning) { Debug.WriteLine( "Warning: Vertex shader uses semantic 'SV_Position' for input register. " + "Please update the shader and use the semantic 'POSITION0' instead. The " + "semantic 'SV_Position' should only be used for the vertex shader output or " + "pixel shader input!"); _printWarning = false; } #endif } catch (SharpDXException) { // Workaround failed. throw new InvalidOperationException(GetInvalidArgMessage(inputElements), ex); } } _cache.Add(vertexInputLayout, inputLayout); return(inputLayout); }