Beispiel #1
0
        /// <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
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        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;
            }
        }
Beispiel #5
0
 /// <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;
 }