File: glwindow.hpp

package info (click to toggle)
glvis 4.5-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 7,780 kB
  • sloc: cpp: 35,217; ansic: 5,695; sh: 340; makefile: 301; python: 193
file content (186 lines) | stat: -rw-r--r-- 5,831 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// Copyright (c) 2010-2026, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-443271.
//
// This file is part of the GLVis visualization tool and library. For more
// information and source code availability see https://glvis.org.
//
// GLVis is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef GLVIS_GLWINDOW_HPP
#define GLVIS_GLWINDOW_HPP

#include <memory>
#include <map>
#include <functional>
#include <string>

#include "gl/renderer.hpp"

class MainThread
{
public:
   virtual ~MainThread() { }

   // Handles all operations that are expected to be handled on the main
   // thread (i.e. events and window creation)
   virtual void MainLoop(bool server_mode) = 0;
};

class GLWindow
{
   friend class EglMainThread;
public:
   typedef Uint8 SDL_Mousebutton;
   struct MouseEventInfo
   {
      Sint32 mouse_x;
      Sint32 mouse_y;
      SDL_Keymod keymod;
   };

   using IdleDelegate = bool (*)();
   using Delegate = void (*)();
   using KeyDelegate = std::function<void(SDL_Keymod)>;
   using MouseDelegate = void (*)(MouseEventInfo*);

protected:
   enum class RenderState
   {
      // window displayed is fully current (no events or backbuffer updates pending)
      Updated,
      // events issued which may require a call to MyExpose
      ExposePending,
      // back buffer updated by MyExpose, now awaiting swap to be displayed on window
      SwapPending
   };
   RenderState wnd_state{RenderState::Updated};

   std::unique_ptr<gl3::MeshRenderer> renderer;

   IdleDelegate onIdle{};
   Delegate onExpose{};
   std::map<SDL_Keycode, KeyDelegate> onKeyDown;
   std::map<SDL_Mousebutton, MouseDelegate> onMouseDown;
   std::map<SDL_Mousebutton, MouseDelegate> onMouseUp;
   std::map<SDL_Mousebutton, MouseDelegate> onMouseMove;

#ifdef __EMSCRIPTEN__
   std::string canvas_id;
#endif
   std::string saved_keys;

   bool initGLEW(bool legacyGlOnly);
   void recordKey(SDL_Keycode k, SDL_Keymod m);

public:
   virtual ~GLWindow() = default;

   /// Creates a new OpenGL window
   virtual bool createWindow(const char *title, int x, int y, int w, int h,
                             bool legacyGlOnly) = 0;

   /// Returns the renderer object
   inline gl3::MeshRenderer& getRenderer() { return *renderer.get(); }

   /// Runs the window loop.
   virtual void mainLoop() = 0;
   virtual void mainIter() = 0;

   /// Signals addition of a new event
   virtual void signalLoop() = 0;

   void setOnIdle(IdleDelegate func) { onIdle = func; }
   void setOnExpose(Delegate func) { onExpose = func; }

   void setOnKeyDown(SDL_Keycode key, Delegate func)
   {
      onKeyDown[key] = [func](SDL_Keymod) { func(); };
   }
   void setOnKeyDown(SDL_Keycode key, KeyDelegate func) { onKeyDown[key] = func; }

   void setOnMouseDown(SDL_Mousebutton btn, MouseDelegate func) { onMouseDown[btn] = func; }
   void setOnMouseUp(SDL_Mousebutton btn, MouseDelegate func) { onMouseUp[btn] = func; }
   void setOnMouseMove(SDL_Mousebutton btn, MouseDelegate func) { onMouseMove[btn] = func; }

   virtual void clearEvents()
   {
      onIdle = nullptr;
      onExpose = nullptr;
      onKeyDown.clear();
      onMouseUp.clear();
      onMouseDown.clear();
      onMouseMove.clear();
   }

   void callKeyDown(SDL_Keycode k, SDL_Keymod mod = KMOD_NONE)
   {
      if (onKeyDown[k])
      {
         onKeyDown[k](mod);
      }
   }

   /// Returns size of the window
   virtual void getWindowSize(int& w, int& h) const { w = h = 0; }

   /// Returns the drawable size
   virtual void getGLDrawSize(int& w, int& h) const { w = h = 0; }

   /// Returns the resolution (DPI) of the display
   virtual void getDpi(int& wdpi, int& hdpi) const { wdpi = hdpi = 0; }

   /// Checks if the display has high resolution (DPI)
   virtual bool isHighDpi() const { return false; }

   /// Set title of the window (string version)
   virtual void setWindowTitle(const std::string& title) { }

   /// Set title of the window (C-string version)
   virtual void setWindowTitle(const char* title) { }

   /// Set window size
   virtual void setWindowSize(int w, int h) { }

   /// Set window position
   virtual void setWindowPos(int x, int y) { }

   /// Returns true if the window has been successfully initialized
   virtual bool isWindowInitialized() const { return false; }

   /// Returns true if the OpenGL context was successfully initialized
   virtual bool isGlInitialized() const { return false; }

   /// Signals key down event
   virtual void signalKeyDown(SDL_Keycode k, SDL_Keymod m = KMOD_NONE) { }

   /// Signals quit event
   virtual void signalQuit() { }

   /// Signals expose event when objects have been updated
   virtual void signalExpose() { wnd_state = RenderState::ExposePending; }

   /// Signals swap event when the back buffer is ready for swapping
   virtual void signalSwap() { wnd_state = RenderState::SwapPending; }

   /// Checks if the expose event is pending
   virtual bool isExposePending() const { return wnd_state == RenderState::ExposePending; }

   /// Checks if the swap event is pending
   virtual bool isSwapPending() const { return wnd_state == RenderState::SwapPending; }

   /// Returns the keyboard events that have been logged by the window.
   std::string getSavedKeys() const { return saved_keys; }

   /// Saves a screenshot ot the file, performing conversion optionally
   virtual void screenshot(std::string filename, bool convert = false) { }

#ifdef __EMSCRIPTEN__
   std::string getCanvasId() const { return canvas_id; }
   void setCanvasId(std::string canvas_id_) { canvas_id = canvas_id_; }
#endif
};

#endif //GLVIS_GLWINDOW_HPP