OpenGL.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /**
  2. * Copyright (c) 2006-2015 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 "graphics/Color.h"
  24. #include "graphics/Texture.h"
  25. #include "common/Matrix.h"
  26. // GLAD
  27. #include "libraries/glad/gladfuncs.hpp"
  28. // C++
  29. #include <vector>
  30. #include <stack>
  31. // The last argument to AttribPointer takes a buffer offset casted to a pointer.
  32. #define BUFFER_OFFSET(i) ((char *) NULL + (i))
  33. namespace love
  34. {
  35. namespace graphics
  36. {
  37. namespace opengl
  38. {
  39. // Awful, but the library uses the namespace in order to use the functions sanely
  40. // with proper autocomplete in IDEs while having name mangling safety -
  41. // no clashes with other GL libraries when linking, etc.
  42. using namespace glad;
  43. // Vertex attribute indices used in shaders by LOVE. The values map to OpenGL
  44. // generic vertex attribute indices.
  45. enum VertexAttribID
  46. {
  47. ATTRIB_POS = 0,
  48. ATTRIB_TEXCOORD,
  49. ATTRIB_COLOR,
  50. ATTRIB_PSEUDO_INSTANCE_ID, // Instance ID used with pseudo-instancing.
  51. ATTRIB_MAX_ENUM
  52. };
  53. /**
  54. * Thin layer between OpenGL and the rest of the program.
  55. * Internally shadows some OpenGL context state for improved efficiency and
  56. * accuracy (compared to glGet etc.)
  57. * A class is more convenient and readable than plain namespaced functions, but
  58. * typically only one OpenGL object should be used (singleton.)
  59. **/
  60. class OpenGL
  61. {
  62. public:
  63. // OpenGL GPU vendors.
  64. enum Vendor
  65. {
  66. VENDOR_ATI_AMD,
  67. VENDOR_NVIDIA,
  68. VENDOR_INTEL,
  69. VENDOR_MESA_SOFT, // Software renderer.
  70. VENDOR_APPLE, // Software renderer on desktops.
  71. VENDOR_MICROSOFT, // Software renderer.
  72. VENDOR_IMGTEC,
  73. VENDOR_ARM,
  74. VENDOR_QUALCOMM,
  75. VENDOR_BROADCOM,
  76. VENDOR_VIVANTE,
  77. VENDOR_UNKNOWN
  78. };
  79. // A rectangle representing an OpenGL viewport or a scissor box.
  80. struct Viewport
  81. {
  82. int x, y;
  83. int w, h;
  84. Viewport()
  85. : x(0), y(0), w(0), h(0)
  86. {}
  87. Viewport(int _x, int _y, int _w, int _h)
  88. : x(_x), y(_y), w(_w), h(_h)
  89. {}
  90. bool operator == (const Viewport &rhs) const
  91. {
  92. return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
  93. }
  94. };
  95. struct BlendState
  96. {
  97. GLenum srcRGB, srcA;
  98. GLenum dstRGB, dstA;
  99. GLenum func;
  100. };
  101. struct
  102. {
  103. std::vector<Matrix> transform;
  104. std::vector<Matrix> projection;
  105. } matrices;
  106. class TempTransform
  107. {
  108. public:
  109. TempTransform(OpenGL &gl)
  110. : gl(gl)
  111. {
  112. gl.pushTransform();
  113. }
  114. ~TempTransform()
  115. {
  116. gl.popTransform();
  117. }
  118. Matrix &get()
  119. {
  120. return gl.getTransform();
  121. }
  122. private:
  123. OpenGL &gl;
  124. };
  125. struct Stats
  126. {
  127. size_t textureMemory;
  128. int drawCalls;
  129. } stats;
  130. OpenGL();
  131. /**
  132. * Initializes the active OpenGL context.
  133. **/
  134. bool initContext();
  135. /**
  136. * Sets up some required context state based on current and default OpenGL
  137. * state. Call this directly after initializing an OpenGL context!
  138. **/
  139. void setupContext();
  140. /**
  141. * Marks current context state as invalid and deletes OpenGL objects owned
  142. * by this class instance. Call this directly before potentially deleting
  143. * an OpenGL context!
  144. **/
  145. void deInitContext();
  146. void pushTransform();
  147. void popTransform();
  148. Matrix &getTransform();
  149. /**
  150. * Set up necessary state (LOVE-provided shader uniforms, etc.) for drawing.
  151. * This *MUST* be called directly before OpenGL drawing functions.
  152. **/
  153. void prepareDraw();
  154. /**
  155. * glDrawArrays and glDrawElements which increment the draw-call counter by
  156. * themselves.
  157. **/
  158. void drawArrays(GLenum mode, GLint first, GLsizei count);
  159. void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
  160. /**
  161. * Sets the current constant color.
  162. **/
  163. void setColor(const Color &c);
  164. /**
  165. * Gets the current constant color.
  166. **/
  167. Color getColor() const;
  168. /**
  169. * Sets the current clear color for all framebuffer objects.
  170. **/
  171. void setClearColor(const Color &c);
  172. /**
  173. * Gets the current clear color.
  174. **/
  175. Color getClearColor() const;
  176. /**
  177. * Sets the OpenGL rendering viewport to the specified rectangle.
  178. * The y-coordinate starts at the top.
  179. **/
  180. void setViewport(const Viewport &v);
  181. /**
  182. * Gets the current OpenGL rendering viewport rectangle.
  183. **/
  184. Viewport getViewport() const;
  185. /**
  186. * Sets the scissor box to the specified rectangle.
  187. * The y-coordinate starts at the top and is flipped internally.
  188. **/
  189. void setScissor(const Viewport &v);
  190. /**
  191. * Gets the current scissor box (regardless of whether scissoring is enabled.)
  192. **/
  193. Viewport getScissor() const;
  194. /**
  195. * Sets blending functionality.
  196. * Note: This does not globally enable or disable blending.
  197. **/
  198. void setBlendState(const BlendState &blend);
  199. /**
  200. * Gets the currently set blending functionality.
  201. **/
  202. BlendState getBlendState() const;
  203. /**
  204. * Sets the global point size.
  205. **/
  206. void setPointSize(float size);
  207. /**
  208. * Gets the global point size.
  209. **/
  210. float getPointSize() const;
  211. /**
  212. * This will usually be 0 (system drawable), but some platforms require a
  213. * non-zero FBO for rendering.
  214. **/
  215. GLuint getDefaultFBO() const;
  216. /**
  217. * Gets the ID for love's default texture (used for "untextured" primitives.)
  218. **/
  219. GLuint getDefaultTexture() const;
  220. /**
  221. * Helper for setting the active texture unit.
  222. *
  223. * @param textureunit Index in the range of [0, maxtextureunits-1]
  224. **/
  225. void setTextureUnit(int textureunit);
  226. /**
  227. * Helper for binding an OpenGL texture.
  228. * Makes sure we aren't redundantly binding textures.
  229. **/
  230. void bindTexture(GLuint texture);
  231. /**
  232. * Helper for binding a texture to a specific texture unit.
  233. *
  234. * @param textureunit Index in the range of [0, maxtextureunits-1]
  235. * @param restoreprev Restore previously bound texture unit when done.
  236. **/
  237. void bindTextureToUnit(GLuint texture, int textureunit, bool restoreprev);
  238. /**
  239. * Helper for deleting an OpenGL texture.
  240. * Cleans up if the texture is currently bound.
  241. **/
  242. void deleteTexture(GLuint texture);
  243. /**
  244. * Sets the texture filter mode for the currently bound texture.
  245. * The anisotropy parameter of the argument is set to the actual amount of
  246. * anisotropy that was used.
  247. **/
  248. void setTextureFilter(graphics::Texture::Filter &f);
  249. /**
  250. * Sets the texture wrap mode for the currently bound texture.
  251. **/
  252. void setTextureWrap(const graphics::Texture::Wrap &w);
  253. /**
  254. * Returns the maximum supported width or height of a texture.
  255. **/
  256. int getMaxTextureSize() const;
  257. /**
  258. * Returns the maximum supported number of simultaneous render targets.
  259. **/
  260. int getMaxRenderTargets() const;
  261. /**
  262. * Returns the maximum supported number of MSAA samples for renderbuffers.
  263. **/
  264. int getMaxRenderbufferSamples() const;
  265. void updateTextureMemorySize(size_t oldsize, size_t newsize);
  266. /**
  267. * Get the GPU vendor of this OpenGL context.
  268. **/
  269. Vendor getVendor() const;
  270. // Get human-readable strings for debug info.
  271. static const char *debugSeverityString(GLenum severity);
  272. static const char *debugSourceString(GLenum source);
  273. static const char *debugTypeString(GLenum type);
  274. private:
  275. void initVendor();
  276. void initOpenGLFunctions();
  277. void initMaxValues();
  278. void initMatrices();
  279. void createDefaultTexture();
  280. bool contextInitialized;
  281. float maxAnisotropy;
  282. int maxTextureSize;
  283. int maxRenderTargets;
  284. int maxRenderbufferSamples;
  285. Vendor vendor;
  286. // Tracked OpenGL state.
  287. struct
  288. {
  289. // Current constant color.
  290. Color color;
  291. Color clearColor;
  292. // Texture unit state (currently bound texture for each texture unit.)
  293. std::vector<GLuint> boundTextures;
  294. // Currently active texture unit.
  295. int curTextureUnit;
  296. Viewport viewport;
  297. Viewport scissor;
  298. float pointSize;
  299. GLuint defaultTexture;
  300. BlendState blend;
  301. Matrix lastProjectionMatrix;
  302. Matrix lastTransformMatrix;
  303. } state;
  304. }; // OpenGL
  305. // OpenGL class instance singleton.
  306. extern OpenGL gl;
  307. } // opengl
  308. } // graphics
  309. } // love
  310. #endif // LOVE_GRAPHICS_OPENGL_OPENGL_H