1 /** @file gl_main.h GL-Graphics Subsystem.
2  * @ingroup gl
3  *
4  * @authors Copyright &copy; 2003-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
5  * @authors Copyright &copy; 2006-2013 Daniel Swanson <danij@dengine.net>
6  *
7  * @par License
8  * GPL: http://www.gnu.org/licenses/gpl.html
9  *
10  * <small>This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by the
12  * Free Software Foundation; either version 2 of the License, or (at your
13  * option) any later version. This program is distributed in the hope that it
14  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details. You should have received a copy of the GNU
17  * General Public License along with this program; if not, write to the Free
18  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19  * 02110-1301 USA</small>
20  */
21 
22 #ifndef DENG_GL_MAIN_H
23 #define DENG_GL_MAIN_H
24 
25 #ifndef __CLIENT__
26 #  error "gl only exists in the Client"
27 #endif
28 
29 #ifndef __cplusplus
30 #  error "gl/gl_main.h requires C++"
31 #endif
32 
33 #include "api_gl.h"
34 #include "sys_opengl.h"
35 
36 #include "gl/gltextureunit.h"
37 #include "render/viewports.h"
38 #include "ClientTexture"
39 #include <de/Matrix>
40 
41 struct ColorRawf_s;
42 struct material_s;
43 struct texturevariant_s;
44 
45 class ColorPalette;
46 namespace world { class Material; }
47 
48 #define TEXQ_BEST               8
49 #define MINTEXWIDTH             8
50 #define MINTEXHEIGHT            8
51 
52 DENG_EXTERN_C float vid_gamma, vid_bright, vid_contrast;
53 DENG_EXTERN_C int r_detail;
54 
55 #ifdef _DEBUG
56 #  define DENG_ASSERT_GL_CONTEXT_ACTIVE()  {DENG2_ASSERT(QOpenGLContext::currentContext() != nullptr);}
57 #else
58 #  define DENG_ASSERT_GL_CONTEXT_ACTIVE()
59 #endif
60 
61 #define Sys_GLCheckError()  Sys_GLCheckErrorArgs(__FILE__, __LINE__)
62 
63 #ifdef _DEBUG
64 #  define LIBDENG_ASSERT_GL_TEXTURE_ISBOUND(tex) { \
65     GLint p; \
66     glGetIntegerv(GL_TEXTURE_BINDING_2D, &p); \
67     Sys_GLCheckError(); \
68     assert(p == (GLint)tex); \
69 }
70 #else
71 #  define LIBDENG_ASSERT_GL_TEXTURE_ISBOUND(tex)
72 #endif
73 
74 void GL_AssertContextActive();
75 
76 /// Register the console commands, variables, etc..., of this module.
77 void GL_Register();
78 
79 /**
80  * One-time initialization of GL and the renderer. This is done very early
81  * on during engine startup and is supposed to be fast. All subsystems
82  * cannot yet be initialized, such as the texture management, so any rendering
83  * occuring before GL_Init() must be done with manually prepared textures.
84  */
85 void GL_EarlyInit();
86 
87 /**
88  * Finishes GL initialization. This can be called once the virtual file
89  * system has been fully loaded up, and the console variables have been
90  * read from the config file.
91  */
92 void GL_Init();
93 
94 /**
95  * Kills the graphics library for good.
96  */
97 void GL_Shutdown();
98 
99 /**
100  * Returns @c true iff the graphics library is currently initialized
101  * for basic drawing (using the OpenGL API directly).
102  */
103 dd_bool GL_IsInited();
104 
105 /**
106  * Determines if the renderer is fully initialized (texture manager, deferring,
107  * etc).
108  */
109 dd_bool GL_IsFullyInited();
110 
111 /**
112  * GL is reset back to the state it was right after initialization.
113  * Use GL_TotalRestore to bring back online.
114  */
115 void GL_TotalReset();
116 
117 /**
118  * To be called after a GL_TotalReset to bring GL back online.
119  */
120 void GL_TotalRestore();
121 
122 /**
123  * Initializes the renderer to 2D state.
124  */
125 void GL_Init2DState();
126 
127 void GL_ProjectionMatrix(bool useFixedFov = false /* psprites use fixed FOV */);
128 
129 de::Rangef GL_DepthClipRange();
130 
131 /**
132  * The first selected unit is active after this call.
133  */
134 void GL_SelectTexUnits(int count);
135 
136 /**
137  * Finish the frame being rendered. Applies the FPS limiter, if enabled.
138  */
139 void GL_FinishFrame();
140 
141 /**
142  * Set the current GL blending mode.
143  */
144 void GL_BlendMode(blendmode_t mode);
145 
146 /**
147  * Utility for translating to a GL texture filter identifier.
148  */
149 GLenum GL_Filter(de::gl::Filter f);
150 
151 /**
152  * Utility for translating to a GL texture wrapping identifier.
153  */
154 GLenum GL_Wrap(de::gl::Wrapping w);
155 
156 /**
157  * Initializes the graphics library for refresh. Also called at update.
158  */
159 void GL_InitRefresh();
160 
161 /**
162  * To be called once at final shutdown.
163  */
164 void GL_ShutdownRefresh();
165 
166 /**
167  * Enables or disables vsync. May cause the OpenGL surface to be recreated.
168  *
169  * @param on  @c true to enable vsync, @c false to disable.
170  */
171 void GL_SetVSync(dd_bool on);
172 
173 /**
174  * Enables or disables multisampling when FSAA is available. You cannot enable
175  * multisampling if FSAA has not been enabled in the Canvas. Never causes the GL surface
176  * or pixel format to be modified; can be called at any time during the rendering of a
177  * frame.
178  *
179  * @param on  @c true to enable multisampling, @c false to disable.
180  */
181 //void GL_SetMultisample(dd_bool on);
182 
183 /**
184  * Reconfigure GL fog according to the setup defined in the specified @a mapInfo definition.
185  */
186 void GL_SetupFogFromMapInfo(de::Record const *mapInfo);
187 
188 //void GL_BlendOp(int op);
189 
190 dd_bool GL_NewList(DGLuint list, int mode);
191 
192 DGLuint GL_EndList();
193 
194 void GL_CallList(DGLuint list);
195 
196 void GL_DeleteLists(DGLuint list, int range);
197 
198 void GL_SetMaterialUI2(world::Material *mat, de::gl::Wrapping wrapS, de::gl::Wrapping wrapT);
199 void GL_SetMaterialUI(world::Material *mat);
200 
201 void GL_SetPSprite(world::Material *mat, int tclass, int tmap);
202 
203 void GL_SetRawImage(lumpnum_t lumpNum, de::gl::Wrapping wrapS, de::gl::Wrapping wrapT);
204 
205 /**
206  * Bind this texture to the currently active texture unit.
207  * The bind process may result in modification of the GL texture state
208  * according to the specification used to define this variant.
209  *
210  * @param tex  Texture::Variant object which represents the GL texture to be bound.
211  */
212 void GL_BindTexture(ClientTexture::Variant *tex);
213 
214 void GL_BindTextureUnmanaged(GLuint texname, de::gl::Wrapping wrapS = de::gl::Repeat,
215     de::gl::Wrapping wrapT = de::gl::Repeat, de::gl::Filter = de::gl::Linear);
216 
217 /**
218  * Bind the associated texture and apply the texture unit configuration to
219  * the @em active GL texture unit. If no texture is associated then nothing
220  * will happen.
221  */
222 void GL_Bind(de::GLTextureUnit const &glTU);
223 
224 /**
225  * Bind the associated texture and apply the texture unit configuration to
226  * the specified GL texture @a unit, which, is made active during this call.
227  * If no texture is associated then nothing will happen.
228  */
229 void GL_BindTo(de::GLTextureUnit const &glTU, int unit);
230 
231 void GL_SetNoTexture();
232 
233 /**
234  * Given a logical anisotropic filtering level return an appropriate multiplier
235  * according to the current GL state and user configuration.
236  */
237 int GL_GetTexAnisoMul(int level);
238 
239 /**
240  * How many mipmap levels are needed for a texture of the given dimensions?
241  *
242  * @param width  Width of the texture in pixels.
243  * @param height  Height of the texture in pixels.
244  * @return  Number of mipmap levels required.
245  */
246 int GL_NumMipmapLevels(int width, int height);
247 
248 /**
249  * Determine the optimal size for a texture. Usually the dimensions are scaled
250  * upwards to the next power of two.
251  *
252  * @param noStretch  If @c true, the stretching can be skipped.
253  * @param isMipMapped  If @c true, we will require mipmaps (this has an effect
254  *     on the optimal size).
255  */
256 dd_bool GL_OptimalTextureSize(int width, int height, dd_bool noStretch, dd_bool isMipMapped,
257     int *optWidth, int *optHeight);
258 
259 /**
260  * @param width  Width of the image in pixels.
261  * @param height  Height of the image in pixels.
262  * @param flags  @ref imageConversionFlags.
263  */
264 int GL_ChooseSmartFilter(int width, int height, int flags);
265 
266 GLuint GL_NewTextureWithParams(dgltexformat_t format, int width, int height, uint8_t const *pixels, int flags);
267 GLuint GL_NewTextureWithParams(dgltexformat_t format, int width, int height, uint8_t const *pixels, int flags,
268                                int grayMipmap, int minFilter, int magFilter, int anisoFilter, int wrapS, int wrapT);
269 
270 /**
271  * in/out format:
272  * 1 = palette indices
273  * 2 = palette indices followed by alpha values
274  * 3 = RGB
275  * 4 = RGBA
276  */
277 uint8_t *GL_ConvertBuffer(uint8_t const *src, int width, int height,
278     int informat, colorpaletteid_t paletteId, int outformat);
279 
280 /**
281  * @param method  Unique identifier of the smart filtering method to apply.
282  * @param src  Source image to be filtered.
283  * @param width  Width of the source image in pixels.
284  * @param height  Height of the source image in pixels.
285  * @param flags  @ref imageConversionFlags.
286  * @param outWidth  Width of resultant image in pixels.
287  * @param outHeight  Height of resultant image in pixels.
288  *
289  * @return  Newly allocated version of the source image if filtered else @c == @a src.
290  */
291 uint8_t *GL_SmartFilter(int method, uint8_t const *src, int width, int height,
292     int flags, int *outWidth, int *outHeight);
293 
294 /**
295  * Calculates the properties of a dynamic light that the given sprite frame
296  * casts. Crop a boundary around the image to remove excess alpha'd pixels
297  * from adversely affecting the calculation.
298  * Handles pixel sizes; 1 (==2), 3 and 4.
299  */
300 void GL_CalcLuminance(uint8_t const *buffer, int width, int height, int comps,
301     colorpaletteid_t paletteId, float *brightX, float *brightY,
302     struct ColorRawf_s *color, float *lumSize);
303 
304 // DGL internal API ---------------------------------------------------------------------
305 
306 void            DGL_Shutdown();
307 unsigned int    DGL_BatchMaxSize();
308 void            DGL_BeginFrame();
309 void            DGL_Flush();
310 void            DGL_AssertNotInPrimitive(void);
311 de::Matrix4f    DGL_Matrix(DGLenum matrixMode);
312 void            DGL_CurrentColor(DGLubyte *rgba);
313 void            DGL_CurrentColor(float *rgba);
314 void            DGL_ModulateTexture(int mode);
315 void            DGL_SetModulationColor(de::Vector4f const &modColor);
316 de::Vector4f    DGL_ModulationColor();
317 void            DGL_FogParams(de::GLUniform &fogRange, de::GLUniform &fogColor);
318 void            DGL_DepthFunc(DGLenum depthFunc);
319 void            DGL_CullFace(DGLenum cull);
320 
321 // Console commands ---------------------------------------------------------------------
322 
323 //D_CMD(UpdateGammaRamp);
324 
325 #endif // DENG_GL_MAIN_H
326