diff options
| author | 2016-05-21 01:04:57 +0200 | |
|---|---|---|
| committer | 2016-06-07 00:06:28 +0200 | |
| commit | a12571c709c5af840bb89c43344bd982a496f21a (patch) | |
| tree | 12af20634c98eb2bfa86aaafdf06f8f87e7f7095 | |
| parent | Rasterizer: Implement fog (diff) | |
| download | yuzu-a12571c709c5af840bb89c43344bd982a496f21a.tar.gz yuzu-a12571c709c5af840bb89c43344bd982a496f21a.tar.xz yuzu-a12571c709c5af840bb89c43344bd982a496f21a.zip | |
OpenGL: Implement fog
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 68 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 17 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 34 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 4 |
5 files changed, 124 insertions, 7 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 931c34a37..328a4f66b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -62,6 +62,8 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { | |||
| 62 | uniform_block_data.lut_dirty[index] = true; | 62 | uniform_block_data.lut_dirty[index] = true; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | uniform_block_data.fog_lut_dirty = true; | ||
| 66 | |||
| 65 | // Set vertex attributes | 67 | // Set vertex attributes |
| 66 | glVertexAttribPointer(GLShader::ATTRIBUTE_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position)); | 68 | glVertexAttribPointer(GLShader::ATTRIBUTE_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position)); |
| 67 | glEnableVertexAttribArray(GLShader::ATTRIBUTE_POSITION); | 69 | glEnableVertexAttribArray(GLShader::ATTRIBUTE_POSITION); |
| @@ -102,6 +104,18 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { | |||
| 102 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 104 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 103 | } | 105 | } |
| 104 | 106 | ||
| 107 | // Setup the LUT for the fog | ||
| 108 | { | ||
| 109 | fog_lut.Create(); | ||
| 110 | state.fog_lut.texture_1d = fog_lut.handle; | ||
| 111 | } | ||
| 112 | state.Apply(); | ||
| 113 | |||
| 114 | glActiveTexture(GL_TEXTURE9); | ||
| 115 | glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, 128, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, nullptr); | ||
| 116 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 117 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 118 | |||
| 105 | // Sync fixed function OpenGL state | 119 | // Sync fixed function OpenGL state |
| 106 | SyncCullMode(); | 120 | SyncCullMode(); |
| 107 | SyncBlendEnabled(); | 121 | SyncBlendEnabled(); |
| @@ -215,6 +229,12 @@ void RasterizerOpenGL::DrawTriangles() { | |||
| 215 | } | 229 | } |
| 216 | } | 230 | } |
| 217 | 231 | ||
| 232 | // Sync the fog lut | ||
| 233 | if (uniform_block_data.fog_lut_dirty) { | ||
| 234 | SyncFogLUT(); | ||
| 235 | uniform_block_data.fog_lut_dirty = false; | ||
| 236 | } | ||
| 237 | |||
| 218 | // Sync the uniform data | 238 | // Sync the uniform data |
| 219 | if (uniform_block_data.dirty) { | 239 | if (uniform_block_data.dirty) { |
| 220 | glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, GL_STATIC_DRAW); | 240 | glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, GL_STATIC_DRAW); |
| @@ -280,6 +300,21 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | |||
| 280 | SyncBlendColor(); | 300 | SyncBlendColor(); |
| 281 | break; | 301 | break; |
| 282 | 302 | ||
| 303 | // Fog state | ||
| 304 | case PICA_REG_INDEX(fog_color): | ||
| 305 | SyncFogColor(); | ||
| 306 | break; | ||
| 307 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[0], 0xe8): | ||
| 308 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[1], 0xe9): | ||
| 309 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[2], 0xea): | ||
| 310 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[3], 0xeb): | ||
| 311 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[4], 0xec): | ||
| 312 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[5], 0xed): | ||
| 313 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[6], 0xee): | ||
| 314 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[7], 0xef): | ||
| 315 | uniform_block_data.fog_lut_dirty = true; | ||
| 316 | break; | ||
| 317 | |||
| 283 | // Alpha test | 318 | // Alpha test |
| 284 | case PICA_REG_INDEX(output_merger.alpha_test): | 319 | case PICA_REG_INDEX(output_merger.alpha_test): |
| 285 | SyncAlphaTest(); | 320 | SyncAlphaTest(); |
| @@ -329,6 +364,7 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | |||
| 329 | break; | 364 | break; |
| 330 | 365 | ||
| 331 | // TEV stages | 366 | // TEV stages |
| 367 | // (This also syncs fog_mode and fog_flip which are part of tev_combiner_buffer_input) | ||
| 332 | case PICA_REG_INDEX(tev_stage0.color_source1): | 368 | case PICA_REG_INDEX(tev_stage0.color_source1): |
| 333 | case PICA_REG_INDEX(tev_stage0.color_modifier1): | 369 | case PICA_REG_INDEX(tev_stage0.color_modifier1): |
| 334 | case PICA_REG_INDEX(tev_stage0.color_op): | 370 | case PICA_REG_INDEX(tev_stage0.color_op): |
| @@ -950,9 +986,15 @@ void RasterizerOpenGL::SetShader() { | |||
| 950 | uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[5]"); | 986 | uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[5]"); |
| 951 | if (uniform_lut != -1) { glUniform1i(uniform_lut, 8); } | 987 | if (uniform_lut != -1) { glUniform1i(uniform_lut, 8); } |
| 952 | 988 | ||
| 989 | GLuint uniform_fog_lut = glGetUniformLocation(shader->shader.handle, "fog_lut"); | ||
| 990 | if (uniform_fog_lut != -1) { glUniform1i(uniform_fog_lut, 9); } | ||
| 991 | |||
| 953 | current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get(); | 992 | current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get(); |
| 954 | 993 | ||
| 955 | unsigned int block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data"); | 994 | unsigned int block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data"); |
| 995 | GLint block_size; | ||
| 996 | glGetActiveUniformBlockiv(current_shader->shader.handle, block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &block_size); | ||
| 997 | ASSERT_MSG(block_size == sizeof(UniformData), "Uniform block size did not match!"); | ||
| 956 | glUniformBlockBinding(current_shader->shader.handle, block_index, 0); | 998 | glUniformBlockBinding(current_shader->shader.handle, block_index, 0); |
| 957 | 999 | ||
| 958 | // Update uniforms | 1000 | // Update uniforms |
| @@ -974,6 +1016,8 @@ void RasterizerOpenGL::SetShader() { | |||
| 974 | SyncLightDistanceAttenuationBias(light_index); | 1016 | SyncLightDistanceAttenuationBias(light_index); |
| 975 | SyncLightDistanceAttenuationScale(light_index); | 1017 | SyncLightDistanceAttenuationScale(light_index); |
| 976 | } | 1018 | } |
| 1019 | |||
| 1020 | SyncFogColor(); | ||
| 977 | } | 1021 | } |
| 978 | } | 1022 | } |
| 979 | 1023 | ||
| @@ -1040,6 +1084,30 @@ void RasterizerOpenGL::SyncBlendColor() { | |||
| 1040 | state.blend.color.alpha = blend_color[3]; | 1084 | state.blend.color.alpha = blend_color[3]; |
| 1041 | } | 1085 | } |
| 1042 | 1086 | ||
| 1087 | void RasterizerOpenGL::SyncFogColor() { | ||
| 1088 | const auto& regs = Pica::g_state.regs; | ||
| 1089 | uniform_block_data.data.fog_color = { | ||
| 1090 | regs.fog_color.r.Value() / 255.0f, | ||
| 1091 | regs.fog_color.g.Value() / 255.0f, | ||
| 1092 | regs.fog_color.b.Value() / 255.0f | ||
| 1093 | }; | ||
| 1094 | uniform_block_data.dirty = true; | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | void RasterizerOpenGL::SyncFogLUT() { | ||
| 1098 | std::array<GLuint, 128> new_data; | ||
| 1099 | |||
| 1100 | std::transform(Pica::g_state.fog.lut.begin(), Pica::g_state.fog.lut.end(), new_data.begin(), [](const auto& entry) { | ||
| 1101 | return entry.raw; | ||
| 1102 | }); | ||
| 1103 | |||
| 1104 | if (new_data != fog_lut_data) { | ||
| 1105 | fog_lut_data = new_data; | ||
| 1106 | glActiveTexture(GL_TEXTURE9); | ||
| 1107 | glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 128, GL_RED_INTEGER, GL_UNSIGNED_INT, fog_lut_data.data()); | ||
| 1108 | } | ||
| 1109 | } | ||
| 1110 | |||
| 1043 | void RasterizerOpenGL::SyncAlphaTest() { | 1111 | void RasterizerOpenGL::SyncAlphaTest() { |
| 1044 | const auto& regs = Pica::g_state.regs; | 1112 | const auto& regs = Pica::g_state.regs; |
| 1045 | if (regs.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) { | 1113 | if (regs.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index bdc7bd0f2..42482df4b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -76,6 +76,9 @@ union PicaShaderConfig { | |||
| 76 | state.tev_stages[i].scales_raw = tev_stage.scales_raw; | 76 | state.tev_stages[i].scales_raw = tev_stage.scales_raw; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | state.fog_mode = regs.fog_mode; | ||
| 80 | state.fog_flip = regs.fog_flip; | ||
| 81 | |||
| 79 | state.combiner_buffer_input = | 82 | state.combiner_buffer_input = |
| 80 | regs.tev_combiner_buffer_input.update_mask_rgb.Value() | | 83 | regs.tev_combiner_buffer_input.update_mask_rgb.Value() | |
| 81 | regs.tev_combiner_buffer_input.update_mask_a.Value() << 4; | 84 | regs.tev_combiner_buffer_input.update_mask_a.Value() << 4; |
| @@ -168,13 +171,14 @@ union PicaShaderConfig { | |||
| 168 | }; | 171 | }; |
| 169 | 172 | ||
| 170 | struct State { | 173 | struct State { |
| 171 | |||
| 172 | Pica::Regs::CompareFunc alpha_test_func; | 174 | Pica::Regs::CompareFunc alpha_test_func; |
| 173 | Pica::Regs::TextureConfig::TextureType texture0_type; | 175 | Pica::Regs::TextureConfig::TextureType texture0_type; |
| 174 | std::array<TevStageConfigRaw, 6> tev_stages; | 176 | std::array<TevStageConfigRaw, 6> tev_stages; |
| 175 | u8 combiner_buffer_input; | 177 | u8 combiner_buffer_input; |
| 176 | 178 | ||
| 177 | Pica::Regs::DepthBuffering depthmap_enable; | 179 | Pica::Regs::DepthBuffering depthmap_enable; |
| 180 | Pica::Regs::FogMode fog_mode; | ||
| 181 | bool fog_flip; | ||
| 178 | 182 | ||
| 179 | struct { | 183 | struct { |
| 180 | struct { | 184 | struct { |
| @@ -324,13 +328,14 @@ private: | |||
| 324 | GLint alphatest_ref; | 328 | GLint alphatest_ref; |
| 325 | GLfloat depth_scale; | 329 | GLfloat depth_scale; |
| 326 | GLfloat depth_offset; | 330 | GLfloat depth_offset; |
| 331 | alignas(16) GLvec3 fog_color; | ||
| 327 | alignas(16) GLvec3 lighting_global_ambient; | 332 | alignas(16) GLvec3 lighting_global_ambient; |
| 328 | LightSrc light_src[8]; | 333 | LightSrc light_src[8]; |
| 329 | alignas(16) GLvec4 const_color[6]; // A vec4 color for each of the six tev stages | 334 | alignas(16) GLvec4 const_color[6]; // A vec4 color for each of the six tev stages |
| 330 | alignas(16) GLvec4 tev_combiner_buffer_color; | 335 | alignas(16) GLvec4 tev_combiner_buffer_color; |
| 331 | }; | 336 | }; |
| 332 | 337 | ||
| 333 | static_assert(sizeof(UniformData) == 0x390, "The size of the UniformData structure has changed, update the structure in the shader"); | 338 | static_assert(sizeof(UniformData) == 0x3A0, "The size of the UniformData structure has changed, update the structure in the shader"); |
| 334 | static_assert(sizeof(UniformData) < 16384, "UniformData structure must be less than 16kb as per the OpenGL spec"); | 339 | static_assert(sizeof(UniformData) < 16384, "UniformData structure must be less than 16kb as per the OpenGL spec"); |
| 335 | 340 | ||
| 336 | /// Sets the OpenGL shader in accordance with the current PICA register state | 341 | /// Sets the OpenGL shader in accordance with the current PICA register state |
| @@ -354,6 +359,10 @@ private: | |||
| 354 | /// Syncs the blend color to match the PICA register | 359 | /// Syncs the blend color to match the PICA register |
| 355 | void SyncBlendColor(); | 360 | void SyncBlendColor(); |
| 356 | 361 | ||
| 362 | /// Syncs the fog states to match the PICA register | ||
| 363 | void SyncFogColor(); | ||
| 364 | void SyncFogLUT(); | ||
| 365 | |||
| 357 | /// Syncs the alpha test states to match the PICA register | 366 | /// Syncs the alpha test states to match the PICA register |
| 358 | void SyncAlphaTest(); | 367 | void SyncAlphaTest(); |
| 359 | 368 | ||
| @@ -421,6 +430,7 @@ private: | |||
| 421 | struct { | 430 | struct { |
| 422 | UniformData data; | 431 | UniformData data; |
| 423 | bool lut_dirty[6]; | 432 | bool lut_dirty[6]; |
| 433 | bool fog_lut_dirty; | ||
| 424 | bool dirty; | 434 | bool dirty; |
| 425 | } uniform_block_data = {}; | 435 | } uniform_block_data = {}; |
| 426 | 436 | ||
| @@ -432,4 +442,7 @@ private: | |||
| 432 | 442 | ||
| 433 | std::array<OGLTexture, 6> lighting_luts; | 443 | std::array<OGLTexture, 6> lighting_luts; |
| 434 | std::array<std::array<GLvec4, 256>, 6> lighting_lut_data{}; | 444 | std::array<std::array<GLvec4, 256>, 6> lighting_lut_data{}; |
| 445 | |||
| 446 | OGLTexture fog_lut; | ||
| 447 | std::array<GLuint, 128> fog_lut_data{}; | ||
| 435 | }; | 448 | }; |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index ea7ab2883..3bace7f01 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -555,6 +555,7 @@ layout (std140) uniform shader_data { | |||
| 555 | int alphatest_ref; | 555 | int alphatest_ref; |
| 556 | float depth_scale; | 556 | float depth_scale; |
| 557 | float depth_offset; | 557 | float depth_offset; |
| 558 | vec3 fog_color; | ||
| 558 | vec3 lighting_global_ambient; | 559 | vec3 lighting_global_ambient; |
| 559 | LightSrc light_src[NUM_LIGHTS]; | 560 | LightSrc light_src[NUM_LIGHTS]; |
| 560 | vec4 const_color[NUM_TEV_STAGES]; | 561 | vec4 const_color[NUM_TEV_STAGES]; |
| @@ -563,6 +564,7 @@ layout (std140) uniform shader_data { | |||
| 563 | 564 | ||
| 564 | uniform sampler2D tex[3]; | 565 | uniform sampler2D tex[3]; |
| 565 | uniform sampler1D lut[6]; | 566 | uniform sampler1D lut[6]; |
| 567 | uniform usampler1D fog_lut; | ||
| 566 | 568 | ||
| 567 | // Rotate the vector v by the quaternion q | 569 | // Rotate the vector v by the quaternion q |
| 568 | vec3 quaternion_rotate(vec4 q, vec3 v) { | 570 | vec3 quaternion_rotate(vec4 q, vec3 v) { |
| @@ -580,6 +582,12 @@ vec4 secondary_fragment_color = vec4(0.0); | |||
| 580 | return out; | 582 | return out; |
| 581 | } | 583 | } |
| 582 | 584 | ||
| 585 | out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; | ||
| 586 | out += "float depth = z_over_w * depth_scale + depth_offset;\n"; | ||
| 587 | if (state.depthmap_enable == Pica::Regs::DepthBuffering::WBuffering) { | ||
| 588 | out += "depth /= gl_FragCoord.w;\n"; | ||
| 589 | } | ||
| 590 | |||
| 583 | if (state.lighting.enable) | 591 | if (state.lighting.enable) |
| 584 | WriteLighting(out, config); | 592 | WriteLighting(out, config); |
| 585 | 593 | ||
| @@ -596,14 +604,30 @@ vec4 secondary_fragment_color = vec4(0.0); | |||
| 596 | out += ") discard;\n"; | 604 | out += ") discard;\n"; |
| 597 | } | 605 | } |
| 598 | 606 | ||
| 599 | out += "color = last_tex_env_out;\n"; | 607 | // Append fog combiner |
| 608 | if (state.fog_mode == Regs::FogMode::Fog) { | ||
| 609 | // Get index into fog LUT | ||
| 610 | if (state.fog_flip) { | ||
| 611 | out += "float fog_index = (1.0 - depth) * 128.0;\n"; | ||
| 612 | } else { | ||
| 613 | out += "float fog_index = depth * 128.0;\n"; | ||
| 614 | } | ||
| 600 | 615 | ||
| 601 | out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; | 616 | // Generate clamped fog factor from LUT for given fog index |
| 602 | out += "float depth = z_over_w * depth_scale + depth_offset;\n"; | 617 | out += "float fog_i = clamp(floor(fog_index), 0.0, 127.0);\n"; |
| 603 | if (state.depthmap_enable == Pica::Regs::DepthBuffering::WBuffering) { | 618 | out += "float fog_f = fog_index - fog_i;\n"; |
| 604 | out += "depth /= gl_FragCoord.w;\n"; | 619 | out += "uint fog_lut_entry = texelFetch(fog_lut, int(fog_i), 0).r;\n"; |
| 620 | out += "float fog_lut_entry_difference = float(int((fog_lut_entry & 0x1FFFU) << 19U) >> 19);\n"; // Extract signed difference | ||
| 621 | out += "float fog_lut_entry_value = float((fog_lut_entry >> 13U) & 0x7FFU);\n"; | ||
| 622 | out += "float fog_factor = (fog_lut_entry_value + fog_lut_entry_difference * fog_f) / 2047.0;\n"; | ||
| 623 | out += "fog_factor = clamp(fog_factor, 0.0, 1.0);\n"; | ||
| 624 | |||
| 625 | // Blend the fog | ||
| 626 | out += "last_tex_env_out.rgb = mix(fog_color.rgb, last_tex_env_out.rgb, fog_factor);\n"; | ||
| 605 | } | 627 | } |
| 628 | |||
| 606 | out += "gl_FragDepth = depth;\n"; | 629 | out += "gl_FragDepth = depth;\n"; |
| 630 | out += "color = last_tex_env_out;\n"; | ||
| 607 | 631 | ||
| 608 | out += "}"; | 632 | out += "}"; |
| 609 | 633 | ||
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index fa141fc9a..13ee986b9 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp | |||
| @@ -58,6 +58,8 @@ OpenGLState::OpenGLState() { | |||
| 58 | lut.texture_1d = 0; | 58 | lut.texture_1d = 0; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | fog_lut.texture_1d = 0; | ||
| 62 | |||
| 61 | draw.read_framebuffer = 0; | 63 | draw.read_framebuffer = 0; |
| 62 | draw.draw_framebuffer = 0; | 64 | draw.draw_framebuffer = 0; |
| 63 | draw.vertex_array = 0; | 65 | draw.vertex_array = 0; |
| @@ -195,6 +197,12 @@ void OpenGLState::Apply() const { | |||
| 195 | } | 197 | } |
| 196 | } | 198 | } |
| 197 | 199 | ||
| 200 | // Fog LUT | ||
| 201 | if (fog_lut.texture_1d != cur_state.fog_lut.texture_1d) { | ||
| 202 | glActiveTexture(GL_TEXTURE9); | ||
| 203 | glBindTexture(GL_TEXTURE_1D, fog_lut.texture_1d); | ||
| 204 | } | ||
| 205 | |||
| 198 | // Framebuffer | 206 | // Framebuffer |
| 199 | if (draw.read_framebuffer != cur_state.draw.read_framebuffer) { | 207 | if (draw.read_framebuffer != cur_state.draw.read_framebuffer) { |
| 200 | glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); | 208 | glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); |
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 228727054..13c71b0a6 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h | |||
| @@ -68,6 +68,10 @@ public: | |||
| 68 | } lighting_luts[6]; | 68 | } lighting_luts[6]; |
| 69 | 69 | ||
| 70 | struct { | 70 | struct { |
| 71 | GLuint texture_1d; // GL_TEXTURE_BINDING_1D | ||
| 72 | } fog_lut; | ||
| 73 | |||
| 74 | struct { | ||
| 71 | GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING | 75 | GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING |
| 72 | GLuint draw_framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING | 76 | GLuint draw_framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING |
| 73 | GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING | 77 | GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING |