win32: restore old style OGL .shader support

This commit is contained in:
OV2 2018-05-22 21:43:51 +02:00
parent 69f5e03ac5
commit a911503d4a
2 changed files with 186 additions and 7 deletions

View File

@ -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);

View File

@ -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);