source: git/src/gla.h

Last change on this file was fd0e32a, checked in by Olly Betts <olly@…>, 3 months ago

Raise wxWidgets requirement to >= 3.2.0

Previously it was >= 3.0.0 but it is starting to become hard to
keep everything working with 3.0.0 and the time and effort seems
better directed to other things.

The last 3.0.x release was 3.0.5.1 released 2020-05-02.

wx3.2.0 was released 2022-07-06 and it seems everywhere with wxWidgets
packages upgraded to 3.2.x some time ago.

  • Property mode set to 100644
File size: 9.5 KB
RevLine 
[56da40e]1//
2//  gla.h
3//
4//  Header file for the GLA abstraction layer.
5//
6//  Copyright (C) 2002 Mark R. Shinwell.
[9284d37]7//  Copyright (C) 2003-2025 Olly Betts
[56da40e]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
[ecbc6c18]21//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
[56da40e]22//
23
[caa5fda]24#ifndef gla_h
25#define gla_h
26
[5627cbb]27#include <string>
[bae6a7c]28#include <vector>
29
30using namespace std;
31
[56da40e]32#include "wx.h"
[08253d9]33#include "vector3.h"
[56da40e]34
[1aa3fb7]35#include "glbitmapfont.h"
[1eeb55a]36
[2279fbed]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
[56da40e]49class GfxCore;
50
[5627cbb]51string GetGLSystemDescription();
[cc1a1d9]52
[d67450e]53// #define GLA_DEBUG
[1897247]54
[147847c]55typedef GLdouble glaCoord;
[56da40e]56
[ba828d4]57typedef GLfloat glaTexCoord;
[f336ab9]58
[aa048c3]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,
[f4c5932]73    col_BLUE,
[39b8117]74    col_MAGENTA,
[aa048c3]75    col_LAST // must be the last entry here
76};
77
[56da40e]78class GLAPen {
[aa048c3]79    friend class GLACanvas; // allow direct access to components
80
[a3f83057]81    double components[3] = { 0.0, 0.0, 0.0 }; // red, green, blue
[9cf3688]82
[56da40e]83public:
[a3f83057]84    GLAPen() {}
[56da40e]85
86    void SetColour(double red, double green, double blue); // arguments in range 0 to 1.0
[f383708]87    void Interpolate(const GLAPen&, double how_far);
[56da40e]88
[f7ea0e1]89    double GetRed() const;
90    double GetGreen() const;
91    double GetBlue() const;
[56da40e]92};
93
[db59b02]94class GLAList {
[a3f83057]95    GLuint gl_list = 0;
96    unsigned int flags = 0;
[db59b02]97  public:
[a3f83057]98    GLAList() { }
[db59b02]99    GLAList(GLuint gl_list_, unsigned int flags_)
100        : gl_list(gl_list_), flags(flags_) { }
101    operator bool() { return gl_list != 0; }
[620c0c9]102    bool need_to_generate();
103    void finalise(unsigned int list_flags);
104    bool DrawList() const;
[b3f1bbe]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    }
[db59b02]111};
112
[56da40e]113class GLACanvas : public wxGLCanvas {
[b3f1bbe]114    friend class GLAList; // For flag values.
[620c0c9]115
[8c048fa]116    wxGLContext ctx;
117
[203d2a7]118#ifdef GLA_DEBUG
119    int m_Vertices;
120#endif
121
[dde4fe7]122    GLdouble modelview_matrix[16];
123    GLdouble projection_matrix[16];
124    GLint viewport[4];
125
[c5fc8eb]126    // Viewing volume diameter:
[a3f83057]127    glaCoord m_VolumeDiameter = 1.0;
[56da40e]128
129    // Parameters for plotting data:
[a3f83057]130    double m_Pan = 0.0, m_Tilt = 0.0;
131    double m_Scale = 0.0;
[d67450e]132    Vector3 m_Translation;
[56da40e]133
[9284d37]134    double z_stretch = 1.0;
135
[1aa3fb7]136    BitmapFont m_Font;
[d9b3270]137
[a3f83057]138    GLUquadric* m_Quadric = nullptr;
[a517825]139
[a3f83057]140    GLuint m_Texture = 0;
[cab6f11]141    GLuint m_BlobTexture;
[95ce35f]142    GLuint m_CrossTexture;
[a517825]143
[a3f83057]144    double alpha = 1.0;
[4a1cede]145
[a3f83057]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;
[807f9dd]151    bool save_hints;
[fe075d7]152    enum { UNKNOWN = 0, POINT = 'P', LINES = 'L', SPRITE = 'S' };
[a3f83057]153    int blob_method = UNKNOWN;
154    int cross_method = UNKNOWN;
[1eeb55a]155
[a3f83057]156    int x_size = 0;
157    int y_size = 0;
[90430f2]158
[fd0e32a]159#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
[705adee9]160    double content_scale_factor = 1.0;
[2dacc8bd]161#else
162    static constexpr unsigned content_scale_factor = 1;
163#endif
[705adee9]164
[db59b02]165    vector<GLAList> drawing_lists;
[90430f2]166
167    enum {
168        INVALIDATE_ON_SCALE = 1,
169        INVALIDATE_ON_X_RESIZE = 2,
170        INVALIDATE_ON_Y_RESIZE = 4,
[2dacc8bd]171        INVALIDATE_ON_HIDPI = 8,
172        NEVER_CACHE = 16,
173        CACHED = 32
[90430f2]174    };
[a3f83057]175    mutable unsigned int list_flags = 0;
[bae6a7c]176
[807f9dd]177    wxString vendor, renderer;
178
179    bool CheckVisualFidelity(const unsigned char * target) const;
180
[56da40e]181public:
[84f1ed1]182    GLACanvas(wxWindow* parent, int id);
[56da40e]183    ~GLACanvas();
[2c8b64f]184
[caa5fda]185    static bool check_visual();
186
[1b12b82]187    void FirstShow();
188
[56da40e]189    void Clear();
[8a7f1c5]190    void ClearNative();
[56da40e]191    void StartDrawing();
192    void FinishDrawing();
193
[c5fc8eb]194    void SetVolumeDiameter(glaCoord diameter);
[56da40e]195    void SetDataTransform();
196    void SetIndicatorTransform();
[9cf3688]197
[d2fcc9b]198    void DrawList(unsigned int l);
[11fe902]199    void DrawListZPrepass(unsigned int l);
[147847c]200    void DrawList2D(unsigned int l, glaCoord x, glaCoord y, double rotation);
[b3f1bbe]201    void InvalidateList(unsigned int l) {
202        if (l < drawing_lists.size()) {
203            // Invalidate any existing cached list.
204            drawing_lists[l].invalidate_if(CACHED);
205        }
206    }
207
[d2fcc9b]208    virtual void GenerateList(unsigned int l) = 0;
[9cf3688]209
[aa048c3]210    void SetColour(const GLAPen& pen, double rgb_scale);
211    void SetColour(const GLAPen& pen);
[d1ce9bd]212    void SetColour(gla_colour colour, double rgb_scale);
[aa048c3]213    void SetColour(gla_colour colour);
[4a1cede]214    void SetAlpha(double new_alpha) { alpha = new_alpha; }
[aa048c3]215
[56da40e]216    void DrawText(glaCoord x, glaCoord y, glaCoord z, const wxString& str);
[1eeb55a]217    void DrawIndicatorText(int x, int y, const wxString& str);
[dbd50e2]218    void GetTextExtent(const wxString& str, int * x_ext, int * y_ext) const;
[9cf3688]219
[56da40e]220    void BeginQuadrilaterals();
221    void EndQuadrilaterals();
222    void BeginLines();
223    void EndLines();
[dde4fe7]224    void BeginTriangleStrip();
225    void EndTriangleStrip();
[56da40e]226    void BeginTriangles();
227    void EndTriangles();
228    void BeginPolyline();
229    void EndPolyline();
[0642381]230    void BeginPolyloop();
231    void EndPolyloop();
[45aa1d6]232    void BeginPolygon();
233    void EndPolygon();
[51eab3b]234    void BeginPoints();
235    void EndPoints();
[e633bb1]236    void BeginBlobs();
237    void EndBlobs();
[86fe6e4]238    void BeginCrosses();
239    void EndCrosses();
[9cf3688]240
[522e0bd]241    void DrawRectangle(gla_colour fill, gla_colour edge,
[d67450e]242                       glaCoord x0, glaCoord y0, glaCoord w, glaCoord h);
[aa048c3]243    void DrawShadedRectangle(const GLAPen & fill_bot, const GLAPen & fill_top,
244                             glaCoord x0, glaCoord y0, glaCoord w, glaCoord h);
245    void DrawCircle(gla_colour edge, gla_colour fill, glaCoord cx, glaCoord cy, glaCoord radius);
246    void DrawSemicircle(gla_colour edge, gla_colour fill, glaCoord cx, glaCoord cy, glaCoord radius, glaCoord start);
[9cf3688]247
[e633bb1]248    void DrawBlob(glaCoord x, glaCoord y, glaCoord z);
[81aea4e]249    void DrawBlob(glaCoord x, glaCoord y);
[86fe6e4]250    void DrawCross(glaCoord x, glaCoord y, glaCoord z);
[e633bb1]251    void DrawRing(glaCoord x, glaCoord y);
[9cf3688]252
[f336ab9]253    void PlaceVertex(const Vector3 & v, glaTexCoord tex_x, glaTexCoord tex_y) {
[b839829]254        PlaceVertex(v.GetX(), v.GetY(), v.GetZ(), tex_x, tex_y);
255    }
[d67450e]256    void PlaceVertex(const Vector3 & v) {
257        PlaceVertex(v.GetX(), v.GetY(), v.GetZ());
258    }
[56da40e]259    void PlaceVertex(glaCoord x, glaCoord y, glaCoord z);
[f336ab9]260    void PlaceVertex(glaCoord x, glaCoord y, glaCoord z,
261                     glaTexCoord tex_x, glaTexCoord tex_y);
[56da40e]262    void PlaceIndicatorVertex(glaCoord x, glaCoord y);
[203d2a7]263
[d67450e]264    void PlaceNormal(const Vector3 &v);
[9cf3688]265
[56da40e]266    void EnableDashedLines();
267    void DisableDashedLines();
268
[d67450e]269    void EnableSmoothPolygons(bool filled);
[1b12b82]270    void DisableSmoothPolygons();
271
[08253d9]272    void SetRotation(double pan, double tilt) {
273        m_Pan = pan;
274        m_Tilt = tilt;
275    }
[147847c]276    void SetScale(double);
[d67450e]277    void SetTranslation(const Vector3 &v) {
278        m_Translation = v;
279    }
280    void AddTranslation(const Vector3 &v) {
281        m_Translation += v;
282    }
283    const Vector3 & GetTranslation() const {
284        return m_Translation;
285    }
[56da40e]286    void AddTranslationScreenCoordinates(int dx, int dy);
287
[147847c]288    bool Transform(const Vector3 & v, glaCoord* x_out, glaCoord* y_out, glaCoord* z_out) const;
289    void ReverseTransform(double x, double y, glaCoord* x_out, glaCoord* y_out, glaCoord* z_out) const;
[56da40e]290
[9284d37]291    void SetZStretch(double z_stretch_) { z_stretch = z_stretch_; }
292
[1aa3fb7]293    int GetFontSize() const { return m_Font.get_font_size(); }
[087bc72]294
[d67450e]295    void ToggleSmoothShading();
296    bool GetSmoothShading() const { return m_SmoothShading; }
297
[147847c]298    double SurveyUnitsAcrossViewport() const;
[6abab84]299
[a517825]300    void ToggleTextured();
301    bool GetTextured() const { return m_Textured; }
302
[6abab84]303    void TogglePerspective() { m_Perspective = !m_Perspective; }
304    bool GetPerspective() const { return m_Perspective; }
[045e2af]305
[c60062d]306    void ToggleFog() { m_Fog = !m_Fog; }
307    bool GetFog() const { return m_Fog; }
308
[db452ae]309    void ToggleAntiAlias() { m_AntiAlias = !m_AntiAlias; }
310    bool GetAntiAlias() const { return m_AntiAlias; }
311
[1ada489]312    bool SaveScreenshot(const wxString & fnm, wxBitmapType type) const;
[aea4f8b]313
314    void ReadPixels(int width, int height, unsigned char * buf) const;
[f9ca87c]315
316    void PolygonOffset(bool on) const;
[90430f2]317
[2dacc8bd]318    int GetXSize() const {
319        list_flags |= INVALIDATE_ON_X_RESIZE;
320        return x_size;
321    }
322
323    int GetYSize() const {
324        list_flags |= INVALIDATE_ON_Y_RESIZE;
325        return y_size;
326    }
327
[fd0e32a]328#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
[2dacc8bd]329    double GetContentScaleFactor() const {
330        list_flags |= INVALIDATE_ON_HIDPI;
331        return content_scale_factor;
332    }
333
334    void UpdateContentScaleFactor();
335    void OnMove(wxMoveEvent & event);
336#else
337    // wxWindow::GetContentScaleFactor() will always return 1.0, so arrange
338    // things so it's a compile-time constant the compiler can optimise away.
[ecf9e9f2]339    // Use a macro so we can return unsigned instead of double without a lot
340    // of pain from trying to override a virtual method while changing the
341    // return type.
342# define GetContentScaleFactor() 1u
[2dacc8bd]343    void UpdateContentScaleFactor() { }
344#endif
[90430f2]345
346    void OnSize(wxSizeEvent & event);
[70acad9]347
348    glaCoord GetVolumeDiameter() const { return m_VolumeDiameter; }
[9071cf5]349
[705adee9]350    void ScaleMouseEvent(wxMouseEvent& e) const {
351        e.SetX(e.GetX() * content_scale_factor);
352        e.SetY(e.GetY() * content_scale_factor);
353    }
354
[9071cf5]355private:
356    DECLARE_EVENT_TABLE()
[56da40e]357};
[caa5fda]358
359#endif
Note: See TracBrowser for help on using the repository browser.