PageRenderTime 52ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/include/lightsky/draw/ShaderProgram.h

https://gitlab.com/hamsham/LightDraw
C Header | 416 lines | 106 code | 58 blank | 252 comment | 3 complexity | 2c88c534837a52c8faf16c0d94ec7c4e MD5 | raw file
  1. /*
  2. * File: draw/shaderProgram.h
  3. * Author: Miles Lacey
  4. *
  5. * Created on January 21, 2014, 6:54 PM
  6. */
  7. #ifndef __LS_DRAW_SHADER_PROGRAM_H__
  8. #define __LS_DRAW_SHADER_PROGRAM_H__
  9. #include <string>
  10. #include <vector>
  11. #include "lightsky/draw/Setup.h"
  12. #include "lightsky/draw/VAOAttrib.h" // vertex_attrib_t
  13. #include "lightsky/draw/ShaderBlockAttrib.h"
  14. #include "lightsky/draw/ShaderAttribArray.h"
  15. namespace ls
  16. {
  17. namespace draw
  18. {
  19. /*-----------------------------------------------------------------------------
  20. * Forward Declarations
  21. -----------------------------------------------------------------------------*/
  22. enum class vertex_attrib_t : int;
  23. enum shader_stage_t : GLint;
  24. class ShaderObject;
  25. class ShaderProgramAssembly;
  26. class UniformBuffer;
  27. class VAOAttrib;
  28. /**----------------------------------------------------------------------------
  29. * @brief Shader Program
  30. *
  31. * Represents a combination of OpenGL vertex, fragment, and geometry shader
  32. * objects.
  33. -----------------------------------------------------------------------------*/
  34. class ShaderProgram
  35. {
  36. friend class ShaderProgramAssembly;
  37. private:
  38. /**
  39. * A handle to the GPU-side shader program within OpenGL.
  40. */
  41. GLuint gpuId;
  42. unsigned numUniformBlocks;
  43. /**
  44. * Array of CPU-side references to uniform blocks in *this shader.
  45. */
  46. utils::Pointer<ShaderBlockAttrib[]> uniformBlocks;
  47. /**
  48. * Member to hold all meta-info for the program uniforms.
  49. */
  50. ShaderAttribArray uniforms;
  51. /**
  52. * Member to hold all meta-info for the vertex shader inputs.
  53. */
  54. ShaderAttribArray vertAttribs;
  55. /**
  56. * Member to hold all meta-info for the vertex shader inputs.
  57. */
  58. ShaderAttribArray fragAttribs;
  59. public:
  60. /**
  61. * @brief Destructor
  62. *
  63. * Destroy this object and free any CPU memory it uses. No GPU-side
  64. * data will be deleted unless "terminate()".
  65. */
  66. ~ShaderProgram() noexcept;
  67. /**
  68. * @brief Constructor
  69. */
  70. ShaderProgram() noexcept;
  71. /**
  72. * @brief Copy Constructor
  73. *
  74. * Copies all data from the input parameter into *this.
  75. */
  76. ShaderProgram(const ShaderProgram&) noexcept;
  77. /**
  78. * @brief Move Constructor
  79. *
  80. * Move all data from the input parameter into *this without performing
  81. * any copies. All member variables within the input parameter will be
  82. * reset to their defaults.
  83. *
  84. * @param sp
  85. * An r-value reference to a shader program object to move into *this.
  86. */
  87. ShaderProgram(ShaderProgram&& sp) noexcept;
  88. /**
  89. * @brief Copy Operator
  90. *
  91. * Copies all data from the input parameter into *this.
  92. *
  93. * @return A reference to *this.
  94. */
  95. ShaderProgram& operator=(const ShaderProgram&) noexcept;
  96. /**
  97. * @brief Move Operator
  98. *
  99. * Move all data from the input parameter into *this without performing
  100. * any copies. All member variables within the input parameter will be
  101. * reset to their defaults.
  102. *
  103. * @param sp
  104. * An r-value reference to a shader program object to move into *this.
  105. *
  106. * @return A reference to *this
  107. */
  108. ShaderProgram& operator=(ShaderProgram&& sp) noexcept;
  109. /**
  110. * Free all memory used by this shader object.
  111. */
  112. void terminate() noexcept;
  113. /**
  114. * @brief Retrieve the OpenGL-assigned ID associated with the shader
  115. * binary used by *this.
  116. *
  117. * @return An unsigned integral type, identifying the shader program
  118. * used by OpenGL.
  119. */
  120. unsigned gpu_id() const noexcept;
  121. /**
  122. * Determine if *this object represents a valid OpenGL shader program which
  123. * can be rendered to.
  124. *
  125. * @return TRUE if *this can be used as a management container for an OpenGL
  126. * shader program, FALSE if not.
  127. */
  128. bool is_valid() const noexcept;
  129. /**
  130. * Bind this program to the current context
  131. */
  132. void bind() const noexcept;
  133. /**
  134. * Unbind this program from the context.
  135. */
  136. void unbind() const noexcept;
  137. /**
  138. * Retrieve an array of all attributes which can be passed into a
  139. * vertex shader.
  140. *
  141. * The returned ShaderAttribArray will only contain values if the
  142. * current shader has successfully been linked.
  143. *
  144. * @return A constant reference to a ShaderAttribArray object which
  145. * represents all input vertex shader attributes found after linking.
  146. */
  147. const ShaderAttribArray& get_vertex_attribs() const noexcept;
  148. /**
  149. * Retrieve an array of all attributes which can output from a fragment
  150. * shader.
  151. *
  152. * The returned ShaderAttribArray will only contain values if the
  153. * current shader has successfully been linked.
  154. *
  155. * @return A constant reference to a ShaderAttribArray object which
  156. * represents all output fragment shader attributes found after
  157. * linking.
  158. */
  159. const ShaderAttribArray& get_fragment_attribs() const noexcept;
  160. /**
  161. * Retrieve the number of uniform blocks active within *this Shader
  162. * program.
  163. *
  164. * @return The current number of uniform blocks in the Shader program
  165. * represented by *this.
  166. */
  167. unsigned get_num_uniform_blocks() const noexcept;
  168. /**
  169. * Retrieve a list of all currently active Uniform Blocks contained within
  170. * *this.
  171. *
  172. * @return A reference to the ShaderBlockAttrib array used by *this for
  173. * referencing uniform blocks in the shader represented by *this.
  174. */
  175. const utils::Pointer<ShaderBlockAttrib[]>& get_uniform_blocks() const noexcept;
  176. /**
  177. * @brief Retrieve a list of all shader uniform attributes.
  178. *
  179. * @return A ShaderAttribArray containing a list of all uniforms which
  180. * were found in the current shader after linking *this with a valid
  181. * vertex and fragment shader.
  182. */
  183. const ShaderAttribArray& get_uniforms() const noexcept;
  184. /**
  185. * @brief Get the location of a uniform variable.
  186. *
  187. * @param name
  188. * A constant reference to an std::string object which contains the
  189. * name of a uniform to query within the currently active shader.
  190. *
  191. * @return GLint
  192. * A positive value to indicate the uniform's location in OpenGL or
  193. * -1 for an invalid uniform index.
  194. */
  195. GLint get_uniform_location(const std::string& name) const noexcept;
  196. /**
  197. * Get the location of a uniform variable.
  198. *
  199. * @param name
  200. * A constant pointer to a constant C-style string which contains the
  201. * name of a uniform to query within the currently active shader.
  202. *
  203. * @return GLint
  204. * A positive value to indicate the uniform's location in OpenGL or
  205. * -1 for an invalid uniform index.
  206. */
  207. GLint get_uniform_location(const GLchar* const name) const noexcept;
  208. /**
  209. * Query the bindings of color numbers to user-defined varying out variables
  210. *
  211. * @param name
  212. * The name of the fragment shader output attribute to be queried.
  213. *
  214. * @return An GLint containing the output index of the attribute which was
  215. * found by "name". A value of -1 is returned if an object by the name of
  216. * "name" doesn't exist.
  217. */
  218. GLint get_frag_data_location(const GLchar* const name) const noexcept;
  219. /**
  220. * Retrieve the ID of a currently attached shader.
  221. *
  222. * @param shaderType
  223. * A value from the shader_stage_t enumeration, representing the type
  224. * of shader to query *this for and have it's ID returned.
  225. *
  226. * @return The ID of a shader attached to this at the "shaderType"
  227. * binding point.
  228. */
  229. GLuint get_attached_shader_id(const shader_stage_t shaderType) const noexcept;
  230. /**
  231. * Retrieve the index of a uniform block which matches the attributes in
  232. * *this ShaderProgram's array of uniform attributes.
  233. *
  234. * @param blockName
  235. * A constant pointer to a constant c-style string which will be used to
  236. * lookup and possibly return the index of a ShaderBlockAttrib in *this.
  237. *
  238. * @return An integer which identifies one of the ShaderBlockAttribs in
  239. * *this. A negative value will be returned if the input string does not
  240. * match any of the block attributes in *this.
  241. */
  242. int get_matching_uniform_block_index(const char* const blockName) const noexcept;
  243. /**
  244. * Retrieve the index of a uniform block which matches the attributes in
  245. * *this ShaderProgram's array of uniform attributes.
  246. *
  247. * @param blockName
  248. * A constant reference to an std::string object which will be used to
  249. * lookup and possibly return the index of a ShaderBlockAttrib in *this.
  250. *
  251. * @return An integer which identifies one of the ShaderBlockAttribs in
  252. * *this. A negative value will be returned if the input string does not
  253. * match any of the block attributes in *this.
  254. */
  255. int get_matching_uniform_block_index(const std::string& blockName) const noexcept;
  256. /**
  257. * Retrieve the index of a uniform block which matches the attributes in a
  258. * UniformBuffer object.
  259. *
  260. * @param ubo
  261. * A constant reference to a UniformBuffer object whose index should be
  262. * retrieved from *this shader.
  263. *
  264. * @return An integer which identifies one of the ShaderBlockAttribs in
  265. * *this. A negative value will be returned if the input UBO does not
  266. * match any of the block attributes in *this.
  267. */
  268. int get_matching_uniform_block_index(const UniformBuffer& ubo) const noexcept;
  269. };
  270. /*-------------------------------------
  271. Get the OpenGL ID used by *this.
  272. -------------------------------------*/
  273. inline unsigned ShaderProgram::gpu_id() const noexcept
  274. {
  275. return gpuId;
  276. }
  277. /*-------------------------------------
  278. Determine if *this is a valid shader object.
  279. -------------------------------------*/
  280. inline bool ShaderProgram::is_valid() const noexcept
  281. {
  282. return gpu_id() != 0
  283. && vertAttribs.get_num_attribs() > 0
  284. && fragAttribs.get_num_attribs() > 0;
  285. }
  286. /*-------------------------------------
  287. Bind this program to the current context
  288. -------------------------------------*/
  289. inline void ShaderProgram::bind() const noexcept
  290. {
  291. glUseProgram(gpu_id());
  292. }
  293. /*-------------------------------------
  294. Unbind this program from the context.
  295. -------------------------------------*/
  296. inline void ShaderProgram::unbind() const noexcept
  297. {
  298. glUseProgram(0);
  299. }
  300. /*-------------------------------------
  301. * Get all vertex shader attributes
  302. -------------------------------------*/
  303. inline const ShaderAttribArray& ShaderProgram::get_vertex_attribs() const noexcept
  304. {
  305. return vertAttribs;
  306. }
  307. /*-------------------------------------
  308. * Get all fragment shader attributes
  309. -------------------------------------*/
  310. inline const ShaderAttribArray& ShaderProgram::get_fragment_attribs() const noexcept
  311. {
  312. return fragAttribs;
  313. }
  314. /*-------------------------------------
  315. * Get the current number of uniform blocks
  316. -------------------------------------*/
  317. inline unsigned ShaderProgram::get_num_uniform_blocks() const noexcept
  318. {
  319. return numUniformBlocks;
  320. }
  321. /*-------------------------------------
  322. * Get all uniform blocks in *this.
  323. -------------------------------------*/
  324. inline const utils::Pointer<ShaderBlockAttrib[]>& ShaderProgram::get_uniform_blocks() const noexcept
  325. {
  326. return uniformBlocks;
  327. }
  328. /*-------------------------------------
  329. * Get all shader uniform names
  330. -------------------------------------*/
  331. inline const ShaderAttribArray& ShaderProgram::get_uniforms() const noexcept
  332. {
  333. return uniforms;
  334. }
  335. /*-------------------------------------
  336. Get the location of a uniform variable.
  337. -------------------------------------*/
  338. inline GLint ShaderProgram::get_uniform_location(const GLchar* const name) const noexcept
  339. {
  340. return glGetUniformLocation(gpu_id(), name);
  341. }
  342. /*-------------------------------------
  343. Get the location of a uniform variable.
  344. -------------------------------------*/
  345. inline GLint ShaderProgram::get_uniform_location(const std::string& name) const noexcept
  346. {
  347. return glGetUniformLocation(gpu_id(), name.c_str());
  348. }
  349. /*-------------------------------------
  350. Query the bindings of color numbers to user-defined varying out variables
  351. -------------------------------------*/
  352. inline GLint ShaderProgram::get_frag_data_location(const GLchar* const name) const noexcept
  353. {
  354. return glGetFragDataLocation(gpu_id(), name);
  355. }
  356. } // end draw namespace
  357. } // end ls namespace
  358. #endif /* __LS_DRAW_SHADER_PROGRAM_H__ */