gl_state.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. blend.enabled = false;
  24. blend.src_rgb_func = GL_ONE;
  25. blend.dst_rgb_func = GL_ZERO;
  26. blend.src_a_func = GL_ONE;
  27. blend.dst_a_func = GL_ZERO;
  28. blend.color.red = 0.0f;
  29. blend.color.green = 0.0f;
  30. blend.color.blue = 0.0f;
  31. blend.color.alpha = 0.0f;
  32. logic_op = GL_COPY;
  33. for (auto& texture_unit : texture_units) {
  34. texture_unit.enabled_2d = false;
  35. texture_unit.texture_2d = 0;
  36. }
  37. draw.framebuffer = 0;
  38. draw.vertex_array = 0;
  39. draw.vertex_buffer = 0;
  40. draw.shader_program = 0;
  41. }
  42. void OpenGLState::Apply() {
  43. // Culling
  44. if (cull.enabled != cur_state.cull.enabled) {
  45. if (cull.enabled) {
  46. glEnable(GL_CULL_FACE);
  47. } else {
  48. glDisable(GL_CULL_FACE);
  49. }
  50. }
  51. if (cull.mode != cur_state.cull.mode) {
  52. glCullFace(cull.mode);
  53. }
  54. // Depth test
  55. if (depth.test_enabled != cur_state.depth.test_enabled) {
  56. if (depth.test_enabled) {
  57. glEnable(GL_DEPTH_TEST);
  58. } else {
  59. glDisable(GL_DEPTH_TEST);
  60. }
  61. }
  62. if (depth.test_func != cur_state.depth.test_func) {
  63. glDepthFunc(depth.test_func);
  64. }
  65. // Depth mask
  66. if (depth.write_mask != cur_state.depth.write_mask) {
  67. glDepthMask(depth.write_mask);
  68. }
  69. // Color mask
  70. if (color_mask.red_enabled != cur_state.color_mask.red_enabled ||
  71. color_mask.green_enabled != cur_state.color_mask.green_enabled ||
  72. color_mask.blue_enabled != cur_state.color_mask.blue_enabled ||
  73. color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) {
  74. glColorMask(color_mask.red_enabled, color_mask.green_enabled,
  75. color_mask.blue_enabled, color_mask.alpha_enabled);
  76. }
  77. // Stencil test
  78. if (stencil.test_enabled != cur_state.stencil.test_enabled) {
  79. if (stencil.test_enabled) {
  80. glEnable(GL_STENCIL_TEST);
  81. } else {
  82. glDisable(GL_STENCIL_TEST);
  83. }
  84. }
  85. if (stencil.test_func != cur_state.stencil.test_func ||
  86. stencil.test_ref != cur_state.stencil.test_ref ||
  87. stencil.test_mask != cur_state.stencil.test_mask) {
  88. glStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask);
  89. }
  90. // Stencil mask
  91. if (stencil.write_mask != cur_state.stencil.write_mask) {
  92. glStencilMask(stencil.write_mask);
  93. }
  94. // Blending
  95. if (blend.enabled != cur_state.blend.enabled) {
  96. if (blend.enabled) {
  97. glEnable(GL_BLEND);
  98. cur_state.logic_op = GL_COPY;
  99. glLogicOp(cur_state.logic_op);
  100. glDisable(GL_COLOR_LOGIC_OP);
  101. } else {
  102. glDisable(GL_BLEND);
  103. glEnable(GL_COLOR_LOGIC_OP);
  104. }
  105. }
  106. if (blend.color.red != cur_state.blend.color.red ||
  107. blend.color.green != cur_state.blend.color.green ||
  108. blend.color.blue != cur_state.blend.color.blue ||
  109. blend.color.alpha != cur_state.blend.color.alpha) {
  110. glBlendColor(blend.color.red, blend.color.green,
  111. blend.color.blue, blend.color.alpha);
  112. }
  113. if (blend.src_rgb_func != cur_state.blend.src_rgb_func ||
  114. blend.dst_rgb_func != cur_state.blend.dst_rgb_func ||
  115. blend.src_a_func != cur_state.blend.src_a_func ||
  116. blend.dst_a_func != cur_state.blend.dst_a_func) {
  117. glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func,
  118. blend.src_a_func, blend.dst_a_func);
  119. }
  120. if (logic_op != cur_state.logic_op) {
  121. glLogicOp(logic_op);
  122. }
  123. // Textures
  124. for (unsigned texture_index = 0; texture_index < ARRAY_SIZE(texture_units); ++texture_index) {
  125. if (texture_units[texture_index].enabled_2d != cur_state.texture_units[texture_index].enabled_2d ||
  126. texture_units[texture_index].texture_2d != cur_state.texture_units[texture_index].texture_2d) {
  127. glActiveTexture(GL_TEXTURE0 + texture_index);
  128. if (texture_units[texture_index].enabled_2d) {
  129. glBindTexture(GL_TEXTURE_2D, texture_units[texture_index].texture_2d);
  130. } else {
  131. glBindTexture(GL_TEXTURE_2D, 0);
  132. }
  133. }
  134. }
  135. // Framebuffer
  136. if (draw.framebuffer != cur_state.draw.framebuffer) {
  137. glBindFramebuffer(GL_FRAMEBUFFER, draw.framebuffer);
  138. }
  139. // Vertex array
  140. if (draw.vertex_array != cur_state.draw.vertex_array) {
  141. glBindVertexArray(draw.vertex_array);
  142. }
  143. // Vertex buffer
  144. if (draw.vertex_buffer != cur_state.draw.vertex_buffer) {
  145. glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer);
  146. }
  147. // Shader program
  148. if (draw.shader_program != cur_state.draw.shader_program) {
  149. glUseProgram(draw.shader_program);
  150. }
  151. cur_state = *this;
  152. }