OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4DrawGL.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2010-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 
17 /* OpenGL implementation of NewGfx */
18 
20 #if !defined(INC_StdGL) && !defined(USE_CONSOLE)
21 #define INC_StdGL
22 
23 #ifdef _WIN32
25 #endif
26 
27 #include <GL/glew.h>
28 
29 #ifdef USE_COCOA
31 #endif
32 #include "graphics/C4Draw.h"
33 #include "graphics/C4Shader.h"
34 
35 class C4Window;
36 
37 class C4DrawGLError: public std::exception
38 {
39 public:
40  C4DrawGLError(const StdStrBuf& buf): Buf(buf) {}
41  virtual ~C4DrawGLError() throw() {}
42 
43  virtual const char* what() const throw() { return Buf.getData(); }
44 
45 private:
46  StdCopyStrBuf Buf;
47 };
48 
49 // Uniform data we give the sprite shader (constants from its viewpoint)
51 {
54  C4SSU_NormalMatrix, // 3x3, transpose-inverse of modelview matrix
55 
56  C4SSU_ClrMod, // always
57  C4SSU_Gamma, // always
58 
59  C4SSU_BaseTex, // C4SSC_BASE
60  C4SSU_OverlayTex, // C4SSC_OVERLAY
61  C4SSU_OverlayClr, // C4SSC_OVERLAY
62 
63  C4SSU_LightTex, // C4SSC_LIGHT
64  C4SSU_LightTransform, // C4SSC_LIGHT
65  C4SSU_NormalTex, // C4SSC_LIGHT | C4SSC_NORMAL
66 
67  C4SSU_AmbientTex, // C4SSC_LIGHT
68  C4SSU_AmbientTransform, // C4SSC_LIGHT
69  C4SSU_AmbientBrightness, // C4SSC_LIGHT
70 
71  C4SSU_MaterialAmbient, // for meshes
72  C4SSU_MaterialDiffuse, // for meshes
73  C4SSU_MaterialSpecular, // for meshes
74  C4SSU_MaterialEmission, // for meshes
75  C4SSU_MaterialShininess, // for meshes
76 
77  C4SSU_Bones, // for meshes
78  C4SSU_CullMode, // for meshes
79 
80  C4SSU_FrameCounter, // for custom shaders
81 
83 };
84 
85 // Attribute data for sprites and meshes
87 {
88  C4SSA_Position, // 2d for sprites, 3d for meshes
89  C4SSA_Normal, // meshes only
91  C4SSA_Color, // sprites only, 4d
92 
95 
98 
100 };
101 
102 // one OpenGL context
104 #ifdef USE_COCOA
105  : public ObjectiveCAssociated
106 #endif
107 {
108 public:
109  CStdGLCtx(); // ctor
110  virtual ~CStdGLCtx() { Clear(); } // dtor
111 
112  virtual void Clear(bool multisample_change = false); // clear objects
113 
114 #ifdef USE_WGL
115  std::vector<int> EnumerateMultiSamples() const;
116 #endif
117  virtual bool Init(C4Window * pWindow, C4AbstractApp *pApp);
118 
119  virtual bool Select(bool verbose = false); // select this context
120  virtual void Deselect(); // select this context
121 
122  virtual bool PageFlip(); // present scene
123 
124 protected:
125  void SelectCommon();
126  // this handles are declared as pointers to structs
127  C4Window * pWindow; // window to draw in
128 #ifdef USE_WGL
129  HDC hDC; // device context handle
130 #elif defined(USE_SDL_MAINLOOP)
131  void * ctx;
132 #endif
133 
134  // Global list of all OpenGL contexts in use
135  static std::list<CStdGLCtx*> contexts;
136  std::list<CStdGLCtx*>::iterator this_context;
137 
138  // VAOs available on this context
139  std::vector<GLuint> hVAOs;
140  // VAOs to be deleted the next time this context is being made current.
141  std::vector<unsigned int> VAOsToBeDeleted;
142 
143  friend class CStdGL;
144  friend class C4Surface;
145 };
146 
147 #ifdef WITH_QT_EDITOR
148 // OpenGL context with Qt as backend. Implemented as subclass to allow co-existance with a different backend for fullscreen.
149 class CStdGLCtxQt : public CStdGLCtx
150 {
151 public:
152  CStdGLCtxQt();
153  virtual ~CStdGLCtxQt() { Clear(); }
154 
155  void Clear(bool multisample_change = false) override; // clear objects
156  bool Init(C4Window * pWindow, C4AbstractApp *pApp) override;
157  bool Select(bool verbose = false) override; // select this context
158  void Deselect() override; // select this context
159  bool PageFlip() override; // present scene
160 
161 private:
162  class QOpenGLContext *context = nullptr;
163  class QOffscreenSurface *surface = nullptr;
164 };
165 #endif
166 
167 // OpenGL encapsulation
168 class CStdGL : public C4Draw
169 {
170 public:
171  CStdGL();
172  ~CStdGL();
173 protected:
174 
175  int iPixelFormat; // used pixel format
176 
177  GLenum sfcFmt; // texture surface format
178  CStdGLCtx * pMainCtx; // main GL context
179  CStdGLCtx *pCurrCtx; // current context (owned if fullscreen)
180  // texture for smooth lines
181  GLuint lines_tex;
182 
183  // The orthographic projection matrix
184  StdProjectionMatrix ProjectionMatrix;
185 
186  // programs for drawing points, lines, quads
187 
188  // Sprite shaders -- there is a variety of shaders to avoid
189  // conditionals in the GLSL code.
196 
207 
208  // Generic VBOs for rendering arbitrary points, lines and
209  // triangles, used by PerformMultiBlt. Use more than one VBO, so that
210  // two PerformMultiBlt calls in quick succession can use two different
211  // buffers. Otherwise, the second call would need to wait until the
212  // rendering pipeline has actually drained the buffer. Each buffer
213  // starts with a fixed size. If more than this many vertices need to
214  // be rendered (can happen e.g. for PXS), then the buffer is resized.
215  static const unsigned int N_GENERIC_VBOS = 16;
216  static const unsigned int GENERIC_VBO_SIZE = 3 * 64; // vertices
219  unsigned int CurrentVBO;
220  // We need twice as much VAOs, since the sprite rendering routines work
221  // both with and without textures (in which case we either need texture
222  // coordinates or not).
223  unsigned int GenericVAOs[N_GENERIC_VBOS * 2];
224 
225  // VAO IDs currently in use.
226  std::set<unsigned int> VAOIDs;
227  std::set<unsigned int>::iterator NextVAOID;
228 
229 public:
230  // Create a new (unique) VAO ID. A VAO ID is a number that identifies
231  // a certain VAO across all OpenGL contexts. This indirection is needed
232  // because, unlike most other GL state, VAOs are not shared between
233  // OpenGL contexts.
234  unsigned int GenVAOID();
235 
236  // Free the given VAO ID, i.e. it can be re-used for new VAOs. This causes
237  // the VAO associated with this ID to be deleted in all OpenGL contexts.
238  void FreeVAOID(unsigned int vaoid);
239 
240  // Return a VAO with the given vao ID in the "vao" output variable.
241  // If the function returns false, the VAO was newly created, otherwise
242  // an existing VAO is returned.
243  bool GetVAO(unsigned int vaoid, GLuint& vao);
244 
245  // General
246  void Clear() override;
247  void Default() override ;
248  virtual bool OnResolutionChanged(unsigned int iXRes, unsigned int iYRes) override; // reinit clipper for new resolution
249  // Clipper
250  bool UpdateClipper() override; // set current clipper to render target
251  const StdProjectionMatrix& GetProjectionMatrix() const { return ProjectionMatrix; }
252  virtual bool PrepareMaterial(StdMeshMatManager& mat_manager, StdMeshMaterialLoader& loader, StdMeshMaterial& mat) override;
253  // Surface
254  virtual bool PrepareRendering(C4Surface * sfcToSurface) override; // check if/make rendering possible to given surface
255  virtual bool PrepareSpriteShader(C4Shader& shader, const char* name, int ssc, C4GroupSet* pGroups, const char* const* additionalDefines, const char* const* additionalSlices) override;
256  bool EnsureMainContextSelected() override;
257 
258  virtual CStdGLCtx *CreateContext(C4Window * pWindow, C4AbstractApp *pApp) override;
259  // Blit
260  void SetupMultiBlt(C4ShaderCall& call, const C4BltTransform* pTransform, GLuint baseTex, GLuint overlayTex, GLuint normalTex, DWORD dwOverlayModClr, StdProjectionMatrix* out_modelview);
261  virtual void PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, C4BltTransform* pTransform) override;
262  void FillBG(DWORD dwClr=0) override;
263  // Drawing
264  virtual void PerformMultiPix(C4Surface* sfcTarget, const C4BltVertex* vertices, unsigned int n_vertices, C4ShaderCall* shader_call) override;
265  virtual void PerformMultiLines(C4Surface* sfcTarget, const C4BltVertex* vertices, unsigned int n_vertices, float width, C4ShaderCall* shader_call) override;
266  virtual void PerformMultiTris(C4Surface* sfcTarget, const C4BltVertex* vertices, unsigned int n_vertices, const C4BltTransform* pTransform, C4TexRef* pTex, C4TexRef* pOverlay, C4TexRef* pNormal, DWORD dwOverlayClrMod, C4ShaderCall* shader_call) override;
267  void PerformMultiBlt(C4Surface* sfcTarget, DrawOperation op, const C4BltVertex* vertices, unsigned int n_vertices, bool has_tex, C4ShaderCall* shader_call);
268  // device objects
269  bool RestoreDeviceObjects() override; // restore device dependent objects
270  bool InvalidateDeviceObjects() override; // free device dependent objects
271  bool DeviceReady() override { return !!pMainCtx; }
272  bool InitShaders(C4GroupSet* pGroups); // load shaders from given group
273  C4Shader* GetSpriteShader(int ssc);
274  C4Shader* GetSpriteShader(bool haveBase, bool haveOverlay, bool haveNormal);
275 
276  struct
277  {
278  bool LowMaxVertexUniformCount;
279  bool ForceSoftwareTransform;
280  } Workarounds;
281  void ObjectLabel(uint32_t identifier, uint32_t name, int32_t length, const char * label);
282 
283 protected:
284  bool CheckGLError(const char *szAtOp);
285  const char* GLErrorString(GLenum code);
286  virtual bool Error(const char *szMsg) override;
287 
288  friend class C4Surface;
289  friend class C4TexRef;
290  friend class C4Pattern;
291  friend class CStdGLCtx;
292  friend class C4StartupOptionsDlg;
293  friend class C4FullScreen;
294  friend class C4Window;
295  friend class C4ShaderCall;
296  friend class C4FoWRegion;
297 #ifdef WITH_QT_EDITOR
298  friend class CStdGLCtxQt;
299 #endif
300 };
301 
302 // Global access pointer
303 extern CStdGL *pGL;
304 
305 #endif // INC_StdGL
const char * getData() const
Definition: StdBuf.h:450
void SelectCommon()
Definition: C4DrawGLCtx.cpp:33
C4Shader SpriteShaderLightBaseNormalOverlay
Definition: C4DrawGL.h:205
virtual bool Select(bool verbose=false)
static std::list< CStdGLCtx * > contexts
Definition: C4DrawGL.h:135
static const unsigned int N_GENERIC_VBOS
Definition: C4DrawGL.h:215
unsigned int CurrentVBO
Definition: C4DrawGL.h:219
CStdGLCtx * pCurrCtx
Definition: C4DrawGL.h:179
virtual void Deselect()
C4Shader SpriteShaderBase
Definition: C4DrawGL.h:192
std::set< unsigned int >::iterator NextVAOID
Definition: C4DrawGL.h:227
C4Shader SpriteShaderLightBaseNormalMod2
Definition: C4DrawGL.h:204
C4SS_Attributes
Definition: C4DrawGL.h:86
bool DeviceReady() override
Definition: C4DrawGL.h:271
CStdGLCtx * pMainCtx
Definition: C4DrawGL.h:178
void FreeVAOID(unsigned int vaoid)
Definition: C4DrawGL.cpp:976
bool EnsureMainContextSelected() override
Definition: C4DrawGL.cpp:764
C4Shader SpriteShaderBaseOverlay
Definition: C4DrawGL.h:194
virtual void PerformMultiTris(C4Surface *sfcTarget, const C4BltVertex *vertices, unsigned int n_vertices, const C4BltTransform *pTransform, C4TexRef *pTex, C4TexRef *pOverlay, C4TexRef *pNormal, DWORD dwOverlayClrMod, C4ShaderCall *shader_call) override
Definition: C4DrawGL.cpp:591
void FillBG(DWORD dwClr=0) override
Definition: C4DrawGL.cpp:153
std::vector< unsigned int > VAOsToBeDeleted
Definition: C4DrawGL.h:141
C4Shader SpriteShaderLightBaseOverlay
Definition: C4DrawGL.h:201
virtual CStdGLCtx * CreateContext(C4Window *pWindow, C4AbstractApp *pApp) override
Definition: C4DrawGL.cpp:291
CStdGL()
Definition: C4DrawGL.cpp:107
GLuint GenericVBOs[N_GENERIC_VBOS]
Definition: C4DrawGL.h:217
C4Shader SpriteShaderLightBaseMod2
Definition: C4DrawGL.h:200
C4Shader SpriteShaderBaseMod2
Definition: C4DrawGL.h:193
virtual ~C4DrawGLError()
Definition: C4DrawGL.h:41
GLenum sfcFmt
Definition: C4DrawGL.h:177
bool UpdateClipper() override
Definition: C4DrawGL.cpp:160
C4Shader SpriteShaderBaseOverlayMod2
Definition: C4DrawGL.h:195
void SetupMultiBlt(C4ShaderCall &call, const C4BltTransform *pTransform, GLuint baseTex, GLuint overlayTex, GLuint normalTex, DWORD dwOverlayModClr, StdProjectionMatrix *out_modelview)
Definition: C4DrawGL.cpp:370
void Default() override
Definition: C4DrawGL.cpp:924
void Clear() override
Definition: C4DrawGL.cpp:123
int iPixelFormat
Definition: C4DrawGL.h:175
std::list< CStdGLCtx * >::iterator this_context
Definition: C4DrawGL.h:136
virtual bool PrepareSpriteShader(C4Shader &shader, const char *name, int ssc, C4GroupSet *pGroups, const char *const *additionalDefines, const char *const *additionalSlices) override
Definition: C4DrawGL.cpp:207
virtual bool PrepareMaterial(StdMeshMatManager &mat_manager, StdMeshMaterialLoader &loader, StdMeshMaterial &mat) override
virtual void PerformMultiLines(C4Surface *sfcTarget, const C4BltVertex *vertices, unsigned int n_vertices, float width, C4ShaderCall *shader_call) override
Definition: C4DrawGL.cpp:531
C4Shader SpriteShaderLightBaseNormalOverlayMod2
Definition: C4DrawGL.h:206
virtual ~CStdGLCtx()
Definition: C4DrawGL.h:110
C4Shader SpriteShader
Definition: C4DrawGL.h:190
bool GetVAO(unsigned int vaoid, GLuint &vao)
Definition: C4DrawGL.cpp:1023
GLuint lines_tex
Definition: C4DrawGL.h:181
virtual const char * what() const
Definition: C4DrawGL.h:43
C4Shader SpriteShaderMod2
Definition: C4DrawGL.h:191
unsigned int GenericVBOSizes[N_GENERIC_VBOS]
Definition: C4DrawGL.h:218
unsigned int GenericVAOs[N_GENERIC_VBOS *2]
Definition: C4DrawGL.h:223
C4Shader SpriteShaderLightBaseOverlayMod2
Definition: C4DrawGL.h:202
virtual bool PageFlip()
C4Window * pWindow
Definition: C4DrawGL.h:127
struct CStdGL::@10 Workarounds
virtual void PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, C4BltTransform *pTransform) override
const char * GLErrorString(GLenum code)
Definition: C4DrawGL.cpp:889
virtual bool OnResolutionChanged(unsigned int iXRes, unsigned int iYRes) override
Definition: C4DrawGL.cpp:916
unsigned int GenVAOID()
Definition: C4DrawGL.cpp:934
static const unsigned int GENERIC_VBO_SIZE
Definition: C4DrawGL.h:216
virtual bool PrepareRendering(C4Surface *sfcToSurface) override
Definition: C4DrawGL.cpp:178
virtual bool Init(C4Window *pWindow, C4AbstractApp *pApp)
C4Shader SpriteShaderLightBaseNormal
Definition: C4DrawGL.h:203
bool RestoreDeviceObjects() override
Definition: C4DrawGL.cpp:769
bool InitShaders(C4GroupSet *pGroups)
Definition: C4DrawGL.cpp:724
void ObjectLabel(uint32_t identifier, uint32_t name, int32_t length, const char *label)
Definition: C4DrawGL.cpp:283
C4DrawGLError(const StdStrBuf &buf)
Definition: C4DrawGL.h:40
virtual bool Error(const char *szMsg) override
Definition: C4DrawGL.cpp:862
virtual void Clear(bool multisample_change=false)
void PerformMultiBlt(C4Surface *sfcTarget, DrawOperation op, const C4BltVertex *vertices, unsigned int n_vertices, bool has_tex, C4ShaderCall *shader_call)
Definition: C4DrawGL.cpp:607
~CStdGL()
Definition: C4DrawGL.cpp:117
virtual void PerformMultiPix(C4Surface *sfcTarget, const C4BltVertex *vertices, unsigned int n_vertices, C4ShaderCall *shader_call) override
Definition: C4DrawGL.cpp:504
std::set< unsigned int > VAOIDs
Definition: C4DrawGL.h:226
const StdProjectionMatrix & GetProjectionMatrix() const
Definition: C4DrawGL.h:251
bool InvalidateDeviceObjects() override
Definition: C4DrawGL.cpp:815
C4Shader SpriteShaderLight
Definition: C4DrawGL.h:197
C4Shader SpriteShaderLightBase
Definition: C4DrawGL.h:199
Definition: C4Draw.h:84
C4Shader * GetSpriteShader(int ssc)
Definition: C4DrawGL.cpp:683
uint32_t DWORD
StdProjectionMatrix ProjectionMatrix
Definition: C4DrawGL.h:184
DrawOperation
Definition: C4Draw.h:87
C4SS_Uniforms
Definition: C4DrawGL.h:50
std::vector< GLuint > hVAOs
Definition: C4DrawGL.h:139
C4AbstractApp * pApp
Definition: C4Draw.h:95
bool CheckGLError(const char *szAtOp)
Definition: C4DrawGL.cpp:905
CStdGL * pGL
Definition: C4DrawGL.cpp:914
C4Shader SpriteShaderLightMod2
Definition: C4DrawGL.h:198