/// <summary> /// Set uniform state variable (floating-point variable). /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for operations. /// </param> /// <param name="uniformName"> /// A <see cref="String"/> that specify the variable name in the shader source. /// </param> /// <param name="v"> /// A <see cref="Single"/> holding the uniform variabile data. /// </param> public void SetUniformBlock(GraphicsContext ctx, string uniformBlockName, UniformBuffer uniformBuffer) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (uniformBuffer == null) { throw new ArgumentNullException("uniformBuffer"); } // Select a binding point, if still invalid ctx.Bind(uniformBuffer); UniformBlockBinding uniformBlockBinding = GetUniformBlock(uniformBlockName); if (uniformBlockBinding == null) { throw new ArgumentException("no uniform block with such name", "uniformBlockName"); } #if ENABLE_UNIFORM_BLOCK_CACHING if (IsUniformBlockChanged(uniformBlockBinding.Index, uniformBuffer) == false) { return; } #endif // Link the uniform buffer Gl.UniformBlockBinding(ObjectName, uniformBlockBinding.Index, uniformBuffer.BindingIndex); #if ENABLE_UNIFORM_BLOCK_CACHING CacheUniformBlock(uniformBlockBinding.Index, uniformBuffer); #endif }
/// <summary> /// Determine whether if an uniform value is different from the one currently cached. /// </summary> /// <param name="uniformName"> /// A <see cref="String"/> that specifies the uniform variable name. /// </param> /// <param name="uniformValue"> /// A <see cref="Object"/> that specifies the uniform variable value updated. /// </param> /// <returns> /// It returns a boolean value indicating whether <paramref name="uniformValue"/> is actually /// different from the current uniform value. /// </returns> private bool IsUniformBlockChanged(uint index, UniformBuffer uniformBuffer) { uint cachedBindingIndex; if (_UniformBlocks.TryGetValue(index, out cachedBindingIndex) == false) { return(true); } return(cachedBindingIndex != uniformBuffer.BindingIndex); }
/// <summary> /// Create an <see cref="UniformBuffer"/> useful for backing with a buffer object the specified uniform block. /// </summary> /// <param name="uniformBlockName"></param> /// <param name="usageMask"></param> /// <returns></returns> public UniformBuffer CreateUniformBlock(string uniformBlockName, MapBufferUsageMask usageMask) { UniformBlockBinding uniformBlockBinding = GetUniformBlock(uniformBlockName); if (uniformBlockBinding == null) { throw new ArgumentException("no uniform block with such name", "uniformBlockName"); } UniformBuffer uniformBuffer = new UniformBuffer(usageMask); // Allocate client storage uniformBuffer.Create(uniformBlockBinding.DataSize); // Map uniform names with MapUniformBlock(uniformBlockName, uniformBuffer); return(uniformBuffer); }
private void MapUniformBlock(string uniformBlockName, UniformBuffer uniformBuffer) { UniformBlockBinding uniformBlockBinding = GetUniformBlock(uniformBlockName); if (uniformBlockBinding == null) { throw new ArgumentException("no uniform block with such name", "uniformBlockName"); } for (int i = 0; i < uniformBlockBinding.UniformIndices.Length; i++) { uint uniformIndex = uniformBlockBinding.UniformIndices[i]; UniformBinding uniformBinding; if (_UniformIndexMap.TryGetValue(uniformIndex, out uniformBinding) == false) { throw new InvalidOperationException("uniform buffer index mismatch with uniforms"); } UniformBuffer.UniformSegment uniformSegment = new UniformBuffer.UniformSegment(); uniformSegment.UniformIndex = uniformIndex; uniformSegment.Type = uniformBinding.UniformType; uniformSegment.Offset = uniformBinding.BlockOffset; uniformSegment.ArrayStride = uniformBinding.BlockArrayStride; uniformSegment.MatrixStride = uniformBinding.BlockMatrixStride; uniformSegment.RowMajor = uniformBinding.BlockMatrixRowMajor; uniformBuffer._UniformSegments[uniformBinding.Name] = uniformSegment; } foreach (KeyValuePair <string, UniformBinding> pair in _UniformMap) { if (pair.Value != null) { continue; } uniformBuffer._UniformSegments[pair.Key] = null; } }
/// <summary> /// Cache the current uniform value. Used to minimize Uniform* calls at the cost of comparing the cached /// object with the call arguments. /// </summary> /// <param name="uniformName"> /// A <see cref="String"/> that specifies the uniform variable name. /// </param> /// <param name="uniformValue"> /// A <see cref="Object"/> that specifies the uniform variable value. /// </param> private void CacheUniformBlock(uint index, UniformBuffer uniformBuffer) { Debug.Assert(uniformBuffer != null); _UniformBlocks[index] = uniformBuffer.BindingIndex; }