public Shader(int startLine, ProgramPipelineParameter shaderType) { LineInFile = startLine; ShaderType = shaderType; gl_MaxClipDistances = GL.GetInteger(GetPName.MaxClipDistances); }
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 })); }