internal int FocusIdxTabRequestNext; // " internal ImGuiWindow(string name) { DC = new ImGuiDrawContext(); IDStack = new ImVector <uint>(); StateStorage = new ImGuiStorage(); MenuColumns = new ImGuiSimpleColumns(); DrawList = new ImDrawList(); Name = name; ID = ImGui.Hash(0, name); IDStack.push_back(ID); MoveID = GetID("#MOVE"); Flags = 0; PosFloat = Pos = new ImVec2(0.0f, 0.0f); Size = SizeFull = new ImVec2(0.0f, 0.0f); SizeContents = SizeContentsExplicit = new ImVec2(0.0f, 0.0f); WindowPadding = new ImVec2(0.0f, 0.0f); Scroll = new ImVec2(0.0f, 0.0f); ScrollTarget = new ImVec2(float.MaxValue, float.MaxValue); ScrollTargetCenterRatio = new ImVec2(0.5f, 0.5f); ScrollbarX = ScrollbarY = false; ScrollbarSizes = new ImVec2(0.0f, 0.0f); BorderSize = 0.0f; Active = WasActive = false; Accessed = false; Collapsed = false; SkipItems = false; BeginCount = 0; PopupID = 0; AutoFitFramesX = AutoFitFramesY = -1; AutoFitOnlyGrows = false; AutoPosLastDirection = -1; HiddenFrames = 0; SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = (int)(ImGuiSetCond.ImGuiSetCond_Always | ImGuiSetCond.ImGuiSetCond_Once | ImGuiSetCond.ImGuiSetCond_FirstUseEver | ImGuiSetCond.ImGuiSetCond_Appearing); SetWindowPosCenterWanted = false; LastFrameActive = -1; ItemWidthDefault = 0.0f; FontWindowScale = 1.0f; RootWindow = null; RootNonPopupWindow = null; FocusIdxAllCounter = FocusIdxTabCounter = -1; FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = int.MaxValue; FocusIdxAllRequestNext = FocusIdxTabRequestNext = int.MaxValue; }
public static void RenderDrawData(ImDrawData drawData, int displayW, int displayH) { // We are using the OpenGL fixed pipeline to make the example code simpler to read! // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. int lastTexture; GL.GetIntegerv(GL.Enum.GL_TEXTURE_BINDING_2D, out lastTexture); Int4 lastViewport; GL.GetIntegerv4(GL.Enum.GL_VIEWPORT, out lastViewport); Int4 lastScissorBox; GL.GetIntegerv4(GL.Enum.GL_SCISSOR_BOX, out lastScissorBox); GL.PushAttrib(GL.Enum.GL_ENABLE_BIT | GL.Enum.GL_COLOR_BUFFER_BIT | GL.Enum.GL_TRANSFORM_BIT); GL.Enable(GL.Enum.GL_BLEND); GL.BlendFunc(GL.Enum.GL_SRC_ALPHA, GL.Enum.GL_ONE_MINUS_SRC_ALPHA); GL.Disable(GL.Enum.GL_CULL_FACE); GL.Disable(GL.Enum.GL_DEPTH_TEST); GL.Enable(GL.Enum.GL_SCISSOR_TEST); GL.EnableClientState(GL.Enum.GL_VERTEX_ARRAY); GL.EnableClientState(GL.Enum.GL_TEXTURE_COORD_ARRAY); GL.EnableClientState(GL.Enum.GL_COLOR_ARRAY); GL.Enable(GL.Enum.GL_TEXTURE_2D); GL.UseProgram(0); // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) ImGuiIO io = ImGui.GetIO(); ImGui.ScaleClipRects(drawData, io.DisplayFramebufferScale); // Setup orthographic projection matrix GL.Viewport(0, 0, displayW, displayH); GL.MatrixMode(GL.Enum.GL_PROJECTION); GL.PushMatrix(); GL.LoadIdentity(); GL.Ortho( 0.0f, io.DisplaySize.X / io.DisplayFramebufferScale.X, io.DisplaySize.Y / io.DisplayFramebufferScale.Y, 0.0f, -1.0f, 1.0f ); GL.MatrixMode(GL.Enum.GL_MODELVIEW); GL.PushMatrix(); GL.LoadIdentity(); // Render command lists for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawList cmdList = drawData[n]; ImVector <ImDrawVert> vtxBuffer = cmdList.VtxBuffer; ImVector <ushort> idxBuffer = cmdList.IdxBuffer; GL.VertexPointer(2, GL.Enum.GL_FLOAT, ImDrawVert.Size, new IntPtr((long)vtxBuffer.Data + ImDrawVert.PosOffset)); GL.TexCoordPointer(2, GL.Enum.GL_FLOAT, ImDrawVert.Size, new IntPtr((long)vtxBuffer.Data + ImDrawVert.UVOffset)); GL.ColorPointer(4, GL.Enum.GL_UNSIGNED_BYTE, ImDrawVert.Size, new IntPtr((long)vtxBuffer.Data + ImDrawVert.ColOffset)); long idxBufferOffset = 0; for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++) { ImDrawCmd pcmd = cmdList.CmdBuffer[cmdi]; if (pcmd.UserCallback != IntPtr.Zero) { pcmd.InvokeUserCallback(ref cmdList, ref pcmd); } else { GL.BindTexture(GL.Enum.GL_TEXTURE_2D, (int)pcmd.TextureId); GL.Scissor( (int)pcmd.ClipRect.X, (int)(io.DisplaySize.Y - pcmd.ClipRect.W), (int)(pcmd.ClipRect.Z - pcmd.ClipRect.X), (int)(pcmd.ClipRect.W - pcmd.ClipRect.Y) ); GL.DrawElements(GL.Enum.GL_TRIANGLES, (int)pcmd.ElemCount, GL.Enum.GL_UNSIGNED_SHORT, new IntPtr((long)idxBuffer.Data + idxBufferOffset)); } idxBufferOffset += pcmd.ElemCount * 2 /*sizeof(ushort)*/; } } // Restore modified state GL.DisableClientState(GL.Enum.GL_COLOR_ARRAY); GL.DisableClientState(GL.Enum.GL_TEXTURE_COORD_ARRAY); GL.DisableClientState(GL.Enum.GL_VERTEX_ARRAY); GL.BindTexture(GL.Enum.GL_TEXTURE_2D, lastTexture); GL.MatrixMode(GL.Enum.GL_MODELVIEW); GL.PopMatrix(); GL.MatrixMode(GL.Enum.GL_PROJECTION); GL.PopMatrix(); GL.PopAttrib(); GL.Viewport(lastViewport.X, lastViewport.Y, lastViewport.Z, lastViewport.W); GL.Scissor(lastScissorBox.X, lastScissorBox.Y, lastScissorBox.Z, lastScissorBox.W); }
internal ImRect RenderText(float size, ImVec2 pos, uint col, ImVec4 clip_rect, char[] text, int text_begin, int text_end, ImDrawList draw_list, float wrap_width = 0.0f, bool cpu_fine_clip = false) { if (text_end == -1) { text_end = text.Length; // FIXME-OPT: Need to avoid this. } // Align to be pixel perfect pos.x = (int)pos.x + DisplayOffset.x; pos.y = (int)pos.y + DisplayOffset.y; float x = pos.x; float y = pos.y; if (y > clip_rect.w) { return(new ImRect()); } float scale = size / FontSize; float line_height = FontSize * scale; bool word_wrap_enabled = (wrap_width > 0.0f); int word_wrap_eol = -1; int vtx_write = draw_list._VtxWritePtr; int idx_write = draw_list._IdxWritePtr; uint vtx_current_idx = draw_list._VtxCurrentIdx; int s = text_begin; if (!word_wrap_enabled && y + line_height < clip_rect.y) { while (s < text_end && text[s] != '\n') // Fast-forward to next line { s++; } } while (s < text_end) { if (word_wrap_enabled) { // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. if (word_wrap_eol != -1) { word_wrap_eol = CalcWordWrapPositionA(scale, text, s, text_end, wrap_width - (x - pos.x)); if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. { word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below } } if (s >= word_wrap_eol) { x = pos.x; y += line_height; word_wrap_eol = -1; // Wrapping skips upcoming blanks while (s < text_end) { char wc = text[s]; if (char.IsSeparator(wc)) { s++; } else if (wc == '\n') { s++; break; } else { break; } } continue; } } // Decode and advance source char c = text[s++]; //if (c< 0x80) //{ // s += 1; //} //else //{ // s += ImTextCharFromUtf8(&c, s, text_end); // if (c == 0) // break; //} if (c < 32) { if (c == '\n') { x = pos.x; y += line_height; if (y > clip_rect.w) { break; } if (!word_wrap_enabled && y + line_height < clip_rect.y) { while (s < text_end && text[s] != '\n') // Fast-forward to next line { s++; } } continue; } if (c == '\r') { continue; } } float char_width = 0.0f; Glyph glyph; if (FindGlyph(c, out glyph)) { char_width = glyph.XAdvance * scale; // Arbitrarily assume that both space and tabs are empty glyphs as an optimization if (c != ' ' && c != '\t') { // We don't do a second finer clipping test on the Y axis as we've already skipped anything before clip_rect.y and exit once we pass clip_rect.w float y1 = (float)(y + glyph.Y0 * scale); float y2 = (float)(y + glyph.Y1 * scale); float x1 = (float)(x + glyph.X0 * scale); float x2 = (float)(x + glyph.X1 * scale); if (x1 <= clip_rect.z && x2 >= clip_rect.x) { // Render a character float u1 = glyph.U0; float v1 = glyph.V0; float u2 = glyph.U1; float v2 = glyph.V1; // CPU side clipping used to fit text in their frame when the frame is too small. Only does clipping for axis aligned quads. if (cpu_fine_clip) { if (x1 < clip_rect.x) { u1 = u1 + (1.0f - (x2 - clip_rect.x) / (x2 - x1)) * (u2 - u1); x1 = clip_rect.x; } if (y1 < clip_rect.y) { v1 = v1 + (1.0f - (y2 - clip_rect.y) / (y2 - y1)) * (v2 - v1); y1 = clip_rect.y; } if (x2 > clip_rect.z) { u2 = u1 + ((clip_rect.z - x1) / (x2 - x1)) * (u2 - u1); x2 = clip_rect.z; } if (y2 > clip_rect.w) { v2 = v1 + ((clip_rect.w - y1) / (y2 - y1)) * (v2 - v1); y2 = clip_rect.w; } if (y1 >= y2) { x += char_width; continue; } } // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug build. // Inlined here: { draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx); draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx + 1); draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx + 2); draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx); draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx + 2); draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx + 3); draw_list.VtxBuffer[vtx_write++] = new ImDrawVert() { pos = new ImVec2(x1, y1), uv = new ImVec2(u1, v1), col = col }; draw_list.VtxBuffer[vtx_write++] = new ImDrawVert() { pos = new ImVec2(x2, y1), uv = new ImVec2(u2, v1), col = col }; draw_list.VtxBuffer[vtx_write++] = new ImDrawVert() { pos = new ImVec2(x2, y2), uv = new ImVec2(u2, v2), col = col }; draw_list.VtxBuffer[vtx_write++] = new ImDrawVert() { pos = new ImVec2(x1, y2), uv = new ImVec2(u1, v2), col = col }; vtx_current_idx += 4; } } } } x += char_width; } draw_list._VtxWritePtr = vtx_write; draw_list._VtxCurrentIdx = vtx_current_idx; draw_list._IdxWritePtr = idx_write; return(new ImRect(pos, new ImVec2(x, y + line_height))); }
public void Dispose() { DrawList.Dispose(); DrawList = null; }
public void RenderDrawData(ImDrawData drawData) { GraphicsDevice device = Game.GraphicsDevice; // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. Viewport lastViewport = device.Viewport; Rectangle lastScissorBox = device.ScissorRectangle; device.BlendFactor = Color.White; device.BlendState = BlendState.NonPremultiplied; device.RasterizerState = RasterizerState; device.DepthStencilState = DepthStencilState.DepthRead; // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) ImGuiIO io = ImGui.GetIO(); ImGui.ScaleClipRects(drawData, io.DisplayFramebufferScale); // Setup projection device.Viewport = new Viewport(0, 0, device.PresentationParameters.BackBufferWidth, device.PresentationParameters.BackBufferHeight); if (Effect == null) { Effect = new BasicEffect(device); } Effect effect = Effect; SetupEffect(this, effect); // Render command lists for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawList cmdList = drawData[n]; ImVector <ImDrawVertXNA> vtxBuffer; unsafe { vtxBuffer = new ImVector <ImDrawVertXNA>(cmdList.VtxBuffer.Native); } ImDrawVertXNA[] vtxArray = new ImDrawVertXNA[vtxBuffer.Size]; for (int i = 0; i < vtxBuffer.Size; i++) { vtxArray[i] = vtxBuffer[i]; } ImVector <short> idxBuffer; unsafe { idxBuffer = new ImVector <short>(cmdList.IdxBuffer.Native); } /* * short[] idxArray = new short[idxBuffer.Size]; * for (int i = 0; i < idxBuffer.Size; i++) * idxArray[i] = idxBuffer[i]; */ uint offset = 0; for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++) { ImDrawCmd pcmd = cmdList.CmdBuffer[cmdi]; if (pcmd.UserCallback != IntPtr.Zero) { pcmd.InvokeUserCallback(ref cmdList, ref pcmd); } else { // Instead of uploading the complete idxBuffer again and again, just upload what's required. short[] idxArray = new short[pcmd.ElemCount]; for (int i = 0; i < pcmd.ElemCount; i++) { idxArray[i] = idxBuffer[(int)offset + i]; } SetEffectTexture(this, effect, GetTexture((int)pcmd.TextureId)); device.ScissorRectangle = new Rectangle( (int)pcmd.ClipRect.X, (int)pcmd.ClipRect.Y, (int)(pcmd.ClipRect.Z - pcmd.ClipRect.X), (int)(pcmd.ClipRect.W - pcmd.ClipRect.Y) ); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); device.DrawUserIndexedPrimitives( PrimitiveType.TriangleList, vtxArray, 0, vtxBuffer.Size, idxArray, 0, (int)pcmd.ElemCount / 3, ImDrawVertXNA._VertexDeclaration ); } } offset += pcmd.ElemCount; } } // Restore modified state device.Viewport = lastViewport; device.ScissorRectangle = lastScissorBox; }