mirror of https://github.com/snes9xgit/snes9x.git
win32: restore old style OGL .shader support
This commit is contained in:
parent
69f5e03ac5
commit
a911503d4a
|
@ -503,10 +503,11 @@ void COpenGL::Render(SSurface Src)
|
|||
//Get maximum rect respecting AR setting
|
||||
displayRect = CalculateDisplayRect(windowSize.right, windowSize.bottom, windowSize.right, windowSize.bottom);
|
||||
|
||||
// GLSL class does all the rendering, no output needed
|
||||
if (shader_type == OGL_SHADER_GLSL) {
|
||||
glslShader->render(drawTexture, afterRenderWidth, afterRenderHeight, displayRect.left, displayRect.top, displayRect.right - displayRect.left, displayRect.bottom - displayRect.top, wOGLViewportCallback);
|
||||
}
|
||||
else {
|
||||
else { // for CG shaders and old style .shader files the last pass is done here, same as no shader
|
||||
if(shader_type == OGL_SHADER_CG) {
|
||||
xySize inputSize = { (float)afterRenderWidth, (float)afterRenderHeight };
|
||||
xySize xywindowSize = { (double)windowSize.right, (double)windowSize.bottom };
|
||||
|
@ -515,6 +516,23 @@ void COpenGL::Render(SSurface Src)
|
|||
xySize textureSize = { (double)outTextureWidth, (double)outTextureHeight };
|
||||
cgShader->Render(drawTexture, textureSize, inputSize, viewportSize, xywindowSize);
|
||||
}
|
||||
else if (shader_type == OGL_SHADER_GLSL_OLD) {
|
||||
GLint location;
|
||||
|
||||
float inputSize[2] = { (float)afterRenderWidth, (float)afterRenderHeight };
|
||||
float outputSize[2] = { (float)(GUI.Stretch ? windowSize.right : afterRenderWidth),
|
||||
(float)(GUI.Stretch ? windowSize.bottom : afterRenderHeight) };
|
||||
float textureSize[2] = { (float)outTextureWidth, (float)outTextureHeight };
|
||||
float frameCnt = (float)++frameCount;
|
||||
location = glGetUniformLocation(shaderProgram, "rubyInputSize");
|
||||
glUniform2fv(location, 1, inputSize);
|
||||
|
||||
location = glGetUniformLocation(shaderProgram, "rubyOutputSize");
|
||||
glUniform2fv(location, 1, outputSize);
|
||||
|
||||
location = glGetUniformLocation(shaderProgram, "rubyTextureSize");
|
||||
glUniform2fv(location, 1, textureSize);
|
||||
}
|
||||
if (Settings.BilinearFilter) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
@ -691,11 +709,14 @@ bool COpenGL::SetShaders(const TCHAR *file)
|
|||
{
|
||||
SetShadersCG(NULL);
|
||||
SetShadersGLSL(NULL);
|
||||
SetShadersGLSL_OLD(NULL);
|
||||
shader_type = OGL_SHADER_NONE;
|
||||
if(file!=NULL && (
|
||||
(lstrlen(file)>3 && _tcsncicmp(&file[lstrlen(file)-3],TEXT(".cg"),3)==0) ||
|
||||
(lstrlen(file)>4 && _tcsncicmp(&file[lstrlen(file)-4],TEXT(".cgp"),4)==0))) {
|
||||
if (file != NULL && (
|
||||
(lstrlen(file) > 3 && _tcsncicmp(&file[lstrlen(file) - 3], TEXT(".cg"), 3) == 0) ||
|
||||
(lstrlen(file) > 4 && _tcsncicmp(&file[lstrlen(file) - 4], TEXT(".cgp"), 4) == 0))) {
|
||||
return SetShadersCG(file);
|
||||
} else if((lstrlen(file) > 7 && _tcsncicmp(&file[lstrlen(file) - 7], TEXT(".shader"), 7) == 0)) {
|
||||
return SetShadersGLSL_OLD(file);
|
||||
} else {
|
||||
return SetShadersGLSL(file);
|
||||
}
|
||||
|
@ -740,10 +761,14 @@ bool COpenGL::SetShadersCG(const TCHAR *file)
|
|||
|
||||
bool COpenGL::SetShadersGLSL(const TCHAR *glslFileName)
|
||||
{
|
||||
if (!glslFileName || !glslShader)
|
||||
if (!glslShader)
|
||||
return false;
|
||||
|
||||
glslShader->destroy();
|
||||
|
||||
if (!glslFileName)
|
||||
return false;
|
||||
|
||||
glslShader->destroy();
|
||||
glslShader->load_shader(_tToChar(glslFileName));
|
||||
|
||||
shader_type = OGL_SHADER_GLSL;
|
||||
|
@ -751,6 +776,159 @@ bool COpenGL::SetShadersGLSL(const TCHAR *glslFileName)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool COpenGL::SetShadersGLSL_OLD(const TCHAR *glslFileName)
|
||||
{
|
||||
char *fragment = NULL, *vertex = NULL;
|
||||
IXMLDOMDocument * pXMLDoc = NULL;
|
||||
IXMLDOMElement * pXDE = NULL;
|
||||
IXMLDOMNode * pXDN = NULL;
|
||||
HRESULT hr;
|
||||
BSTR queryString, nodeContent;
|
||||
|
||||
TCHAR errorMsg[MAX_PATH + 50];
|
||||
|
||||
if (fragmentShader) {
|
||||
glDetachShader(shaderProgram, fragmentShader);
|
||||
glDeleteShader(fragmentShader);
|
||||
fragmentShader = 0;
|
||||
}
|
||||
if (vertexShader) {
|
||||
glDetachShader(shaderProgram, vertexShader);
|
||||
glDeleteShader(vertexShader);
|
||||
vertexShader = 0;
|
||||
}
|
||||
if (shaderProgram) {
|
||||
glUseProgram(0);
|
||||
glDeleteProgram(shaderProgram);
|
||||
shaderProgram = 0;
|
||||
}
|
||||
|
||||
if (glslFileName == NULL || *glslFileName == TEXT('\0'))
|
||||
return true;
|
||||
|
||||
if (!LoadShaderFunctions()) {
|
||||
MessageBox(NULL, TEXT("Unable to load OpenGL shader functions"), TEXT("Shader Loading Error"),
|
||||
MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pXMLDoc));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
MessageBox(NULL, TEXT("Error creating XML Parser"), TEXT("Shader Loading Error"),
|
||||
MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
|
||||
VARIANT fileName;
|
||||
VARIANT_BOOL ret;
|
||||
fileName.vt = VT_BSTR;
|
||||
#ifdef UNICODE
|
||||
fileName.bstrVal = SysAllocString(glslFileName);
|
||||
#else
|
||||
wchar_t tempfilename[MAX_PATH];
|
||||
MultiByteToWideChar(CP_UTF8, 0, glslFileName, -1, tempfilename, MAX_PATH);
|
||||
fileName.bstrVal = SysAllocString(tempfilename);
|
||||
#endif
|
||||
hr = pXMLDoc->load(fileName, &ret);
|
||||
SysFreeString(fileName.bstrVal);
|
||||
|
||||
if (FAILED(hr) || hr == S_FALSE) {
|
||||
_stprintf(errorMsg, TEXT("Error loading GLSL shader file:\n%s"), glslFileName);
|
||||
MessageBox(NULL, errorMsg, TEXT("Shader Loading Error"), MB_OK | MB_ICONEXCLAMATION);
|
||||
pXMLDoc->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
VARIANT attributeValue;
|
||||
BSTR attributeName;
|
||||
|
||||
hr = pXMLDoc->get_documentElement(&pXDE);
|
||||
if (FAILED(hr) || hr == S_FALSE) {
|
||||
_stprintf(errorMsg, TEXT("Error loading root element from file:\n%s"), glslFileName);
|
||||
MessageBox(NULL, errorMsg, TEXT("Shader Loading Error"), MB_OK | MB_ICONEXCLAMATION);
|
||||
pXMLDoc->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
attributeName = SysAllocString(L"language");
|
||||
pXDE->getAttribute(attributeName, &attributeValue);
|
||||
SysFreeString(attributeName);
|
||||
pXDE->Release();
|
||||
|
||||
if (attributeValue.vt != VT_BSTR || lstrcmpiW(attributeValue.bstrVal, L"glsl")) {
|
||||
_stprintf(errorMsg, TEXT("Shader language is <%s>, expected <GLSL> in file:\n%s"), attributeValue.bstrVal, glslFileName);
|
||||
MessageBox(NULL, errorMsg, TEXT("Shader Loading Error"), MB_OK | MB_ICONEXCLAMATION);
|
||||
if (attributeValue.vt == VT_BSTR) SysFreeString(attributeValue.bstrVal);
|
||||
pXMLDoc->Release();
|
||||
return false;
|
||||
}
|
||||
if (attributeValue.vt == VT_BSTR) SysFreeString(attributeValue.bstrVal);
|
||||
|
||||
queryString = SysAllocString(L"/shader/fragment");
|
||||
hr = pXMLDoc->selectSingleNode(queryString, &pXDN);
|
||||
SysFreeString(queryString);
|
||||
|
||||
if (hr == S_OK) {
|
||||
hr = pXDN->get_text(&nodeContent);
|
||||
if (hr == S_OK) {
|
||||
int requiredChars = WideCharToMultiByte(CP_ACP, 0, nodeContent, -1, fragment, 0, NULL, NULL);
|
||||
fragment = new char[requiredChars];
|
||||
WideCharToMultiByte(CP_UTF8, 0, nodeContent, -1, fragment, requiredChars, NULL, NULL);
|
||||
}
|
||||
SysFreeString(nodeContent);
|
||||
pXDN->Release();
|
||||
pXDN = NULL;
|
||||
}
|
||||
|
||||
queryString = SysAllocString(L"/shader/vertex");
|
||||
hr = pXMLDoc->selectSingleNode(queryString, &pXDN);
|
||||
SysFreeString(queryString);
|
||||
|
||||
if (hr == S_OK) {
|
||||
hr = pXDN->get_text(&nodeContent);
|
||||
if (hr == S_OK) {
|
||||
int requiredChars = WideCharToMultiByte(CP_ACP, 0, nodeContent, -1, vertex, 0, NULL, NULL);
|
||||
vertex = new char[requiredChars];
|
||||
WideCharToMultiByte(CP_UTF8, 0, nodeContent, -1, vertex, requiredChars, NULL, NULL);
|
||||
}
|
||||
SysFreeString(nodeContent);
|
||||
pXDN->Release();
|
||||
pXDN = NULL;
|
||||
}
|
||||
|
||||
pXMLDoc->Release();
|
||||
|
||||
if (!fragment && !vertex) {
|
||||
_stprintf(errorMsg, TEXT("No vertex or fragment program in file:\n%s"), glslFileName);
|
||||
MessageBox(NULL, errorMsg, TEXT("Shader Loading Error"), MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
|
||||
shaderProgram = glCreateProgram();
|
||||
if (vertex) {
|
||||
vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexShader, 1, (const GLchar **)&vertex, NULL);
|
||||
glCompileShader(vertexShader);
|
||||
glAttachShader(shaderProgram, vertexShader);
|
||||
delete[] vertex;
|
||||
}
|
||||
if (fragment) {
|
||||
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragmentShader, 1, (const GLchar **)&fragment, NULL);
|
||||
glCompileShader(fragmentShader);
|
||||
glAttachShader(shaderProgram, fragmentShader);
|
||||
delete[] fragment;
|
||||
}
|
||||
|
||||
glLinkProgram(shaderProgram);
|
||||
glUseProgram(shaderProgram);
|
||||
|
||||
shader_type = OGL_SHADER_GLSL_OLD;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool COpenGL::ShaderAailable()
|
||||
{
|
||||
const char *extensions = (const char *)glGetString(GL_EXTENSIONS);
|
||||
|
|
|
@ -203,7 +203,7 @@
|
|||
#include "wglext.h"
|
||||
#include "IS9xDisplayOutput.h"
|
||||
|
||||
enum current_ogl_shader_type { OGL_SHADER_NONE, OGL_SHADER_GLSL, OGL_SHADER_CG };
|
||||
enum current_ogl_shader_type { OGL_SHADER_NONE, OGL_SHADER_GLSL, OGL_SHADER_CG, OGL_SHADER_GLSL_OLD};
|
||||
|
||||
class COpenGL : public IS9xDisplayOutput
|
||||
{
|
||||
|
@ -247,6 +247,7 @@ private:
|
|||
void checkForCgError(const char *situation);
|
||||
bool SetShadersCG(const TCHAR *file);
|
||||
bool SetShadersGLSL(const TCHAR *glslFileName);
|
||||
bool SetShadersGLSL_OLD(const TCHAR *glslFileName);
|
||||
bool LoadShaderFunctions();
|
||||
bool LoadPBOFunctions();
|
||||
void CreateDrawSurface(unsigned int width, unsigned int height);
|
||||
|
|
Loading…
Reference in New Issue