diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 681fdca8d1..092351dcee 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -587,12 +587,12 @@ void RasterizerOpenGL::SyncCullMode() { case Pica::Regs::CullMode::KeepClockWise: state.cull.enabled = true; - state.cull.mode = GL_BACK; + state.cull.front_face = GL_CW; break; case Pica::Regs::CullMode::KeepCounterClockWise: state.cull.enabled = true; - state.cull.mode = GL_FRONT; + state.cull.front_face = GL_CCW; break; default: @@ -683,9 +683,8 @@ void RasterizerOpenGL::SyncDrawState() { // OpenGL uses different y coordinates, so negate corner offset and flip origin // TODO: Ensure viewport_corner.x should not be negated or origin flipped // TODO: Use floating-point viewports for accuracy if supported - glViewport((GLsizei)static_cast(regs.viewport_corner.x), - -(GLsizei)static_cast(regs.viewport_corner.y) - + regs.framebuffer.GetHeight() - viewport_height, + glViewport((GLsizei)regs.viewport_corner.x, + (GLsizei)regs.viewport_corner.y, viewport_width, viewport_height); // Sync bound texture(s), upload if not cached @@ -724,7 +723,7 @@ void RasterizerOpenGL::ReloadColorBuffer() { for (int x = 0; x < fb_color_texture.width; ++x) { const u32 coarse_y = y & ~7; u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel; - u32 gl_pixel_index = (x + y * fb_color_texture.width) * bytes_per_pixel; + u32 gl_pixel_index = (x + (fb_color_texture.height - 1 - y) * fb_color_texture.width) * bytes_per_pixel; u8* pixel = color_buffer + dst_offset; memcpy(&temp_fb_color_buffer[gl_pixel_index], pixel, bytes_per_pixel); @@ -770,7 +769,7 @@ void RasterizerOpenGL::ReloadDepthBuffer() { for (int x = 0; x < fb_depth_texture.width; ++x) { const u32 coarse_y = y & ~7; u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; - u32 gl_pixel_index = (x + y * fb_depth_texture.width); + u32 gl_pixel_index = (x + (fb_depth_texture.height - 1 - y) * fb_depth_texture.width); u8* pixel = depth_buffer + dst_offset; u32 depth_stencil = *(u32*)pixel; @@ -782,7 +781,7 @@ void RasterizerOpenGL::ReloadDepthBuffer() { for (int x = 0; x < fb_depth_texture.width; ++x) { const u32 coarse_y = y & ~7; u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; - u32 gl_pixel_index = (x + y * fb_depth_texture.width) * gl_bpp; + u32 gl_pixel_index = (x + (fb_depth_texture.height - 1 - y) * fb_depth_texture.width) * gl_bpp; u8* pixel = depth_buffer + dst_offset; memcpy(&temp_fb_depth_data[gl_pixel_index], pixel, bytes_per_pixel); @@ -837,7 +836,7 @@ void RasterizerOpenGL::CommitColorBuffer() { for (int x = 0; x < fb_color_texture.width; ++x) { const u32 coarse_y = y & ~7; u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel; - u32 gl_pixel_index = x * bytes_per_pixel + y * fb_color_texture.width * bytes_per_pixel; + u32 gl_pixel_index = x * bytes_per_pixel + (fb_color_texture.height - 1 - y) * fb_color_texture.width * bytes_per_pixel; u8* pixel = color_buffer + dst_offset; memcpy(pixel, &temp_gl_color_buffer[gl_pixel_index], bytes_per_pixel); @@ -879,7 +878,7 @@ void RasterizerOpenGL::CommitDepthBuffer() { for (int x = 0; x < fb_depth_texture.width; ++x) { const u32 coarse_y = y & ~7; u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; - u32 gl_pixel_index = (x + y * fb_depth_texture.width); + u32 gl_pixel_index = (x + (fb_depth_texture.height - 1 - y) * fb_depth_texture.width); u8* pixel = depth_buffer + dst_offset; u32 depth_stencil = ((u32*)temp_gl_depth_data)[gl_pixel_index]; @@ -891,7 +890,7 @@ void RasterizerOpenGL::CommitDepthBuffer() { for (int x = 0; x < fb_depth_texture.width; ++x) { const u32 coarse_y = y & ~7; u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; - u32 gl_pixel_index = (x + y * fb_depth_texture.width) * gl_bpp; + u32 gl_pixel_index = (x + (fb_depth_texture.height - 1 - y) * fb_depth_texture.width) * gl_bpp; u8* pixel = depth_buffer + dst_offset; memcpy(pixel, &temp_gl_depth_data[gl_pixel_index], bytes_per_pixel); diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 498c506e7b..38de5d469c 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -382,7 +382,7 @@ void main() { texcoord[0] = vert_texcoord0; texcoord[1] = vert_texcoord1; texcoord[2] = vert_texcoord2; - gl_Position = vec4(vert_position.x, -vert_position.y, -vert_position.z, vert_position.w); + gl_Position = vec4(vert_position.x, vert_position.y, -vert_position.z, vert_position.w); } )"; diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index c44497fc32..a823729956 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -11,6 +11,7 @@ OpenGLState::OpenGLState() { // These all match default OpenGL values cull.enabled = false; cull.mode = GL_BACK; + cull.front_face = GL_CCW; depth.test_enabled = false; depth.test_func = GL_LESS; @@ -67,6 +68,10 @@ void OpenGLState::Apply() { glCullFace(cull.mode); } + if (cull.front_face != cur_state.cull.front_face) { + glFrontFace(cull.front_face); + } + // Depth test if (depth.test_enabled != cur_state.depth.test_enabled) { if (depth.test_enabled) { diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 84b3d49bca..b8ab45bb8d 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -11,6 +11,7 @@ public: struct { bool enabled; // GL_CULL_FACE GLenum mode; // GL_CULL_FACE_MODE + GLenum front_face; // GL_FRONT_FACE } cull; struct {