Ejemplo n.º 1
0
 public Shader(int startLine, ProgramPipelineParameter shaderType)
 {
     LineInFile          = startLine;
     ShaderType          = shaderType;
     gl_MaxClipDistances = GL.GetInteger(GetPName.MaxClipDistances);
 }
Ejemplo n.º 2
0
        protected static object GetUniform(string uniformName, Type uniformType, ProgramPipelineParameter shader)
        {
            int size;
            var locations = new int[1];

            // get current shader program pipeline
            var pipeline = GL.GetInteger(GetPName.ProgramPipelineBinding);

            if (pipeline <= 0)
            {
                return(DebugGetError(uniformType, new StackTrace(true)));
            }

            // get vertex shader
            GL.GetProgramPipeline(pipeline, shader, out int program);
            if (program <= 0)
            {
                return(DebugGetError(uniformType, new StackTrace(true)));
            }

            // get uniform buffer object block index
            int block = GL.GetUniformBlockIndex(program, uniformName.Substring(0, uniformName.IndexOf('.')));

            if (block < 0)
            {
                return(DebugGetError(uniformType, new StackTrace(true)));
            }

            // get bound buffer object
            GL.GetActiveUniformBlock(program, block, ActiveUniformBlockParameter.UniformBlockBinding, out int unit);
            GL.GetInteger(GetIndexedPName.UniformBufferBinding, unit, out int glbuf);
            if (glbuf <= 0)
            {
                return(DebugGetError(uniformType, new StackTrace(true)));
            }

            // get uniform indices in uniform block
            GL.GetUniformIndices(program, 1, new[] { uniformName }, locations);
            var location = locations[0];

            if (location < 0)
            {
                return(DebugGetError(uniformType, new StackTrace(true)));
            }

            // get uniform information
            GL.GetActiveUniforms(program, 1, ref location, ActiveUniformParameter.UniformType, out int type);
            GL.GetActiveUniforms(program, 1, ref location, ActiveUniformParameter.UniformSize, out int length);
            GL.GetActiveUniforms(program, 1, ref location, ActiveUniformParameter.UniformOffset, out int offset);
            GL.GetActiveUniforms(program, 1, ref location, ActiveUniformParameter.UniformArrayStride, out int stride);

            // get size of the uniform type
            switch ((All)type)
            {
            case All.IntVec2:
            case All.UnsignedIntVec2:
            case All.FloatVec2:
            case All.Double:
                size = 8;
                break;

            case All.IntVec3:
            case All.UnsignedIntVec3:
            case All.FloatVec3:
                size = 12;
                break;

            case All.IntVec4:
            case All.UnsignedIntVec4:
            case All.FloatVec4:
            case All.DoubleVec2:
            case All.FloatMat2:
                size = 16;
                break;

            case All.DoubleVec3:
                size = 24;
                break;

            case All.DoubleVec4:
                size = 32;
                break;

            case All.FloatMat3:
                size = 36;
                break;

            case All.FloatMat4:
                size = 64;
                break;

            default:
                size = 4;
                break;
            }

            // read uniform buffer data
            var array = new byte[Math.Max(stride, size) * length];
            var src   = GL.MapNamedBufferRange(glbuf, (IntPtr)offset, array.Length, BufferAccessMask.MapReadBit);

            Marshal.Copy(src, array, 0, array.Length);
            GL.UnmapNamedBuffer(glbuf);

            DebugGetError(new StackTrace(true));

            // if the return type is an array
            if (uniformType.IsArray && BaseTypes.Any(x => x == uniformType.GetElementType()))
            {
                return(array.To(uniformType.GetElementType()));
            }

            // if the return type is a base type
            if (BaseTypes.Any(x => x == uniformType))
            {
                return(array.To(uniformType).GetValue(0));
            }

            // create new object from byte array
            return(uniformType.GetConstructor(new[] { typeof(byte[]) })?.Invoke(new[] { array }));
        }