OpenGL.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. /**
  2. * Copyright (c) 2006-2020 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 "common/Color.h"
  27. #include "graphics/Texture.h"
  28. #include "graphics/vertex.h"
  29. #include "graphics/renderstate.h"
  30. #include "common/Matrix.h"
  31. // GLAD
  32. #include "libraries/glad/gladfuncs.hpp"
  33. // C++
  34. #include <vector>
  35. #include <stack>
  36. // The last argument to AttribPointer takes a buffer offset casted to a pointer.
  37. #define BUFFER_OFFSET(i) ((char *) NULL + (i))
  38. namespace love
  39. {
  40. namespace graphics
  41. {
  42. class Resource;
  43. class Buffer;
  44. namespace opengl
  45. {
  46. // Awful, but the library uses the namespace in order to use the functions sanely
  47. // with proper autocomplete in IDEs while having name mangling safety -
  48. // no clashes with other GL libraries when linking, etc.
  49. using namespace glad;
  50. /**
  51. * Thin layer between OpenGL and the rest of the program.
  52. * Internally shadows some OpenGL context state for improved efficiency and
  53. * accuracy (compared to glGet etc.)
  54. * A class is more convenient and readable than plain namespaced functions, but
  55. * typically only one OpenGL object should be used (singleton.)
  56. **/
  57. class OpenGL
  58. {
  59. public:
  60. // OpenGL GPU vendors.
  61. enum Vendor
  62. {
  63. VENDOR_AMD,
  64. VENDOR_NVIDIA,
  65. VENDOR_INTEL,
  66. VENDOR_MESA_SOFT, // Software renderer.
  67. VENDOR_APPLE, // Software renderer on desktops.
  68. VENDOR_MICROSOFT, // Software renderer.
  69. VENDOR_IMGTEC,
  70. VENDOR_ARM,
  71. VENDOR_QUALCOMM,
  72. VENDOR_BROADCOM,
  73. VENDOR_VIVANTE,
  74. VENDOR_UNKNOWN
  75. };
  76. enum FramebufferTarget
  77. {
  78. FRAMEBUFFER_READ = (1 << 0),
  79. FRAMEBUFFER_DRAW = (1 << 1),
  80. FRAMEBUFFER_ALL = (FRAMEBUFFER_READ | FRAMEBUFFER_DRAW),
  81. };
  82. enum EnableState
  83. {
  84. ENABLE_BLEND,
  85. ENABLE_DEPTH_TEST,
  86. ENABLE_STENCIL_TEST,
  87. ENABLE_SCISSOR_TEST,
  88. ENABLE_FACE_CULL,
  89. ENABLE_FRAMEBUFFER_SRGB,
  90. ENABLE_MAX_ENUM
  91. };
  92. struct TextureFormat
  93. {
  94. GLenum internalformat = 0;
  95. GLenum externalformat = 0;
  96. GLenum type = 0;
  97. // For depth/stencil formats.
  98. GLenum framebufferAttachments[2];
  99. bool swizzled = false;
  100. GLint swizzle[4];
  101. };
  102. class TempDebugGroup
  103. {
  104. public:
  105. TempDebugGroup(const char *name);
  106. ~TempDebugGroup();
  107. };
  108. struct Stats
  109. {
  110. int shaderSwitches;
  111. } stats;
  112. struct Bugs
  113. {
  114. /**
  115. * On AMD's Windows (and probably Linux) drivers,
  116. * glBindFramebuffer + glClear + glBindFramebuffer + draw(fbo_tex) won't
  117. * work unless there's some kind of draw or state change which causes
  118. * the driver to update the texture's contents (just drawing the texture
  119. * won't always do it, with this driver bug).
  120. * Activating shader program 0 and then activating the actual program
  121. * seems to always 'fix' it for me.
  122. * Bug observed January 2016 with multiple AMD GPUs and driver versions.
  123. * https://love2d.org/forums/viewtopic.php?f=4&t=81496
  124. **/
  125. bool clearRequiresDriverTextureStateUpdate;
  126. /**
  127. * AMD's Windows drivers don't always properly generate mipmaps unless
  128. * glEnable(GL_TEXTURE_2D) is called directly before glGenerateMipmap.
  129. * This only applies to legacy and Compatibility Profile contexts, of
  130. * course.
  131. * https://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation
  132. **/
  133. bool generateMipmapsRequiresTexture2DEnable;
  134. /**
  135. * Report: Intel HD 4000 on Windows hangs during glClientWaitSync.
  136. * I found this when googling the issue:
  137. * https://github.com/mjn33/planetgen/commit/235e23873a22e219fffdd9ede706c1051aa0f107
  138. **/
  139. bool clientWaitSyncStalls;
  140. /**
  141. * glTexStorage on some older AMD/ATI graphics drivers on Windows seems
  142. * to break subsequent sub-rectangle glTexSubImage calls after an
  143. * initial full-size one (determined after some investigation with an
  144. * affected user on Discord.)
  145. * https://bitbucket.org/rude/love/issues/1436/bug-with-lovegraphicsprint-on-older-ati
  146. * https://github.com/love2d/love/issues/1563
  147. **/
  148. bool texStorageBreaksSubImage;
  149. /**
  150. * An Android device with an Adreno 630 (supposedly GLES3.2-capable)
  151. * fails with GL_INVALID_OPERATION in glTexImage2D if the image is
  152. * GL_R8, despite the GLES 3.0 spec mandating support for that format.
  153. * It's possible more Adreno GPUs / drivers are affected as well.
  154. **/
  155. bool brokenR8PixelFormat;
  156. /**
  157. * Intel HD Graphics drivers on Windows prior to the HD 2500/4000 have
  158. * completely broken sRGB support.
  159. * https://github.com/love2d/love/issues/1592
  160. **/
  161. bool brokenSRGB;
  162. /**
  163. * Other bugs which have workarounds that don't use conditional code at
  164. * the moment:
  165. *
  166. * Kepler nvidia GPUs in at least OS X 10.10 and 10.11 fail to render
  167. * geometry with glDrawElements if index data comes from a Buffer Object
  168. * and vertex data doesn't. One workaround is to use a CPU-side index
  169. * array when there's also a CPU-side vertex array.
  170. * https://love2d.org/forums/viewtopic.php?f=4&t=81401&start=10
  171. *
  172. * Some android drivers don't seem to initialize the sampler index
  173. * values of sampler uniforms in shaders to 0 (which is required by the
  174. * GLSL ES specification) when linking the shader program. One
  175. * workaround is to always set the values of said sampler uniforms to 0
  176. * just after linking the shader program.
  177. * https://love2d.org/forums/viewtopic.php?f=4&t=81458
  178. **/
  179. } bugs;
  180. OpenGL();
  181. /**
  182. * Initializes the active OpenGL context.
  183. **/
  184. bool initContext();
  185. /**
  186. * Sets up some required context state based on current and default OpenGL
  187. * state. Call this directly after initializing an OpenGL context!
  188. **/
  189. void setupContext();
  190. /**
  191. * Marks current context state as invalid and deletes OpenGL objects owned
  192. * by this class instance. Call this directly before potentially deleting
  193. * an OpenGL context!
  194. **/
  195. void deInitContext();
  196. /**
  197. * Set up necessary state (LOVE-provided shader uniforms, etc.) for drawing.
  198. * This *MUST* be called directly before OpenGL drawing functions.
  199. **/
  200. void prepareDraw(love::graphics::Graphics *gfx);
  201. /**
  202. * State-tracked glBindBuffer.
  203. * NOTE: This does not account for multiple VAOs being used! Index buffer
  204. * bindings are per-VAO in OpenGL, but this doesn't know about that.
  205. **/
  206. void bindBuffer(BufferType type, GLuint buffer);
  207. /**
  208. * glDeleteBuffers which updates our shadowed state.
  209. **/
  210. void deleteBuffer(GLuint buffer);
  211. /**
  212. * Set all vertex attribute state.
  213. **/
  214. void setVertexAttributes(const VertexAttributes &attributes, const BufferBindings &buffers);
  215. /**
  216. * Wrapper for glCullFace which eliminates redundant state setting.
  217. **/
  218. void setCullMode(CullMode mode);
  219. /**
  220. * Wrapper for glClearDepth and glClearDepthf.
  221. **/
  222. void clearDepth(double value);
  223. /**
  224. * Sets the OpenGL rendering viewport to the specified rectangle.
  225. * The y-coordinate starts at the top.
  226. **/
  227. void setViewport(const Rect &v);
  228. Rect getViewport() const;
  229. /**
  230. * Sets the scissor box to the specified rectangle.
  231. * The y-coordinate starts at the top and is flipped internally.
  232. **/
  233. void setScissor(const Rect &v, bool rtActive);
  234. /**
  235. * Sets the global point size.
  236. **/
  237. void setPointSize(float size);
  238. float getPointSize() const;
  239. /**
  240. * State-tracked version of glEnable.
  241. **/
  242. void setEnableState(EnableState state, bool enable);
  243. bool isStateEnabled(EnableState state) const;
  244. /**
  245. * Binds a Framebuffer Object to the specified target.
  246. **/
  247. void bindFramebuffer(FramebufferTarget target, GLuint framebuffer);
  248. GLuint getFramebuffer(FramebufferTarget target) const;
  249. void deleteFramebuffer(GLuint framebuffer);
  250. void framebufferTexture(GLenum attachment, TextureType texType, GLuint texture, int level, int layer = 0, int face = 0);
  251. /**
  252. * Calls glDepthMask.
  253. **/
  254. void setDepthWrites(bool enable);
  255. bool hasDepthWrites() const;
  256. /**
  257. * Calls glUseProgram.
  258. **/
  259. void useProgram(GLuint program);
  260. /**
  261. * This will usually be 0 (system drawable), but some platforms require a
  262. * non-zero FBO for rendering.
  263. **/
  264. GLuint getDefaultFBO() const;
  265. /**
  266. * Gets the ID for love's default texture (used for "untextured" primitives.)
  267. **/
  268. GLuint getDefaultTexture(TextureType type) const;
  269. /**
  270. * Gets the texture ID for love's default texel buffer.
  271. **/
  272. GLuint getDefaultTexelBuffer() const { return state.defaultTexelBuffer; }
  273. void setDefaultTexelBuffer(GLuint tex) { state.defaultTexelBuffer = tex; }
  274. GLuint getDefaultStorageBuffer() const { return state.defaultStorageBuffer; }
  275. void setDefaultStorageBuffer(GLuint buf) { state.defaultStorageBuffer = buf; }
  276. /**
  277. * Helper for setting the active texture unit.
  278. *
  279. * @param textureunit Index in the range of [0, maxtextureunits-1]
  280. **/
  281. void setTextureUnit(int textureunit);
  282. /**
  283. * Helper for binding a texture to a specific texture unit.
  284. *
  285. * @param textureunit Index in the range of [0, maxtextureunits-1]
  286. * @param restoreprev Restore previously bound texture unit when done.
  287. * @param bindforedit If false, the active texture unit may be left alone.
  288. **/
  289. void bindTextureToUnit(TextureType target, GLuint texture, int textureunit, bool restoreprev, bool bindforedit = true);
  290. void bindTextureToUnit(Texture *texture, int textureunit, bool restoreprev, bool bindforedit = true);
  291. void bindBufferTextureToUnit(GLuint texture, int textureunit, bool restoreprev, bool bindforedit);
  292. void bindIndexedBuffer(GLuint buffer, BufferType type, int index);
  293. /**
  294. * Helper for deleting an OpenGL texture.
  295. * Cleans up if the texture is currently bound.
  296. **/
  297. void deleteTexture(GLuint texture);
  298. /**
  299. * Sets sampler state parameters for the currently bound texture.
  300. **/
  301. void setSamplerState(TextureType target, SamplerState &s);
  302. /**
  303. * Equivalent to glTexStorage2D/3D on platforms that support it. Equivalent
  304. * to glTexImage2D/3D for all levels and slices of a texture otherwise.
  305. * NOTE: this does not handle compressed texture formats.
  306. **/
  307. bool rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, bool &isSRGB, int width, int height, int depth = 1);
  308. bool isTextureTypeSupported(TextureType type) const;
  309. bool isBufferTypeSupported(BufferType type) const;
  310. bool isClampZeroOneTextureWrapSupported() const;
  311. bool isPixelShaderHighpSupported() const;
  312. bool isInstancingSupported() const;
  313. bool isDepthCompareSampleSupported() const;
  314. bool isSamplerLODBiasSupported() const;
  315. bool isBaseVertexSupported() const;
  316. bool isMultiFormatMRTSupported() const;
  317. /**
  318. * Returns the maximum supported width or height of a texture.
  319. **/
  320. int getMax2DTextureSize() const;
  321. int getMax3DTextureSize() const;
  322. int getMaxCubeTextureSize() const;
  323. int getMaxTextureLayers() const;
  324. /**
  325. * Returns the maximum number of values in a texel buffer.
  326. **/
  327. int getMaxTexelBufferSize() const;
  328. /**
  329. * Returns the maximum number of bytes in a shader storage buffer.
  330. **/
  331. int getMaxShaderStorageBufferSize() const;
  332. /**
  333. * Returns the maximum supported number of simultaneous render targets.
  334. **/
  335. int getMaxRenderTargets() const;
  336. /**
  337. * Returns the maximum supported number of MSAA sampless.
  338. **/
  339. int getMaxSamples() const;
  340. /**
  341. * Returns the maximum number of accessible texture units.
  342. **/
  343. int getMaxTextureUnits() const;
  344. /**
  345. * Returns the maximum number of shader storage buffer bindings.
  346. **/
  347. int getMaxShaderStorageBufferBindings() const;
  348. /**
  349. * Returns the maximum point size.
  350. **/
  351. float getMaxPointSize() const;
  352. /**
  353. * Returns the maximum anisotropic filtering value that can be used for
  354. * Texture filtering.
  355. **/
  356. float getMaxAnisotropy() const;
  357. float getMaxLODBias() const;
  358. /**
  359. * Gets whether the context is Core Profile OpenGL 3.2+.
  360. **/
  361. bool isCoreProfile() const;
  362. /**
  363. * Get the GPU vendor of this OpenGL context.
  364. **/
  365. Vendor getVendor() const;
  366. static GLenum getGLPrimitiveType(PrimitiveType type);
  367. static GLenum getGLBufferType(BufferType type);
  368. static GLenum getGLIndexDataType(IndexDataType type);
  369. static GLenum getGLVertexDataType(DataFormat format, int &components, GLboolean &normalized, bool &intformat);
  370. static GLenum getGLBufferUsage(BufferUsage usage);
  371. static GLenum getGLTextureType(TextureType type);
  372. static GLint getGLWrapMode(SamplerState::WrapMode wmode);
  373. static GLint getGLCompareMode(CompareMode mode);
  374. static TextureFormat convertPixelFormat(PixelFormat pixelformat, bool renderbuffer, bool &isSRGB);
  375. static bool isTexStorageSupported();
  376. static bool isPixelFormatSupported(PixelFormat pixelformat, bool rendertarget, bool readable, bool isSRGB);
  377. static bool hasTextureFilteringSupport(PixelFormat pixelformat);
  378. static const char *errorString(GLenum errorcode);
  379. static const char *framebufferStatusString(GLenum status);
  380. // Get human-readable strings for debug info.
  381. static const char *debugSeverityString(GLenum severity);
  382. static const char *debugSourceString(GLenum source);
  383. static const char *debugTypeString(GLenum type);
  384. private:
  385. void initVendor();
  386. void initOpenGLFunctions();
  387. void initMaxValues();
  388. void createDefaultTexture();
  389. bool contextInitialized;
  390. bool pixelShaderHighpSupported;
  391. bool baseVertexSupported;
  392. float maxAnisotropy;
  393. float maxLODBias;
  394. int max2DTextureSize;
  395. int max3DTextureSize;
  396. int maxCubeTextureSize;
  397. int maxTextureArrayLayers;
  398. int maxTexelBufferSize;
  399. int maxShaderStorageBufferSize;
  400. int maxRenderTargets;
  401. int maxSamples;
  402. int maxTextureUnits;
  403. int maxShaderStorageBufferBindings;
  404. float maxPointSize;
  405. bool coreProfile;
  406. Vendor vendor;
  407. // Tracked OpenGL state.
  408. struct
  409. {
  410. GLuint boundBuffers[BUFFERTYPE_MAX_ENUM];
  411. // Texture unit state (currently bound texture for each texture unit.)
  412. std::vector<GLuint> boundTextures[TEXTURE_MAX_ENUM + 1];
  413. std::vector<GLuint> boundIndexedBuffers[BUFFERTYPE_MAX_ENUM];
  414. bool enableState[ENABLE_MAX_ENUM];
  415. GLenum faceCullMode;
  416. int curTextureUnit;
  417. uint32 enabledAttribArrays;
  418. uint32 instancedAttribArrays;
  419. Rect viewport;
  420. Rect scissor;
  421. float pointSize;
  422. bool depthWritesEnabled = true;
  423. GLuint boundFramebuffers[2];
  424. GLuint defaultTexture[TEXTURE_MAX_ENUM];
  425. GLuint defaultTexelBuffer;
  426. GLuint defaultStorageBuffer;
  427. } state;
  428. }; // OpenGL
  429. // OpenGL class instance singleton.
  430. extern OpenGL gl;
  431. } // opengl
  432. } // graphics
  433. } // love
  434. #endif // LOVE_GRAPHICS_OPENGL_OPENGL_H