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 |
|
---|
40 | using System;
|
---|
41 | using System.Drawing;
|
---|
42 | using System.Drawing.Imaging;
|
---|
43 | using System.Windows.Forms;
|
---|
44 | using System.Diagnostics;
|
---|
45 | using ILNumerics.Exceptions;
|
---|
46 | using ILNumerics.Drawing;
|
---|
47 | using ILNumerics.Drawing.Graphs;
|
---|
48 | using ILNumerics.Drawing.Lighting;
|
---|
49 | using ILNumerics.Drawing.Interfaces;
|
---|
50 | using OpenTK.Graphics;
|
---|
51 | using OpenTK.Platform;
|
---|
52 | using OpenTK;
|
---|
53 | using OpenTK.Math;
|
---|
54 | using ILNumerics.Drawing.Shapes;
|
---|
55 | using System.Linq;
|
---|
56 |
|
---|
57 | namespace ILNumerics.Drawing.Platform.OpenGL {
|
---|
58 | /// <summary>
|
---|
59 | /// OpenGL implementation for ILPanel
|
---|
60 | /// </summary>
|
---|
61 | internal partial class ILOGLPanel : ILPanel, IILCreationFactory{
|
---|
62 |
|
---|
63 | #region members / properties
|
---|
64 | bool m_mustReconfigureLight = true;
|
---|
65 | GraphicsMode m_format;
|
---|
66 | IWindowInfo m_window_info;
|
---|
67 | IGraphicsContext m_context;
|
---|
68 | IGLControl m_implementation;
|
---|
69 | private const float Sqrt2 = 1.4142135623730950488016887242097f;
|
---|
70 | double[] m_projMatrix = new double[16];
|
---|
71 | double[] m_modelViewMatrix = new double[16];
|
---|
72 | int[] m_viewMatrix = new int[16];
|
---|
73 | float[] m_selectionVertices = new float[32]; // V2F format, interleaved
|
---|
74 | int m_errorCount = 0;
|
---|
75 | private readonly int MAXERRORLOGCOUNT = 100;
|
---|
76 | protected bool m_polyOffsetEnable = true;
|
---|
77 | /// <summary>
|
---|
78 | /// Gets an interface to the underlying GraphicsContext used by this GLControl.
|
---|
79 | /// </summary>
|
---|
80 | public override object GetDeviceContext() {
|
---|
81 | return m_context;
|
---|
82 | }
|
---|
83 |
|
---|
84 | internal double[] ProjectionMatrix {
|
---|
85 | get {
|
---|
86 | return m_projMatrix;
|
---|
87 | }
|
---|
88 | }
|
---|
89 | internal double[] ModelviewMatrix {
|
---|
90 | get {
|
---|
91 | return m_modelViewMatrix;
|
---|
92 | }
|
---|
93 | }
|
---|
94 | internal int[] ViewMatrix {
|
---|
95 | get {
|
---|
96 | return m_viewMatrix;
|
---|
97 | }
|
---|
98 | }
|
---|
99 |
|
---|
100 | /// <summary>
|
---|
101 | /// Control polygon offset ([on]/off)
|
---|
102 | /// </summary>
|
---|
103 | public bool PolyOffsetEnable {
|
---|
104 | get {
|
---|
105 | return m_polyOffsetEnable;
|
---|
106 | }
|
---|
107 | set {
|
---|
108 | m_polyOffsetEnable = value;
|
---|
109 | }
|
---|
110 | }
|
---|
111 |
|
---|
112 | #endregion private members
|
---|
113 |
|
---|
114 | #region constructors
|
---|
115 |
|
---|
116 | internal ILOGLPanel() : base( GraphicDeviceType.OpenGL ) {
|
---|
117 | #if TRACE
|
---|
118 | Trace.TraceInformation("{0},{1} ILOGLPanel.ctor(mode) start",DateTime.Now, Environment.TickCount);
|
---|
119 | Trace.Indent();
|
---|
120 | #endif
|
---|
121 |
|
---|
122 | this.SetStyle(ControlStyles.Opaque, true);
|
---|
123 | this.SetStyle(ControlStyles.UserPaint, true);
|
---|
124 | this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
---|
125 | m_format = GraphicsMode.Default;
|
---|
126 |
|
---|
127 | if (Configuration.RunningOnWindows)
|
---|
128 | m_implementation = new OpenTK.Platform.Windows.WinGLControl(m_format, this);
|
---|
129 | else if (Configuration.RunningOnX11)
|
---|
130 | m_implementation = new OpenTK.Platform.X11.X11GLControl(m_format, this);
|
---|
131 | else if (Configuration.RunningOnOSX)
|
---|
132 | throw new PlatformNotSupportedException("Refer to http://www.opentk.com for more information.");
|
---|
133 |
|
---|
134 | this.CreateControl();
|
---|
135 |
|
---|
136 | #if TRACE
|
---|
137 | Trace.Unindent();
|
---|
138 | Trace.TraceInformation("{0},{1} ILPanel.ctor(mode) end",DateTime.Now, Environment.TickCount);
|
---|
139 | #endif
|
---|
140 | }
|
---|
141 |
|
---|
142 | #endregion
|
---|
143 |
|
---|
144 | #region panel setup / destroy
|
---|
145 |
|
---|
146 | /// <summary>
|
---|
147 | /// will get called after the handle has been created
|
---|
148 | /// </summary>
|
---|
149 | /// <param name="e"></param>
|
---|
150 | protected override void OnHandleCreated(EventArgs e) {
|
---|
151 | base.OnHandleCreated(e);
|
---|
152 | if (DesignMode)
|
---|
153 | m_context = new DummyGLContext(null);
|
---|
154 | else
|
---|
155 | m_context = m_implementation.CreateContext();
|
---|
156 |
|
---|
157 | m_window_info = m_implementation.WindowInfo;
|
---|
158 | this.MakeCurrent();
|
---|
159 | ((IGraphicsContextInternal)m_context).LoadAll();
|
---|
160 | OnGraphicsDeviceCreated();
|
---|
161 | }
|
---|
162 | /// <summary>
|
---|
163 | /// gets called, after the handle has been destroyed
|
---|
164 | /// </summary>
|
---|
165 | /// <param name="e"></param>
|
---|
166 | protected override void OnHandleDestroyed(EventArgs e)
|
---|
167 | {
|
---|
168 | base.OnHandleDestroyed(e);
|
---|
169 | if (m_context != null)
|
---|
170 | {
|
---|
171 | m_context.Dispose();
|
---|
172 | m_context = null;
|
---|
173 | }
|
---|
174 | m_window_info = null;
|
---|
175 | }
|
---|
176 | /// <summary>
|
---|
177 | /// Dispose off the panels resources
|
---|
178 | /// </summary>
|
---|
179 | /// <param name="disposing"></param>
|
---|
180 | protected override void Dispose(bool disposing) {
|
---|
181 | m_active = false;
|
---|
182 | base.Dispose(disposing);
|
---|
183 | if (disposing) {
|
---|
184 | // he ?
|
---|
185 | }
|
---|
186 | if (m_context != null && disposing) {
|
---|
187 | m_context.Dispose();
|
---|
188 | m_context = null;
|
---|
189 | }
|
---|
190 | }
|
---|
191 |
|
---|
192 | #endregion
|
---|
193 |
|
---|
194 | #region rendering related
|
---|
195 |
|
---|
196 | /// <summary>
|
---|
197 | /// set up viewport, projection and modelview matrices
|
---|
198 | /// </summary>
|
---|
199 | protected override void UpdateMatrices(float width2D, float height2D, float zDepth) {
|
---|
200 | if (ClientSize.IsEmpty) return;
|
---|
201 | if (m_plotBoxScreenRectF.Size.IsEmpty) return;
|
---|
202 |
|
---|
203 | float worldSceneWidth;
|
---|
204 | float worldSceneHeight;
|
---|
205 | // ILPoint3Df camPos = m_camera.Position;
|
---|
206 | ILPoint3Df top;
|
---|
207 | ILPoint3Df moveOffset;
|
---|
208 | helperUpdateMatrices(width2D, height2D, out worldSceneWidth, out worldSceneHeight, out top, out moveOffset);
|
---|
209 |
|
---|
210 | #region projection
|
---|
211 | GL.MatrixMode(MatrixMode.Projection);
|
---|
212 | GL.LoadIdentity();
|
---|
213 |
|
---|
214 | float nearPlane = 0f; // Math.Max(0.0f, m_camera.Distance - m_clippingView.SphereRadius);
|
---|
215 | float farPlane = m_camera.Distance + m_clippingView.SphereRadius * 100;
|
---|
216 | if (m_projection == Projection.Perspective) {
|
---|
217 | float angle = (float)Math.Atan2(worldSceneHeight / 2.0f, m_camera.Distance - (zDepth / 2)) * 2.0f;
|
---|
218 | Glu.Perspective(angle / Math.PI * 180, (double)worldSceneWidth / worldSceneHeight,
|
---|
219 | nearPlane, farPlane);
|
---|
220 | } else {
|
---|
221 | GL.Ortho(
|
---|
222 | -worldSceneWidth / 2.0, worldSceneWidth / 2.0
|
---|
223 | , -worldSceneHeight / 2.0, worldSceneHeight / 2.0
|
---|
224 | , nearPlane, farPlane);
|
---|
225 | }
|
---|
226 | GL.GetDouble(GetPName.ProjectionMatrix,m_projMatrix);
|
---|
227 | // set viewport
|
---|
228 | GL.Viewport(0,0,ClientSize.Width,ClientSize.Height);
|
---|
229 | GL.GetInteger(GetPName.Viewport,m_viewMatrix);
|
---|
230 | #endregion
|
---|
231 |
|
---|
232 | #region modelview
|
---|
233 | GL.MatrixMode(MatrixMode.Modelview);
|
---|
234 | GL.LoadIdentity();
|
---|
235 | ILGLU.LookAt (m_camera.Position, m_camera.LookAt, m_camera.Top, moveOffset);
|
---|
236 |
|
---|
237 | // Glu.LookAt(camPos.X, camPos.Y, camPos.Z
|
---|
238 | // , m_camera.LookAt.X, m_camera.LookAt.Y, m_camera.LookAt.Z
|
---|
239 | // , m_camera.Top.X, m_camera.Top.Y, m_camera.Top.Z);
|
---|
240 | // GL.Translate(moveOffset.X,moveOffset.Y,moveOffset.Z);
|
---|
241 |
|
---|
242 | GL.GetDouble(GetPName.ModelviewMatrix, m_modelViewMatrix);
|
---|
243 | //Console.Out.WriteLine("Camera: {0} || Top: {1} \n m_modelViewMatr:{2}",m_camera.ToString(), m_camera.Top.ToString(), String.Join(", ", m_modelViewMatrix));
|
---|
244 | //Console.Out.WriteLine("Camera: {0} || Top: {1} \n m_modelViewMatr:{2}",m_camera.ToString(), m_camera.Top.ToString(), String.Join(", ", m_modelViewMatrix));
|
---|
245 | #endregion
|
---|
246 |
|
---|
247 | }
|
---|
248 |
|
---|
249 | protected override void iRenderingState1(ILRenderProperties p) {
|
---|
250 | MakeCurrent();
|
---|
251 | }
|
---|
252 | /// <summary>
|
---|
253 | /// Render the OpenGL scene
|
---|
254 | /// </summary>
|
---|
255 | /// <param name="g"></param>
|
---|
256 | protected override void iRenderingState2(ILRenderProperties p) {
|
---|
257 |
|
---|
258 | if (m_context == null || (!m_active && !m_drawHidden))
|
---|
259 | return;
|
---|
260 | try {
|
---|
261 | //System.Diagnostics.Debug.WriteLine(String.Format("ILOGLPanel{0}: RenderScene, Thread={1}"
|
---|
262 | // ,this.GetHashCode(), System.Threading.Thread.CurrentThread.GetHashCode()));
|
---|
263 | // draw background
|
---|
264 | GL.ClearColor(m_backColor);
|
---|
265 | GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
---|
266 | // draw back axis
|
---|
267 | GL.Enable(EnableCap.DepthTest);
|
---|
268 | if (m_fillBackground)
|
---|
269 | renderBackground();
|
---|
270 | GL.Enable(EnableCap.Blend);
|
---|
271 | //GL.MatrixMode(MatrixMode.Modelview);
|
---|
272 | //GL.PushMatrix();
|
---|
273 | if (m_polyOffsetEnable) {
|
---|
274 | GL.Enable(EnableCap.PolygonOffsetFill);
|
---|
275 | } else {
|
---|
276 | GL.Disable(EnableCap.PolygonOffsetFill);
|
---|
277 | }
|
---|
278 | GL.PolygonOffset(1.0f,1.0f);
|
---|
279 | GL.Disable(EnableCap.Blend);
|
---|
280 | m_axes.XAxis.RenderState1(p);
|
---|
281 | m_axes.YAxis.RenderState1(p);
|
---|
282 | if (m_camera.SinRho > 1e-5)
|
---|
283 | m_axes.ZAxis.RenderState1(p);
|
---|
284 |
|
---|
285 | if ((m_plotBoxScreenSizeMode != PlotBoxScreenSizeMode.StrictOptimal)
|
---|
286 | || (p.PassCount > 0)) {
|
---|
287 |
|
---|
288 | #region enable clipping planes
|
---|
289 | if (m_renderProperties.Clipping) {
|
---|
290 | unsafe {
|
---|
291 | fixed (double* pClip = m_clipplanes) {
|
---|
292 | if (m_clippingView.WidthF > 0) {
|
---|
293 | GL.ClipPlane(ClipPlaneName.ClipPlane0, pClip);
|
---|
294 | GL.ClipPlane(ClipPlaneName.ClipPlane1, pClip + 4);
|
---|
295 | GL.Enable(EnableCap.ClipPlane0);
|
---|
296 | GL.Enable(EnableCap.ClipPlane1);
|
---|
297 | }
|
---|
298 | if (m_clippingView.HeightF > 0) {
|
---|
299 | GL.ClipPlane(ClipPlaneName.ClipPlane2, pClip + 8);
|
---|
300 | GL.ClipPlane(ClipPlaneName.ClipPlane3, pClip + 12);
|
---|
301 | GL.Enable(EnableCap.ClipPlane2);
|
---|
302 | GL.Enable(EnableCap.ClipPlane3);
|
---|
303 | }
|
---|
304 | if (m_clippingView.DepthF > 0) {
|
---|
305 | GL.ClipPlane(ClipPlaneName.ClipPlane4, pClip + 16);
|
---|
306 | GL.ClipPlane(ClipPlaneName.ClipPlane5, pClip + 20);
|
---|
307 | GL.Enable(EnableCap.ClipPlane4);
|
---|
308 | GL.Enable(EnableCap.ClipPlane5);
|
---|
309 | }
|
---|
310 | }
|
---|
311 | }
|
---|
312 | }
|
---|
313 | #endregion
|
---|
314 | // draw all graphs
|
---|
315 | //GL.MatrixMode(MatrixMode.Modelview);
|
---|
316 | //ILPoint3Df ab = m_clippingView.CenterToUnitCube();
|
---|
317 | //GL.Translate(ab.X, ab.Y, ab.Z);
|
---|
318 | //ab = m_clippingView.ScaleToUnitCube();
|
---|
319 | //GL.Scale(ab.X, ab.Y, ab.Z); //Identity; //RotationZ(m_cameraPhi);
|
---|
320 |
|
---|
321 | #region lighting
|
---|
322 | if (m_mustReconfigureLight) {
|
---|
323 | m_mustReconfigureLight = false;
|
---|
324 | if (m_lights.Enabled) {
|
---|
325 | float[] tmpF = new float[4]; tmpF[3] = 1.0f;
|
---|
326 | foreach (ILLight light in m_lights) {
|
---|
327 | EnableCap lightID = EnableCap.Light0 + light.Index;
|
---|
328 | if (!light.Enabled) {
|
---|
329 | GL.Disable(lightID);
|
---|
330 | continue;
|
---|
331 | }
|
---|
332 | GL.Enable(lightID);
|
---|
333 | tmpF[0] = light.Position.X;
|
---|
334 | tmpF[1] = light.Position.Y;
|
---|
335 | tmpF[2] = light.Position.Z;
|
---|
336 | GL.Lightv((LightName)lightID, LightParameter.Position, tmpF);
|
---|
337 | tmpF[0] = (float)light.Ambient.R / 255;
|
---|
338 | tmpF[1] = (float)light.Ambient.G / 255;
|
---|
339 | tmpF[2] = (float)light.Ambient.B / 255;
|
---|
340 | GL.Lightv((LightName)lightID, LightParameter.Ambient, tmpF);
|
---|
341 | tmpF[0] = (float)light.Specular.R / 255;
|
---|
342 | tmpF[1] = (float)light.Specular.G / 255;
|
---|
343 | tmpF[2] = (float)light.Specular.B / 255;
|
---|
344 | GL.Lightv((LightName)lightID, LightParameter.Specular, tmpF);
|
---|
345 | tmpF[0] = (float)light.Diffuse.R / 255;
|
---|
346 | tmpF[1] = (float)light.Diffuse.G / 255;
|
---|
347 | tmpF[2] = (float)light.Diffuse.B / 255;
|
---|
348 | GL.Lightv((LightName)lightID, LightParameter.Diffuse, tmpF);
|
---|
349 | }
|
---|
350 | }
|
---|
351 | }
|
---|
352 | #endregion
|
---|
353 |
|
---|
354 | #region graph rendering
|
---|
355 | // Easy sorting - this expects a few graphs in the collection only.
|
---|
356 | // For situations, where a large number of graphs need to be sorted here,
|
---|
357 | // one may implement sorting in the way it is done in ILSceneGraph
|
---|
358 | // (via ILNumerics.ILArray and ILMath.sort).
|
---|
359 |
|
---|
360 | //m_graphs.Sort(new ILNumerics.Drawing.Misc.ILGraphComparer());
|
---|
361 | m_sortingCacheList.Clear();
|
---|
362 | m_graphs.GetSortedList4Render(m_camera, m_sortingCacheList);
|
---|
363 | foreach (ILGraph graph in m_sortingCacheList) {
|
---|
364 | try {
|
---|
365 | graph.Draw(p);
|
---|
366 | } catch (Exception e) {
|
---|
367 | #if TRACE
|
---|
368 | m_errorCount++;
|
---|
369 |
|
---|
370 | if (m_errorCount < MAXERRORLOGCOUNT) {
|
---|
371 | System.Diagnostics.Trace.TraceError(String.Format("[{0}].Draw() failed: {1}",graph.GetType().Name,e.ToString()));
|
---|
372 | } else if (m_errorCount == MAXERRORLOGCOUNT) {
|
---|
373 | System.Diagnostics.Trace.TraceError(String.Format("(more than {0} errors. Further reporting disabled.)",m_errorCount));
|
---|
374 | }
|
---|
375 | #endif
|
---|
376 | if (m_errorCount < 3) {
|
---|
377 | MessageBox.Show(e.Message, "ILNumerics.Drawing");
|
---|
378 | }
|
---|
379 |
|
---|
380 | }
|
---|
381 | }
|
---|
382 | #endregion
|
---|
383 |
|
---|
384 | #region world label test, please delete me
|
---|
385 | //ILNumerics.Drawing.Labeling.ILLabel label = new ILNumerics.Drawing.Labeling.ILLabel(this);
|
---|
386 | //label.Position = new Point(0,0);
|
---|
387 | //label.Text = "World";
|
---|
388 | //label.Renderer = TextRendererManager.GetDefault(CoordSystem.World3D);
|
---|
389 | //label.Draw(g);
|
---|
390 | #endregion
|
---|
391 |
|
---|
392 | #region disable clipping planes
|
---|
393 | GL.Disable(EnableCap.ClipPlane0);
|
---|
394 | GL.Disable(EnableCap.ClipPlane1);
|
---|
395 | GL.Disable(EnableCap.ClipPlane2);
|
---|
396 | GL.Disable(EnableCap.ClipPlane3);
|
---|
397 | GL.Disable(EnableCap.ClipPlane4);
|
---|
398 | GL.Disable(EnableCap.ClipPlane5);
|
---|
399 | #endregion disable clipping planes
|
---|
400 |
|
---|
401 | }
|
---|
402 | // render front axis
|
---|
403 | //GL.MatrixMode(MatrixMode.Modelview);
|
---|
404 | //GL.PopMatrix();
|
---|
405 | GL.Enable(EnableCap.Blend);
|
---|
406 | GL.Enable(EnableCap.LineSmooth);
|
---|
407 | m_axes.XAxis.RenderState2(p);
|
---|
408 | m_axes.YAxis.RenderState2(p);
|
---|
409 | if (m_camera.SinRho > 1e-5)
|
---|
410 | m_axes.ZAxis.RenderState2(p);
|
---|
411 |
|
---|
412 | } catch (ILArgumentException e) {
|
---|
413 | throw new ILArgumentException("rendering failed at state 2",e);
|
---|
414 | }
|
---|
415 | }
|
---|
416 | /// <summary>
|
---|
417 | /// swap buffers and finalize rendering
|
---|
418 | /// </summary>
|
---|
419 | /// <param name="p"></param>
|
---|
420 | protected override void iRenderingState3(ILRenderProperties p) {
|
---|
421 |
|
---|
422 | try {
|
---|
423 | p.Graphics = null;
|
---|
424 | m_legend.Draw(p, Rectangle.Empty);
|
---|
425 |
|
---|
426 | #region screen label test, please delete me
|
---|
427 | //label = new ILNumerics.Drawing.Labeling.ILLabel(this);
|
---|
428 | //label.Position = new Point(30,40);
|
---|
429 | //label.Text = "Screen";
|
---|
430 | //label.Renderer = TextRendererManager.GetDefault(CoordSystem.Screen);
|
---|
431 | //label.Draw(g);
|
---|
432 | #endregion
|
---|
433 |
|
---|
434 | //GL.MatrixMode(MatrixMode.Modelview);
|
---|
435 | if (m_selectingMode == InteractiveModes.ZoomRectangle && m_isDragging)
|
---|
436 | drawSelectionRect(PointToClient(MousePosition));
|
---|
437 |
|
---|
438 | #if DRAWPLOTCUBESCREENRECT
|
---|
439 | #region
|
---|
440 | float[] viewport = new float[4];
|
---|
441 | GL.GetFloat(GetPName.Viewport, viewport);
|
---|
442 | GL.MatrixMode(MatrixMode.Projection);
|
---|
443 | GL.PushMatrix();
|
---|
444 | GL.LoadIdentity();
|
---|
445 | GL.Ortho(viewport[0], viewport[2], viewport[3], viewport[1], -1.0, 1.0);
|
---|
446 | GL.MatrixMode(MatrixMode.Modelview);
|
---|
447 | GL.PushMatrix();
|
---|
448 | GL.LoadIdentity();
|
---|
449 | GL.Color3(Color.LightGray);
|
---|
450 | GL.LineWidth(1f);
|
---|
451 | GL.Begin(BeginMode.LineLoop);
|
---|
452 | GL.Vertex2(m_plotBoxScreenRectF.Left * ClientSize.Width, m_plotBoxScreenRectF.Top * ClientSize.Height);
|
---|
453 | GL.Vertex2(m_plotBoxScreenRectF.Right * ClientSize.Width, m_plotBoxScreenRectF.Top * ClientSize.Height);
|
---|
454 | GL.Vertex2(m_plotBoxScreenRectF.Right * ClientSize.Width, m_plotBoxScreenRectF.Bottom * ClientSize.Height);
|
---|
455 | GL.Vertex2(m_plotBoxScreenRectF.Left * ClientSize.Width, m_plotBoxScreenRectF.Bottom * ClientSize.Height);
|
---|
456 | GL.End();
|
---|
457 | GL.PopMatrix();
|
---|
458 | GL.MatrixMode(MatrixMode.Projection);
|
---|
459 | GL.PopMatrix();
|
---|
460 | #endregion
|
---|
461 |
|
---|
462 | #endif
|
---|
463 | //GL.Finish();
|
---|
464 | // update model matrix (to be avilable for zooming etc.)
|
---|
465 | //GL.GetDouble(GetPName.ModelviewMatrix,m_modelViewMatrix);
|
---|
466 |
|
---|
467 |
|
---|
468 | #if DRAWTEXTURESHEET
|
---|
469 | #region
|
---|
470 | // prepare GL
|
---|
471 | float[] deb_viewport = new float[4];
|
---|
472 | GL.GetFloat(GetPName.Viewport, deb_viewport);
|
---|
473 | GL.MatrixMode(MatrixMode.Projection);
|
---|
474 | GL.PushMatrix();
|
---|
475 | GL.LoadIdentity();
|
---|
476 | GL.Ortho(deb_viewport[0], deb_viewport[2], deb_viewport[3], deb_viewport[1], -1.0, 1.0);
|
---|
477 | GL.MatrixMode(MatrixMode.Modelview);
|
---|
478 | GL.PushMatrix();
|
---|
479 | GL.LoadIdentity();
|
---|
480 | GL.PushAttrib(AttribMask.TextureBit | AttribMask.EnableBit | AttribMask.ColorBufferBit);
|
---|
481 | GL.Enable(EnableCap.Texture2D);
|
---|
482 | GL.Enable(EnableCap.Blend);
|
---|
483 | GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
|
---|
484 | GL.Disable(EnableCap.DepthTest);
|
---|
485 | // draw one large quad with whole texture sheet
|
---|
486 | GL.Begin(BeginMode.Quads);
|
---|
487 | GL.TexCoord2(0,1);
|
---|
488 | GL.Vertex2(0,ClientSize.Height/2); // ul
|
---|
489 | GL.TexCoord2(0,0);
|
---|
490 | GL.Vertex2(0,0); // bl
|
---|
491 | GL.TexCoord2(1,0);
|
---|
492 | GL.Vertex2(ClientSize.Width,0); // br
|
---|
493 | GL.TexCoord2(1,1);
|
---|
494 | GL.Vertex2(ClientSize.Width,ClientSize.Height/2); // tr
|
---|
495 | GL.End();
|
---|
496 | #endregion
|
---|
497 | #endif
|
---|
498 |
|
---|
499 | SwapBuffers();
|
---|
500 | m_axes.XAxis.RenderState3(p);
|
---|
501 | m_axes.YAxis.RenderState3(p);
|
---|
502 | if (m_camera.SinRho > 1e-5)
|
---|
503 | m_axes.ZAxis.RenderState3(p);
|
---|
504 |
|
---|
505 | //if (false) {
|
---|
506 | // p.Graphics.DrawLine(new Pen(new SolidBrush(Color.Red)), m_axes[0].Label.m_position, m_axes[0].Label.m_position);
|
---|
507 | // p.Graphics.DrawLine(new Pen(new SolidBrush(Color.Green)), m_axes[1].Label.m_position, m_axes[0].Label.m_position);
|
---|
508 | // p.Graphics.DrawLine(new Pen(new SolidBrush(Color.Blue)), m_axes[2].Label.m_position, m_axes[0].Label.m_position);
|
---|
509 | //}
|
---|
510 | } catch (ILArgumentException exc) {
|
---|
511 | throw new ILArgumentException("rendering failed aat state 3",exc);
|
---|
512 | // todo: exception handling
|
---|
513 | }
|
---|
514 | }
|
---|
515 | /// <summary>
|
---|
516 | /// draws the selection rectangle va OpenGL (rather than GDI in base class)
|
---|
517 | /// </summary>
|
---|
518 | /// <param name="endPoint"></param>
|
---|
519 | protected override void drawSelectionRect(Point endPoint) {
|
---|
520 | float [] viewport = new float[4];
|
---|
521 | GL.GetFloat(GetPName.Viewport, viewport);
|
---|
522 | GL.MatrixMode(MatrixMode.Projection);
|
---|
523 | GL.PushMatrix();
|
---|
524 | GL.LoadIdentity();
|
---|
525 | GL.Ortho(viewport[0], viewport[2], viewport[3], viewport[1], -1.0, 1.0);
|
---|
526 |
|
---|
527 | GL.MatrixMode(MatrixMode.Modelview);
|
---|
528 | GL.PushMatrix();
|
---|
529 | GL.LoadIdentity();
|
---|
530 |
|
---|
531 | //GL.Enable(EnableCap.Texture2D);
|
---|
532 | //GL.Enable(EnableCap.Blend);
|
---|
533 | //GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
|
---|
534 |
|
---|
535 | GL.Disable(EnableCap.DepthTest);
|
---|
536 | SetupLineStyle(m_selectionRectangle);
|
---|
537 | //// upper left corner
|
---|
538 | m_selectionVertices[0] = m_mouseStart.X;
|
---|
539 | m_selectionVertices[1] = m_mouseStart.Y + (endPoint.Y - m_mouseStart.Y) / 4;
|
---|
540 | m_selectionVertices[2] = m_mouseStart.X;
|
---|
541 | m_selectionVertices[3] = m_mouseStart.Y;
|
---|
542 | m_selectionVertices[4] = m_mouseStart.X;
|
---|
543 | m_selectionVertices[5] = m_mouseStart.Y;
|
---|
544 | m_selectionVertices[6] = m_mouseStart.X + (endPoint.X - m_mouseStart.X) / 4;
|
---|
545 | m_selectionVertices[7] = m_mouseStart.Y;
|
---|
546 | // lower left corner
|
---|
547 | m_selectionVertices[8] = m_mouseStart.X;
|
---|
548 | m_selectionVertices[9] = endPoint.Y - (endPoint.Y - m_mouseStart.Y) / 4;
|
---|
549 | m_selectionVertices[10] = m_mouseStart.X;
|
---|
550 | m_selectionVertices[11] = endPoint.Y;
|
---|
551 | m_selectionVertices[12] = m_mouseStart.X;
|
---|
552 | m_selectionVertices[13] = endPoint.Y;
|
---|
553 | m_selectionVertices[14] = m_mouseStart.X + (endPoint.X - m_mouseStart.X) / 4;
|
---|
554 | m_selectionVertices[15] = endPoint.Y;
|
---|
555 | // lower right corner
|
---|
556 | m_selectionVertices[16] = endPoint.X;
|
---|
557 | m_selectionVertices[17] = endPoint.Y - (endPoint.Y - m_mouseStart.Y) / 4;
|
---|
558 | m_selectionVertices[18] = endPoint.X;
|
---|
559 | m_selectionVertices[19] = endPoint.Y;
|
---|
560 | m_selectionVertices[20] = endPoint.X;
|
---|
561 | m_selectionVertices[21] = endPoint.Y;
|
---|
562 | m_selectionVertices[22] = endPoint.X - (endPoint.X - m_mouseStart.X) / 4;
|
---|
563 | m_selectionVertices[23] = endPoint.Y;
|
---|
564 | // upper right corner
|
---|
565 | m_selectionVertices[24] = endPoint.X;
|
---|
566 | m_selectionVertices[25] = m_mouseStart.Y + (endPoint.Y - m_mouseStart.Y) / 4;
|
---|
567 | m_selectionVertices[26] = endPoint.X;
|
---|
568 | m_selectionVertices[27] = m_mouseStart.Y;
|
---|
569 | m_selectionVertices[28] = endPoint.X;
|
---|
570 | m_selectionVertices[29] = m_mouseStart.Y;
|
---|
571 | m_selectionVertices[30] = endPoint.X - (endPoint.X - m_mouseStart.X) / 4;
|
---|
572 | m_selectionVertices[31] = m_mouseStart.Y;
|
---|
573 | // draw them
|
---|
574 | unsafe {
|
---|
575 | fixed (float* verticesP = m_selectionVertices) {
|
---|
576 | GL.InterleavedArrays(InterleavedArrayFormat.V2f,8,(IntPtr)verticesP);
|
---|
577 | GL.DrawArrays(BeginMode.Lines,0,16);
|
---|
578 | }
|
---|
579 | }
|
---|
580 | GL.MatrixMode(MatrixMode.Modelview);
|
---|
581 | GL.PopMatrix();
|
---|
582 | GL.MatrixMode(MatrixMode.Projection);
|
---|
583 | GL.PopMatrix();
|
---|
584 | }
|
---|
585 | /// <summary>
|
---|
586 | /// Swaps the front and back buffers, presenting the rendered scene to the screen.
|
---|
587 | /// </summary>
|
---|
588 | protected void SwapBuffers() {
|
---|
589 | if (m_context != null)
|
---|
590 | m_context.SwapBuffers();
|
---|
591 | }
|
---|
592 | /// <summary>
|
---|
593 | /// Makes the underlying this GLControl current in the calling thread.
|
---|
594 | /// All OpenGL commands issued are hereafter interpreted by this GLControl.
|
---|
595 | /// </summary>
|
---|
596 | protected void MakeCurrent() {
|
---|
597 | if (m_context != null)
|
---|
598 | m_context.MakeCurrent(m_implementation.WindowInfo);
|
---|
599 | }
|
---|
600 |
|
---|
601 | public override void DrawToBitmap(Bitmap bitmap, Rectangle bounds) {
|
---|
602 | RenderScene(m_renderProperties);
|
---|
603 | BitmapData bmpData = bitmap.LockBits(bounds,ImageLockMode.ReadWrite,
|
---|
604 | System.Drawing.Imaging.PixelFormat.Format24bppRgb);
|
---|
605 | // reset any changes to pixel store
|
---|
606 | GL.PixelStore(PixelStoreParameter.UnpackAlignment,4.0f);
|
---|
607 | GL.PixelStore(PixelStoreParameter.UnpackRowLength,bmpData.Width);
|
---|
608 | GL.PixelStore(PixelStoreParameter.UnpackSkipRows,bounds.Y);
|
---|
609 | GL.PixelStore(PixelStoreParameter.UnpackSkipPixels,bounds.X);
|
---|
610 | GL.ReadPixels(0,0,bounds.Width,bounds.Height,OpenTK.Graphics.PixelFormat.Bgr,
|
---|
611 | PixelType.UnsignedByte,(IntPtr)bmpData.Scan0);
|
---|
612 | bitmap.UnlockBits(bmpData);
|
---|
613 | bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
---|
614 | }
|
---|
615 | #endregion
|
---|
616 |
|
---|
617 | #region IILGraphFactory member
|
---|
618 | /// <summary>
|
---|
619 | /// Create specific graph (device dependent)
|
---|
620 | /// </summary>
|
---|
621 | /// <param name="data">numeric data to be visualized, any numeric type is accepted</param>
|
---|
622 | /// <param name="type">type of graph to be created</param>
|
---|
623 | /// <param name="additionalParams">user defined parameter, depend on concrete device type</param>
|
---|
624 | /// <returns>Concrete ILGraph object</returns>
|
---|
625 | public ILGraph CreateGraph(ILInArray<float> data, GraphType graphType, params ILArray<float>[] parameter) {
|
---|
626 | using (ILScope.Enter(data)) {
|
---|
627 | switch (graphType) {
|
---|
628 | case GraphType.Plot2D:
|
---|
629 | if (parameter != null && parameter.Length == 1
|
---|
630 | && parameter[0] != null && parameter[0] is ILArray<float>) {
|
---|
631 | return new ILOGLPlot2DGraph(this, parameter[0] as ILArray<float>,
|
---|
632 | data, m_graphs.Limits);
|
---|
633 | } else {
|
---|
634 | return new ILOGLPlot2DGraph(this, data, m_graphs.Limits);
|
---|
635 | }
|
---|
636 | case GraphType.Surf:
|
---|
637 | if (parameter == null || parameter.Length == 0)
|
---|
638 | return new ILOGLSurfaceGraph(this, null, null, data, null, m_graphs.Limits);
|
---|
639 | if (parameter.Length == 2) {
|
---|
640 | return new ILOGLSurfaceGraph(this, data, parameter[0] as ILArray<float>,
|
---|
641 | parameter[1] as ILArray<float>, null, m_graphs.Limits);
|
---|
642 | } else if (parameter.Length == 1) {
|
---|
643 | return new ILOGLSurfaceGraph(this, null, null, data,
|
---|
644 | parameter[0] as ILArray<float>, m_graphs.Limits);
|
---|
645 | } else if (parameter.Length == 3) {
|
---|
646 | return new ILOGLSurfaceGraph(this, parameter[0] as ILArray<float>, parameter[1] as ILArray<float>,
|
---|
647 | data, parameter[2] as ILArray<float>, m_graphs.Limits);
|
---|
648 | } else
|
---|
649 | throw new ILArgumentException("graph creation: invalid number of arguments! (surface)");
|
---|
650 | case GraphType.Imagesc:
|
---|
651 | return new ILOGLImageSCGraph(this, null, null, data, null, m_graphs.Limits);
|
---|
652 | default:
|
---|
653 | throw new ILInvalidOperationException("Graph type not supported: " + graphType.ToString());
|
---|
654 | }
|
---|
655 | }
|
---|
656 | }
|
---|
657 | /// <summary>
|
---|
658 | /// Create Axis (device dependent)
|
---|
659 | /// </summary>
|
---|
660 | /// <param name="name">specfies axis name (X,Y,ZAxis)</param>
|
---|
661 | /// <param name="clippingView">the global clipping view object for the axis</param>
|
---|
662 | /// <param name="parameters">user defined parameters (implementation dependent)</param>
|
---|
663 | /// <returns>ILAXis object</returns>
|
---|
664 | public ILAxis CreateAxis(AxisNames name, ILClippingData clippingView, params object[] parameters) {
|
---|
665 | switch (name) {
|
---|
666 | case AxisNames.XAxis:
|
---|
667 | return new ILOGLXAxis(clippingView, m_layoutData, this);
|
---|
668 | case AxisNames.YAxis:
|
---|
669 | return new ILOGLYAxis(clippingView, m_layoutData, this);
|
---|
670 | default:
|
---|
671 | return new ILOGLZAxis(clippingView, m_layoutData, this);
|
---|
672 | }
|
---|
673 | }
|
---|
674 | /// <summary>
|
---|
675 | /// create a new device dependent scene graph for hosting shapes, internally used
|
---|
676 | /// </summary>
|
---|
677 | /// <returns>scene graph</returns>
|
---|
678 | public ILSceneGraph CreateSceneGraph() {
|
---|
679 | return new ILSceneGraph(this,m_graphs.Limits);
|
---|
680 | }
|
---|
681 | public ILVertexRenderer CreateVertexRenderer(Type vertexType, ILShape shape) {
|
---|
682 | if (vertexType == typeof(C4bV3f)) {
|
---|
683 | ILVertexRenderer ret;
|
---|
684 | if (shape is ILQuads) {
|
---|
685 | ret = new ILOGLVertexRendererC4bV3f(BeginMode.Quads);
|
---|
686 | } else if (shape is ILPolygon) {
|
---|
687 | ret = new ILOGLVertexRendererC4bV3f(BeginMode.Polygon);
|
---|
688 | } else if (shape is ILLine) {
|
---|
689 | ret = new ILOGLLineRendererC4bV3f(shape.VertexCount);
|
---|
690 | ret.CloseLines = false;
|
---|
691 | } else if (shape is ILTriangle) {
|
---|
692 | ret = new ILOGLVertexRendererC4bV3f(BeginMode.Triangles);
|
---|
693 | } else if (shape is ILQuad) {
|
---|
694 | ret = new ILOGLVertexRendererC4bV3f(BeginMode.Quads);
|
---|
695 | } else if (shape is ILLines) {
|
---|
696 | ret = new ILOGLLinesRendererC4bV3f();
|
---|
697 | } else if (shape is ILTriangles) {
|
---|
698 | ret = new ILOGLVertexRendererC4bV3f(BeginMode.Triangles);
|
---|
699 | } else if (shape is ILPoints) {
|
---|
700 | ret = new ILOGLPointsRendererC4bV3f();
|
---|
701 | } else
|
---|
702 | throw new NotSupportedException ("Shape of type " + shape.GetType().Name + " is not supported!");
|
---|
703 | return ret;
|
---|
704 | } else if (vertexType == typeof(C4fN3fV3f)) {
|
---|
705 | ILOGLVertexRendererC4fN3fV3f ret;
|
---|
706 | if (shape is ILLitQuads) {
|
---|
707 | ret = new ILOGLVertexRendererC4fN3fV3f(BeginMode.Quads);
|
---|
708 | ret.UseLight = true;
|
---|
709 | } else if (shape is ILLitPolygon) {
|
---|
710 | ret = new ILOGLVertexRendererC4fN3fV3f(BeginMode.Polygon);
|
---|
711 | ret.UseLight = true;
|
---|
712 | } else if (shape is ILLitQuad) {
|
---|
713 | ret = new ILOGLVertexRendererC4fN3fV3f(BeginMode.Quads);
|
---|
714 | ret.UseLight = true;
|
---|
715 | } else if (shape is ILLitTriangle) {
|
---|
716 | ret = new ILOGLVertexRendererC4fN3fV3f(BeginMode.Triangles);
|
---|
717 | ret.UseLight = true;
|
---|
718 | } else if (shape is ILLitSphere) {
|
---|
719 | ret = new ILOGLVertexRendererC4fN3fV3f(BeginMode.Triangles);
|
---|
720 | ret.UseLight = true;
|
---|
721 | } else if (shape is ILLitTriangles) {
|
---|
722 | ret = new ILOGLVertexRendererC4fN3fV3f(BeginMode.Triangles);
|
---|
723 | ret.UseLight = true;
|
---|
724 | } else {
|
---|
725 | throw new NotSupportedException("Shape of type " + shape.GetType().Name + " is not supported for vertex type " + vertexType.Name + "!");
|
---|
726 | }
|
---|
727 | return ret;
|
---|
728 | } else {
|
---|
729 | throw new NotSupportedException("VertexType is not supported!");
|
---|
730 | }
|
---|
731 | }
|
---|
732 | internal override IILCreationFactory GetCreationFactory() {
|
---|
733 | return this;
|
---|
734 | }
|
---|
735 |
|
---|
736 | #endregion
|
---|
737 |
|
---|
738 | #region public methods
|
---|
739 |
|
---|
740 | public override Point World2Screen(ILPoint3Df world) {
|
---|
741 | //Vector3 w = new Vector3(world.X, world.Y, world.Z);
|
---|
742 | ILPoint3Df screen;
|
---|
743 | ILGLU.Project(world,m_modelViewMatrix, m_projMatrix, m_viewMatrix, out screen);
|
---|
744 | return new Point((int)screen.X,(int)(ClientSize.Height - screen.Y));
|
---|
745 | }
|
---|
746 | public override Point World2Screen(ILPoint3Df world, double[] modelview) {
|
---|
747 | //Vector3 w = new Vector3(world.X, world.Y, world.Z);
|
---|
748 | ILPoint3Df screen;
|
---|
749 | ILGLU.Project(world,modelview, m_projMatrix, m_viewMatrix, out screen);
|
---|
750 | return new Point((int)screen.X,(int)(ClientSize.Height - screen.Y));
|
---|
751 | }
|
---|
752 |
|
---|
753 | public static void SetupLineStyle(ILLineProperties wireprops) {
|
---|
754 | if (wireprops.Style == LineStyle.Solid) {
|
---|
755 | GL.Disable(EnableCap.LineStipple);
|
---|
756 | } else {
|
---|
757 | int stipFactr = 1;
|
---|
758 | short stipple;
|
---|
759 | if (wireprops.Style != LineStyle.UserPattern)
|
---|
760 | stipple = ILPanel.StippleFromLineStyle(
|
---|
761 | wireprops.Style, ref stipFactr);
|
---|
762 | else {
|
---|
763 | stipple = wireprops.Pattern;
|
---|
764 | stipFactr = (int)wireprops.PatternScale;
|
---|
765 | }
|
---|
766 | GL.Enable(EnableCap.LineStipple);
|
---|
767 | GL.LineStipple(stipFactr, stipple);
|
---|
768 | }
|
---|
769 | if (wireprops.Antialiasing && wireprops.Width > 1)
|
---|
770 | GL.Enable(EnableCap.LineSmooth);
|
---|
771 | else
|
---|
772 | GL.Disable(EnableCap.LineSmooth);
|
---|
773 | GL.LineWidth(wireprops.Width);
|
---|
774 | GL.Color3(wireprops.Color);
|
---|
775 | }
|
---|
776 |
|
---|
777 | private string DebugJoin(string seperator, double[] list) {
|
---|
778 | System.Text.StringBuilder ret = new System.Text.StringBuilder();
|
---|
779 | foreach (object o in list) {
|
---|
780 | ret.Append(seperator + String.Format("{0:f2}",o));
|
---|
781 | }
|
---|
782 | return ret.ToString();
|
---|
783 | }
|
---|
784 |
|
---|
785 | /// <summary>
|
---|
786 | /// Transform 2 world coordinates into screen coords under current matrices
|
---|
787 | /// </summary>
|
---|
788 | /// <param name="p1_3D">world coord point 1</param>
|
---|
789 | /// <param name="p2_3D">world coord point 2</param>
|
---|
790 | /// <param name="p1_2D">(output) screen coord point 1</param>
|
---|
791 | /// <param name="p2_2D">(output) screen coord point 2</param>
|
---|
792 | public override void World2Screen(ILPoint3Df p1_3D, ILPoint3Df p2_3D, out Point p1_2D, out Point p2_2D) {
|
---|
793 | ILPoint3Df s, e;
|
---|
794 | ILGLU.Project(p1_3D, m_modelViewMatrix, m_projMatrix, m_viewMatrix, out s);
|
---|
795 | ILGLU.Project(p2_3D, m_modelViewMatrix, m_projMatrix, m_viewMatrix, out e);
|
---|
796 | p1_2D = new Point((int)s.X,(int)(ClientSize.Height - s.Y));
|
---|
797 | p2_2D = new Point((int)e.X,(int)(ClientSize.Height - e.Y));
|
---|
798 | }
|
---|
799 | /// <summary>
|
---|
800 | /// transform from screen space into world space using OpenGL
|
---|
801 | /// </summary>
|
---|
802 | /// <param name="x">screen X</param>
|
---|
803 | /// <param name="y">screen Y</param>
|
---|
804 | /// <returns>world coord</returns>
|
---|
805 | public override void Screen2World(int x, int y, out ILPoint3Df nearClip, out ILPoint3Df farClip) {
|
---|
806 | // TODO: check the Z coord values. 0.68 here was result of trial only!
|
---|
807 | ILGLU.UnProject(new ILPoint3Df(x, y, 0.0f), m_modelViewMatrix, m_projMatrix, m_viewMatrix, out nearClip);
|
---|
808 | ILGLU.UnProject(new ILPoint3Df(x, y, 1.0f), m_modelViewMatrix, m_projMatrix, m_viewMatrix, out farClip);
|
---|
809 |
|
---|
810 | }
|
---|
811 | public override ILPoint3Df Screen2World2D(int x, int y) {
|
---|
812 | ILPoint3Df ret;
|
---|
813 | ILGLU.UnProject(new ILPoint3Df(x, y, 0), m_modelViewMatrix, m_projMatrix, m_viewMatrix, out ret);
|
---|
814 | ret.Z = m_clippingView.CenterF.Z;
|
---|
815 | return ret;
|
---|
816 | }
|
---|
817 |
|
---|
818 | #endregion
|
---|
819 |
|
---|
820 | #region private helper
|
---|
821 | private void renderBackground () {
|
---|
822 | //determine, which edges are in the back, fill with cube background color
|
---|
823 | GL.Begin(BeginMode.TriangleStrip);
|
---|
824 | GL.Color3(m_cubeBGColor);
|
---|
825 | float xmin = m_clippingView.XMin;
|
---|
826 | float xmax = m_clippingView.XMax;
|
---|
827 | float ymin = m_clippingView.YMin;
|
---|
828 | float ymax = m_clippingView.YMax;
|
---|
829 | float zmin = m_clippingView.ZMin;
|
---|
830 | float zmax = m_clippingView.ZMax;
|
---|
831 | if (!m_camera.LooksFromLeft) {
|
---|
832 | if (m_camera.LooksFromFront) {
|
---|
833 | // left & back border
|
---|
834 | GL.Vertex3(xmin,ymin,zmin);
|
---|
835 | GL.Vertex3(xmin,ymin,zmax);
|
---|
836 | GL.Vertex3(xmin,ymax,zmin);
|
---|
837 | GL.Vertex3(xmin,ymax,zmax);
|
---|
838 | GL.Vertex3(xmax,ymax,zmin);
|
---|
839 | GL.Vertex3(xmax,ymax,zmax);
|
---|
840 | } else {
|
---|
841 | GL.Vertex3(xmin,ymax,zmin); //
|
---|
842 | GL.Vertex3(xmin,ymax,zmax);
|
---|
843 | GL.Vertex3(xmin,ymin,zmin);
|
---|
844 | GL.Vertex3(xmin,ymin,zmax);
|
---|
845 | GL.Vertex3(xmax,ymin,zmin);
|
---|
846 | GL.Vertex3(xmax,ymin,zmax);
|
---|
847 | }
|
---|
848 | } else {
|
---|
849 | if (!m_camera.LooksFromFront) {
|
---|
850 | GL.Vertex3(xmin,ymin,zmin);
|
---|
851 | GL.Vertex3(xmin,ymin,zmax);
|
---|
852 | GL.Vertex3(xmax,ymin,zmin);
|
---|
853 | GL.Vertex3(xmax,ymin,zmax);
|
---|
854 | GL.Vertex3(xmax,ymax,zmin);
|
---|
855 | GL.Vertex3(xmax,ymax,zmax);
|
---|
856 | } else {
|
---|
857 | GL.Vertex3(xmin,ymax,zmin);
|
---|
858 | GL.Vertex3(xmin,ymax,zmax);
|
---|
859 | GL.Vertex3(xmax,ymax,zmin);
|
---|
860 | GL.Vertex3(xmax,ymax,zmax);
|
---|
861 | GL.Vertex3(xmax,ymin,zmin);
|
---|
862 | GL.Vertex3(xmax,ymin,zmax);
|
---|
863 | }
|
---|
864 | }
|
---|
865 | GL.End();
|
---|
866 | // draw bottom
|
---|
867 | if (m_camera.LooksFromTop) {
|
---|
868 | GL.Begin(BeginMode.TriangleStrip);
|
---|
869 | GL.Vertex3(xmin,ymin,zmin);
|
---|
870 | GL.Vertex3(xmax,ymin,zmin);
|
---|
871 | GL.Vertex3(xmin,ymax,zmin);
|
---|
872 | GL.Vertex3(xmax,ymax,zmin);
|
---|
873 | GL.End();
|
---|
874 | }
|
---|
875 | }
|
---|
876 | #endregion
|
---|
877 |
|
---|
878 | }
|
---|
879 | } |
---|