private void compile() { if (IsDisposed) { throw new ObjectDisposedException(ToString(), "Can not compile a disposed shader."); } if (IsLoaded) { throw new InvalidOperationException("Attempting to compile an already-compiled shader."); } parts.RemoveAll(p => p == null); if (parts.Count == 0) { return; } programID = CreateProgram(); if (!CompileInternal()) { throw new ProgramLinkingFailedException(name, GetProgramLog()); } IsLoaded = true; SetupUniforms(); GlobalPropertyManager.Register(this); }
protected virtual void Dispose(bool disposing) { if (Loaded) { Unbind(); GLWrapper.DeleteProgram(this); Loaded = false; programID = -1; GlobalPropertyManager.Unregister(this); } }
protected virtual void Dispose(bool disposing) => GLWrapper.ScheduleDisposal(() => { if (IsLoaded) { IsLoaded = false; Unbind(); GL.DeleteProgram(this); GlobalPropertyManager.Unregister(this); programID = -1; } });
internal void Compile() { parts.RemoveAll(p => p == null); Uniforms.Clear(); uniformsArray = null; Log.Clear(); if (programID != -1) { Dispose(true); } if (parts.Count == 0) { return; } programID = GL.CreateProgram(); foreach (ShaderPart p in parts) { if (!p.Compiled) { p.Compile(); } GL.AttachShader(this, p); foreach (ShaderInputInfo input in p.ShaderInputs) { GL.BindAttribLocation(this, input.Location, input.Name); } } GL.LinkProgram(this); GL.GetProgram(this, GetProgramParameterName.LinkStatus, out int linkResult); string linkLog = GL.GetProgramInfoLog(this); Log.AppendLine(string.Format(ShaderPart.BOUNDARY, name)); Log.AppendLine($"Linked: {linkResult == 1}"); if (linkResult == 0) { Log.AppendLine("Log:"); Log.AppendLine(linkLog); } foreach (var part in parts) { GL.DetachShader(this, part); } Loaded = linkResult == 1; if (Loaded) { // Obtain all the shader uniforms GL.GetProgram(this, GetProgramParameterName.ActiveUniforms, out int uniformCount); uniformsArray = new IUniform[uniformCount]; for (int i = 0; i < uniformCount; i++) { GL.GetActiveUniform(this, i, 100, out _, out _, out ActiveUniformType type, out string uniformName); IUniform createUniform <T>(string name) where T : struct { int location = GL.GetUniformLocation(this, name); if (GlobalPropertyManager.CheckGlobalExists(name)) { return(new GlobalUniform <T>(this, name, location)); } return(new Uniform <T>(this, name, location)); } IUniform uniform; switch (type) { case ActiveUniformType.Bool: uniform = createUniform <bool>(uniformName); break; case ActiveUniformType.Float: uniform = createUniform <float>(uniformName); break; case ActiveUniformType.Int: uniform = createUniform <int>(uniformName); break; case ActiveUniformType.FloatMat3: uniform = createUniform <Matrix3>(uniformName); break; case ActiveUniformType.FloatMat4: uniform = createUniform <Matrix4>(uniformName); break; case ActiveUniformType.FloatVec2: uniform = createUniform <Vector2>(uniformName); break; case ActiveUniformType.FloatVec3: uniform = createUniform <Vector3>(uniformName); break; case ActiveUniformType.FloatVec4: uniform = createUniform <Vector4>(uniformName); break; default: continue; } uniformsArray[i] = uniform; Uniforms.Add(uniformName, uniformsArray[i]); } GlobalPropertyManager.Register(this); } }