source: git/src/gla.h

Last change on this file 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
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
[0b99107]20//  along with this program; if not, see
21//  <https://www.gnu.org/licenses/>.
[56da40e]22//
23
[caa5fda]24#ifndef gla_h
25#define gla_h
26
[a871ac3]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>
[bae6a7c]32
[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
[a871ac3]49#include <string>
50#include <vector>
51
52using namespace std;
53
[56da40e]54class GfxCore;
55
[5627cbb]56string GetGLSystemDescription();
[cc1a1d9]57
[d67450e]58// #define GLA_DEBUG
[1897247]59
[147847c]60typedef GLdouble glaCoord;
[56da40e]61
[ba828d4]62typedef GLfloat glaTexCoord;
[f336ab9]63
[aa048c3]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,
[f4c5932]78    col_BLUE,
[39b8117]79    col_MAGENTA,
[aa048c3]80    col_LAST // must be the last entry here
81};
82
[56da40e]83class GLAPen {
[aa048c3]84    friend class GLACanvas; // allow direct access to components
85
[a3f83057]86    double components[3] = { 0.0, 0.0, 0.0 }; // red, green, blue
[9cf3688]87
[56da40e]88public:
[a3f83057]89    GLAPen() {}
[56da40e]90
91    void SetColour(double red, double green, double blue); // arguments in range 0 to 1.0
[f383708]92    void Interpolate(const GLAPen&, double how_far);
[56da40e]93
[f7ea0e1]94    double GetRed() const;
95    double GetGreen() const;
96    double GetBlue() const;
[56da40e]97};
98
[db59b02]99class GLAList {
[a3f83057]100    GLuint gl_list = 0;
101    unsigned int flags = 0;
[db59b02]102  public:
[a3f83057]103    GLAList() { }
[db59b02]104    GLAList(GLuint gl_list_, unsigned int flags_)
105        : gl_list(gl_list_), flags(flags_) { }
106    operator bool() { return gl_list != 0; }
[620c0c9]107    bool need_to_generate();
108    void finalise(unsigned int list_flags);
109    bool DrawList() const;
[b3f1bbe]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    }
[db59b02]116};
117
[56da40e]118class GLACanvas : public wxGLCanvas {
[b3f1bbe]119    friend class GLAList; // For flag values.
[620c0c9]120
[8c048fa]121    wxGLContext ctx;
122
[203d2a7]123#ifdef GLA_DEBUG
124    int m_Vertices;
125#endif
126
[dde4fe7]127    GLdouble modelview_matrix[16];
128    GLdouble projection_matrix[16];
129    GLint viewport[4];
130
[c5fc8eb]131    // Viewing volume diameter:
[a3f83057]132    glaCoord m_VolumeDiameter = 1.0;
[56da40e]133
134    // Parameters for plotting data:
[a3f83057]135    double m_Pan = 0.0, m_Tilt = 0.0;
136    double m_Scale = 0.0;
[d67450e]137    Vector3 m_Translation;
[56da40e]138
[9284d37]139    double z_stretch = 1.0;
140
[1aa3fb7]141    BitmapFont m_Font;
[d9b3270]142
[a3f83057]143    GLUquadric* m_Quadric = nullptr;
[a517825]144
[a3f83057]145    GLuint m_Texture = 0;
[cab6f11]146    GLuint m_BlobTexture;
[95ce35f]147    GLuint m_CrossTexture;
[a517825]148
[a3f83057]149    double alpha = 1.0;
[4a1cede]150
[a3f83057]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;
[807f9dd]156    bool save_hints;
[fe075d7]157    enum { UNKNOWN = 0, POINT = 'P', LINES = 'L', SPRITE = 'S' };
[a3f83057]158    int blob_method = UNKNOWN;
159    int cross_method = UNKNOWN;
[1eeb55a]160
[a3f83057]161    int x_size = 0;
162    int y_size = 0;
[90430f2]163
[eadf5fd]164    double dpi_scale_factor = 1.0;
[705adee9]165
[db59b02]166    vector<GLAList> drawing_lists;
[90430f2]167
168    enum {
169        INVALIDATE_ON_SCALE = 1,
170        INVALIDATE_ON_X_RESIZE = 2,
171        INVALIDATE_ON_Y_RESIZE = 4,
[2dacc8bd]172        INVALIDATE_ON_HIDPI = 8,
173        NEVER_CACHE = 16,
174        CACHED = 32
[90430f2]175    };
[a3f83057]176    mutable unsigned int list_flags = 0;
[bae6a7c]177
[807f9dd]178    wxString vendor, renderer;
179
180    bool CheckVisualFidelity(const unsigned char * target) const;
181
[5f8464d]182    void UpdateSize();
183
[56da40e]184public:
[84f1ed1]185    GLACanvas(wxWindow* parent, int id);
[56da40e]186    ~GLACanvas();
[2c8b64f]187
[caa5fda]188    static bool check_visual();
189
[1b12b82]190    void FirstShow();
191
[56da40e]192    void Clear();
[8a7f1c5]193    void ClearNative();
[56da40e]194    void StartDrawing();
195    void FinishDrawing();
196
[c5fc8eb]197    void SetVolumeDiameter(glaCoord diameter);
[56da40e]198    void SetDataTransform();
199    void SetIndicatorTransform();
[9cf3688]200
[d2fcc9b]201    void DrawList(unsigned int l);
[11fe902]202    void DrawListZPrepass(unsigned int l);
[147847c]203    void DrawList2D(unsigned int l, glaCoord x, glaCoord y, double rotation);
[b3f1bbe]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
[d2fcc9b]211    virtual void GenerateList(unsigned int l) = 0;
[9cf3688]212
[aa048c3]213    void SetColour(const GLAPen& pen, double rgb_scale);
214    void SetColour(const GLAPen& pen);
[d1ce9bd]215    void SetColour(gla_colour colour, double rgb_scale);
[aa048c3]216    void SetColour(gla_colour colour);
[4a1cede]217    void SetAlpha(double new_alpha) { alpha = new_alpha; }
[aa048c3]218
[56da40e]219    void DrawText(glaCoord x, glaCoord y, glaCoord z, const wxString& str);
[1eeb55a]220    void DrawIndicatorText(int x, int y, const wxString& str);
[dbd50e2]221    void GetTextExtent(const wxString& str, int * x_ext, int * y_ext) const;
[9cf3688]222
[56da40e]223    void BeginQuadrilaterals();
224    void EndQuadrilaterals();
225    void BeginLines();
226    void EndLines();
[dde4fe7]227    void BeginTriangleStrip();
228    void EndTriangleStrip();
[56da40e]229    void BeginTriangles();
230    void EndTriangles();
231    void BeginPolyline();
232    void EndPolyline();
[0642381]233    void BeginPolyloop();
234    void EndPolyloop();
[45aa1d6]235    void BeginPolygon();
236    void EndPolygon();
[51eab3b]237    void BeginPoints();
238    void EndPoints();
[e633bb1]239    void BeginBlobs();
240    void EndBlobs();
[86fe6e4]241    void BeginCrosses();
242    void EndCrosses();
[9cf3688]243
[522e0bd]244    void DrawRectangle(gla_colour fill, gla_colour edge,
[d67450e]245                       glaCoord x0, glaCoord y0, glaCoord w, glaCoord h);
[aa048c3]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);
[9cf3688]250
[e633bb1]251    void DrawBlob(glaCoord x, glaCoord y, glaCoord z);
[81aea4e]252    void DrawBlob(glaCoord x, glaCoord y);
[86fe6e4]253    void DrawCross(glaCoord x, glaCoord y, glaCoord z);
[e633bb1]254    void DrawRing(glaCoord x, glaCoord y);
[9cf3688]255
[f336ab9]256    void PlaceVertex(const Vector3 & v, glaTexCoord tex_x, glaTexCoord tex_y) {
[b839829]257        PlaceVertex(v.GetX(), v.GetY(), v.GetZ(), tex_x, tex_y);
258    }
[d67450e]259    void PlaceVertex(const Vector3 & v) {
260        PlaceVertex(v.GetX(), v.GetY(), v.GetZ());
261    }
[56da40e]262    void PlaceVertex(glaCoord x, glaCoord y, glaCoord z);
[f336ab9]263    void PlaceVertex(glaCoord x, glaCoord y, glaCoord z,
264                     glaTexCoord tex_x, glaTexCoord tex_y);
[56da40e]265    void PlaceIndicatorVertex(glaCoord x, glaCoord y);
[203d2a7]266
[d67450e]267    void PlaceNormal(const Vector3 &v);
[9cf3688]268
[56da40e]269    void EnableDashedLines();
270    void DisableDashedLines();
271
[d67450e]272    void EnableSmoothPolygons(bool filled);
[1b12b82]273    void DisableSmoothPolygons();
274
[08253d9]275    void SetRotation(double pan, double tilt) {
276        m_Pan = pan;
277        m_Tilt = tilt;
278    }
[147847c]279    void SetScale(double);
[d67450e]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    }
[56da40e]289    void AddTranslationScreenCoordinates(int dx, int dy);
290
[147847c]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;
[56da40e]293
[9284d37]294    void SetZStretch(double z_stretch_) { z_stretch = z_stretch_; }
295
[1aa3fb7]296    int GetFontSize() const { return m_Font.get_font_size(); }
[087bc72]297
[d67450e]298    void ToggleSmoothShading();
299    bool GetSmoothShading() const { return m_SmoothShading; }
300
[147847c]301    double SurveyUnitsAcrossViewport() const;
[6abab84]302
[a517825]303    void ToggleTextured();
304    bool GetTextured() const { return m_Textured; }
305
[6abab84]306    void TogglePerspective() { m_Perspective = !m_Perspective; }
307    bool GetPerspective() const { return m_Perspective; }
[045e2af]308
[c60062d]309    void ToggleFog() { m_Fog = !m_Fog; }
310    bool GetFog() const { return m_Fog; }
311
[db452ae]312    void ToggleAntiAlias() { m_AntiAlias = !m_AntiAlias; }
313    bool GetAntiAlias() const { return m_AntiAlias; }
314
[1ada489]315    bool SaveScreenshot(const wxString & fnm, wxBitmapType type) const;
[aea4f8b]316
317    void ReadPixels(int width, int height, unsigned char * buf) const;
[f9ca87c]318
319    void PolygonOffset(bool on) const;
[90430f2]320
[2dacc8bd]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
[eadf5fd]331    double GetDPIScaleFactor() const {
[2dacc8bd]332        list_flags |= INVALIDATE_ON_HIDPI;
[eadf5fd]333        return dpi_scale_factor;
[2dacc8bd]334    }
335
336    void OnMove(wxMoveEvent & event);
[90430f2]337
338    void OnSize(wxSizeEvent & event);
[70acad9]339
340    glaCoord GetVolumeDiameter() const { return m_VolumeDiameter; }
[9071cf5]341
[705adee9]342    void ScaleMouseEvent(wxMouseEvent& e) const {
[2ef89f9]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
[705adee9]351    }
352
[9071cf5]353private:
354    DECLARE_EVENT_TABLE()
[56da40e]355};
[caa5fda]356
357#endif
Note: See TracBrowser for help on using the repository browser.