public void RenderBeforeChildrenForLegacyPicking(LegacyPickEventArgs arg) { this.PushProjectionViewMatrix(arg); this.PushModelMatrix(); DoRender(); this.PopModelMatrix(); this.PopProjectionViewMatrix(); }
/// <summary> /// Push and calculate projection+view matrix in legacy OpenGL for picking. /// </summary> /// <param name="renderer"></param> /// <param name="arg"></param> public static void PushProjectionViewMatrix(this RendererBase renderer, LegacyPickEventArgs arg) { GL.Instance.MatrixMode(GL.GL_PROJECTION); GL.Instance.PushMatrix(); mat4 projection = arg.pickMatrix * arg.scene.Camera.GetProjectionMatrix(); mat4 view = arg.scene.Camera.GetViewMatrix(); GL.Instance.LoadIdentity(); GL.Instance.MultMatrixf((projection * view).ToArray()); }
private void RenderForPicking(RendererBase sceneElement, LegacyPickEventArgs arg, ref uint currentName) { var pickable = sceneElement as ILegacyPickable; if (pickable != null) { mat4 parentCascadeModelMatrix = arg.ModelMatrixStack.Peek(); sceneElement.cascadeModelMatrix = sceneElement.GetModelMatrix(parentCascadeModelMatrix); ThreeFlags flags = pickable.EnableLegacyPicking; if ((flags & ThreeFlags.BeforeChildren) == ThreeFlags.BeforeChildren) { // Load and map the name. GL.Instance.LoadName(currentName); arg.hitMap[currentName] = sceneElement; pickable.RenderBeforeChildrenForLegacyPicking(arg); // Increment the name. currentName++; } if ((flags & ThreeFlags.Children) == ThreeFlags.Children) { arg.ModelMatrixStack.Push(sceneElement.cascadeModelMatrix); foreach (var item in sceneElement.Children) { this.RenderForPicking(item, arg, ref currentName); } arg.ModelMatrixStack.Pop(); } //if ((flags & ThreeFlags.AfterChildren) == ThreeFlags.AfterChildren) //{ // // Load and map the name. // GL.Instance.LoadName(currentName); // arg.hitMap[currentName] = sceneElement; // pickable.RenderAfterChildrenForLegacyPicking(arg); // // Increment the name. // currentName++; //} } }
public void RenderBeforeChildrenForLegacyPicking(LegacyPickEventArgs arg) { throw new NotImplementedException(); }
/// <summary> /// Pick <see cref="RendererBase"/>s at specified positon. /// </summary> /// <param name="x">Left Down is (0, 0)</param> /// <param name="y">Left Down is (0, 0)</param> /// <param name="deltaX"></param> /// <param name="deltaY"></param> /// <param name="selectBufferLength"></param> /// <returns></returns> public List <HitTarget> Pick(int x, int y, int deltaX = 1, int deltaY = 1, int selectBufferLength = 512) { // Create a select buffer. var selectBuffer = new uint[selectBufferLength]; GL.Instance.SelectBuffer(selectBuffer.Length, selectBuffer); // Enter select mode. GL.Instance.RenderMode(GL.GL_SELECT); // Initialise the names, and add the first name. GL.Instance.InitNames(); GL.Instance.PushName(0); var viewport = new int[4]; GL.Instance.GetIntegerv((uint)GetTarget.Viewport, viewport); mat4 pickMatrix = glm.pickMatrix(new ivec2(x, y), new ivec2(deltaX, deltaY), new ivec4(viewport[0], viewport[1], viewport[2], viewport[3])); var arg = new LegacyPickEventArgs(pickMatrix, this, x, y); uint currentName = 1; this.RenderForPicking(this.RootElement, arg, ref currentName); // Flush commands. GL.Instance.Flush(); List <HitTarget> pickedRenderer = null; // End selection. int hits = GL.Instance.RenderMode(GL.GL_RENDER); if (hits < 0)// select buffer is not long enough. { pickedRenderer = this.Pick(x, y, deltaX, deltaY, selectBufferLength * 2); } else { // Create result set. pickedRenderer = new List <HitTarget>(); uint posinarray = 0; // Go through each name. for (int hit = 0; hit < hits; hit++) { uint nameCount = selectBuffer[posinarray++]; uint zNear = selectBuffer[posinarray++]; uint zFar = selectBuffer[posinarray++]; if (nameCount == 0) { continue; } // Add each hit element to the result set to the array. for (int i = 0; i < nameCount; i++) { uint hitName = selectBuffer[posinarray++]; pickedRenderer.Add(new HitTarget(arg.hitMap[hitName], zNear, zFar)); } } } // Return the result set. return(pickedRenderer); }