private void RenderGroupId(Group group) { renderer.Requested.Material = idMaterial; renderer.Requested.Program = renderer.Requested.Material.Program; renderer.Requested.MeshMode = MeshMode.PolygonFill; renderer.UpdateCamera(); if ( RenderStack.Graphics.Configuration.canUseInstancing && (RenderStack.Graphics.Configuration.useGl1 == false) /* && RenderStack.Graphics.Configuration.canUseBaseVertex */ ) { // Instanced code path foreach (var kvp in group.AllInstances.Collection) { var tuple = kvp.Key; var models2 = kvp.Value; renderer.Requested.Mesh = tuple.Item1; var indexBufferRange = renderer.Requested.Mesh.IndexBufferRange(MeshMode.PolygonFill); uint count = indexBufferRange.Count; uint powerOfTwo = NextPowerOfTwo(count); uint mask = powerOfTwo - 1; renderer.RenderInstancedPrepare(); int i = 0; foreach (var model in models2) { renderer.Models.Floats("model_to_world_matrix").SetI( i, model.Frame.LocalToWorld.Matrix ); uint currentBits = idOffset & mask; if (currentBits != 0) { uint add = powerOfTwo - currentBits; idOffset += add; } Vector3 v = Vector3.Vector3FromUint(idOffset); renderer.Models.Floats("id_offset_vec3").SetI(i, v.X, v.Y, v.Z); i++; if (i > 49) { renderer.Models.Sync(); renderer.RenderCurrent(i); i = 0; } if ( (indexBufferRange != null) && (indexBufferRange.Count > 0) ) { IDListEntry entry = new IDListEntry(idOffset, model); group.IdList.Add(entry); idOffset += indexBufferRange.Count; } } if (i > 0) { renderer.Models.Sync(); if (i > 1) { renderer.RenderCurrent(i); } else { renderer.RenderCurrent(); } } } } else { // Non-instanced code path foreach (var model in group.Models) { renderer.Requested.Mesh = model.Batch.Mesh; renderer.SetFrame(model.Frame); var indexBufferRange = renderer.Requested.Mesh.IndexBufferRange(MeshMode.PolygonFill); if (RenderStack.Graphics.Configuration.useIntegerPolygonIDs) { renderer.Models.UInts("id_offset_uint").SetI(0, idOffset); } else { uint count = indexBufferRange.Count; uint powerOfTwo = NextPowerOfTwo(count); uint mask = powerOfTwo - 1; uint currentBits = idOffset & mask; if (currentBits != 0) { uint add = powerOfTwo - currentBits; idOffset += add; } Vector3 v = Vector3.Vector3FromUint(idOffset); renderer.Models.Floats("id_offset_vec3").SetI(0, v.X, v.Y, v.Z); } renderer.Models.Sync(); renderer.RenderCurrent(); if ( (indexBufferRange != null) && (indexBufferRange.Count > 0) ) { IDListEntry entry = new IDListEntry(idOffset, model); #if DEBUG if (group.AlreadyHas(entry)) { System.Diagnostics.Debugger.Break(); } #endif group.IdList.Add(entry); idOffset += indexBufferRange.Count; } } } { IDListEntry entry = new IDListEntry(idOffset, null); #if DEBUG if (group.AlreadyHas(entry)) { System.Diagnostics.Debugger.Break(); } #endif group.IdList.Add(entry); } idGroupsRendered.Add(group); }
public void ProcessIdBuffer(IDRenderer.HoverInfo hover, int px, int py) { ResetHover(); uint compareId = 0xfffffeu; if(hover.Id == compareId) { HoverModel = null; HoverGroup.Clear(); return; } try { Vector3 positionInWorld = sceneManager.Camera.WorldToClip.InverseMatrix.UnProject( (float)px, (float)py, hover.Depth, renderer.Requested.Viewport.X, renderer.Requested.Viewport.Y, renderer.Requested.Viewport.Width, renderer.Requested.Viewport.Height ); HoverPosition = positionInWorld; if(userInterfaceManager.AutoFocus) { Camera camera = sceneManager.Camera; StereoParameters stereo = camera.Projection.StereoParameters; float distance = camera.Frame.LocalToWorld.Matrix.GetColumn(3).Xyz.Distance(positionInWorld); stereo.ViewportCenter.Z = distance; } HoverDepth = hover.Depth; uint modelPolygonId = 0; uint manipulatorPolygonId = 0; IDListEntry compareKey = new IDListEntry(hover.Id); Model renderModel = null; if(manipulatorManager != null) { manipulatorManager.ManipulatorModel = manipulatorManager.ManipulatorGroup.IdTest(compareKey, out manipulatorPolygonId); if(manipulatorManager.ManipulatorModel == null) { foreach(var group in hover.Groups) { renderModel = group.IdTest(compareKey, out modelPolygonId); if(renderModel != null) { break; } } } } UpdateHover(renderModel, modelPolygonId); } catch(System.Exception) { return; } }