gl_state.cpp 4.9 KB

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