/// <summary> /// Draws all items contained in a given render queue /// </summary> /// <param name="queue">render queue</param> /// <param name="x1">x1-position</param> /// <param name="y1">y1-position</param> /// <param name="z1">z1-position</param> /// <param name="x2">x2-position</param> /// <param name="y2">y2-position</param> /// <param name="z2">z2-position</param> /// <param name="color">base color for items not containing individual colors</param> /// <remarks><para>The render queue must contain only keys for already cached items!</para> /// <para>The color parameter serves as a global color definition. It may be overwritten /// by individual color specifications of the queue items.</para> /// <para>Use this function to draw the render queue in world coords. The position parameters mark the upper left /// and lower right corner of the quads to contain the render queue content.</para> /// </remarks> public void Draw(ILRenderQueue queue, float x1, float y1, float z1, float x2, float y2, float z2, Color color) { float x, y, xm, ym; xm = (x2 - x1) / (queue.Size.Width); ym = (y2 - y1) / (queue.Size.Height); x = 0.5f; y = 0.5f; int lineHeight = 0; m_textureManager.Reset(); GLColor3(color); foreach (ILRenderQueueItem item in queue) { // special symbols & control sequences switch (item.Key) { case "\r": x = 0.5f; break; case "\n": x = 0.5f; y += lineHeight; lineHeight = 0; break; default: //since textures (may) lay on different sheets in GL memory, // we cannot switch them in between Begin() and End(), // we must start a new Begin with each Quad :( // possible workaround: If only one sheet is used, draw all // quads at once. ILTextureData textData = m_textureManager.GetTextureItem(item.Key, true); if (item.Color != Color.Empty) { GLColor3(item.Color); } else { GLColor3(color); } GL.Begin(BeginMode.Quads); RectangleF rectF = textData.TextureRectangle; GL.TexCoord2(rectF.Left, rectF.Bottom); GL.Vertex3(x * xm + x1, (y + textData.Height + item.Offset.Y - 1) * ym + y1, z1); // ul GL.TexCoord2(rectF.Left, rectF.Top); GL.Vertex3(x * xm + x1, (y + item.Offset.Y) * ym + y1, z1); // bl x += textData.Width - 1; GL.TexCoord2(rectF.Right, rectF.Top); GL.Vertex3(x * xm + x1, (y + item.Offset.Y) * ym + y1, z1); // br GL.TexCoord2(rectF.Right, rectF.Bottom); GL.Vertex3(x * xm + x1, (y + textData.Height + item.Offset.Y - 1) * ym + y1, z1); // tr if (textData.Height > lineHeight) { lineHeight = textData.Height; } GL.End(); #if BOUNDINGBOXES_ITEM //// define DEBUG symbol to draw bounding box around each item (debug feature) // todo: modify to draw in world coords if needed!! //GL.Color3(Color.Red); //GL.Begin(BeginMode.LineLoop); // w-= textData.Width; // GL.Vertex2(w,h + textData.Height); // ul // GL.Vertex2(w,h); // bl // w += textData.Width; // GL.Vertex2(w,h); // br // GL.Vertex2(w,h + textData.Height); // tr //GL.End(); #endif break; } } #if BOUNDINGBOXES //// define debugsymbol "BOUNDINGBOXES", to draw bounding box around whole expression // todo: modify to draw in world coords if needed!! //GL.Disable(EnableCap.Texture2D); //GL.Color3(Color.Red); //GL.LineWidth(1); //GL.Begin(BeginMode.LineLoop); // GL.Vertex2(0,0); // ul // GL.Vertex2(0,queue.Size.Height); // bl // GL.Vertex2(queue.Size.Width,queue.Size.Height); // br // GL.Vertex2(queue.Size.Width,0); // tr //GL.End(); //GL.Enable(EnableCap.Texture2D); #endif }
/// <summary> /// Draws all items contained in a given render queue /// </summary> /// <param name="queue">render queue</param> /// <param name="location">starting point</param> /// <param name="orientation">orientation for the whole queues output</param> /// <param name="color">starting color</param> /// <remarks><para>The render queue must contain only keys for already cached items!</para> /// <para>The color parameter serves as a global color definition. It may be overridem /// by individual color specifications of the queue items.</para> /// </remarks> public void Draw(ILRenderQueue queue, System.Drawing.Point location, TextOrientation orientation, Color color) { float w, h; if (String.IsNullOrEmpty(queue.Expression.Trim())) { return; } w = queue.Size.Width; h = queue.Size.Height; // compensate for unexact glx.MeasureString results... (to be fixed!) //w *= 1.09f; //h *= 1.09f; if (orientation == TextOrientation.Vertical) { GL.Rotate(90, 0, 0, 1); } GL.GetFloat(GetPName.ModelviewMatrix, m_curPosition); m_curPosition[12] = location.X; m_curPosition[13] = location.Y; GL.LoadMatrix(m_curPosition); m_textureManager.Reset(); w = 0.5f; h = 0.5f; int lineHeight = 0; float drawPosY; float xMin = float.MaxValue; // relative to label (include rotation) float yMin = float.MaxValue; float xMax = float.MinValue; float yMax = float.MinValue; GLColor3(color); foreach (ILRenderQueueItem item in queue) { // special symbols & control sequences switch (item.Key) { case "\r": w = 0.5f; break; case "\n": w = 0.5f; h += lineHeight; lineHeight = 0; break; default: //since textures (may) lay on different sheets in GL memory, // we cannot switch them in between Begin() and End(), // we must start a new Begin with each Quad :( // possible workaround: If only one sheet is used, draw all // quads at once. ILTextureData textData = m_textureManager.GetTextureItem(item.Key, true); if (item.Color != Color.Empty) { GLColor3(item.Color); } else { GLColor3(color); } drawPosY = h + item.Offset.Y; GL.Begin(BeginMode.Quads); RectangleF rectF = textData.TextureRectangle; GL.TexCoord2(rectF.Left, rectF.Bottom); GL.Vertex2(w, drawPosY + textData.Height - 1); // bl GL.TexCoord2(rectF.Left, rectF.Top); GL.Vertex2(w, drawPosY); // tl if (xMin > w) { xMin = w; } if (yMin > drawPosY) { yMin = drawPosY; } w += textData.Width - 1; GL.TexCoord2(rectF.Right, rectF.Top); GL.Vertex2(w, drawPosY); // tr GL.TexCoord2(rectF.Right, rectF.Bottom); GL.Vertex2(w, drawPosY + textData.Height - 1); // br if (textData.Height > lineHeight) { lineHeight = textData.Height; } GL.End(); if (xMax < w) { xMax = w; } if (yMax < drawPosY + textData.Height - 1) { yMax = drawPosY + textData.Height - 1; } #if BOUNDINGBOXES_ITEM // define DEBUG symbol to draw bounding box around each item (debug feature) GL.Color3(Color.Red); GL.Begin(BeginMode.LineLoop); w -= textData.Width; GL.Vertex2(w, h + textData.Height); // ul GL.Vertex2(w, h); // bl w += textData.Width; GL.Vertex2(w, h); // br GL.Vertex2(w, h + textData.Height); // tr GL.End(); #endif break; } } #if BOUNDINGBOXES // define debugsymbol "BOUNDINGBOXES", to draw bounding box around whole expression GL.Disable(EnableCap.Texture2D); GL.Color3(Color.Red); GL.LineWidth(1); GL.Disable(EnableCap.LineStipple); GL.Begin(BeginMode.LineLoop); GL.Vertex2(0, 0); // ul GL.Vertex2(0, queue.Size.Height); // bl GL.Vertex2(queue.Size.Width, queue.Size.Height); // br GL.Vertex2(queue.Size.Width, 0); // tr GL.End(); GL.Enable(EnableCap.Texture2D); #endif // check outer limits if (orientation == TextOrientation.Horizontal) { if (m_xMin > location.X + xMin) { m_xMin = location.X + xMin; } if (m_xMax < location.X + xMax) { m_xMax = location.X + xMax; } if (m_yMin > location.Y + yMin) { m_yMin = location.Y + yMin; } if (m_yMax < location.Y + yMax) { m_yMax = location.Y + yMax; } } else if (orientation == TextOrientation.Vertical) { if (m_xMin > location.X - yMax) { m_xMin = location.X - yMax; } if (m_xMax < location.X - yMin) { m_xMax = location.X - yMin; } if (m_yMin > location.Y - xMin) { m_yMin = location.Y - xMin; } if (m_yMax < location.Y - xMax) { m_yMax = location.Y - xMax; } } }