source: git/src/gla.h @ 92cfa6ee

stereo-2025
Last change on this file since 92cfa6ee was a3f83057, checked in by Olly Betts <olly@…>, 7 months ago

Use C++11 member initialisation where sensible

  • Property mode set to 100644
File size: 9.5 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,2004,2005,2006,2007,2011,2012,2014,2017,2018 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, write to the Free Software
21//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22//
23
24#ifndef gla_h
25#define gla_h
26
27#include <string>
28#include <vector>
29
30using namespace std;
31
32#include "wx.h"
33#include "aventypes.h"
34#include "vector3.h"
35
36#include "glbitmapfont.h"
37
38class GfxCore;
39
40string GetGLSystemDescription();
41
42// #define GLA_DEBUG
43
44typedef GLdouble glaCoord;
45
46typedef GLfloat glaTexCoord;
47
48// Colours for drawing.  Don't reorder these!
49enum gla_colour {
50    col_BLACK = 0,
51    col_GREY,
52    col_LIGHT_GREY,
53    col_LIGHT_GREY_2,
54    col_DARK_GREY,
55    col_WHITE,
56    col_TURQUOISE,
57    col_GREEN,
58    col_INDICATOR_1,
59    col_INDICATOR_2,
60    col_YELLOW,
61    col_RED,
62    col_BLUE,
63    col_MAGENTA,
64    col_LAST // must be the last entry here
65};
66
67class GLAPen {
68    friend class GLACanvas; // allow direct access to components
69
70    double components[3] = { 0.0, 0.0, 0.0 }; // red, green, blue
71
72public:
73    GLAPen() {}
74
75    void SetColour(double red, double green, double blue); // arguments in range 0 to 1.0
76    void Interpolate(const GLAPen&, double how_far);
77
78    double GetRed() const;
79    double GetGreen() const;
80    double GetBlue() const;
81};
82
83class GLAList {
84    GLuint gl_list = 0;
85    unsigned int flags = 0;
86  public:
87    GLAList() { }
88    GLAList(GLuint gl_list_, unsigned int flags_)
89        : gl_list(gl_list_), flags(flags_) { }
90    operator bool() { return gl_list != 0; }
91    bool need_to_generate();
92    void finalise(unsigned int list_flags);
93    bool DrawList() const;
94    void invalidate_if(unsigned int mask) {
95        // If flags == NEVER_CACHE, the list won't be invalidated (unless
96        // mask is 0, which isn't a normal thing to pass).
97        if (flags & mask)
98            flags = 0;
99    }
100};
101
102class GLACanvas : public wxGLCanvas {
103    friend class GLAList; // For flag values.
104
105    wxGLContext ctx;
106
107#ifdef GLA_DEBUG
108    int m_Vertices;
109#endif
110
111    GLdouble modelview_matrix[16];
112    GLdouble projection_matrix[16];
113    GLint viewport[4];
114
115    // Viewing volume diameter:
116    glaCoord m_VolumeDiameter = 1.0;
117
118    // Parameters for plotting data:
119    double m_Pan = 0.0, m_Tilt = 0.0;
120    double m_Scale = 0.0;
121    Vector3 m_Translation;
122
123    BitmapFont m_Font;
124
125    GLUquadric* m_Quadric = nullptr;
126
127    GLuint m_Texture = 0;
128    GLuint m_BlobTexture;
129    GLuint m_CrossTexture;
130
131    double alpha = 1.0;
132
133    bool m_SmoothShading = false;
134    bool m_Textured = false;
135    bool m_Perspective = false;
136    bool m_Fog = false;
137    bool m_AntiAlias = false;
138    bool save_hints;
139    enum { UNKNOWN = 0, POINT = 'P', LINES = 'L', SPRITE = 'S' };
140    int blob_method = UNKNOWN;
141    int cross_method = UNKNOWN;
142
143    int x_size = 0;
144    int y_size = 0;
145
146    // wxHAS_DPI_INDEPENDENT_PIXELS is new in 3.1.6.  In older versions we just
147    // always do the scaling which is slightly less efficient for platforms
148    // where pixel coordinates don't scale with DPI.
149#if defined wxHAS_DPI_INDEPENDENT_PIXELS || \
150    !wxCHECK_VERSION(3,1,6)
151# define HAS_DPI_INDEPENDENT_PIXELS
152#endif
153
154#ifdef HAS_DPI_INDEPENDENT_PIXELS
155    double content_scale_factor = 1.0;
156#else
157    static constexpr unsigned content_scale_factor = 1;
158#endif
159
160    vector<GLAList> drawing_lists;
161
162    enum {
163        INVALIDATE_ON_SCALE = 1,
164        INVALIDATE_ON_X_RESIZE = 2,
165        INVALIDATE_ON_Y_RESIZE = 4,
166        INVALIDATE_ON_HIDPI = 8,
167        NEVER_CACHE = 16,
168        CACHED = 32
169    };
170    mutable unsigned int list_flags = 0;
171
172    wxString vendor, renderer;
173
174    bool CheckVisualFidelity(const unsigned char * target) const;
175
176public:
177    GLACanvas(wxWindow* parent, int id);
178    ~GLACanvas();
179
180    static bool check_visual();
181
182    void FirstShow();
183
184    void Clear();
185    void ClearNative();
186    void StartDrawing();
187    void FinishDrawing();
188
189    void SetVolumeDiameter(glaCoord diameter);
190    void SetDataTransform();
191    void SetIndicatorTransform();
192
193    void DrawList(unsigned int l);
194    void DrawListZPrepass(unsigned int l);
195    void DrawList2D(unsigned int l, glaCoord x, glaCoord y, double rotation);
196    void InvalidateList(unsigned int l) {
197        if (l < drawing_lists.size()) {
198            // Invalidate any existing cached list.
199            drawing_lists[l].invalidate_if(CACHED);
200        }
201    }
202
203    virtual void GenerateList(unsigned int l) = 0;
204
205    void SetColour(const GLAPen& pen, double rgb_scale);
206    void SetColour(const GLAPen& pen);
207    void SetColour(gla_colour colour, double rgb_scale);
208    void SetColour(gla_colour colour);
209    void SetAlpha(double new_alpha) { alpha = new_alpha; }
210
211    void DrawText(glaCoord x, glaCoord y, glaCoord z, const wxString& str);
212    void DrawIndicatorText(int x, int y, const wxString& str);
213    void GetTextExtent(const wxString& str, int * x_ext, int * y_ext) const;
214
215    void BeginQuadrilaterals();
216    void EndQuadrilaterals();
217    void BeginLines();
218    void EndLines();
219    void BeginTriangleStrip();
220    void EndTriangleStrip();
221    void BeginTriangles();
222    void EndTriangles();
223    void BeginPolyline();
224    void EndPolyline();
225    void BeginPolyloop();
226    void EndPolyloop();
227    void BeginPolygon();
228    void EndPolygon();
229    void BeginPoints();
230    void EndPoints();
231    void BeginBlobs();
232    void EndBlobs();
233    void BeginCrosses();
234    void EndCrosses();
235
236    void DrawRectangle(gla_colour fill, gla_colour edge,
237                       glaCoord x0, glaCoord y0, glaCoord w, glaCoord h);
238    void DrawShadedRectangle(const GLAPen & fill_bot, const GLAPen & fill_top,
239                             glaCoord x0, glaCoord y0, glaCoord w, glaCoord h);
240    void DrawCircle(gla_colour edge, gla_colour fill, glaCoord cx, glaCoord cy, glaCoord radius);
241    void DrawSemicircle(gla_colour edge, gla_colour fill, glaCoord cx, glaCoord cy, glaCoord radius, glaCoord start);
242
243    void DrawBlob(glaCoord x, glaCoord y, glaCoord z);
244    void DrawBlob(glaCoord x, glaCoord y);
245    void DrawCross(glaCoord x, glaCoord y, glaCoord z);
246    void DrawRing(glaCoord x, glaCoord y);
247
248    void PlaceVertex(const Vector3 & v, glaTexCoord tex_x, glaTexCoord tex_y) {
249        PlaceVertex(v.GetX(), v.GetY(), v.GetZ(), tex_x, tex_y);
250    }
251    void PlaceVertex(const Vector3 & v) {
252        PlaceVertex(v.GetX(), v.GetY(), v.GetZ());
253    }
254    void PlaceVertex(glaCoord x, glaCoord y, glaCoord z);
255    void PlaceVertex(glaCoord x, glaCoord y, glaCoord z,
256                     glaTexCoord tex_x, glaTexCoord tex_y);
257    void PlaceIndicatorVertex(glaCoord x, glaCoord y);
258
259    void PlaceNormal(const Vector3 &v);
260
261    void EnableDashedLines();
262    void DisableDashedLines();
263
264    void EnableSmoothPolygons(bool filled);
265    void DisableSmoothPolygons();
266
267    void SetRotation(double pan, double tilt) {
268        m_Pan = pan;
269        m_Tilt = tilt;
270    }
271    void SetScale(double);
272    void SetTranslation(const Vector3 &v) {
273        m_Translation = v;
274    }
275    void AddTranslation(const Vector3 &v) {
276        m_Translation += v;
277    }
278    const Vector3 & GetTranslation() const {
279        return m_Translation;
280    }
281    void AddTranslationScreenCoordinates(int dx, int dy);
282
283    bool Transform(const Vector3 & v, glaCoord* x_out, glaCoord* y_out, glaCoord* z_out) const;
284    void ReverseTransform(double x, double y, glaCoord* x_out, glaCoord* y_out, glaCoord* z_out) const;
285
286    int GetFontSize() const { return m_Font.get_font_size(); }
287
288    void ToggleSmoothShading();
289    bool GetSmoothShading() const { return m_SmoothShading; }
290
291    double SurveyUnitsAcrossViewport() const;
292
293    void ToggleTextured();
294    bool GetTextured() const { return m_Textured; }
295
296    void TogglePerspective() { m_Perspective = !m_Perspective; }
297    bool GetPerspective() const { return m_Perspective; }
298
299    void ToggleFog() { m_Fog = !m_Fog; }
300    bool GetFog() const { return m_Fog; }
301
302    void ToggleAntiAlias() { m_AntiAlias = !m_AntiAlias; }
303    bool GetAntiAlias() const { return m_AntiAlias; }
304
305    bool SaveScreenshot(const wxString & fnm, wxBitmapType type) const;
306
307    void ReadPixels(int width, int height, unsigned char * buf) const;
308
309    void PolygonOffset(bool on) const;
310
311    int GetXSize() const {
312        list_flags |= INVALIDATE_ON_X_RESIZE;
313        return x_size;
314    }
315
316    int GetYSize() const {
317        list_flags |= INVALIDATE_ON_Y_RESIZE;
318        return y_size;
319    }
320
321#ifdef HAS_DPI_INDEPENDENT_PIXELS
322    double GetContentScaleFactor() const {
323        list_flags |= INVALIDATE_ON_HIDPI;
324        return content_scale_factor;
325    }
326
327    void UpdateContentScaleFactor();
328    void OnMove(wxMoveEvent & event);
329#else
330    // wxWindow::GetContentScaleFactor() will always return 1.0, so arrange
331    // things so it's a compile-time constant the compiler can optimise away.
332    // Use a macro so we can return unsigned instead of double without a lot
333    // of pain from trying to override a virtual method while changing the
334    // return type.
335# define GetContentScaleFactor() 1u
336    void UpdateContentScaleFactor() { }
337#endif
338
339    void OnSize(wxSizeEvent & event);
340
341    glaCoord GetVolumeDiameter() const { return m_VolumeDiameter; }
342
343    void ScaleMouseEvent(wxMouseEvent& e) const {
344        e.SetX(e.GetX() * content_scale_factor);
345        e.SetY(e.GetY() * content_scale_factor);
346    }
347
348private:
349    DECLARE_EVENT_TABLE()
350};
351
352#endif
Note: See TracBrowser for help on using the repository browser.