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
|
//Get maximum rect respecting AR setting
|
||||||
displayRect = CalculateDisplayRect(windowSize.right, windowSize.bottom, windowSize.right, windowSize.bottom);
|
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) {
|
if (shader_type == OGL_SHADER_GLSL) {
|
||||||
glslShader->render(drawTexture, afterRenderWidth, afterRenderHeight, displayRect.left, displayRect.top, displayRect.right - displayRect.left, displayRect.bottom - displayRect.top, wOGLViewportCallback);
|
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) {
|
if(shader_type == OGL_SHADER_CG) {
|
||||||
xySize inputSize = { (float)afterRenderWidth, (float)afterRenderHeight };
|
xySize inputSize = { (float)afterRenderWidth, (float)afterRenderHeight };
|
||||||
xySize xywindowSize = { (double)windowSize.right, (double)windowSize.bottom };
|
xySize xywindowSize = { (double)windowSize.right, (double)windowSize.bottom };
|
||||||
|
@ -515,6 +516,23 @@ void COpenGL::Render(SSurface Src)
|
||||||
xySize textureSize = { (double)outTextureWidth, (double)outTextureHeight };
|
xySize textureSize = { (double)outTextureWidth, (double)outTextureHeight };
|
||||||
cgShader->Render(drawTexture, textureSize, inputSize, viewportSize, xywindowSize);
|
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) {
|
if (Settings.BilinearFilter) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
|
SetShadersCG(NULL);
|
||||||
SetShadersGLSL(NULL);
|
SetShadersGLSL(NULL);
|
||||||
|
SetShadersGLSL_OLD(NULL);
|
||||||
shader_type = OGL_SHADER_NONE;
|
shader_type = OGL_SHADER_NONE;
|
||||||
if (file != NULL && (
|
if (file != NULL && (
|
||||||
(lstrlen(file) > 3 && _tcsncicmp(&file[lstrlen(file) - 3], TEXT(".cg"), 3) == 0) ||
|
(lstrlen(file) > 3 && _tcsncicmp(&file[lstrlen(file) - 3], TEXT(".cg"), 3) == 0) ||
|
||||||
(lstrlen(file) > 4 && _tcsncicmp(&file[lstrlen(file) - 4], TEXT(".cgp"), 4) == 0))) {
|
(lstrlen(file) > 4 && _tcsncicmp(&file[lstrlen(file) - 4], TEXT(".cgp"), 4) == 0))) {
|
||||||
return SetShadersCG(file);
|
return SetShadersCG(file);
|
||||||
|
} else if((lstrlen(file) > 7 && _tcsncicmp(&file[lstrlen(file) - 7], TEXT(".shader"), 7) == 0)) {
|
||||||
|
return SetShadersGLSL_OLD(file);
|
||||||
} else {
|
} else {
|
||||||
return SetShadersGLSL(file);
|
return SetShadersGLSL(file);
|
||||||
}
|
}
|
||||||
|
@ -740,10 +761,14 @@ bool COpenGL::SetShadersCG(const TCHAR *file)
|
||||||
|
|
||||||
bool COpenGL::SetShadersGLSL(const TCHAR *glslFileName)
|
bool COpenGL::SetShadersGLSL(const TCHAR *glslFileName)
|
||||||
{
|
{
|
||||||
if (!glslFileName || !glslShader)
|
if (!glslShader)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
glslShader->destroy();
|
glslShader->destroy();
|
||||||
|
|
||||||
|
if (!glslFileName)
|
||||||
|
return false;
|
||||||
|
|
||||||
glslShader->load_shader(_tToChar(glslFileName));
|
glslShader->load_shader(_tToChar(glslFileName));
|
||||||
|
|
||||||
shader_type = OGL_SHADER_GLSL;
|
shader_type = OGL_SHADER_GLSL;
|
||||||
|
@ -751,6 +776,159 @@ bool COpenGL::SetShadersGLSL(const TCHAR *glslFileName)
|
||||||
return true;
|
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()
|
bool COpenGL::ShaderAailable()
|
||||||
{
|
{
|
||||||
const char *extensions = (const char *)glGetString(GL_EXTENSIONS);
|
const char *extensions = (const char *)glGetString(GL_EXTENSIONS);
|
||||||
|
|
|
@ -203,7 +203,7 @@
|
||||||
#include "wglext.h"
|
#include "wglext.h"
|
||||||
#include "IS9xDisplayOutput.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
|
class COpenGL : public IS9xDisplayOutput
|
||||||
{
|
{
|
||||||
|
@ -247,6 +247,7 @@ private:
|
||||||
void checkForCgError(const char *situation);
|
void checkForCgError(const char *situation);
|
||||||
bool SetShadersCG(const TCHAR *file);
|
bool SetShadersCG(const TCHAR *file);
|
||||||
bool SetShadersGLSL(const TCHAR *glslFileName);
|
bool SetShadersGLSL(const TCHAR *glslFileName);
|
||||||
|
bool SetShadersGLSL_OLD(const TCHAR *glslFileName);
|
||||||
bool LoadShaderFunctions();
|
bool LoadShaderFunctions();
|
||||||
bool LoadPBOFunctions();
|
bool LoadPBOFunctions();
|
||||||
void CreateDrawSurface(unsigned int width, unsigned int height);
|
void CreateDrawSurface(unsigned int width, unsigned int height);
|
||||||
|
|
Loading…
Reference in New Issue