💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
4.8 KiB

  1. /*
  2. * Copyright (C) 2021 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_GL_SHADER_PROGRAM_HPP
  20. #define ANTKEEPER_GL_SHADER_PROGRAM_HPP
  21. #include <list>
  22. #include <string>
  23. #include <unordered_map>
  24. #include <unordered_set>
  25. namespace gl {
  26. class shader_object;
  27. class rasterizer;
  28. class shader_input;
  29. /**
  30. * Shader program which can be linked to shader objects and executed.
  31. *
  32. * @see gl::shader_object
  33. */
  34. class shader_program
  35. {
  36. public:
  37. /**
  38. * Creates an empty shader program.
  39. *
  40. * @exception std::runtime_error An error occurred while creating an OpenGL shader program.
  41. */
  42. shader_program();
  43. /**
  44. * Destroys a shader program.
  45. */
  46. ~shader_program();
  47. /**
  48. * Attaches a shader object to the shader program. Attaching a shader object has no effect on a shader program until shader_program::link() is called.
  49. *
  50. * @param object Shader object to attach.
  51. *
  52. * @exception std::runtime_error Shader object is already attached to the shader program.
  53. * @exception std::runtime_error OpenGL shader program is not a valid program object.
  54. * @exception std::runtime_error OpenGL shader object is not a valid shader object.
  55. * @exception std::runtime_error OpenGL shader object is already attached to the shader program.
  56. *
  57. * @see shader_program::link()
  58. */
  59. void attach(const shader_object* object);
  60. /**
  61. * Detaches a shader object from the shader program. Detaching a shader object has no effect on a shader program until shader_program::link() is called.
  62. *
  63. * @param object Shader object to detach.
  64. *
  65. * @exception std::runtime_error Shader object is not attached to the shader program.
  66. * @exception std::runtime_error OpenGL shader program is not a valid program object.
  67. * @exception std::runtime_error OpenGL shader object is not a valid shader object.
  68. * @exception std::runtime_error OpenGL shader object is not attached to the shader program.
  69. *
  70. * @see shader_program::link()
  71. */
  72. void detach(const shader_object* object);
  73. /**
  74. * Detaches all shader objects from the shader program.
  75. *
  76. * @exception std::runtime_error Shader object is not attached to the shader program.
  77. * @exception std::runtime_error OpenGL shader program is not a valid program object.
  78. * @exception std::runtime_error OpenGL shader object is not a valid shader object.
  79. * @exception std::runtime_error OpenGL shader object is not attached to the shader program.
  80. *
  81. * @see shader_program::detach(const shader_object*)
  82. */
  83. void detach_all();
  84. /**
  85. * Links all attached shader objects to create an executable shader program.
  86. *
  87. * @warning All existing pointers to a shader program's shader inputs will be invalidated if the program is re-linked.
  88. *
  89. * @return `true` if the attached shader objects were successfully linked into the shader program, `false` otherwise. If linking fails, check the info log via shader_program::get_info_log() for more information.
  90. */
  91. bool link();
  92. /// Returns the shader program info log, which is updated when the shader program is linked.
  93. const std::string& get_info_log() const;
  94. /// Returns `true` if the shader program has been successfully linked, `false` otherwise.
  95. bool was_linked() const;
  96. shader_program(const shader_program&) = delete;
  97. shader_program& operator=(const shader_program&) = delete;
  98. const std::list<shader_input*>* get_inputs() const;
  99. const shader_input* get_input(const std::string& name) const;
  100. private:
  101. friend class rasterizer;
  102. unsigned int gl_program_id;
  103. std::string info_log;
  104. bool linked;
  105. std::unordered_set<const shader_object*> attached_objects;
  106. void find_inputs();
  107. void free_inputs();
  108. std::list<shader_input*> inputs;
  109. std::unordered_map<std::string, shader_input*> input_map;
  110. };
  111. inline const std::string& shader_program::get_info_log() const
  112. {
  113. return info_log;
  114. }
  115. inline bool shader_program::was_linked() const
  116. {
  117. return linked;
  118. }
  119. inline const std::list<shader_input*>* shader_program::get_inputs() const
  120. {
  121. return &inputs;
  122. }
  123. inline const shader_input* shader_program::get_input(const std::string& name) const
  124. {
  125. auto it = input_map.find(name);
  126. if (it == input_map.end())
  127. {
  128. return nullptr;
  129. }
  130. return it->second;
  131. }
  132. } // namespace gl
  133. #endif // ANTKEEPER_GL_SHADER_PROGRAM_HPP