gl_state.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // Copyright 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "video_core/renderer_opengl/gl_state.h"
  5. #include "video_core/pica.h"
  6. OpenGLState OpenGLState::cur_state;
  7. OpenGLState::OpenGLState() {
  8. // These all match default OpenGL values
  9. cull.enabled = false;
  10. cull.mode = GL_BACK;
  11. depth.test_enabled = false;
  12. depth.test_func = GL_LESS;
  13. depth.write_mask = GL_TRUE;
  14. color_mask.red_enabled = GL_TRUE;
  15. color_mask.green_enabled = GL_TRUE;
  16. color_mask.blue_enabled = GL_TRUE;
  17. color_mask.alpha_enabled = GL_TRUE;
  18. stencil.test_enabled = false;
  19. stencil.test_func = GL_ALWAYS;
  20. stencil.test_ref = 0;
  21. stencil.test_mask = -1;
  22. stencil.write_mask = -1;
  23. stencil.action_depth_fail = GL_KEEP;
  24. stencil.action_depth_pass = GL_KEEP;
  25. stencil.action_stencil_fail = GL_KEEP;
  26. blend.enabled = false;
  27. blend.src_rgb_func = GL_ONE;
  28. blend.dst_rgb_func = GL_ZERO;
  29. blend.src_a_func = GL_ONE;
  30. blend.dst_a_func = GL_ZERO;
  31. blend.color.red = 0.0f;
  32. blend.color.green = 0.0f;
  33. blend.color.blue = 0.0f;
  34. blend.color.alpha = 0.0f;
  35. logic_op = GL_COPY;
  36. for (auto& texture_unit : texture_units) {
  37. texture_unit.texture_2d = 0;
  38. texture_unit.sampler = 0;
  39. }
  40. draw.framebuffer = 0;
  41. draw.vertex_array = 0;
  42. draw.vertex_buffer = 0;
  43. draw.shader_program = 0;
  44. }
  45. void OpenGLState::Apply() {
  46. // Culling
  47. if (cull.enabled != cur_state.cull.enabled) {
  48. if (cull.enabled) {
  49. glEnable(GL_CULL_FACE);
  50. } else {
  51. glDisable(GL_CULL_FACE);
  52. }
  53. }
  54. if (cull.mode != cur_state.cull.mode) {
  55. glCullFace(cull.mode);
  56. }
  57. // Depth test
  58. if (depth.test_enabled != cur_state.depth.test_enabled) {
  59. if (depth.test_enabled) {
  60. glEnable(GL_DEPTH_TEST);
  61. } else {
  62. glDisable(GL_DEPTH_TEST);
  63. }
  64. }
  65. if (depth.test_func != cur_state.depth.test_func) {
  66. glDepthFunc(depth.test_func);
  67. }
  68. // Depth mask
  69. if (depth.write_mask != cur_state.depth.write_mask) {
  70. glDepthMask(depth.write_mask);
  71. }
  72. // Color mask
  73. if (color_mask.red_enabled != cur_state.color_mask.red_enabled ||
  74. color_mask.green_enabled != cur_state.color_mask.green_enabled ||
  75. color_mask.blue_enabled != cur_state.color_mask.blue_enabled ||
  76. color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) {
  77. glColorMask(color_mask.red_enabled, color_mask.green_enabled,
  78. color_mask.blue_enabled, color_mask.alpha_enabled);
  79. }
  80. // Stencil test
  81. if (stencil.test_enabled != cur_state.stencil.test_enabled) {
  82. if (stencil.test_enabled) {
  83. glEnable(GL_STENCIL_TEST);
  84. } else {
  85. glDisable(GL_STENCIL_TEST);
  86. }
  87. }
  88. if (stencil.test_func != cur_state.stencil.test_func ||
  89. stencil.test_ref != cur_state.stencil.test_ref ||
  90. stencil.test_mask != cur_state.stencil.test_mask) {
  91. glStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask);
  92. }
  93. if (stencil.action_depth_fail != cur_state.stencil.action_depth_fail ||
  94. stencil.action_depth_pass != cur_state.stencil.action_depth_pass ||
  95. stencil.action_stencil_fail != cur_state.stencil.action_stencil_fail) {
  96. glStencilOp(stencil.action_stencil_fail, stencil.action_depth_fail, stencil.action_depth_pass);
  97. }
  98. // Stencil mask
  99. if (stencil.write_mask != cur_state.stencil.write_mask) {
  100. glStencilMask(stencil.write_mask);
  101. }
  102. // Blending
  103. if (blend.enabled != cur_state.blend.enabled) {
  104. if (blend.enabled) {
  105. glEnable(GL_BLEND);
  106. cur_state.logic_op = GL_COPY;
  107. glLogicOp(cur_state.logic_op);
  108. glDisable(GL_COLOR_LOGIC_OP);
  109. } else {
  110. glDisable(GL_BLEND);
  111. glEnable(GL_COLOR_LOGIC_OP);
  112. }
  113. }
  114. if (blend.color.red != cur_state.blend.color.red ||
  115. blend.color.green != cur_state.blend.color.green ||
  116. blend.color.blue != cur_state.blend.color.blue ||
  117. blend.color.alpha != cur_state.blend.color.alpha) {
  118. glBlendColor(blend.color.red, blend.color.green,
  119. blend.color.blue, blend.color.alpha);
  120. }
  121. if (blend.src_rgb_func != cur_state.blend.src_rgb_func ||
  122. blend.dst_rgb_func != cur_state.blend.dst_rgb_func ||
  123. blend.src_a_func != cur_state.blend.src_a_func ||
  124. blend.dst_a_func != cur_state.blend.dst_a_func) {
  125. glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func,
  126. blend.src_a_func, blend.dst_a_func);
  127. }
  128. if (logic_op != cur_state.logic_op) {
  129. glLogicOp(logic_op);
  130. }
  131. // Textures
  132. for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) {
  133. if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) {
  134. glActiveTexture(GL_TEXTURE0 + i);
  135. glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d);
  136. }
  137. if (texture_units[i].sampler != cur_state.texture_units[i].sampler) {
  138. glBindSampler(i, texture_units[i].sampler);
  139. }
  140. }
  141. // Framebuffer
  142. if (draw.framebuffer != cur_state.draw.framebuffer) {
  143. glBindFramebuffer(GL_FRAMEBUFFER, draw.framebuffer);
  144. }
  145. // Vertex array
  146. if (draw.vertex_array != cur_state.draw.vertex_array) {
  147. glBindVertexArray(draw.vertex_array);
  148. }
  149. // Vertex buffer
  150. if (draw.vertex_buffer != cur_state.draw.vertex_buffer) {
  151. glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer);
  152. }
  153. // Shader program
  154. if (draw.shader_program != cur_state.draw.shader_program) {
  155. glUseProgram(draw.shader_program);
  156. }
  157. cur_state = *this;
  158. }
  159. void OpenGLState::ResetTexture(GLuint id) {
  160. for (auto& unit : cur_state.texture_units) {
  161. if (unit.texture_2d == id) {
  162. unit.texture_2d = 0;
  163. }
  164. }
  165. }
  166. void OpenGLState::ResetSampler(GLuint id) {
  167. for (auto& unit : cur_state.texture_units) {
  168. if (unit.sampler == id) {
  169. unit.sampler = 0;
  170. }
  171. }
  172. }
  173. void OpenGLState::ResetProgram(GLuint id) {
  174. if (cur_state.draw.shader_program == id) {
  175. cur_state.draw.shader_program = 0;
  176. }
  177. }
  178. void OpenGLState::ResetBuffer(GLuint id) {
  179. if (cur_state.draw.vertex_buffer == id) {
  180. cur_state.draw.vertex_buffer = 0;
  181. }
  182. }
  183. void OpenGLState::ResetVertexArray(GLuint id) {
  184. if (cur_state.draw.vertex_array == id) {
  185. cur_state.draw.vertex_array = 0;
  186. }
  187. }
  188. void OpenGLState::ResetFramebuffer(GLuint id) {
  189. if (cur_state.draw.framebuffer == id) {
  190. cur_state.draw.framebuffer = 0;
  191. }
  192. }