OpenGL.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /**
  2. * Copyright (c) 2006-2016 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #ifndef LOVE_GRAPHICS_OPENGL_OPENGL_H
  21. #define LOVE_GRAPHICS_OPENGL_OPENGL_H
  22. // LOVE
  23. #include "common/config.h"
  24. #include "common/int.h"
  25. #include "common/math.h"
  26. #include "graphics/Color.h"
  27. #include "graphics/Texture.h"
  28. #include "graphics/vertex.h"
  29. #include "common/Matrix.h"
  30. // GLAD
  31. #include "libraries/glad/gladfuncs.hpp"
  32. // C++
  33. #include <vector>
  34. #include <stack>
  35. // The last argument to AttribPointer takes a buffer offset casted to a pointer.
  36. #define BUFFER_OFFSET(i) ((char *) NULL + (i))
  37. namespace love
  38. {
  39. namespace graphics
  40. {
  41. namespace opengl
  42. {
  43. // Awful, but the library uses the namespace in order to use the functions sanely
  44. // with proper autocomplete in IDEs while having name mangling safety -
  45. // no clashes with other GL libraries when linking, etc.
  46. using namespace glad;
  47. // Vertex attribute indices used in shaders by LOVE. The values map to OpenGL
  48. // generic vertex attribute indices.
  49. enum VertexAttribID
  50. {
  51. ATTRIB_POS = 0,
  52. ATTRIB_TEXCOORD,
  53. ATTRIB_COLOR,
  54. ATTRIB_CONSTANTCOLOR,
  55. ATTRIB_MAX_ENUM
  56. };
  57. enum VertexAttribFlags
  58. {
  59. ATTRIBFLAG_POS = 1 << ATTRIB_POS,
  60. ATTRIBFLAG_TEXCOORD = 1 << ATTRIB_TEXCOORD,
  61. ATTRIBFLAG_COLOR = 1 << ATTRIB_COLOR,
  62. ATTRIBFLAG_CONSTANTCOLOR = 1 << ATTRIB_CONSTANTCOLOR
  63. };
  64. /**
  65. * Thin layer between OpenGL and the rest of the program.
  66. * Internally shadows some OpenGL context state for improved efficiency and
  67. * accuracy (compared to glGet etc.)
  68. * A class is more convenient and readable than plain namespaced functions, but
  69. * typically only one OpenGL object should be used (singleton.)
  70. **/
  71. class OpenGL
  72. {
  73. public:
  74. // OpenGL GPU vendors.
  75. enum Vendor
  76. {
  77. VENDOR_AMD,
  78. VENDOR_NVIDIA,
  79. VENDOR_INTEL,
  80. VENDOR_MESA_SOFT, // Software renderer.
  81. VENDOR_APPLE, // Software renderer on desktops.
  82. VENDOR_MICROSOFT, // Software renderer.
  83. VENDOR_IMGTEC,
  84. VENDOR_ARM,
  85. VENDOR_QUALCOMM,
  86. VENDOR_BROADCOM,
  87. VENDOR_VIVANTE,
  88. VENDOR_UNKNOWN
  89. };
  90. enum FramebufferTarget
  91. {
  92. FRAMEBUFFER_READ = (1 << 0),
  93. FRAMEBUFFER_DRAW = (1 << 1),
  94. FRAMEBUFFER_ALL = (FRAMEBUFFER_READ | FRAMEBUFFER_DRAW),
  95. };
  96. struct TextureFormat
  97. {
  98. GLenum internalformat = 0;
  99. GLenum externalformat = 0;
  100. GLenum type = 0;
  101. };
  102. class TempDebugGroup
  103. {
  104. public:
  105. #if defined(LOVE_IOS)
  106. TempDebugGroup(const char *name)
  107. {
  108. if (GLAD_EXT_debug_marker)
  109. glPushGroupMarkerEXT(0, (const GLchar *) name);
  110. }
  111. #else
  112. TempDebugGroup(const char *) {}
  113. #endif
  114. #if defined(LOVE_IOS)
  115. ~TempDebugGroup()
  116. {
  117. if (GLAD_EXT_debug_marker)
  118. glPopGroupMarkerEXT();
  119. }
  120. #endif
  121. };
  122. struct Stats
  123. {
  124. size_t textureMemory;
  125. int drawCalls;
  126. int shaderSwitches;
  127. } stats;
  128. struct Bugs
  129. {
  130. /**
  131. * On AMD's Windows (and probably Linux) drivers,
  132. * glBindFramebuffer + glClear + glBindFramebuffer + draw(fbo_tex) won't
  133. * work unless there's some kind of draw or state change which causes
  134. * the driver to update the texture's contents (just drawing the texture
  135. * won't always do it, with this driver bug).
  136. * Activating shader program 0 and then activating the actual program
  137. * seems to always 'fix' it for me.
  138. * Bug observed January 2016 with multiple AMD GPUs and driver versions.
  139. * https://love2d.org/forums/viewtopic.php?f=4&t=81496
  140. **/
  141. bool clearRequiresDriverTextureStateUpdate;
  142. /**
  143. * AMD's Windows drivers don't always properly generate mipmaps unless
  144. * glEnable(GL_TEXTURE_2D) is called directly before glGenerateMipmap.
  145. * This only applies to legacy and Compatibility Profile contexts, of
  146. * course.
  147. * https://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation
  148. **/
  149. bool generateMipmapsRequiresTexture2DEnable;
  150. /**
  151. * Other bugs which have workarounds that don't use conditional code at
  152. * the moment:
  153. *
  154. * Kepler nvidia GPUs in at least OS X 10.10 and 10.11 fail to render
  155. * geometry with glDrawElements if index data comes from a Buffer Object
  156. * and vertex data doesn't. One workaround is to use a CPU-side index
  157. * array when there's also a CPU-side vertex array.
  158. * https://love2d.org/forums/viewtopic.php?f=4&t=81401&start=10
  159. *
  160. * Some android drivers don't seem to initialize the sampler index
  161. * values of sampler uniforms in shaders to 0 (which is required by the
  162. * GLSL ES specification) when linking the shader program. One
  163. * workaround is to always set the values of said sampler uniforms to 0
  164. * just after linking the shader program.
  165. * https://love2d.org/forums/viewtopic.php?f=4&t=81458
  166. **/
  167. } bugs;
  168. OpenGL();
  169. /**
  170. * Initializes the active OpenGL context.
  171. **/
  172. bool initContext();
  173. /**
  174. * Sets up some required context state based on current and default OpenGL
  175. * state. Call this directly after initializing an OpenGL context!
  176. **/
  177. void setupContext();
  178. /**
  179. * Marks current context state as invalid and deletes OpenGL objects owned
  180. * by this class instance. Call this directly before potentially deleting
  181. * an OpenGL context!
  182. **/
  183. void deInitContext();
  184. /**
  185. * Set up necessary state (LOVE-provided shader uniforms, etc.) for drawing.
  186. * This *MUST* be called directly before OpenGL drawing functions.
  187. **/
  188. void prepareDraw();
  189. /**
  190. * State-tracked glBindBuffer.
  191. * NOTE: This does not account for multiple VAOs being used! Index buffer
  192. * bindings are per-VAO in OpenGL, but this doesn't know about that.
  193. **/
  194. void bindBuffer(BufferType type, GLuint buffer);
  195. /**
  196. * glDeleteBuffers which updates our shadowed state.
  197. **/
  198. void deleteBuffer(GLuint buffer);
  199. /**
  200. * glDrawArrays and glDrawElements which increment the draw-call counter by
  201. * themselves.
  202. **/
  203. void drawArrays(GLenum mode, GLint first, GLsizei count);
  204. void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
  205. /**
  206. * Sets the enabled vertex attribute arrays based on the specified attribute
  207. * bits. Each bit in the uint32 represents an enabled attribute array index.
  208. * For example, useVertexAttribArrays(1 << 0) will enable attribute index 0.
  209. * See the VertexAttribFlags enum for the standard vertex attributes.
  210. * This function *must* be used instead of glEnable/DisableVertexAttribArray.
  211. **/
  212. void useVertexAttribArrays(uint32 arraybits);
  213. /**
  214. * Sets the OpenGL rendering viewport to the specified rectangle.
  215. * The y-coordinate starts at the top.
  216. **/
  217. void setViewport(const Rect &v, bool canvasActive);
  218. /**
  219. * Gets the current OpenGL rendering viewport rectangle.
  220. **/
  221. Rect getViewport() const;
  222. /**
  223. * Sets the scissor box to the specified rectangle.
  224. * The y-coordinate starts at the top and is flipped internally.
  225. **/
  226. void setScissor(const Rect &v, bool canvasActive);
  227. /**
  228. * Gets the current scissor box (regardless of whether scissoring is enabled.)
  229. **/
  230. Rect getScissor() const;
  231. /**
  232. * Sets the global point size.
  233. **/
  234. void setPointSize(float size);
  235. /**
  236. * Gets the global point size.
  237. **/
  238. float getPointSize() const;
  239. /**
  240. * Calls glEnable/glDisable(GL_FRAMEBUFFER_SRGB).
  241. **/
  242. void setFramebufferSRGB(bool enable);
  243. /**
  244. * Equivalent to glIsEnabled(GL_FRAMEBUFFER_SRGB).
  245. **/
  246. bool hasFramebufferSRGB() const;
  247. /**
  248. * Binds a Framebuffer Object to the specified target.
  249. **/
  250. void bindFramebuffer(FramebufferTarget target, GLuint framebuffer);
  251. GLuint getFramebuffer(FramebufferTarget target) const;
  252. void deleteFramebuffer(GLuint framebuffer);
  253. /**
  254. * Calls glUseProgram.
  255. **/
  256. void useProgram(GLuint program);
  257. /**
  258. * This will usually be 0 (system drawable), but some platforms require a
  259. * non-zero FBO for rendering.
  260. **/
  261. GLuint getDefaultFBO() const;
  262. /**
  263. * Gets the ID for love's default texture (used for "untextured" primitives.)
  264. **/
  265. GLuint getDefaultTexture() const;
  266. /**
  267. * Helper for setting the active texture unit.
  268. *
  269. * @param textureunit Index in the range of [0, maxtextureunits-1]
  270. **/
  271. void setTextureUnit(int textureunit);
  272. /**
  273. * Helper for binding a texture to a specific texture unit.
  274. *
  275. * @param textureunit Index in the range of [0, maxtextureunits-1]
  276. * @param restoreprev Restore previously bound texture unit when done.
  277. **/
  278. void bindTextureToUnit(GLuint texture, int textureunit, bool restoreprev);
  279. void bindTextureToUnit(Texture *texture, int textureunit, bool restoreprev);
  280. /**
  281. * Helper for deleting an OpenGL texture.
  282. * Cleans up if the texture is currently bound.
  283. **/
  284. void deleteTexture(GLuint texture);
  285. /**
  286. * Sets the texture filter mode for the currently bound texture.
  287. * The anisotropy parameter of the argument is set to the actual amount of
  288. * anisotropy that was used.
  289. **/
  290. void setTextureFilter(graphics::Texture::Filter &f);
  291. /**
  292. * Sets the texture wrap mode for the currently bound texture.
  293. **/
  294. void setTextureWrap(const graphics::Texture::Wrap &w);
  295. bool isClampZeroTextureWrapSupported() const;
  296. bool isPixelShaderHighpSupported() const;
  297. /**
  298. * Returns the maximum supported width or height of a texture.
  299. **/
  300. int getMaxTextureSize() const;
  301. /**
  302. * Returns the maximum supported number of simultaneous render targets.
  303. **/
  304. int getMaxRenderTargets() const;
  305. /**
  306. * Returns the maximum supported number of MSAA samples for renderbuffers.
  307. **/
  308. int getMaxRenderbufferSamples() const;
  309. /**
  310. * Returns the maximum number of accessible texture units.
  311. **/
  312. int getMaxTextureUnits() const;
  313. /**
  314. * Returns the maximum point size.
  315. **/
  316. float getMaxPointSize() const;
  317. /**
  318. * Returns the maximum anisotropic filtering value that can be used for
  319. * Texture filtering.
  320. **/
  321. float getMaxAnisotropy() const;
  322. void updateTextureMemorySize(size_t oldsize, size_t newsize);
  323. /**
  324. * Get the GPU vendor of this OpenGL context.
  325. **/
  326. Vendor getVendor() const;
  327. static GLenum getGLBufferType(BufferType type);
  328. static GLint getGLWrapMode(Texture::WrapMode wmode);
  329. static TextureFormat convertPixelFormat(PixelFormat pixelformat, bool renderbuffer, bool &isSRGB);
  330. static bool isPixelFormatSupported(PixelFormat pixelformat, bool rendertarget, bool isSRGB);
  331. static bool hasTextureFilteringSupport(PixelFormat pixelformat);
  332. static const char *errorString(GLenum errorcode);
  333. static const char *framebufferStatusString(GLenum status);
  334. // Get human-readable strings for debug info.
  335. static const char *debugSeverityString(GLenum severity);
  336. static const char *debugSourceString(GLenum source);
  337. static const char *debugTypeString(GLenum type);
  338. private:
  339. void initVendor();
  340. void initOpenGLFunctions();
  341. void initMaxValues();
  342. void createDefaultTexture();
  343. bool contextInitialized;
  344. bool pixelShaderHighpSupported;
  345. float maxAnisotropy;
  346. int maxTextureSize;
  347. int maxRenderTargets;
  348. int maxRenderbufferSamples;
  349. int maxTextureUnits;
  350. float maxPointSize;
  351. Vendor vendor;
  352. // Tracked OpenGL state.
  353. struct
  354. {
  355. GLuint boundBuffers[BUFFER_MAX_ENUM];
  356. // Texture unit state (currently bound texture for each texture unit.)
  357. std::vector<GLuint> boundTextures;
  358. // Currently active texture unit.
  359. int curTextureUnit;
  360. uint32 enabledAttribArrays;
  361. Rect viewport;
  362. Rect scissor;
  363. float pointSize;
  364. GLuint boundFramebuffers[2];
  365. bool framebufferSRGBEnabled;
  366. GLuint defaultTexture;
  367. Matrix4 lastProjectionMatrix;
  368. Matrix4 lastTransformMatrix;
  369. } state;
  370. }; // OpenGL
  371. // OpenGL class instance singleton.
  372. extern OpenGL gl;
  373. } // opengl
  374. } // graphics
  375. } // love
  376. #endif // LOVE_GRAPHICS_OPENGL_OPENGL_H