/// <summary> /// 遍历以<see cref="lastVerteID"/>为最后一个顶点的图元, /// 瞄准每个图元的索引(例如1个三角形有3个索引)中的最后一个索引, /// 将此索引在<see cref="indexBufferPtr"/>中的索引(位置)收集起来。 /// </summary> /// <param name="lastVertexId"></param> /// <returns></returns> private List <RecognizedPrimitiveIndex> GetLastIndexIdList(RenderEventArgs arg, uint lastVertexId) { PrimitiveRecognizer recognizer = PrimitiveRecognizerFactory.Create( (arg.RenderMode == RenderModes.ColorCodedPicking && arg.PickingGeometryType == GeometryType.Point && this.indexBufferPtr.Mode.ToGeometryType() == GeometryType.Line) ? DrawMode.Points : this.indexBufferPtr.Mode); PrimitiveRestartSwitch glSwitch = GetPrimitiveRestartSwitch(); OpenGL.BindBuffer(BufferTarget.ElementArrayBuffer, this.indexBufferPtr.BufferId); IntPtr pointer = OpenGL.MapBuffer(BufferTarget.ElementArrayBuffer, MapBufferAccess.ReadOnly); List <RecognizedPrimitiveIndex> lastIndexIdList = null; if (glSwitch == null) { lastIndexIdList = recognizer.Recognize(lastVertexId, pointer, this.indexBufferPtr as OneIndexBufferPtr); } else { lastIndexIdList = recognizer.Recognize(lastVertexId, pointer, this.indexBufferPtr as OneIndexBufferPtr, glSwitch.RestartIndex); } OpenGL.UnmapBuffer(BufferTarget.ElementArrayBuffer); OpenGL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); return(lastIndexIdList); }
/// <summary> /// 遍历以<paramref name="lastVertexId"/>为最后一个顶点的图元, /// 瞄准每个图元的索引(例如1个三角形有3个索引)中的最后一个索引, /// 将此索引在<see cref="IndexBufferPtr"/>中的索引(位置)收集起来。 /// </summary> /// <param name="arg"></param> /// <param name="lastVertexId"></param> /// <returns></returns> private List <RecognizedPrimitiveInfo> GetLastIndexIdList(RenderEventArgs arg, uint lastVertexId) { PrimitiveRecognizer recognizer = PrimitiveRecognizerFactory.Create( (arg.RenderMode == RenderModes.ColorCodedPicking && arg.PickingGeometryType == GeometryType.Point && this.indexBufferPtr.Mode.ToGeometryType() == GeometryType.Line) ? DrawMode.Points : this.indexBufferPtr.Mode); PrimitiveRestartSwitch glSwitch = GetPrimitiveRestartSwitch(); var bufferPtr = this.indexBufferPtr as OneIndexBufferPtr; IntPtr pointer = bufferPtr.MapBuffer(MapBufferAccess.ReadOnly); List <RecognizedPrimitiveInfo> primitiveInfoList = null; if (glSwitch == null) { primitiveInfoList = recognizer.Recognize(lastVertexId, pointer, this.indexBufferPtr as OneIndexBufferPtr); } else { primitiveInfoList = recognizer.Recognize(lastVertexId, pointer, this.indexBufferPtr as OneIndexBufferPtr, glSwitch.RestartIndex); } bufferPtr.UnmapBuffer(); return(primitiveInfoList); }
protected override void DoInitialize() { // init shader program this.Program = PickingShaderHelper.GetPickingShaderProgram(); // init property buffer objects var propertyBufferPtrs = new PropertyBufferPtr[propertyNameMap.Count()]; int index = 0; foreach (var item in propertyNameMap) { PropertyBufferPtr bufferPtr = this.bufferable.GetProperty( item.NameInIBufferable, item.VarNameInShader); if (bufferPtr == null) { throw new Exception(); } propertyBufferPtrs[index++] = bufferPtr; } this.propertyBufferPtrs = propertyBufferPtrs; this.indexBufferPtr = this.bufferable.GetIndex(); foreach (var item in propertyNameMap) { PropertyBufferPtr bufferPtr = this.bufferable.GetProperty( item.NameInIBufferable, item.VarNameInShader); if (bufferPtr == null) { throw new Exception(); } if (item.NameInIBufferable == positionNameInIBufferable) { this.positionBufferPtr = new PropertyBufferPtr( "in_Position",// in_Postion same with in the PickingShader.vert shader bufferPtr.BufferId, bufferPtr.DataSize, bufferPtr.DataType, bufferPtr.Length, bufferPtr.ByteLength); break; } } // 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 = this.indexBufferPtr as OneIndexBufferPtr; if (ptr != null) { GLSwitch glSwitch = new PrimitiveRestartSwitch(ptr); this.switchList.Add(glSwitch); } // 由于picking.vert/frag只支持vec3的position buffer,所以有此硬性规定。 if (this.positionBufferPtr.DataSize != 3 || this.positionBufferPtr.DataType != OpenGL.GL_FLOAT) { throw new Exception(string.Format("Position buffer must use a type composed of 3 float as PropertyBuffer<T>'s T!")); } }
private void ColorCodedRender(RenderEventArgs arg, IndexBufferPtr temporaryIndexBufferPtr = null) { UpdatePolygonMode(arg.PickingGeometryType); ShaderProgram program = this.Program; // 绑定shader program.Bind(); program.SetUniform("pickingBaseId", temporaryIndexBufferPtr == null ? (int)this.PickingBaseId : 0); UniformMat4 uniformmMVP4Picking = this.uniformmMVP4Picking; bool mvpUpdated = uniformmMVP4Picking.Updated; if (mvpUpdated) { uniformmMVP4Picking.SetUniform(program); } PickingSwitchesOn(); GLSwitch primitiveRestartIndexSwitch = null; var oneIndexBufferPtr = temporaryIndexBufferPtr as OneIndexBufferPtr; if (oneIndexBufferPtr != null) { primitiveRestartIndexSwitch = new PrimitiveRestartSwitch(oneIndexBufferPtr); primitiveRestartIndexSwitch.On(); } if (this.vertexArrayObject == null) { var vertexArrayObject = new VertexArrayObject( this.indexBufferPtr, this.positionBufferPtr); vertexArrayObject.Create(arg, program); this.vertexArrayObject = vertexArrayObject; } //else { this.vertexArrayObject.Render(arg, program, temporaryIndexBufferPtr); } if (oneIndexBufferPtr != null) { primitiveRestartIndexSwitch.Off(); } PickingSwitchesOff(); if (mvpUpdated) { uniformmMVP4Picking.ResetUniform(program); } // 解绑shader program.Unbind(); }
protected override void DoInitialize() { base.DoInitialize(); // init index buffer var primitiveRestartSwitch4Picking = new PrimitiveRestartSwitch(this.indexBufferPtr as OneIndexBufferPtr); this.primitiveRestartSwitch4Picking = primitiveRestartSwitch4Picking; this.switchList.Add(primitiveRestartSwitch4Picking); }
protected override void DoInitialize() { base.DoInitialize(); var renderer = this.Renderer as OneIndexRenderer; if (renderer != null) { GLSwitch primitiveRestartSwitch = new PrimitiveRestartSwitch(renderer.IndexBufferPtr); renderer.SwitchList.Add(primitiveRestartSwitch); } }
/// <summary> /// /// </summary> protected override void DoInitialize() { // init shader program. ShaderProgram program = this.shaderCodes.CreateProgram(); // init vertex attribute buffer objects. 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)); } list.Add(bufferPtr); } vertexAttributeBufferPtrs = list.ToArray(); } // 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, vertexAttributeBufferPtrs); vertexArrayObject.Initialize(program); // sets fields. this.Program = program; this.vertexAttributeBufferPtrs = vertexAttributeBufferPtrs; this.indexBufferPtr = indexBufferPtr; this.vertexArrayObject = vertexArrayObject; }
private void ColorCodedRender(RenderEventArgs arg, IndexBufferPtr temporaryIndexBufferPtr = null) { UpdatePolygonMode(arg.PickingGeometryType); ShaderProgram program = this.Program; // 绑定shader program.Bind(); program.SetUniform("pickingBaseId", temporaryIndexBufferPtr == null ? (int)this.PickingBaseId : 0); UniformMat4 uniformmMVP4Picking = this.uniformmMVP4Picking; { mat4 projection = arg.Camera.GetProjectionMatrix(); mat4 view = arg.Camera.GetViewMatrix(); mat4 model = this.GetModelMatrix(); uniformmMVP4Picking.Value = projection * view * model; } uniformmMVP4Picking.SetUniform(program); PickingSwitchesOn(); GLSwitch primitiveRestartIndexSwitch = null; var oneIndexBufferPtr = temporaryIndexBufferPtr as OneIndexBufferPtr; if (oneIndexBufferPtr != null) { primitiveRestartIndexSwitch = new PrimitiveRestartSwitch(oneIndexBufferPtr); primitiveRestartIndexSwitch.On(); } { this.vertexArrayObject.Render(arg, program, temporaryIndexBufferPtr); } if (oneIndexBufferPtr != null) { primitiveRestartIndexSwitch.Off(); } PickingSwitchesOff(); //if (mvpUpdated) { uniformmMVP4Picking.ResetUniform(program); } // 解绑shader program.Unbind(); }
private void NoPrimitiveRestartIndex(List <RecognizedPrimitiveIndex> lastIndexIdList) { PrimitiveRestartSwitch glSwitch = GetPrimitiveRestartSwitch(); if (glSwitch != null) { foreach (var lastIndexId in lastIndexIdList) { foreach (var indexId in lastIndexId.IndexIdList) { if (indexId == glSwitch.RestartIndex) { throw new Exception(); } } } } }
/// <summary> /// /// </summary> protected override void DoInitialize() { // init shader program var program = new ShaderProgram(); var shaders = (from item in shaderCodes select item.CreateShader()).ToArray(); program.Create(shaders); this.Program = program; foreach (var item in shaders) { item.Delete(); } // init property buffer objects var propertyBufferPtrs = new PropertyBufferPtr[propertyNameMap.Count()]; int index = 0; foreach (var item in propertyNameMap) { PropertyBufferPtr bufferPtr = this.bufferable.GetProperty( item.NameInIBufferable, item.VarNameInShader); if (bufferPtr == null) { throw new Exception(string.Format("[{0}] returns null buffer pointer!", this.bufferable)); } propertyBufferPtrs[index++] = bufferPtr; } this.propertyBufferPtrs = propertyBufferPtrs; this.indexBufferPtr = this.bufferable.GetIndex(); // 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 = this.indexBufferPtr as OneIndexBufferPtr; if (ptr != null) { GLSwitch glSwitch = new PrimitiveRestartSwitch(ptr); this.switchList.Add(glSwitch); } }
protected override void DoInitialize() { // init shader program ShaderProgram program = new ShaderProgram(); var shaders = (from item in shaderCodes select item.CreateShader()).ToArray(); program.Create(shaders); this.shaderProgram = program; foreach (var item in shaders) { item.Delete(); } // init property buffer objects var propertyBufferPtrs = new PropertyBufferPtr[propertyNameMap.Count()]; int index = 0; foreach (var item in propertyNameMap) { PropertyBufferPtr bufferPtr = this.bufferable.GetProperty( item.nameInIBufferable, item.VarNameInShader); if (bufferPtr == null) { throw new Exception(); } propertyBufferPtrs[index++] = bufferPtr; } this.propertyBufferPtrs = propertyBufferPtrs; this.indexBufferPtr = this.bufferable.GetIndex(); var ptr = this.indexBufferPtr as OneIndexBufferPtr; if (ptr != null) { var glSwitch = new PrimitiveRestartSwitch(ptr); this.switchList.Add(glSwitch); } }
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> /// /// </summary> protected override void DoInitialize() { // init shader program. ShaderProgram program = this.shaderCodes.CreateProgram(); // init property buffer objects. 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 == positionNameInIBufferable) { positionBufferPtr = new VertexAttributeBufferPtr( "in_Position",// in_Postion same with in the PickingShader.vert shader bufferPtr.BufferId, bufferPtr.Config, bufferPtr.Length, bufferPtr.ByteLength); } list.Add(bufferPtr); } vertexAttributeBufferPtrs = list.ToArray(); } // init index buffer OneIndexBufferPtr indexBufferPtr; { using (var buffer = new OneIndexBuffer(IndexElementType.UInt, DrawMode.Points, // any mode is OK as we'll update it later in other place. BufferUsage.DynamicDraw)) { buffer.Create(positionBufferPtr.ByteLength / (positionBufferPtr.DataSize * positionBufferPtr.DataTypeByteLength)); indexBufferPtr = buffer.GetBufferPtr() as OneIndexBufferPtr; } this.maxElementCount = indexBufferPtr.ElementCount; indexBufferPtr.ElementCount = 0;// 高亮0个图元 // RULE: Renderer takes uint.MaxValue, ushort.MaxValue or byte.MaxValue as PrimitiveRestartIndex. So take care this rule when designing a model's index buffer. GLSwitch glSwitch = new PrimitiveRestartSwitch(indexBufferPtr); this.switchList.Add(glSwitch); } // init VAO. var vertexArrayObject = new VertexArrayObject(indexBufferPtr, vertexAttributeBufferPtrs); vertexArrayObject.Initialize(program); // sets fields. this.Program = program; this.vertexAttributeBufferPtrs = vertexAttributeBufferPtrs; this.indexBufferPtr = indexBufferPtr; this.vertexArrayObject = vertexArrayObject; this.positionBufferPtr = positionBufferPtr; }