Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Drawing/Platform/OpenGL/ILOGLRenderer.cs @ 10903

Last change on this file since 10903 was 9102, checked in by gkronber, 12 years ago

#1967: ILNumerics source for experimentation

File size: 15.4 KB
Line 
1///
2///    This file is part of ILNumerics Community Edition.
3///
4///    ILNumerics Community Edition - high performance computing for applications.
5///    Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
6///
7///    ILNumerics Community Edition is free software: you can redistribute it and/or modify
8///    it under the terms of the GNU General Public License version 3 as published by
9///    the Free Software Foundation.
10///
11///    ILNumerics Community Edition is distributed in the hope that it will be useful,
12///    but WITHOUT ANY WARRANTY; without even the implied warranty of
13///    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14///    GNU General Public License for more details.
15///
16///    You should have received a copy of the GNU General Public License
17///    along with ILNumerics Community Edition. See the file License.txt in the root
18///    of your distribution package. If not, see <http://www.gnu.org/licenses/>.
19///
20///    In addition this software uses the following components and/or licenses:
21///
22///    =================================================================================
23///    The Open Toolkit Library License
24///   
25///    Copyright (c) 2006 - 2009 the Open Toolkit library.
26///   
27///    Permission is hereby granted, free of charge, to any person obtaining a copy
28///    of this software and associated documentation files (the "Software"), to deal
29///    in the Software without restriction, including without limitation the rights to
30///    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
31///    the Software, and to permit persons to whom the Software is furnished to do
32///    so, subject to the following conditions:
33///
34///    The above copyright notice and this permission notice shall be included in all
35///    copies or substantial portions of the Software.
36///
37///    =================================================================================
38///   
39
40using System;
41using System.Text;
42using System.Drawing; 
43using System.Collections.Generic;
44using ILNumerics.Drawing.Interfaces;
45using OpenTK;
46using OpenTK.Graphics;
47using OpenTK.Graphics.OpenGL;
48using OpenTK.Graphics.OpenGL.Enums;
49using ILNumerics.Drawing;
50using ILNumerics.Drawing.Labeling; 
51
52namespace ILNumerics.Drawing.Platform.OpenGL {
53    /// <summary>
54    /// OpenGL text renderer in screen coords
55    /// </summary>
56    [ILRenderer(GraphicDeviceType.OpenGL,"Outline","OpenGL cached, outlined textures",true,CoordSystem.Screen)]
57    public class ILOGLRenderer : IILTextRenderer {
58
59        #region event handling
60        /// <summary>
61        /// (IILTextRenderer) Event firing if the texture storage has been cleared
62        /// </summary>
63        public event EventHandler CacheCleared;
64        void m_textureManager_TextureCacheCleared(object sender, EventArgs e) {
65            if (CacheCleared != null)
66                CacheCleared(this,null);
67        }
68        #endregion
69
70        #region member / properties
71        ILTextureManager m_textureManager;
72        float[] m_curPosition = new float[16];
73        Color m_colorOverride = Color.Empty;
74        float m_xMin, m_xMax, m_yMin, m_yMax;
75        #endregion
76
77        #region constructors
78
79        public ILOGLRenderer (ILPanel panel) {
80            m_textureManager = panel.TextureManager;
81            m_textureManager.TextureCacheCleared += new EventHandler(m_textureManager_TextureCacheCleared);
82        }
83           
84        #endregion
85
86        #region IILTextRenderer Member
87
88        public CoordSystem CoordSystem {
89            get { return CoordSystem.Screen; }
90        }
91
92        public bool Cached {
93            get {
94                return true;
95            }
96        }
97
98        public string Name {
99            get { return "Outline fonts"; }
100        }
101
102        public string NameLong {
103            get { return "OpenGL outline fonts (OpenTK)"; }
104        }
105
106        public GraphicDeviceType DeviceType {
107            get { return GraphicDeviceType.OpenGL; }
108        }
109
110        public bool DrawAfterBufferSwapped {
111            get { return false; }
112        }
113
114        public void Begin(ILRenderProperties p) {
115            if (GraphicsContext.CurrentContext == null)
116                throw new GraphicsContextException("No GraphicsContext is current in the calling thread.");
117
118            float[] viewport = new float[4];
119            GL.GetFloat(GetPName.Viewport, viewport);
120
121            // Prepare to draw text. We want pixel perfect precision, so we setup a 2D mode,
122            // with size equal to the window (in pixels).
123            // While we could also render text in 3D mode, it would be very hard to get
124            // pixel-perfect precision.
125            GL.MatrixMode(MatrixMode.Projection);
126            GL.PushMatrix();     
127            GL.LoadIdentity();
128            GL.Ortho(viewport[0], viewport[2], viewport[3], viewport[1], -1.0, 1.0);
129
130            GL.MatrixMode(MatrixMode.Modelview);
131            GL.PushMatrix();
132            GL.LoadIdentity();
133
134            GL.PushAttrib(AttribMask.TextureBit | AttribMask.EnableBit | AttribMask.ColorBufferBit);
135
136            GL.Enable(EnableCap.Texture2D);
137            GL.Enable(EnableCap.Blend);
138            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
139            GL.Disable(EnableCap.DepthTest);
140            if (p.Clipping) {
141                GL.Disable(EnableCap.ClipPlane0);
142                GL.Disable(EnableCap.ClipPlane1);
143                GL.Disable(EnableCap.ClipPlane2);
144                GL.Disable(EnableCap.ClipPlane3);
145                GL.Disable(EnableCap.ClipPlane4);
146                GL.Disable(EnableCap.ClipPlane5);
147            }
148            if (p.PassCount == 0) {
149                m_xMin = float.MaxValue;
150                m_xMax = float.MinValue;
151                m_yMin = float.MaxValue;
152                m_yMax = float.MinValue;
153            }
154        }
155       
156        public void Begin (ILRenderProperties p, ref double[] modelview) {
157            if (modelview == null || modelview.Length < 16) {
158                modelview = new double[16];
159            }
160            GL.GetDouble(GetPName.ModelviewMatrix,modelview);
161            Begin(p);
162        }
163        public void End(ILRenderProperties p) {
164            if (p.Clipping) {
165                GL.Enable(EnableCap.ClipPlane0);
166                GL.Enable(EnableCap.ClipPlane1);
167                GL.Enable(EnableCap.ClipPlane2);
168                GL.Enable(EnableCap.ClipPlane3);
169                GL.Enable(EnableCap.ClipPlane4);
170                GL.Enable(EnableCap.ClipPlane5);
171            }
172            GL.PopAttrib();
173            GL.MatrixMode(MatrixMode.Modelview);
174            GL.PopMatrix();
175            GL.MatrixMode(MatrixMode.Projection);
176            GL.PopMatrix();
177            if (p.PassCount == 0) {
178                if (p.MinX > m_xMin) p.MinX = (int)m_xMin;
179                if (p.MaxX < m_xMax) p.MaxX = (int)m_xMax;
180                if (p.MaxY < m_yMax) p.MaxY = (int)m_yMax;
181                if (p.MinY > m_yMin) p.MinY = (int)m_yMin;
182            }
183        }
184        #endregion
185
186        #region IILTextRenderer Member
187        /// <summary>
188        /// Place a new item into the texture cache
189        /// </summary>
190        /// <param name="key">unique key to identify the item for later reference</param>
191        /// <param name="bmp">bitmap containing the item data</param>
192        /// <param name="rect">area in <paramref name="bmp"/> containing the item's data</param>
193        public void Cache(string key, Bitmap bmp, RectangleF rect) {
194            m_textureManager.StoreTextureItem(key,bmp,rect);
195        }
196
197        /// <summary>
198        /// Test if the cache contains an item with a specific key
199        /// </summary>
200        /// <param name="key">key</param>
201        /// <returns>true if the item was cached, false otherwise</returns>
202        public bool ExistsKey(string key) {
203            return m_textureManager.Exists(key);
204        }
205
206        /// <summary>
207        /// try to get the size (screen pixels) of an item
208        /// </summary>
209        /// <param name="key">unique key identifying the item</param>
210        /// <param name="size">[output] size of the item (if found)</param>
211        /// <returns>true, if the item was found, false otherwise</returns>
212        public bool TryGetSize(string key, ref Size size) {
213            ILTextureData item;
214            if (m_textureManager.TryGetTextureItem(key,out item)) {
215                size = new Size(item.Width,item.Height);
216                return true;
217            } else {
218                return false;
219            }
220        }
221
222        /// <summary>
223        /// Draws all items contained in a given render queue
224        /// </summary>
225        /// <param name="queue">render queue</param>
226        /// <param name="location">starting point</param>
227        /// <param name="orientation">orientation for the whole queues output</param>
228        /// <param name="color">starting color</param>
229        /// <remarks><para>The render queue must contain only keys for already cached items!</para>
230        /// <para>The color parameter serves as a global color definition. It may be overridem
231        /// by individual color specifications of the queue items.</para>
232        /// </remarks>
233        public void Draw(ILRenderQueue queue,
234                        System.Drawing.Point location,
235                        TextOrientation orientation,
236                        Color color) {
237            float w, h;
238            if (String.IsNullOrEmpty(queue.Expression.Trim())) return;
239            w = queue.Size.Width;
240            h = queue.Size.Height;
241            // compensate for unexact glx.MeasureString results... (to be fixed!)
242            //w *= 1.09f;
243            //h *= 1.09f;
244            if (orientation == TextOrientation.Vertical) {
245                GL.Rotate(90,0,0,1);
246            }
247            GL.GetFloat(GetPName.ModelviewMatrix,m_curPosition);
248            m_curPosition[12] = location.X;
249            m_curPosition[13] = location.Y;
250
251            GL.LoadMatrix(m_curPosition);
252            m_textureManager.Reset();
253            w = 0.5f; h = 0.5f;
254            int lineHeight = 0;
255            float drawPosY;
256            float xMin = float.MaxValue; // relative to label (include rotation)
257            float yMin = float.MaxValue;
258            float xMax = float.MinValue;
259            float yMax = float.MinValue;
260            GLColor3(color);
261            foreach (ILRenderQueueItem item in queue) {
262                // special symbols & control sequences
263                switch (item.Key) {
264                case "\r":
265                    w = 0.5f;
266                    break;
267                case "\n":
268                    w = 0.5f;
269                    h += lineHeight;
270                    lineHeight = 0;
271                    break;
272                default:
273                    //since textures (may) lay on different sheets in GL memory,
274                    // we cannot switch them in between Begin() and End(),
275                    // we must start a new Begin with each Quad :(
276                    // possible workaround: If only one sheet is used, draw all
277                    // quads at once.
278                    ILTextureData textData = m_textureManager.GetTextureItem(item.Key,true);
279                    if (item.Color != Color.Empty) {
280                        GLColor3(item.Color);
281                    } else {
282                        GLColor3(color);
283                    }
284                    drawPosY = h + item.Offset.Y;
285
286                    GL.Begin(BeginMode.Quads);
287                    RectangleF rectF = textData.TextureRectangle;
288                    GL.TexCoord2(rectF.Left,rectF.Bottom);
289                    GL.Vertex2(w, drawPosY + textData.Height - 1);      // bl
290                    GL.TexCoord2(rectF.Left,rectF.Top);
291                    GL.Vertex2(w, drawPosY);                    // tl
292                    if (xMin > w) xMin = w;
293                    if (yMin > drawPosY) yMin = drawPosY;
294
295                    w += textData.Width-1;
296                    GL.TexCoord2(rectF.Right,rectF.Top);
297                    GL.Vertex2(w, drawPosY);                    // tr
298                    GL.TexCoord2(rectF.Right,rectF.Bottom);
299                    GL.Vertex2(w, drawPosY + textData.Height - 1);      // br
300                    if (textData.Height > lineHeight)
301                        lineHeight = textData.Height;
302                    GL.End();
303                    if (xMax < w) xMax = w;
304                    if (yMax < drawPosY + textData.Height - 1)
305                        yMax = drawPosY + textData.Height - 1;
306
307#if BOUNDINGBOXES_ITEM
308            // define DEBUG symbol to draw bounding box around each item (debug feature)
309            GL.Color3(Color.Red);
310            GL.Begin(BeginMode.LineLoop);
311                w-= textData.Width;
312                GL.Vertex2(w,h + textData.Height);      // ul
313                GL.Vertex2(w,h);                    // bl
314                w += textData.Width;
315                GL.Vertex2(w,h);                    // br
316                GL.Vertex2(w,h + textData.Height);      // tr
317            GL.End();
318#endif
319                        break;
320                }
321            }
322#if BOUNDINGBOXES
323            // define debugsymbol "BOUNDINGBOXES", to draw bounding box around whole expression
324            GL.Disable(EnableCap.Texture2D);
325            GL.Color3(Color.Red);
326            GL.LineWidth(1);
327            GL.Disable(EnableCap.LineStipple);
328            GL.Begin(BeginMode.LineLoop);
329                GL.Vertex2(0,0);      // ul
330                GL.Vertex2(0,queue.Size.Height);                    // bl
331                GL.Vertex2(queue.Size.Width,queue.Size.Height);                    // br
332                GL.Vertex2(queue.Size.Width,0);      // tr
333            GL.End();
334            GL.Enable(EnableCap.Texture2D);
335#endif
336            // check outer limits
337            if (orientation == TextOrientation.Horizontal) {
338                if (m_xMin > location.X + xMin) m_xMin = location.X + xMin;
339                if (m_xMax < location.X + xMax) m_xMax = location.X + xMax;
340                if (m_yMin > location.Y + yMin) m_yMin = location.Y + yMin;
341                if (m_yMax < location.Y + yMax) m_yMax = location.Y + yMax;
342            } else if (orientation == TextOrientation.Vertical) {
343                if (m_xMin > location.X - yMax) m_xMin = location.X - yMax;
344                if (m_xMax < location.X - yMin) m_xMax = location.X - yMin;
345                if (m_yMin > location.Y - xMin) m_yMin = location.Y - xMin;
346                if (m_yMax < location.Y - xMax) m_yMax = location.Y - xMax;
347            }
348        }
349
350        public void Draw(ILRenderQueue renderQueue, float x1, float y1, float z1, float x2, float y2, float z2, Color color) {
351            Draw(renderQueue,new Point((int)x1,(int)y1),TextOrientation.Horizontal,color);
352        }
353        public Color ColorOverride {
354            get {
355                return m_colorOverride;
356            }
357            set {
358                m_colorOverride = value;
359            }
360        }
361
362        #endregion
363
364        private void GLColor3(Color color) {
365            if (m_colorOverride.IsEmpty) {
366                GL.Color3(color);
367            } else {
368                GL.Color3(m_colorOverride);
369            }
370        }
371
372    }
373}
Note: See TracBrowser for help on using the repository browser.