Rework HUD rendering with OpenGL.

-Fixes regression from commit 5906d44 where HUD would appear smaller when using HD scaling. (only fixed with OpenGL for now)
-Remove use of backlightIntensity for displaying. Fixes bug where screen would appear dark on the first frame after loading a save state. Underlying cause should probably still be fixed, though. (Why would the backlight level affect the display anyway? That setting on the DS is only present because it has its own physical screens and makes no sense here.)
This commit is contained in:
SuuperW 2018-07-12 11:23:23 -05:00
parent dc41f09189
commit 6fc7161f19
1 changed files with 88 additions and 103 deletions

View File

@ -1643,82 +1643,13 @@ struct GLDISPLAY
} gldisplay;
static void OGL_DoDisplay()
static void OGL_DrawTexture(RECT* srcRects, RECT* dstRects)
{
if(!gldisplay.begin()) return;
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
static GLuint tex = 0;
if(tex == 0)
glGenTextures(1,&tex);
glBindTexture(GL_TEXTURE_2D,tex);
if(gpu_bpp == 15)
{
//yeah, it's 32bits here still. we've converted it previously, for compositing the HUD
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, video.width, video.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, video.finalBuffer());
}
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, video.width, video.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, video.finalBuffer());
//the ds screen fills the texture entirely, so we dont have garbage at edge to worry about,
//but we need to make sure this is clamped for when filtering is selected
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
if(GetStyle()&DWS_FILTER)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
}
glEnable(GL_TEXTURE_2D);
RECT rc;
HWND hwnd = MainWindow->getHWnd();
GetClientRect(hwnd,&rc);
int width = rc.right - rc.left;
int height = rc.bottom - rc.top;
glDisable(GL_LIGHTING);
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, (float)width, (float)height, 0.0f, -100.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
RECT dr[] = {MainScreenRect, SubScreenRect, GapRect};
for(int i=0;i<2;i++) //dont change gap rect, for some reason
{
ScreenToClient(hwnd,(LPPOINT)&dr[i].left);
ScreenToClient(hwnd,(LPPOINT)&dr[i].right);
}
//clear entire area, for cases where the screen is maximized
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
//use clear+scissor for gap
if (video.screengap > 0)
{
//adjust client rect into scissor rect (0,0 at bottomleft)
dr[2].bottom = height - dr[2].bottom;
dr[2].top = height - dr[2].top;
glScissor(dr[2].left,dr[2].bottom,dr[2].right-dr[2].left,dr[2].top-dr[2].bottom);
glScissor(dstRects[2].left, dstRects[2].bottom, dstRects[2].right - dstRects[2].left, dstRects[2].top - dstRects[2].bottom);
u32 color_rev = (u32)ScreenGapColor;
int r = (color_rev >> 0) & 0xFF;
@ -1730,44 +1661,8 @@ static void OGL_DoDisplay()
glDisable(GL_SCISSOR_TEST);
}
RECT srcRects [2];
const bool isMainGPUFirst = (displayInfo.engineID[NDSDisplayID_Main] == GPUEngineID_Main);
if(video.swap == 0)
{
srcRects[0] = MainScreenSrcRect;
srcRects[1] = SubScreenSrcRect;
if(osd) osd->swapScreens = false;
}
else if(video.swap == 1)
{
srcRects[0] = SubScreenSrcRect;
srcRects[1] = MainScreenSrcRect;
if(osd) osd->swapScreens = true;
}
else if(video.swap == 2)
{
srcRects[0] = (!isMainGPUFirst) ? SubScreenSrcRect : MainScreenSrcRect;
srcRects[1] = (!isMainGPUFirst) ? MainScreenSrcRect : SubScreenSrcRect;
if(osd) osd->swapScreens = !isMainGPUFirst;
}
else if(video.swap == 3)
{
srcRects[0] = (!isMainGPUFirst) ? MainScreenSrcRect : SubScreenSrcRect;
srcRects[1] = (!isMainGPUFirst) ? SubScreenSrcRect : MainScreenSrcRect;
if(osd) osd->swapScreens = isMainGPUFirst;
}
//printf("%d,%d %dx%d -- %d,%d %dx%d\n",
// srcRects[0].left,srcRects[0].top, srcRects[0].right-srcRects[0].left, srcRects[0].bottom-srcRects[0].top,
// srcRects[1].left,srcRects[1].top, srcRects[1].right-srcRects[1].left, srcRects[1].bottom-srcRects[1].top
// );
//draw two screens
glBegin(GL_QUADS);
for (int i = 0; i<2; i++)
{
//none of this makes any goddamn sense. dont even try.
@ -1800,26 +1695,113 @@ static void OGL_DoDisplay()
float u[] = { u1,u2,u2,u1 };
float v[] = { v1,v1,v2,v2 };
const GLfloat backlightIntensity = displayInfo.backlightIntensity[i];
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs + 0) % 4], v[(ofs + 0) % 4]);
glVertex2i(dr[i].left,dr[i].top);
glVertex2i(dstRects[i].left, dstRects[i].top);
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs + 1) % 4], v[(ofs + 1) % 4]);
glVertex2i(dr[i].right,dr[i].top);
glVertex2i(dstRects[i].right, dstRects[i].top);
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs + 2) % 4], v[(ofs + 2) % 4]);
glVertex2i(dr[i].right,dr[i].bottom);
glVertex2i(dstRects[i].right, dstRects[i].bottom);
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs + 3) % 4], v[(ofs + 3) % 4]);
glVertex2i(dr[i].left,dr[i].bottom);
glVertex2i(dstRects[i].left, dstRects[i].bottom);
}
glEnd();
}
static void OGL_DoDisplay()
{
if(!gldisplay.begin()) return;
//the ds screen fills the texture entirely, so we dont have garbage at edge to worry about,
//but we need to make sure this is clamped for when filtering is selected
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
if(GetStyle()&DWS_FILTER)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
}
glEnd();
RECT rc;
HWND hwnd = MainWindow->getHWnd();
GetClientRect(hwnd,&rc);
int width = rc.right - rc.left;
int height = rc.bottom - rc.top;
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, (float)width, (float)height, 0.0f, -100.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//clear entire area, for cases where the screen is maximized
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
// get dest and src rects
RECT dr[] = {MainScreenRect, SubScreenRect, GapRect};
for(int i=0;i<2;i++) //dont change gap rect, for some reason
{
ScreenToClient(hwnd,(LPPOINT)&dr[i].left);
ScreenToClient(hwnd,(LPPOINT)&dr[i].right);
}
dr[2].bottom = height - dr[2].bottom;
dr[2].top = height - dr[2].top;
RECT srcRects [2];
const bool isMainGPUFirst = (GPU->GetDisplayInfo().engineID[NDSDisplayID_Main] == GPUEngineID_Main);
if(video.swap == 0)
{
srcRects[0] = MainScreenSrcRect;
srcRects[1] = SubScreenSrcRect;
if(osd) osd->swapScreens = false;
}
else if(video.swap == 1)
{
srcRects[0] = SubScreenSrcRect;
srcRects[1] = MainScreenSrcRect;
if(osd) osd->swapScreens = true;
}
else if(video.swap == 2)
{
srcRects[0] = (!isMainGPUFirst) ? SubScreenSrcRect : MainScreenSrcRect;
srcRects[1] = (!isMainGPUFirst) ? MainScreenSrcRect : SubScreenSrcRect;
if(osd) osd->swapScreens = !isMainGPUFirst;
}
else if(video.swap == 3)
{
srcRects[0] = (!isMainGPUFirst) ? MainScreenSrcRect : SubScreenSrcRect;
srcRects[1] = (!isMainGPUFirst) ? SubScreenSrcRect : MainScreenSrcRect;
if(osd) osd->swapScreens = isMainGPUFirst;
}
//printf("%d,%d %dx%d -- %d,%d %dx%d\n",
// srcRects[0].left,srcRects[0].top, srcRects[0].right-srcRects[0].left, srcRects[0].bottom-srcRects[0].top,
// srcRects[1].left,srcRects[1].top, srcRects[1].right-srcRects[1].left, srcRects[1].bottom-srcRects[1].top
// );
glEnable(GL_TEXTURE_2D);
// draw DS display
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, video.width, video.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, video.finalBuffer());
OGL_DrawTexture(srcRects, dr);
// draw HUD
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2, 0, GL_BGRA, GL_UNSIGNED_BYTE, aggDraw.hud->buf().buf());
OGL_DrawTexture(srcRects, dr);
glDisable(GL_BLEND);
gldisplay.showPage();
@ -2029,7 +2011,10 @@ static void DoDisplay()
}
// draw HUD
if (ddhw || ddsw)
aggDraw.hud->attach((u8*)video.buffer, video.prefilterWidth, video.prefilterHeight, video.prefilterWidth * 4);
else
aggDraw.hud->clear();
DoDisplay_DrawHud();
//apply user's filter