mirror of https://github.com/snes9xgit/snes9x.git
win32: use npot textures in OGL if available, use glsl viewport callback
This commit is contained in:
parent
3b5ca2397b
commit
69f5e03ac5
|
@ -210,8 +210,6 @@ COpenGL::COpenGL(void)
|
||||||
hWnd = NULL;
|
hWnd = NULL;
|
||||||
drawTexture = 0;
|
drawTexture = 0;
|
||||||
initDone = false;
|
initDone = false;
|
||||||
quadTextureSize = 0;
|
|
||||||
filterScale = 0;
|
|
||||||
afterRenderWidth = 0;
|
afterRenderWidth = 0;
|
||||||
afterRenderHeight = 0;
|
afterRenderHeight = 0;
|
||||||
fullscreen = false;
|
fullscreen = false;
|
||||||
|
@ -336,8 +334,6 @@ void COpenGL::DeInitialize()
|
||||||
}
|
}
|
||||||
hWnd = NULL;
|
hWnd = NULL;
|
||||||
initDone = false;
|
initDone = false;
|
||||||
quadTextureSize = 0;
|
|
||||||
filterScale = 0;
|
|
||||||
afterRenderWidth = 0;
|
afterRenderWidth = 0;
|
||||||
afterRenderHeight = 0;
|
afterRenderHeight = 0;
|
||||||
shaderFunctionsLoaded = false;
|
shaderFunctionsLoaded = false;
|
||||||
|
@ -355,28 +351,32 @@ void COpenGL::DeInitialize()
|
||||||
cgAvailable = false;
|
cgAvailable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void COpenGL::CreateDrawSurface()
|
void COpenGL::CreateDrawSurface(unsigned int width, unsigned int height)
|
||||||
{
|
{
|
||||||
unsigned int neededSize;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
//we need at least 512 pixels (SNES_WIDTH * 2) so we can start with that value
|
if (!NPOTAvailable()) {
|
||||||
quadTextureSize = 512;
|
unsigned int neededSize = max(width, height);
|
||||||
neededSize = SNES_WIDTH * filterScale;
|
//we need at least 512 pixels (SNES_WIDTH * 2) so we can start with that value
|
||||||
while(quadTextureSize < neededSize)
|
unsigned int quadTextureSize = 512;
|
||||||
quadTextureSize *=2;
|
while (quadTextureSize < neededSize)
|
||||||
|
quadTextureSize *= 2;
|
||||||
|
width = height = quadTextureSize;
|
||||||
|
}
|
||||||
|
|
||||||
if(!drawTexture) {
|
if(!drawTexture) {
|
||||||
|
outTextureWidth = width;
|
||||||
|
outTextureHeight = height;
|
||||||
glGenTextures(1,&drawTexture);
|
glGenTextures(1,&drawTexture);
|
||||||
glBindTexture(GL_TEXTURE_2D,drawTexture);
|
glBindTexture(GL_TEXTURE_2D,drawTexture);
|
||||||
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,quadTextureSize,quadTextureSize,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,NULL);
|
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB, outTextureWidth, outTextureHeight,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,NULL);
|
||||||
if(pboFunctionsLoaded) {
|
if(pboFunctionsLoaded) {
|
||||||
glGenBuffers(1,&drawBuffer);
|
glGenBuffers(1,&drawBuffer);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,drawBuffer);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,drawBuffer);
|
||||||
glBufferData(GL_PIXEL_UNPACK_BUFFER,quadTextureSize*quadTextureSize*2,NULL,GL_STREAM_DRAW);
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, outTextureWidth*outTextureHeight *2,NULL,GL_STREAM_DRAW);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,0);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,0);
|
||||||
} else {
|
} else {
|
||||||
noPboBuffer = new BYTE[quadTextureSize*quadTextureSize*2];
|
noPboBuffer = new BYTE[outTextureWidth*outTextureHeight *2];
|
||||||
}
|
}
|
||||||
|
|
||||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
|
@ -400,12 +400,10 @@ void COpenGL::DestroyDrawSurface()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool COpenGL::ChangeDrawSurfaceSize(unsigned int scale)
|
bool COpenGL::ChangeDrawSurfaceSize(unsigned int width, unsigned int height)
|
||||||
{
|
{
|
||||||
filterScale = scale;
|
|
||||||
|
|
||||||
DestroyDrawSurface();
|
DestroyDrawSurface();
|
||||||
CreateDrawSurface();
|
CreateDrawSurface(width, height);
|
||||||
SetupVertices();
|
SetupVertices();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -421,8 +419,8 @@ void COpenGL::SetupVertices()
|
||||||
vertices[6] = 0.0f;
|
vertices[6] = 0.0f;
|
||||||
vertices[7] = 1.0f;
|
vertices[7] = 1.0f;
|
||||||
|
|
||||||
float tX = (float)afterRenderWidth / (float)quadTextureSize;
|
float tX = (float)afterRenderWidth / (float)outTextureWidth;
|
||||||
float tY = (float)afterRenderHeight / (float)quadTextureSize;
|
float tY = (float)afterRenderHeight / (float)outTextureHeight;
|
||||||
|
|
||||||
texcoords[0] = 0.0f;
|
texcoords[0] = 0.0f;
|
||||||
texcoords[1] = tY;
|
texcoords[1] = tY;
|
||||||
|
@ -435,6 +433,24 @@ void COpenGL::SetupVertices()
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
|
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wOGLViewportCallback(int source_width, int source_height,
|
||||||
|
int viewport_x, int viewport_y,
|
||||||
|
int viewport_width, int viewport_height,
|
||||||
|
int *out_dst_x, int *out_dst_y,
|
||||||
|
int *out_dst_width, int *out_dst_height)
|
||||||
|
{
|
||||||
|
/* get window size here instead of using viewport passed in - we limited the viewport before the glsl render
|
||||||
|
call already, this is simply to position smaller outputs correctly in the actual viewport
|
||||||
|
*/
|
||||||
|
RECT windowSize;
|
||||||
|
GetClientRect(GUI.hWnd, &windowSize);
|
||||||
|
RECT displayRect = CalculateDisplayRect(source_width, source_height, windowSize.right, windowSize.bottom);
|
||||||
|
*out_dst_x = displayRect.left;
|
||||||
|
*out_dst_y = displayRect.top;
|
||||||
|
*out_dst_width = displayRect.right - displayRect.left;
|
||||||
|
*out_dst_height = displayRect.bottom - displayRect.top;
|
||||||
|
}
|
||||||
|
|
||||||
void COpenGL::Render(SSurface Src)
|
void COpenGL::Render(SSurface Src)
|
||||||
{
|
{
|
||||||
SSurface Dst;
|
SSurface Dst;
|
||||||
|
@ -445,11 +461,9 @@ void COpenGL::Render(SSurface Src)
|
||||||
if(!initDone) return;
|
if(!initDone) return;
|
||||||
|
|
||||||
//create a new draw surface if the filter scale changes
|
//create a new draw surface if the filter scale changes
|
||||||
//at least factor 2 so we can display unscaled hi-res images
|
dstRect = GetFilterOutputSize(Src);
|
||||||
newFilterScale = max(2,max(GetFilterScale(GUI.ScaleHiRes),GetFilterScale(GUI.Scale)));
|
if(outTextureWidth != dstRect.right || outTextureHeight != dstRect.bottom)
|
||||||
if(newFilterScale!=filterScale) {
|
ChangeDrawSurfaceSize(dstRect.right, dstRect.bottom);
|
||||||
ChangeDrawSurfaceSize(newFilterScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pboFunctionsLoaded) {
|
if(pboFunctionsLoaded) {
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, drawBuffer);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, drawBuffer);
|
||||||
|
@ -457,9 +471,9 @@ void COpenGL::Render(SSurface Src)
|
||||||
} else {
|
} else {
|
||||||
Dst.Surface = noPboBuffer;
|
Dst.Surface = noPboBuffer;
|
||||||
}
|
}
|
||||||
Dst.Height = quadTextureSize;
|
Dst.Height = outTextureHeight;
|
||||||
Dst.Width = quadTextureSize;
|
Dst.Width = outTextureWidth;
|
||||||
Dst.Pitch = quadTextureSize * 2;
|
Dst.Pitch = outTextureWidth * 2;
|
||||||
|
|
||||||
RenderMethod (Src, Dst, &dstRect);
|
RenderMethod (Src, Dst, &dstRect);
|
||||||
if(!Settings.AutoDisplayMessages) {
|
if(!Settings.AutoDisplayMessages) {
|
||||||
|
@ -478,7 +492,7 @@ void COpenGL::Render(SSurface Src)
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D,drawTexture);
|
glBindTexture(GL_TEXTURE_2D,drawTexture);
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, quadTextureSize);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, outTextureWidth);
|
||||||
glTexSubImage2D (GL_TEXTURE_2D,0,0,0,dstRect.right-dstRect.left,dstRect.bottom-dstRect.top,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,pboFunctionsLoaded?0:noPboBuffer);
|
glTexSubImage2D (GL_TEXTURE_2D,0,0,0,dstRect.right-dstRect.left,dstRect.bottom-dstRect.top,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,pboFunctionsLoaded?0:noPboBuffer);
|
||||||
|
|
||||||
if(pboFunctionsLoaded)
|
if(pboFunctionsLoaded)
|
||||||
|
@ -490,7 +504,7 @@ void COpenGL::Render(SSurface Src)
|
||||||
displayRect = CalculateDisplayRect(windowSize.right, windowSize.bottom, windowSize.right, windowSize.bottom);
|
displayRect = CalculateDisplayRect(windowSize.right, windowSize.bottom, windowSize.right, windowSize.bottom);
|
||||||
|
|
||||||
if (shader_type == OGL_SHADER_GLSL) {
|
if (shader_type == OGL_SHADER_GLSL) {
|
||||||
glslShader->render(drawTexture, afterRenderWidth, afterRenderHeight, displayRect.right - displayRect.left, displayRect.bottom - displayRect.top, displayRect.left, displayRect.top);
|
glslShader->render(drawTexture, afterRenderWidth, afterRenderHeight, displayRect.left, displayRect.top, displayRect.right - displayRect.left, displayRect.bottom - displayRect.top, wOGLViewportCallback);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(shader_type == OGL_SHADER_CG) {
|
if(shader_type == OGL_SHADER_CG) {
|
||||||
|
@ -498,7 +512,7 @@ void COpenGL::Render(SSurface Src)
|
||||||
xySize xywindowSize = { (double)windowSize.right, (double)windowSize.bottom };
|
xySize xywindowSize = { (double)windowSize.right, (double)windowSize.bottom };
|
||||||
xySize viewportSize = { (double)(displayRect.right - displayRect.left),
|
xySize viewportSize = { (double)(displayRect.right - displayRect.left),
|
||||||
(double)(displayRect.bottom - displayRect.top) };
|
(double)(displayRect.bottom - displayRect.top) };
|
||||||
xySize textureSize = { (double)quadTextureSize, (double)quadTextureSize };
|
xySize textureSize = { (double)outTextureWidth, (double)outTextureHeight };
|
||||||
cgShader->Render(drawTexture, textureSize, inputSize, viewportSize, xywindowSize);
|
cgShader->Render(drawTexture, textureSize, inputSize, viewportSize, xywindowSize);
|
||||||
}
|
}
|
||||||
if (Settings.BilinearFilter) {
|
if (Settings.BilinearFilter) {
|
||||||
|
|
|
@ -221,8 +221,8 @@ private:
|
||||||
|
|
||||||
bool initDone;
|
bool initDone;
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
unsigned int quadTextureSize;
|
unsigned int outTextureWidth;
|
||||||
unsigned int filterScale;
|
unsigned int outTextureHeight;
|
||||||
unsigned int afterRenderWidth, afterRenderHeight;
|
unsigned int afterRenderWidth, afterRenderHeight;
|
||||||
|
|
||||||
bool shaderFunctionsLoaded;
|
bool shaderFunctionsLoaded;
|
||||||
|
@ -249,9 +249,9 @@ private:
|
||||||
bool SetShadersGLSL(const TCHAR *glslFileName);
|
bool SetShadersGLSL(const TCHAR *glslFileName);
|
||||||
bool LoadShaderFunctions();
|
bool LoadShaderFunctions();
|
||||||
bool LoadPBOFunctions();
|
bool LoadPBOFunctions();
|
||||||
void CreateDrawSurface(void);
|
void CreateDrawSurface(unsigned int width, unsigned int height);
|
||||||
void DestroyDrawSurface(void);
|
void DestroyDrawSurface(void);
|
||||||
bool ChangeDrawSurfaceSize(unsigned int scale);
|
bool ChangeDrawSurfaceSize(unsigned int width, unsigned int height);
|
||||||
void SetupVertices();
|
void SetupVertices();
|
||||||
bool ShaderAailable();
|
bool ShaderAailable();
|
||||||
bool NPOTAvailable();
|
bool NPOTAvailable();
|
||||||
|
|
|
@ -477,6 +477,42 @@ inline static bool GetFilterBlendSupport(RenderFilter filterID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void SetRect(RECT* rect, int width, int height, int scale)
|
||||||
|
{
|
||||||
|
rect->left = 0;
|
||||||
|
rect->right = width * scale;
|
||||||
|
rect->top = 0;
|
||||||
|
rect->bottom = (height - (GUI.HeightExtend ? 0 : 15)) * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT GetFilterOutputSize(SSurface Src)
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
RenderFilter filterID = GUI.Scale;
|
||||||
|
if (Src.Height > SNES_HEIGHT_EXTENDED || Src.Width == 512) {
|
||||||
|
filterID = GUI.ScaleHiRes;
|
||||||
|
}
|
||||||
|
// default to fixed factor
|
||||||
|
SetRect(&rect, SNES_WIDTH, SNES_HEIGHT_EXTENDED, GetFilterScale(filterID));
|
||||||
|
|
||||||
|
// handle special cases
|
||||||
|
switch (filterID)
|
||||||
|
{
|
||||||
|
case FILTER_NONE:
|
||||||
|
SetRect(&rect, Src.Width, Src.Height, 1);
|
||||||
|
break;
|
||||||
|
case FILTER_BLARGGCOMP:
|
||||||
|
case FILTER_BLARGGSVID:
|
||||||
|
case FILTER_BLARGGRGB:
|
||||||
|
SetRect(&rect, SNES_WIDTH, SNES_HEIGHT_EXTENDED, 2);
|
||||||
|
rect.right = SNES_NTSC_OUT_WIDTH(256);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
void SelectRenderMethod()
|
void SelectRenderMethod()
|
||||||
{
|
{
|
||||||
TRenderMethod OldRenderMethod = _RenderMethod;
|
TRenderMethod OldRenderMethod = _RenderMethod;
|
||||||
|
@ -701,15 +737,6 @@ inline void ThreeHalfLine32( uint32 *lpDst, uint16 *lpSrc, unsigned int Width){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void SetRect(RECT* rect, int width, int height, int scale)
|
|
||||||
{
|
|
||||||
rect->left = 0;
|
|
||||||
rect->right = width * scale;
|
|
||||||
rect->top = 0;
|
|
||||||
rect->bottom = (height - (GUI.HeightExtend?0:15)) * scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define AVERAGE_565(el0, el1) (((el0) & (el1)) + ((((el0) ^ (el1)) & 0xF7DE) >> 1))
|
#define AVERAGE_565(el0, el1) (((el0) & (el1)) + ((((el0) ^ (el1)) & 0xF7DE) >> 1))
|
||||||
void RenderMergeHires(void *src, int srcPitch , void* dst, int dstPitch, unsigned int width, unsigned int height)
|
void RenderMergeHires(void *src, int srcPitch , void* dst, int dstPitch, unsigned int width, unsigned int height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -212,4 +212,6 @@ void SelectRenderMethod();
|
||||||
void InitRenderFilters();
|
void InitRenderFilters();
|
||||||
void DeInitRenderFilters();
|
void DeInitRenderFilters();
|
||||||
|
|
||||||
|
RECT GetFilterOutputSize(SSurface Src);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue