source: git/src/gla.h @ 236a1b1

stereo
Last change on this file since 236a1b1 was 236a1b1, checked in by Olly Betts <olly@…>, 6 years ago

Add --stereo option

Supports arguments "buffers" (OpenGL stereo buffers), "anaglyph"
(for use with coloured glasses) and "2up" (suitable for use with
a "cardboard" headset).

  • Property mode set to 100644
File size: 8.4 KB
RevLine 
[56da40e]1//
2//  gla.h
3//
4//  Header file for the GLA abstraction layer.
5//
6//  Copyright (C) 2002 Mark R. Shinwell.
[522e0bd]7//  Copyright (C) 2003,2004,2005,2006,2007,2011,2012,2014,2017,2018 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"
33#include "aventypes.h"
[08253d9]34#include "vector3.h"
[56da40e]35
[1aa3fb7]36#include "glbitmapfont.h"
[1eeb55a]37
[56da40e]38class GfxCore;
39
[5627cbb]40string GetGLSystemDescription();
[cc1a1d9]41
[d67450e]42// #define GLA_DEBUG
[1897247]43
[56da40e]44typedef Double glaCoord;
45
[ba828d4]46typedef GLfloat glaTexCoord;
[f336ab9]47
[236a1b1]48enum stereo_mode_type {
49    STEREO_MONO = 0, STEREO_ANAGLYPH, STEREO_2UP, STEREO_BUFFERS
50};
51
[aa048c3]52// Colours for drawing.  Don't reorder these!
53enum gla_colour {
54    col_BLACK = 0,
55    col_GREY,
56    col_LIGHT_GREY,
57    col_LIGHT_GREY_2,
58    col_DARK_GREY,
59    col_WHITE,
60    col_TURQUOISE,
61    col_GREEN,
62    col_INDICATOR_1,
63    col_INDICATOR_2,
64    col_YELLOW,
65    col_RED,
[f4c5932]66    col_BLUE,
[aa048c3]67    col_LAST // must be the last entry here
68};
69
[56da40e]70class GLAPen {
[aa048c3]71    friend class GLACanvas; // allow direct access to components
72
73    double components[3]; // red, green, blue
[9cf3688]74
[56da40e]75public:
76    GLAPen();
77
78    void SetColour(double red, double green, double blue); // arguments in range 0 to 1.0
[f383708]79    void Interpolate(const GLAPen&, double how_far);
[56da40e]80
[f7ea0e1]81    double GetRed() const;
82    double GetGreen() const;
83    double GetBlue() const;
[56da40e]84};
85
[db59b02]86class GLAList {
87    GLuint gl_list;
88    unsigned int flags;
89  public:
90    GLAList() : gl_list(0), flags(0) { }
91    GLAList(GLuint gl_list_, unsigned int flags_)
92        : gl_list(gl_list_), flags(flags_) { }
93    operator bool() { return gl_list != 0; }
[620c0c9]94    bool need_to_generate();
95    void finalise(unsigned int list_flags);
96    bool DrawList() const;
[b3f1bbe]97    void invalidate_if(unsigned int mask) {
98        // If flags == NEVER_CACHE, the list won't be invalidated (unless
99        // mask is 0, which isn't a normal thing to pass).
100        if (flags & mask)
101            flags = 0;
102    }
[db59b02]103};
104
[56da40e]105class GLACanvas : public wxGLCanvas {
[b3f1bbe]106    friend class GLAList; // For flag values.
[620c0c9]107
[8c048fa]108    wxGLContext ctx;
109
[203d2a7]110#ifdef GLA_DEBUG
111    int m_Vertices;
112#endif
113
[dde4fe7]114    GLdouble modelview_matrix[16];
115    GLdouble projection_matrix[16];
116    GLint viewport[4];
117
[c5fc8eb]118    // Viewing volume diameter:
119    glaCoord m_VolumeDiameter;
[56da40e]120
121    // Parameters for plotting data:
[08253d9]122    Double m_Pan, m_Tilt;
[56da40e]123    Double m_Scale;
[d67450e]124    Vector3 m_Translation;
[56da40e]125
[1aa3fb7]126    BitmapFont m_Font;
[d9b3270]127
[1b12b82]128    GLUquadric* m_Quadric;
[a517825]129
130    GLuint m_Texture;
[cab6f11]131    GLuint m_BlobTexture;
[95ce35f]132    GLuint m_CrossTexture;
[a517825]133
[4a1cede]134    Double alpha;
135
[d67450e]136    bool m_SmoothShading;
[a517825]137    bool m_Textured;
[1eeb55a]138    bool m_Perspective;
[c60062d]139    bool m_Fog;
[db452ae]140    bool m_AntiAlias;
[807f9dd]141    bool save_hints;
[fe075d7]142    enum { UNKNOWN = 0, POINT = 'P', LINES = 'L', SPRITE = 'S' };
143    int blob_method;
144    int cross_method;
[1eeb55a]145
[90430f2]146    int x_size;
147    int y_size;
148
[db59b02]149    vector<GLAList> drawing_lists;
[90430f2]150
151    enum {
152        INVALIDATE_ON_SCALE = 1,
153        INVALIDATE_ON_X_RESIZE = 2,
154        INVALIDATE_ON_Y_RESIZE = 4,
[620c0c9]155        NEVER_CACHE = 8,
156        CACHED = 16
[90430f2]157    };
[db59b02]158    mutable unsigned int list_flags;
[bae6a7c]159
[807f9dd]160    wxString vendor, renderer;
161
162    bool CheckVisualFidelity(const unsigned char * target) const;
163
[e9c9ce0f]164protected:
165    int m_Eye;
166
[236a1b1]167    const stereo_mode_type& stereo_mode;
168
[56da40e]169public:
[84f1ed1]170    GLACanvas(wxWindow* parent, int id);
[56da40e]171    ~GLACanvas();
[2c8b64f]172
[caa5fda]173    static bool check_visual();
174
[236a1b1]175    static void SetStereoMode(stereo_mode_type mode);
176
[1b12b82]177    void FirstShow();
178
[56da40e]179    void Clear();
180    void StartDrawing();
181    void FinishDrawing();
182
[c5fc8eb]183    void SetVolumeDiameter(glaCoord diameter);
[56da40e]184    void SetDataTransform();
185    void SetIndicatorTransform();
[9cf3688]186
[d2fcc9b]187    void DrawList(unsigned int l);
[11fe902]188    void DrawListZPrepass(unsigned int l);
[76dd228]189    void DrawList2D(unsigned int l, glaCoord x, glaCoord y, Double rotation);
[b3f1bbe]190    void InvalidateList(unsigned int l) {
191        if (l < drawing_lists.size()) {
192            // Invalidate any existing cached list.
193            drawing_lists[l].invalidate_if(CACHED);
194        }
195    }
196
[d2fcc9b]197    virtual void GenerateList(unsigned int l) = 0;
[9cf3688]198
[aa048c3]199    void SetColour(const GLAPen& pen, double rgb_scale);
200    void SetColour(const GLAPen& pen);
[d1ce9bd]201    void SetColour(gla_colour colour, double rgb_scale);
[aa048c3]202    void SetColour(gla_colour colour);
[4a1cede]203    void SetAlpha(double new_alpha) { alpha = new_alpha; }
[aa048c3]204
[56da40e]205    void DrawText(glaCoord x, glaCoord y, glaCoord z, const wxString& str);
[1eeb55a]206    void DrawIndicatorText(int x, int y, const wxString& str);
[dbd50e2]207    void GetTextExtent(const wxString& str, int * x_ext, int * y_ext) const;
[9cf3688]208
[56da40e]209    void BeginQuadrilaterals();
210    void EndQuadrilaterals();
211    void BeginLines();
212    void EndLines();
[dde4fe7]213    void BeginTriangleStrip();
214    void EndTriangleStrip();
[56da40e]215    void BeginTriangles();
216    void EndTriangles();
217    void BeginPolyline();
218    void EndPolyline();
[45aa1d6]219    void BeginPolygon();
220    void EndPolygon();
[e633bb1]221    void BeginBlobs();
222    void EndBlobs();
[86fe6e4]223    void BeginCrosses();
224    void EndCrosses();
[9cf3688]225
[522e0bd]226    void DrawRectangle(gla_colour fill, gla_colour edge,
[d67450e]227                       glaCoord x0, glaCoord y0, glaCoord w, glaCoord h);
[aa048c3]228    void DrawShadedRectangle(const GLAPen & fill_bot, const GLAPen & fill_top,
229                             glaCoord x0, glaCoord y0, glaCoord w, glaCoord h);
230    void DrawCircle(gla_colour edge, gla_colour fill, glaCoord cx, glaCoord cy, glaCoord radius);
231    void DrawSemicircle(gla_colour edge, gla_colour fill, glaCoord cx, glaCoord cy, glaCoord radius, glaCoord start);
[d67450e]232    void DrawTriangle(gla_colour edge, gla_colour fill,
233                      const Vector3 &p0, const Vector3 &p1, const Vector3 &p2);
[9cf3688]234
[e633bb1]235    void DrawBlob(glaCoord x, glaCoord y, glaCoord z);
[81aea4e]236    void DrawBlob(glaCoord x, glaCoord y);
[86fe6e4]237    void DrawCross(glaCoord x, glaCoord y, glaCoord z);
[e633bb1]238    void DrawRing(glaCoord x, glaCoord y);
[9cf3688]239
[f336ab9]240    void PlaceVertex(const Vector3 & v, glaTexCoord tex_x, glaTexCoord tex_y) {
[b839829]241        PlaceVertex(v.GetX(), v.GetY(), v.GetZ(), tex_x, tex_y);
242    }
[d67450e]243    void PlaceVertex(const Vector3 & v) {
244        PlaceVertex(v.GetX(), v.GetY(), v.GetZ());
245    }
[56da40e]246    void PlaceVertex(glaCoord x, glaCoord y, glaCoord z);
[f336ab9]247    void PlaceVertex(glaCoord x, glaCoord y, glaCoord z,
248                     glaTexCoord tex_x, glaTexCoord tex_y);
[56da40e]249    void PlaceIndicatorVertex(glaCoord x, glaCoord y);
[203d2a7]250
[d67450e]251    void PlaceNormal(const Vector3 &v);
[9cf3688]252
[56da40e]253    void EnableDashedLines();
254    void DisableDashedLines();
255
[d67450e]256    void EnableSmoothPolygons(bool filled);
[1b12b82]257    void DisableSmoothPolygons();
258
[08253d9]259    void SetRotation(double pan, double tilt) {
260        m_Pan = pan;
261        m_Tilt = tilt;
262    }
[56da40e]263    void SetScale(Double);
[d67450e]264    void SetTranslation(const Vector3 &v) {
265        m_Translation = v;
266    }
267    void AddTranslation(const Vector3 &v) {
268        m_Translation += v;
269    }
270    const Vector3 & GetTranslation() const {
271        return m_Translation;
272    }
[56da40e]273    void AddTranslationScreenCoordinates(int dx, int dy);
274
[f6d8375]275    bool Transform(const Vector3 & v, double* x_out, double* y_out, double* z_out) const;
276    void ReverseTransform(Double x, Double y, double* x_out, double* y_out, double* z_out) const;
[56da40e]277
[1aa3fb7]278    int GetFontSize() const { return m_Font.get_font_size(); }
[087bc72]279
[d67450e]280    void ToggleSmoothShading();
281    bool GetSmoothShading() const { return m_SmoothShading; }
282
[e7f9e99]283    Double SurveyUnitsAcrossViewport() const;
[6abab84]284
[a517825]285    void ToggleTextured();
286    bool GetTextured() const { return m_Textured; }
287
[6abab84]288    void TogglePerspective() { m_Perspective = !m_Perspective; }
289    bool GetPerspective() const { return m_Perspective; }
[045e2af]290
[c60062d]291    void ToggleFog() { m_Fog = !m_Fog; }
292    bool GetFog() const { return m_Fog; }
293
[db452ae]294    void ToggleAntiAlias() { m_AntiAlias = !m_AntiAlias; }
295    bool GetAntiAlias() const { return m_AntiAlias; }
296
[1ada489]297    bool SaveScreenshot(const wxString & fnm, wxBitmapType type) const;
[aea4f8b]298
299    void ReadPixels(int width, int height, unsigned char * buf) const;
[f9ca87c]300
301    void PolygonOffset(bool on) const;
[90430f2]302
[236a1b1]303    int GetXSize() const {
304        list_flags |= INVALIDATE_ON_X_RESIZE;
305        return (stereo_mode == STEREO_2UP ? x_size / 2 : x_size);
306    }
307
[90430f2]308    int GetYSize() const { list_flags |= INVALIDATE_ON_Y_RESIZE; return y_size; }
309
310    void OnSize(wxSizeEvent & event);
[70acad9]311
312    glaCoord GetVolumeDiameter() const { return m_VolumeDiameter; }
[9071cf5]313
314private:
315    DECLARE_EVENT_TABLE()
[56da40e]316};
[caa5fda]317
318#endif
Note: See TracBrowser for help on using the repository browser.