-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use a flipped coordinate system in framebuffers to avoid manual flipping of texture coordinates #8130
Conversation
@@ -1012,7 +1011,7 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame | |||
// And also the UVs, same order. | |||
const float uvleft = u1 * invWidth; | |||
const float uvright = u2 * invWidth; | |||
const float uvtop = 1.0f - v1 * invHeight; | |||
const float uvtop = 1.0f - v1 * invHeight; // TODO: Seems we should ditch the "1.0f - " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, definitely, the positions need to agree too. Otherwise it won't use the correct subset.
-[Unknown]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, this is DX9... yeah maybe this is a typo, oops...
-[Unknown]
a0625f4
to
fff1364
Compare
@@ -659,7 +665,7 @@ void FramebufferManager::ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w, u16 h | |||
|
|||
vfb->fbo = fbo_create(vfb->renderWidth, vfb->renderHeight, 1, true, (FBOColorDepth)vfb->colorDepth); | |||
if (old.fbo) { | |||
INFO_LOG(SCEGE, "Resizing FBO for %08x : %i x %i x %i", vfb->fb_address, w, h, vfb->format); | |||
WARN_LOG(SCEGE, "Resizing FBO for %08x : %i x %i x %i", vfb->fb_address, w, h, vfb->format); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I don't think this is really a "warning" per se.
-[Unknown]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that was supposed to be temporary.
Cool this fixed #4665 |
Neat. Not quite sure why though :) There are still a couple of bugs lurking so I can't merge yet. |
Well there are some problems with effects, where select cursor or maybe just all transparent effects, shows inverted graphics inside of them, but other than that looks nice:). Possibly it also affected #6736 but I don't have this one. |
Okay, so just to take inventory: What this does is draw everything "right side up" until drawing to the actual backbuffer. Previously we used the OpenGL "upside down" coordinate system throughout all drawing. Example:
Then when drawing to the final backbuffer, the image is flipped appropriately to match the OpenGL system. In this way, textures (which use the "right side up" coordinate system) match framebuffers. Problems and what I assume the solution is (still need to audit, though I've reviewed the code):
I'm most concerned about the last ones. If #4665 was fixed by this, it probably means there was a bug in that code already. Just to make sure I'm clear, sometimes OpenGL framebuffers are reused and larger than the height we "know" they have. Before this ended up as the ASCII art above, where X's represent non-valid pixel data. There's two ways the coordinate system could be flipped:
I think we are using the more logical type 1 (which will avoid problems with resizing.) As such, when flipping offsets, we need to account for this. An example of download (glReadPixels):
OpenGL's coordinates on on the right side, sane coordinates are on the left. When downloading 0,0 with width and height of 4, we want OpenGL row 6 first, then 5, then 4, then 3. More than that, we also have to ensure we account for the offset - OpenGL row 0 is garbage data for us in this example, since it is outside the valid pixels. #4665 looks very much like it was previously texturing or something from a 512 tall framebuffer, and it read the wrong half, and did so even upside down. If it was fixed now, that's great, but it seems like now other games have the reverse problem: downloads are upside down. -[Unknown] |
@@ -1348,7 +1359,7 @@ void FramebufferManager::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int | |||
// Should maybe revamp that interface. | |||
float srcW = src->bufferWidth; | |||
float srcH = src->bufferHeight; | |||
DrawActiveTexture(0, dstX1, dstY, w * dstXFactor, h, dst->bufferWidth, dst->bufferHeight, !flip, srcX1 / srcW, srcY / srcH, srcX2 / srcW, (srcY + h) / srcH, draw2dprogram_); | |||
DrawActiveTexture(0, dstX1, dstY, w * dstXFactor, h, dst->bufferWidth, dst->bufferHeight, srcX1 / srcW, srcY / srcH, srcX2 / srcW, srcY2 / srcH, draw2dprogram_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this is a bit confusing, since the factors are fixed to 1 here. Should probably change dstY
to dstY1
and srcY
to srcY1
to match, and either add * dstYFactor
to h
or remove from w
. Before y was always "unscaled" in this statement, although that's sorta confusing anyway.
-[Unknown]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, yeah, should clean this up. Anyway, it's in the !useBlit path so not likely to cause the remaining issues on my hardware at least..
Viewport y offset is off in Star Ocean 1 outside towns. This game uses a 272 Y scale (meaning, 272 * 2 total Y viewport height.) -[Unknown] |
Yeah, I believe the viewport clipping code in StateMapping might not be working properly. It hasn't been converted to view the world the new way... |
@unknownbrackets in "Framebuffer -> memory offset" Where's this flipping calculation you refer to? ("Accounted for by flipping y1/y2 in y/h calculation") |
Oh, btw, we need to set flipped = false in all the debug buffers at the end of Framebuffer.cpp. I can send a pull. About the offset... when downloading: int byteOffset = y * vfb->fb_stride * 4;
glReadPixels(0, y, vfb->fb_stride, h, glfmt, GL_UNSIGNED_BYTE, packed + byteOffset); Right now, it offsets the memory and y1 position it downloads from. This code was designed for flipped framebuffers, though, and so I think somewhere things need to be accounted for. -[Unknown] |
I think that should be right, actually - seems it might have been wrong before? |
Maybe I'm confused. This is all very annoying.
Won't glReadPixels y=0, h=4 do the following:
This means that memory will now look like this, right?
Or am I missing something? Edit: no wait, maybe it would be the flipped view of this, but either way it'd be from the bottom, right? Before, it was flipped, so it worked out:
-[Unknown] |
Well, now that we don't flip Y/V in various ways anymore, except for the final blit to the screen, you could now consider 0,0 to be top left in image space, it's really arbitrary if we call positive Y "up" or "down". glReadPixel will read from increasing Y line numbers into increasing memory addresses. When you consider GL coordinates the normal way, that would be upwards, but in our point of view, it's downwards and glReadPixels should thus behave the way we want... |
Okay, sorry, I had it backwards. Thanks. Well, the only thing I'm seeing wrong at this point is the viewport in Star Ocean 1. Grand Knights History and 3rd Birthday work with the other fixes so far. -[Unknown] |
Should this branch help with #8016 at this point? Since there doesn't seem to be any difference for that. Great work on figuring out all those problems through, seems like it's not breaking anything anymore while taking care of another ancient issue:). |
@LunaMoo No you won't, I'm going to merge your branch first and rebase this branch myself, don't worry. |
Oh I'm not worried about that:3, I'm actually glad I had to use rebase a few times since I finally learned how and it's pretty easy even when there are conflicts to resolve:). Git is kind of overwhelming without some practice. |
Oh and I forgot to answer, yeah, it will help with #8016. I will commit the fixes to that after merging this. |
… fix bugs in games, too. Fixes the strange camera issues in FF:CC.
… flips where we actually need them.
Add some missing projection matrix flips (flipped viewport emulation) Fix issue with DrawPixels in non-buffered in D3D9
5e41343
to
3a7edd8
Compare
Last commit broke Wipeout in GL buffered, will need to figure out that before merge. BTW does Star Ocean work in cities with all the stencil stuff? |
Use a flipped coordinate system in framebuffers to avoid manual flipping of texture coordinates
Flip display layout editor coordinates to match #8130:)
Simplifies a lot of things and gets rid of a few shaders, although there are a few new differences between buffered and non-buffered, as we are effectively flipped again when drawing to the backbuffer directly, which we do in non-buffered.
This will help #8016 .