gl_state.cpp 4.6 KB

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