source: git/src/gla.h @ 889f75e

v1.4.18
Last change on this file since 889f75e was 2ef89f9, checked in by Olly Betts <olly@…>, 12 days ago

Fully resolve HiDPI scaling on Microsoft Windows

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