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:
parent
dc41f09189
commit
6fc7161f19
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue