/// <summary> /// Bind this uniform buffer object and a uniform block to the same binding point. /// </summary> /// <param name="uniformBlockIndex">index of uniform block got by (glGetUniformBlockIndex).</param> /// <param name="uniformBlockBindingPoint">binding point maintained by OpenGL context.</param> /// <param name="program">shader program.</param> public void Binding(ShaderProgram program, uint uniformBlockIndex, uint uniformBlockBindingPoint) { if (glBindBufferBase == null) { glBindBufferBase = OpenGL.GetDelegateFor<OpenGL.glBindBufferBase>(); } if (glUniformBlockBinding == null) { glUniformBlockBinding = OpenGL.GetDelegateFor<OpenGL.glUniformBlockBinding>(); } glBindBufferBase(OpenGL.GL_UNIFORM_BUFFER, uniformBlockBindingPoint, this.BufferId); glUniformBlockBinding(program.ProgramId, uniformBlockIndex, uniformBlockBindingPoint); }
public override void ResetUniform(ShaderProgram program) { //base.ResetUniform(program); //if (glActiveTexture == null) //{ glActiveTexture = OpenGL.GetDelegateFor<OpenGL.glActiveTexture>(); } //glActiveTexture(value.ActiveTextureIndex); ////OpenGL.BindTexture(OpenGL.GL_TEXTURE_2D, 0); //OpenGL.BindTexture(value.target, 0); }
/// <summary> /// Bind this uniform buffer object and a uniform block to the same binding point. /// </summary> /// <param name="program">shader program.</param> /// <param name="storageBlockName">name of buffer block in shader.</param> /// <param name="storageBlockBindingPoint">binding point maintained by OpenGL context.</param> public void Binding(ShaderProgram program, string storageBlockName, uint storageBlockBindingPoint) { if (glGetProgramResourceIndex == null) { glGetProgramResourceIndex = OpenGL.GetDelegateFor<OpenGL.glGetProgramResourceIndex>(); } if (glBindBufferBase == null) { glBindBufferBase = OpenGL.GetDelegateFor<OpenGL.glBindBufferBase>(); } if (glShaderStorageBlockBinding == null) { glShaderStorageBlockBinding = OpenGL.GetDelegateFor<OpenGL.glShaderStorageBlockBinding>(); } uint storageBlockIndex = glGetProgramResourceIndex(program.ProgramId, OpenGL.GL_SHADER_STORAGE_BLOCK, storageBlockName); glBindBufferBase(OpenGL.GL_SHADER_STORAGE_BUFFER, storageBlockBindingPoint, this.BufferId); glShaderStorageBlockBinding(program.ProgramId, storageBlockIndex, storageBlockBindingPoint); }
public static ShaderProgram GetHighlightShaderProgram() { var shaderCodes = new ShaderCode[2]; shaderCodes[0] = new ShaderCode(GetShaderSource(ShaderType.VertexShader), ShaderType.VertexShader); shaderCodes[1] = new ShaderCode(GetShaderSource(ShaderType.FragmentShader), ShaderType.FragmentShader); var shaderProgram = new ShaderProgram(); shaderProgram.Create((from item in shaderCodes select item.CreateShader()).ToArray()); return shaderProgram; }
public override void SetUniform(ShaderProgram program) { if (glActiveTexture == null) { glActiveTexture = OpenGL.GetDelegateFor<OpenGL.glActiveTexture>(); } for (int i = 0; i < this.value.Length; i++) { glActiveTexture(this.value[i].ActiveTextureIndex); //OpenGL.BindTexture(OpenGL.GL_TEXTURE_2D, this.value[i].TextureId); OpenGL.BindTexture(this.value[i].target, this.value[i].TextureId); // TODO: assign the first location or last? this.Location = program.SetUniform(VarName, this.value[i].activeTextureIndex); } }
public static ShaderProgram GetPickingShaderProgram() { var shaderCodes = new ShaderCode[2]; shaderCodes[0] = new ShaderCode(GetShaderSource(ShaderType.VertexShader), ShaderType.VertexShader); shaderCodes[1] = new ShaderCode(GetShaderSource(ShaderType.FragmentShader), ShaderType.FragmentShader); ShaderProgram program = new ShaderProgram(); var shaders = (from item in shaderCodes select item.CreateShader()).ToArray(); program.Create(shaders); foreach (var item in shaders) { item.Delete(); } return program; }
public override void Render(RenderEventArgs arg, ShaderProgram shaderProgram) { if (arg.RenderMode == RenderModes.ColorCodedPicking && arg.PickingGeometryType == GeometryType.Point && this.Mode.ToGeometryType() == GeometryType.Line)// picking point from a line { // this maybe render points that should not appear. // so need to select by another picking OpenGL.DrawArrays(DrawMode.Points, this.FirstVertex, this.VertexCount); } else { OpenGL.DrawArrays(this.Mode, this.FirstVertex, this.VertexCount); } }
/// <summary> /// 在OpenGL中创建VAO。 /// 创建的过程就是执行一次渲染的过程。 /// </summary> /// <param name="arg"></param> /// <param name="shaderProgram"></param> public void Create(RenderEventArg arg, ShaderProgram shaderProgram) { if (this.ID != 0) { throw new Exception(string.Format("ID[{0}] is already generated!", this.ID)); } uint[] buffers = new uint[1]; glGenVertexArrays(1, buffers); this.ID = buffers[0]; this.Bind(); BufferPtr[] propertyBufferPtrs = this.propertyBufferPtrs; if (propertyBufferPtrs != null) { foreach (var item in propertyBufferPtrs) { item.Render(arg, shaderProgram); } } this.Unbind(); }
/// <summary> /// 默认重置Updated = false; /// <para>以避免重复设置。</para> /// <para>某些类型的uniform可能需要重复调用SetUniform()(例如纹理类型的uniform sampler2D)</para> /// </summary> /// <param name="program"></param> public virtual void ResetUniform(ShaderProgram program) { this.Updated = false; }
/// <summary> /// /// </summary> /// <param name="program"></param> public override void SetUniform(ShaderProgram program) { this.Location = program.SetUniform(VarName, value.x, value.y, value.z); }
public override void SetUniform(ShaderProgram program) { this.Location = program.SetUniformMatrix3(VarName, this.value); }
public override void SetUniform(ShaderProgram program) { program.SetUniformMatrix4(VarName, this.value.to_array()); }
/// <summary> /// Creates a shader program by multiple shaders. /// </summary> /// <param name="shaderCodes"></param> /// <returns></returns> public static ShaderProgram CreateProgram(this ShaderCode[] shaderCodes) { var program = new ShaderProgram(); Shader[] shaders = (from item in shaderCodes select item.CreateShader()).ToArray(); program.Initialize(shaders); foreach (Shader item in shaders) { item.Dispose(); } return program; }
/// <summary> /// Creates a shader program object by a single shader. /// </summary> /// <param name="shaderCode"></param> /// <returns></returns> public static ShaderProgram CreateProgram(this ShaderCode shaderCode) { var program = new ShaderProgram(); Shader shader = shaderCode.CreateShader(); program.Initialize(shader); shader.Dispose(); return program; }
/// <summary> /// 执行一次渲染的过程。 /// </summary> /// <param name="arg"></param> /// <param name="shaderProgram"></param> /// <param name="temporaryIndexBufferPtr">render by a temporary index buffer</param> public void Render(RenderEventArg arg, ShaderProgram shaderProgram, IndexBufferPtr temporaryIndexBufferPtr = null) { if (temporaryIndexBufferPtr != null) { this.Bind(); temporaryIndexBufferPtr.Render(arg, shaderProgram); this.Unbind(); } else { IndexBufferPtr indexBufferPtr = this.IndexBufferPtr; if (indexBufferPtr != null) { this.Bind(); indexBufferPtr.Render(arg, shaderProgram); this.Unbind(); } } }
/// <summary> /// 执行一次渲染的过程。 /// <para>Execute rendering command.</para> /// </summary> /// <param name="arg"></param> /// <param name="shaderProgram"></param> /// <param name="temporaryIndexBuffer">render by a temporary index buffer</param> public void Render(RenderEventArgs arg, ShaderProgram shaderProgram, IndexBuffer temporaryIndexBuffer = null) { if (temporaryIndexBuffer != null) { this.Bind(); temporaryIndexBuffer.Render(arg); this.Unbind(); } else { this.Bind(); this.IndexBuffer.Render(arg); this.Unbind(); } }
/// <summary> /// 在使用<see cref="VertexArrayObject"/>后,此方法只会执行一次。 /// This method will only be invoked once when using <see cref="VertexArrayObject"/>. /// </summary> /// <param name="shaderProgram"></param> public void Standby(ShaderProgram shaderProgram) { int location = shaderProgram.GetAttributeLocation(this.VarNameInVertexShader); if (location < 0) { throw new ArgumentException(); } uint loc = (uint)location; VBOConfigDetail detail = this.Config.Parse(); int patchVertexes = this.PatchVertexes; uint divisor = this.InstancedDivisor; // 选中此VBO // select this VBO. if (glBindBuffer == null) { glBindBuffer = OpenGL.GetDelegateFor<OpenGL.glBindBuffer>(); } glBindBuffer(OpenGL.GL_ARRAY_BUFFER, this.BufferId); for (uint i = 0; i < detail.locationCount; i++) { // 指定格式 // set up data format. switch (detail.pointerType) { case VertexAttribPointerType.Default: if (glVertexAttribPointer == null) { glVertexAttribPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribPointer>(); } glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit)); break; case VertexAttribPointerType.Integer: if (glVertexAttribIPointer != null) { if (glVertexAttribIPointer == null) { glVertexAttribIPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribIPointer>(); } glVertexAttribIPointer(loc + i, detail.dataSize, detail.dataType, detail.stride, new IntPtr(i * detail.startOffsetUnit)); } else { if (glVertexAttribPointer == null) { glVertexAttribPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribPointer>(); } glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit)); } break; case VertexAttribPointerType.Long: if (glVertexAttribLPointer != null) { if (glVertexAttribLPointer == null) { glVertexAttribLPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribLPointer>(); } glVertexAttribLPointer(loc + i, detail.dataSize, detail.dataType, detail.stride, new IntPtr(i * detail.startOffsetUnit)); } else { if (glVertexAttribPointer == null) { glVertexAttribPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribPointer>(); } glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit)); } break; default: throw new NotImplementedException(); } if (patchVertexes > 0)// tessellation shading. { if (glPatchParameteri != null) { if (glPatchParameteri == null) { glPatchParameteri = OpenGL.GetDelegateFor<OpenGL.glPatchParameteri>(); } glPatchParameteri(OpenGL.GL_PATCH_VERTICES, patchVertexes); } } // 启用 // enable this VBO. if (glEnableVertexAttribArray == null) { glEnableVertexAttribArray = OpenGL.GetDelegateFor<OpenGL.glEnableVertexAttribArray>(); } glEnableVertexAttribArray(loc + i); if (divisor > 0)// instanced rendering. { if (glVertexAttribDivisor == null) { glVertexAttribDivisor = OpenGL.GetDelegateFor<OpenGL.glVertexAttribDivisor>(); } glVertexAttribDivisor(loc + i, divisor); } } glBindBuffer(OpenGL.GL_ARRAY_BUFFER, 0); }
public override void SetUniform(ShaderProgram program) { this.Location = program.SetUniform(VarName, value.x, value.y); }
/// <summary> /// A smallest unit that can render somthing. /// </summary> /// <param name="program"></param> /// <param name="vao"></param> /// <param name="positionBuffers"></param> /// <param name="switches"></param> public IPickableRenderMethod(ShaderProgram program, VertexArrayObject[] vao, VertexBuffer[] positionBuffers, params GLSwitch[] switches) : base(program, vao, switches) { this.PositionBuffers = positionBuffers; }
/// <summary> /// /// </summary> /// <param name="program"></param> public override void SetUniform(ShaderProgram program) { this.Location = program.SetUniformMatrix4(VarName, this.Value.Array); }
protected override void DoRender(RenderEventArgs arg) { ShaderProgram program = this.shaderProgram; if (program == null) { return; } // 绑定shader program.Bind(); var updatedUniforms = (from item in this.uniformVariables where item.Updated select item).ToArray(); foreach (var item in updatedUniforms) { item.SetUniform(program); } int count = this.switchList.Count; for (int i = 0; i < count; i++) { this.switchList[i].On(); } IndexBufferPtr indexBufferPtr = this.indexBufferPtr; if (this.vertexArrayObject == null) { PropertyBufferPtr[] propertyBufferPtrs = this.propertyBufferPtrs; if (indexBufferPtr != null && propertyBufferPtrs != null) { var vertexArrayObject = new VertexArrayObject( indexBufferPtr, propertyBufferPtrs); vertexArrayObject.Create(arg, program); this.vertexArrayObject = vertexArrayObject; } } { VertexArrayObject vertexArrayObject = this.vertexArrayObject; if (vertexArrayObject != null) { if (vertexArrayObject.IndexBufferPtr != indexBufferPtr) { vertexArrayObject.IndexBufferPtr = indexBufferPtr; } vertexArrayObject.Render(arg, program); } } for (int i = count - 1; i >= 0; i--) { this.switchList[i].Off(); } foreach (var item in updatedUniforms) { item.ResetUniform(program); } // 解绑shader program.Unbind(); }
public override void SetUniform(ShaderProgram program) { vec2 value = this.value; program.SetUniform(VarName, value.x, value.y); }
protected override void DoInitialize() { // init shader program. ShaderProgram program = this.shaderCodes.CreateProgram(); VertexAttributeBufferPtr positionBufferPtr = null; IBufferable model = this.Model; VertexAttributeBufferPtr[] vertexAttributeBufferPtrs; { var list = new List <VertexAttributeBufferPtr>(); foreach (var item in this.attributeMap) { VertexAttributeBufferPtr bufferPtr = model.GetVertexAttributeBufferPtr( item.NameInIBufferable, item.VarNameInShader); if (bufferPtr == null) { throw new Exception(string.Format("[{0}] returns null buffer pointer!", model)); } if (item.NameInIBufferable == this.PositionNameInIBufferable) { positionBufferPtr = new VertexAttributeBufferPtr( "in_Position",// in_Postion same with in the PickingShader.vert shader bufferPtr.BufferId, bufferPtr.Config, bufferPtr.Length, bufferPtr.ByteLength); break; } list.Add(bufferPtr); } vertexAttributeBufferPtrs = list.ToArray(); } // 由于picking.vert/frag只支持vec3的position buffer,所以有此硬性规定。 if (positionBufferPtr == null || positionBufferPtr.Config != VertexAttributeConfig.Vec3) { throw new Exception(string.Format("Position buffer must use a type composed of 3 float as PropertyBuffer<T>'s T!")); } // init index buffer. IndexBufferPtr indexBufferPtr = model.GetIndexBufferPtr(); // RULE: Renderer takes uint.MaxValue, ushort.MaxValue or byte.MaxValue as PrimitiveRestartIndex. So take care this rule when designing a model's index buffer. var ptr = indexBufferPtr as OneIndexBufferPtr; if (ptr != null) { GLSwitch glSwitch = new PrimitiveRestartSwitch(ptr); this.switchList.Add(glSwitch); } // init VAO. var vertexArrayObject = new VertexArrayObject(indexBufferPtr, positionBufferPtr); vertexArrayObject.Initialize(program); // sets fields. this.Program = program; this.vertexAttributeBufferPtrs = new VertexAttributeBufferPtr[] { positionBufferPtr }; this.indexBufferPtr = indexBufferPtr; this.vertexArrayObject = vertexArrayObject; }
/// <summary> /// A smallest unit that can render somthing. /// </summary> /// <param name="program"></param> /// <param name="vao"></param> /// <param name="positionBuffer"></param> /// <param name="states"></param> public IPickableRenderMethod(ShaderProgram program, VertexArrayObject vao, VertexBuffer positionBuffer, params GLState[] states) : base(program, vao, states) { this.PositionBuffer = positionBuffer; }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <returns></returns> public RenderMethod ToRenderMethod(IBufferSource model) { // init shader program. ShaderProgram program = this.programProvider.GetShaderProgram(); // init vertex attribute buffer objects. var attrCount = this.map.Count(); // how many kinds of vertex attributes? var allBlocks = new List <VertexBuffer> [attrCount]; var allNames = new string[attrCount]; int blockCount = 0; // how many blocks an attribute is divided into? int index = 0; foreach (AttributeMap.NamePair item in this.map) { blockCount = 0; allBlocks[index] = new List <VertexBuffer>(); foreach (var buffer in model.GetVertexAttributeBuffer(item.NameInIBufferSource)) { if (buffer == null) { throw new Exception(string.Format("[{0}] returns null buffer pointer!", model)); } allBlocks[index].Add(buffer); allNames[index] = item.VarNameInShader; blockCount++; } if (blockCount != allBlocks[0].Count) { throw new Exception("Not all vertex attribute buffers' block count are the same!"); } index++; } // init draw commands. var drawCmds = (from item in model.GetDrawCommand() where (item != null) select item).ToArray(); int cmdCount = drawCmds.Length; if (attrCount > 0 && cmdCount != blockCount) { throw new Exception("Draw Commands count != vertex buffer block count."); } // init VAOs. var vaos = new VertexArrayObject[cmdCount]; for (int c = 0; c < cmdCount; c++) { var vertexShaderAttributes = new VertexShaderAttribute[attrCount]; for (int a = 0; a < attrCount; a++) { List <VertexBuffer> vertexAttribute = allBlocks[a]; string varNameInShader = allNames[a]; vertexShaderAttributes[a] = new VertexShaderAttribute(vertexAttribute[c], varNameInShader); } vaos[c] = new VertexArrayObject(drawCmds[c], program, vertexShaderAttributes); } return(new RenderMethod(program, vaos, this.switches)); }
/// <summary> /// 执行此VBO的渲染操作。 /// </summary> /// <param name="arg"></param> /// <param name="shaderProgram">此VBO使用的shader program。</param> public abstract void Render(RenderEventArgs arg, ShaderProgram shaderProgram);
/// <summary> /// 在OpenGL中创建VAO。 /// 创建的过程就是执行一次渲染的过程。 /// <para>Creates VAO and bind it to specified VBOs.</para> /// <para>The whole process of binding is also the process of rendering.</para> /// </summary> /// <param name="shaderProgram"></param> public void Initialize(ShaderProgram shaderProgram) { if (this.Id != 0) { throw new Exception(string.Format("Id[{0}] is already generated!", this.Id)); } if (glGenVertexArrays == null) { glGenVertexArrays = OpenGL.GetDelegateFor<OpenGL.glGenVertexArrays>(); glBindVertexArray = OpenGL.GetDelegateFor<OpenGL.glBindVertexArray>(); glDeleteVertexArrays = OpenGL.GetDelegateFor<OpenGL.glDeleteVertexArrays>(); } glGenVertexArrays(1, ids); this.Bind();// this vertex array object will record all stand-by actions. VertexBuffer[] vertexAttributeBuffers = this.VertexAttributeBuffers; if (vertexAttributeBuffers != null) { foreach (VertexBuffer item in vertexAttributeBuffers) { item.Standby(shaderProgram); } } this.Unbind();// this vertex array object has recorded all stand-by actions. }
/// <summary> /// /// </summary> /// <param name="program"></param> public abstract void SetUniform(ShaderProgram program);
/// <summary> /// /// </summary> /// <param name="program"></param> public override void SetUniform(ShaderProgram program) { this.Location = program.SetUniformMatrix2(VarName, this.value.ToArray()); }