source: git/src/gla.h @ 8a7804fb

Last change on this file since 8a7804fb was 0b99107, checked in by Olly Betts <olly@…>, 4 days ago

Eliminate old FSF addresses

Update GPL/LGPL licence files and boilerplate to direct people who
didn't receive the licence text to the FSF website, as the current
versions of the FSF licence texts now do, rather than giving a postal
address.

  • Property mode set to 100644
File size: 9.1 KB
Line 
1//
2//  gla.h
3//
4//  Header file for the GLA abstraction layer.
5//
6//  Copyright (C) 2002 Mark R. Shinwell.
7//  Copyright (C) 2003-2025 Olly Betts
8//
9//  This program is free software; you can redistribute it and/or modify
10//  it under the terms of the GNU General Public License as published by
11//  the Free Software Foundation; either version 2 of the License, or
12//  (at your option) any later version.
13//
14//  This program is distributed in the hope that it will be useful,
15//  but WITHOUT ANY WARRANTY; without even the implied warranty of
16//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17//  GNU General Public License for more details.
18//
19//  You should have received a copy of the GNU General Public License
20//  along with this program; if not, see
21//  <https://www.gnu.org/licenses/>.
22//
23
24#ifndef gla_h
25#define gla_h
26
27#include <wx/wx.h>
28#if !wxUSE_GLCANVAS
29# error wxWidgets must be built with wxUSE_GLCANVAS set to 1
30#endif
31#include <wx/glcanvas.h>
32
33#include "vector3.h"
34
35#include "glbitmapfont.h"
36
37#ifdef HAVE_GL_GL_H
38# include <GL/gl.h>
39#elif defined HAVE_OPENGL_GL_H
40# include <OpenGL/gl.h>
41#endif
42
43#ifdef HAVE_GL_GLU_H
44# include <GL/glu.h>
45#elif defined HAVE_OPENGL_GLU_H
46# include <OpenGL/glu.h>
47#endif
48
49#include <string>
50#include <vector>
51
52using namespace std;
53
54class GfxCore;
55
56string GetGLSystemDescription();
57
58// #define GLA_DEBUG
59
60typedef GLdouble glaCoord;
61
62typedef GLfloat glaTexCoord;
63
64// Colours for drawing.  Don't reorder these!
65enum gla_colour {
66    col_BLACK = 0,
67    col_GREY,
68    col_LIGHT_GREY,
69    col_LIGHT_GREY_2,
70    col_DARK_GREY,
71    col_WHITE,
72    col_TURQUOISE,
73    col_GREEN,
74    col_INDICATOR_1,
75    col_INDICATOR_2,
76    col_YELLOW,
77    col_RED,
78    col_BLUE,
79    col_MAGENTA,
80    col_LAST // must be the last entry here
81};
82
83class GLAPen {
84    friend class GLACanvas; // allow direct access to components
85
86    double components[3] = { 0.0, 0.0, 0.0 }; // red, green, blue
87
88public:
89    GLAPen() {}
90
91    void SetColour(double red, double green, double blue); // arguments in range 0 to 1.0
92    void Interpolate(const GLAPen&, double how_far);
93
94    double GetRed() const;
95    double GetGreen() const;
96    double GetBlue() const;
97};
98
99class GLAList {
100    GLuint gl_list = 0;
101    unsigned int flags = 0;
102  public:
103    GLAList() { }
104    GLAList(GLuint gl_list_, unsigned int flags_)
105        : gl_list(gl_list_), flags(flags_) { }
106    operator bool() { return gl_list != 0; }
107    bool need_to_generate();
108    void finalise(unsigned int list_flags);
109    bool DrawList() const;
110    void invalidate_if(unsigned int mask) {
111        // If flags == NEVER_CACHE, the list won't be invalidated (unless
112        // mask is 0, which isn't a normal thing to pass).
113        if (flags & mask)
114            flags = 0;
115    }
116};
117
118class GLACanvas : public wxGLCanvas {
119    friend class GLAList; // For flag values.
120
121    wxGLContext ctx;
122
123#ifdef GLA_DEBUG
124    int m_Vertices;
125#endif
126
127    GLdouble modelview_matrix[16];
128    GLdouble projection_matrix[16];
129    GLint viewport[4];
130
131    // Viewing volume diameter:
132    glaCoord m_VolumeDiameter = 1.0;
133
134    // Parameters for plotting data:
135    double m_Pan = 0.0, m_Tilt = 0.0;
136    double m_Scale = 0.0;
137    Vector3 m_Translation;
138
139    double z_stretch = 1.0;
140
141    BitmapFont m_Font;
142
143    GLUquadric* m_Quadric = nullptr;
144
145    GLuint m_Texture = 0;
146    GLuint m_BlobTexture;
147    GLuint m_CrossTexture;
148
149    double alpha = 1.0;
150
151    bool m_SmoothShading = false;
152    bool m_Textured = false;
153    bool m_Perspective = false;
154    bool m_Fog = false;
155    bool m_AntiAlias = false;
156    bool save_hints;
157    enum { UNKNOWN = 0, POINT = 'P', LINES = 'L', SPRITE = 'S' };
158    int blob_method = UNKNOWN;
159    int cross_method = UNKNOWN;
160
161    int x_size = 0;
162    int y_size = 0;
163
164    double dpi_scale_factor = 1.0;
165
166    vector<GLAList> drawing_lists;
167
168    enum {
169        INVALIDATE_ON_SCALE = 1,
170        INVALIDATE_ON_X_RESIZE = 2,
171        INVALIDATE_ON_Y_RESIZE = 4,
172        INVALIDATE_ON_HIDPI = 8,
173        NEVER_CACHE = 16,
174        CACHED = 32
175    };
176    mutable unsigned int list_flags = 0;
177
178    wxString vendor, renderer;
179
180    bool CheckVisualFidelity(const unsigned char * target) const;
181
182    void UpdateSize();
183
184public:
185    GLACanvas(wxWindow* parent, int id);
186    ~GLACanvas();
187
188    static bool check_visual();
189
190    void FirstShow();
191
192    void Clear();
193    void ClearNative();
194    void StartDrawing();
195    void FinishDrawing();
196
197    void SetVolumeDiameter(glaCoord diameter);
198    void SetDataTransform();
199    void SetIndicatorTransform();
200
201    void DrawList(unsigned int l);
202    void DrawListZPrepass(unsigned int l);
203    void DrawList2D(unsigned int l, glaCoord x, glaCoord y, double rotation);
204    void InvalidateList(unsigned int l) {
205        if (l < drawing_lists.size()) {
206            // Invalidate any existing cached list.
207            drawing_lists[l].invalidate_if(CACHED);
208        }
209    }
210
211    virtual void GenerateList(unsigned int l) = 0;
212
213    void SetColour(const GLAPen& pen, double rgb_scale);
214    void SetColour(const GLAPen& pen);
215    void SetColour(gla_colour colour, double rgb_scale);
216    void SetColour(gla_colour colour);
217    void SetAlpha(double new_alpha) { alpha = new_alpha; }
218
219    void DrawText(glaCoord x, glaCoord y, glaCoord z, const wxString& str);
220    void DrawIndicatorText(int x, int y, const wxString& str);
221    void GetTextExtent(const wxString& str, int * x_ext, int * y_ext) const;
222
223    void BeginQuadrilaterals();
224    void EndQuadrilaterals();
225    void BeginLines();
226    void EndLines();
227    void BeginTriangleStrip();
228    void EndTriangleStrip();
229    void BeginTriangles();
230    void EndTriangles();
231    void BeginPolyline();
232    void EndPolyline();
233    void BeginPolyloop();
234    void EndPolyloop();
235    void BeginPolygon();
236    void EndPolygon();
237    void BeginPoints();
238    void EndPoints();
239    void BeginBlobs();
240    void EndBlobs();
241    void BeginCrosses();
242    void EndCrosses();
243
244    void DrawRectangle(gla_colour fill, gla_colour edge,
245                       glaCoord x0, glaCoord y0, glaCoord w, glaCoord h);
246    void DrawShadedRectangle(const GLAPen & fill_bot, const GLAPen & fill_top,
247                             glaCoord x0, glaCoord y0, glaCoord w, glaCoord h);
248    void DrawCircle(gla_colour edge, gla_colour fill, glaCoord cx, glaCoord cy, glaCoord radius);
249    void DrawSemicircle(gla_colour edge, gla_colour fill, glaCoord cx, glaCoord cy, glaCoord radius, glaCoord start);
250
251    void DrawBlob(glaCoord x, glaCoord y, glaCoord z);
252    void DrawBlob(glaCoord x, glaCoord y);
253    void DrawCross(glaCoord x, glaCoord y, glaCoord z);
254    void DrawRing(glaCoord x, glaCoord y);
255
256    void PlaceVertex(const Vector3 & v, glaTexCoord tex_x, glaTexCoord tex_y) {
257        PlaceVertex(v.GetX(), v.GetY(), v.GetZ(), tex_x, tex_y);
258    }
259    void PlaceVertex(const Vector3 & v) {
260        PlaceVertex(v.GetX(), v.GetY(), v.GetZ());
261    }
262    void PlaceVertex(glaCoord x, glaCoord y, glaCoord z);
263    void PlaceVertex(glaCoord x, glaCoord y, glaCoord z,
264                     glaTexCoord tex_x, glaTexCoord tex_y);
265    void PlaceIndicatorVertex(glaCoord x, glaCoord y);
266
267    void PlaceNormal(const Vector3 &v);
268
269    void EnableDashedLines();
270    void DisableDashedLines();
271
272    void EnableSmoothPolygons(bool filled);
273    void DisableSmoothPolygons();
274
275    void SetRotation(double pan, double tilt) {
276        m_Pan = pan;
277        m_Tilt = tilt;
278    }
279    void SetScale(double);
280    void SetTranslation(const Vector3 &v) {
281        m_Translation = v;
282    }
283    void AddTranslation(const Vector3 &v) {
284        m_Translation += v;
285    }
286    const Vector3 & GetTranslation() const {
287        return m_Translation;
288    }
289    void AddTranslationScreenCoordinates(int dx, int dy);
290
291    bool Transform(const Vector3 & v, glaCoord* x_out, glaCoord* y_out, glaCoord* z_out) const;
292    void ReverseTransform(double x, double y, glaCoord* x_out, glaCoord* y_out, glaCoord* z_out) const;
293
294    void SetZStretch(double z_stretch_) { z_stretch = z_stretch_; }
295
296    int GetFontSize() const { return m_Font.get_font_size(); }
297
298    void ToggleSmoothShading();
299    bool GetSmoothShading() const { return m_SmoothShading; }
300
301    double SurveyUnitsAcrossViewport() const;
302
303    void ToggleTextured();
304    bool GetTextured() const { return m_Textured; }
305
306    void TogglePerspective() { m_Perspective = !m_Perspective; }
307    bool GetPerspective() const { return m_Perspective; }
308
309    void ToggleFog() { m_Fog = !m_Fog; }
310    bool GetFog() const { return m_Fog; }
311
312    void ToggleAntiAlias() { m_AntiAlias = !m_AntiAlias; }
313    bool GetAntiAlias() const { return m_AntiAlias; }
314
315    bool SaveScreenshot(const wxString & fnm, wxBitmapType type) const;
316
317    void ReadPixels(int width, int height, unsigned char * buf) const;
318
319    void PolygonOffset(bool on) const;
320
321    int GetXSize() const {
322        list_flags |= INVALIDATE_ON_X_RESIZE;
323        return x_size;
324    }
325
326    int GetYSize() const {
327        list_flags |= INVALIDATE_ON_Y_RESIZE;
328        return y_size;
329    }
330
331    double GetDPIScaleFactor() const {
332        list_flags |= INVALIDATE_ON_HIDPI;
333        return dpi_scale_factor;
334    }
335
336    void OnMove(wxMoveEvent & event);
337
338    void OnSize(wxSizeEvent & event);
339
340    glaCoord GetVolumeDiameter() const { return m_VolumeDiameter; }
341
342    void ScaleMouseEvent(wxMouseEvent& e) const {
343#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
344        auto content_scale_factor = GetContentScaleFactor();
345
346        e.SetX(e.GetX() * content_scale_factor);
347        e.SetY(e.GetY() * content_scale_factor);
348#else
349        (void)e;
350#endif
351    }
352
353private:
354    DECLARE_EVENT_TABLE()
355};
356
357#endif
Note: See TracBrowser for help on using the repository browser.