forked from Mirrors/openclonk
Use the core api for shaders instead of the ARB one
parent
bc8db0589e
commit
16d2eb5cb1
|
@ -289,7 +289,7 @@ void C4Shader::Clear()
|
|||
#ifndef USE_CONSOLE
|
||||
if (!hProg) return;
|
||||
// Need to be detached, then deleted
|
||||
glDeleteObjectARB(hProg);
|
||||
glDeleteProgram(hProg);
|
||||
hProg = 0;
|
||||
// Clear uniform data
|
||||
Uniforms.clear();
|
||||
|
@ -313,43 +313,46 @@ bool C4Shader::Init(const char *szWhat, const char **szUniforms, const char **sz
|
|||
|
||||
#ifndef USE_CONSOLE
|
||||
// Attempt to create shaders
|
||||
const GLint hVert = Create(GL_VERTEX_SHADER_ARB,
|
||||
FormatString("%s vertex shader", szWhat).getData(),
|
||||
VertexShader.getData());
|
||||
const GLint hFrag = Create(GL_FRAGMENT_SHADER_ARB,
|
||||
FormatString("%s fragment shader", szWhat).getData(),
|
||||
FragmentShader.getData());
|
||||
const GLuint hVert = Create(GL_VERTEX_SHADER,
|
||||
FormatString("%s vertex shader", szWhat).getData(),
|
||||
VertexShader.getData());
|
||||
const GLuint hFrag = Create(GL_FRAGMENT_SHADER,
|
||||
FormatString("%s fragment shader", szWhat).getData(),
|
||||
FragmentShader.getData());
|
||||
|
||||
if(!hFrag || !hVert)
|
||||
{
|
||||
if (hVert) glDeleteObjectARB(hVert);
|
||||
if (hFrag) glDeleteShader(hFrag);
|
||||
if (hVert) glDeleteShader(hVert);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Link program
|
||||
const GLint hNewProg = glCreateProgramObjectARB();
|
||||
const GLuint hNewProg = glCreateProgram();
|
||||
#ifdef GL_KHR_debug
|
||||
if (glObjectLabel)
|
||||
glObjectLabel(GL_PROGRAM, hNewProg, -1, szWhat);
|
||||
#endif
|
||||
glAttachObjectARB(hNewProg, hVert);
|
||||
glAttachObjectARB(hNewProg, hFrag);
|
||||
glLinkProgramARB(hNewProg);
|
||||
glAttachShader(hNewProg, hVert);
|
||||
glAttachShader(hNewProg, hFrag);
|
||||
glLinkProgram(hNewProg);
|
||||
// Delete vertex and fragment shader after we linked the program
|
||||
glDeleteObjectARB(hFrag);
|
||||
glDeleteObjectARB(hVert);
|
||||
glDeleteShader(hFrag);
|
||||
glDeleteShader(hVert);
|
||||
|
||||
// Link successful?
|
||||
DumpInfoLog(FormatString("%s shader program", szWhat).getData(), hNewProg);
|
||||
if(GetObjectStatus(hNewProg, GL_OBJECT_LINK_STATUS_ARB) != 1) {
|
||||
glDeleteObjectARB(hNewProg);
|
||||
DumpInfoLog(FormatString("%s shader program", szWhat).getData(), hNewProg, true);
|
||||
GLint status;
|
||||
glGetProgramiv(hNewProg, GL_LINK_STATUS, &status);
|
||||
if(status != GL_TRUE) {
|
||||
glDeleteProgram(hNewProg);
|
||||
ShaderLogF(" gl: Failed to link %s shader!", szWhat);
|
||||
return false;
|
||||
}
|
||||
ShaderLogF(" gl: %s shader linked successfully", szWhat);
|
||||
|
||||
// Everything successful, delete old shader
|
||||
if (hProg != 0) glDeleteObjectARB(hProg);
|
||||
if (hProg != 0) glDeleteProgram(hProg);
|
||||
hProg = hNewProg;
|
||||
|
||||
// Allocate uniform and attribute arrays
|
||||
|
@ -368,13 +371,13 @@ bool C4Shader::Init(const char *szWhat, const char **szUniforms, const char **sz
|
|||
// Get uniform and attribute locations. Note this is expected to fail for a few of them
|
||||
// because the respective uniforms got optimized out!
|
||||
for (int i = 0; i < iUniformCount; i++) {
|
||||
Uniforms[i].address = glGetUniformLocationARB(hProg, szUniforms[i]);
|
||||
Uniforms[i].address = glGetUniformLocation(hProg, szUniforms[i]);
|
||||
Uniforms[i].name = szUniforms[i];
|
||||
ShaderLogF("Uniform %s = %d", szUniforms[i], Uniforms[i].address);
|
||||
}
|
||||
|
||||
for (int i = 0; i < iAttributeCount; i++) {
|
||||
Attributes[i].address = glGetAttribLocationARB(hProg, szAttributes[i]);
|
||||
Attributes[i].address = glGetAttribLocation(hProg, szAttributes[i]);
|
||||
Attributes[i].name = szAttributes[i];
|
||||
ShaderLogF("Attribute %s = %d", szAttributes[i], Attributes[i].address);
|
||||
}
|
||||
|
@ -465,15 +468,15 @@ StdStrBuf C4Shader::Build(const ShaderSliceList &Slices, bool fDebug)
|
|||
StdStrBuf Buf;
|
||||
#ifndef USE_CONSOLE
|
||||
GLint iMaxFrags = 0, iMaxVerts = 0;
|
||||
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &iMaxFrags);
|
||||
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &iMaxVerts);
|
||||
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &iMaxFrags);
|
||||
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &iMaxVerts);
|
||||
#else
|
||||
int iMaxFrags = INT_MAX, iMaxVerts = INT_MAX;
|
||||
#endif
|
||||
Buf.Format("#version %d\n"
|
||||
"#define MAX_FRAGMENT_UNIFORM_COMPONENTS %d\n"
|
||||
"#define MAX_VERTEX_UNIFORM_COMPONENTS %d\n",
|
||||
C4Shader_Version, iMaxFrags, iMaxVerts);
|
||||
"#define MAX_FRAGMENT_UNIFORM_COMPONENTS %d\n"
|
||||
"#define MAX_VERTEX_UNIFORM_COMPONENTS %d\n",
|
||||
C4Shader_Version, iMaxFrags, iMaxVerts);
|
||||
|
||||
// Put slices
|
||||
int iPos = -1, iNextPos = -1;
|
||||
|
@ -516,56 +519,56 @@ StdStrBuf C4Shader::Build(const ShaderSliceList &Slices, bool fDebug)
|
|||
}
|
||||
|
||||
#ifndef USE_CONSOLE
|
||||
GLhandleARB C4Shader::Create(GLenum iShaderType, const char *szWhat, const char *szShader)
|
||||
GLuint C4Shader::Create(GLenum iShaderType, const char *szWhat, const char *szShader)
|
||||
{
|
||||
// Create shader
|
||||
GLhandleARB hShader = glCreateShaderObjectARB(iShaderType);
|
||||
GLuint hShader = glCreateShader(iShaderType);
|
||||
#ifdef GL_KHR_debug
|
||||
if (glObjectLabel)
|
||||
glObjectLabel(GL_SHADER, hShader, -1, szWhat);
|
||||
#endif
|
||||
|
||||
// Compile
|
||||
glShaderSourceARB(hShader, 1, &szShader, 0);
|
||||
glCompileShaderARB(hShader);
|
||||
glShaderSource(hShader, 1, &szShader, 0);
|
||||
glCompileShader(hShader);
|
||||
|
||||
// Dump any information to log
|
||||
DumpInfoLog(szWhat, hShader);
|
||||
DumpInfoLog(szWhat, hShader, false);
|
||||
|
||||
// Success?
|
||||
if(GetObjectStatus(hShader, GL_OBJECT_COMPILE_STATUS_ARB) == 1)
|
||||
int status;
|
||||
glGetShaderiv(hShader, GL_COMPILE_STATUS, &status);
|
||||
if (status == GL_TRUE)
|
||||
return hShader;
|
||||
|
||||
// Did not work :/
|
||||
glDeleteObjectARB(hShader);
|
||||
glDeleteShader(hShader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void C4Shader::DumpInfoLog(const char *szWhat, GLhandleARB hShader)
|
||||
void C4Shader::DumpInfoLog(const char *szWhat, GLuint hShader, bool forProgram)
|
||||
{
|
||||
// Get length of info line
|
||||
int iLength = 0;
|
||||
glGetObjectParameterivARB(hShader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &iLength);
|
||||
GLint iLength = 0;
|
||||
if (forProgram)
|
||||
glGetProgramiv(hShader, GL_INFO_LOG_LENGTH, &iLength);
|
||||
else
|
||||
glGetShaderiv(hShader, GL_INFO_LOG_LENGTH, &iLength);
|
||||
if(iLength <= 1) return;
|
||||
|
||||
// Allocate buffer, get data
|
||||
char *pBuf = new char [iLength + 1];
|
||||
std::vector<char> buf(iLength + 1);
|
||||
int iActualLength = 0;
|
||||
glGetInfoLogARB(hShader, iLength, &iActualLength, pBuf);
|
||||
if (forProgram)
|
||||
glGetProgramInfoLog(hShader, iLength, &iActualLength, &buf[0]);
|
||||
else
|
||||
glGetShaderInfoLog(hShader, iLength, &iActualLength, &buf[0]);
|
||||
if(iActualLength > iLength || iActualLength <= 0) return;
|
||||
|
||||
// Terminate, log
|
||||
pBuf[iActualLength] = '\0';
|
||||
buf[iActualLength] = '\0';
|
||||
ShaderLogF(" gl: Compiling %s:", szWhat);
|
||||
ShaderLog(pBuf);
|
||||
delete[] pBuf;
|
||||
}
|
||||
|
||||
int C4Shader::GetObjectStatus(GLhandleARB hObj, GLenum type)
|
||||
{
|
||||
int iStatus = 0;
|
||||
glGetObjectParameterivARB(hObj, type, &iStatus);
|
||||
return iStatus;
|
||||
ShaderLog(&buf[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -605,7 +608,7 @@ void C4ShaderCall::Start()
|
|||
const_cast<C4Shader *>(pShader)->Refresh();
|
||||
|
||||
// Activate shader
|
||||
glUseProgramObjectARB(pShader->hProg);
|
||||
glUseProgram(pShader->hProg);
|
||||
fStarted = true;
|
||||
}
|
||||
|
||||
|
@ -613,7 +616,7 @@ void C4ShaderCall::Finish()
|
|||
{
|
||||
// Remove shader
|
||||
if (fStarted) {
|
||||
glUseProgramObjectARB(0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
iUnits = 0;
|
||||
|
|
|
@ -77,7 +77,7 @@ private:
|
|||
|
||||
#ifndef USE_CONSOLE
|
||||
// shaders
|
||||
GLhandleARB hProg;
|
||||
GLuint hProg;
|
||||
// shader variables
|
||||
struct Variable { int address; const char* name; };
|
||||
std::vector<Variable> Uniforms;
|
||||
|
@ -151,9 +151,8 @@ private:
|
|||
StdStrBuf Build(const ShaderSliceList &Slices, bool fDebug = false);
|
||||
|
||||
#ifndef USE_CONSOLE
|
||||
GLhandleARB Create(GLenum iShaderType, const char *szWhat, const char *szShader);
|
||||
void DumpInfoLog(const char *szWhat, GLhandleARB hShader);
|
||||
int GetObjectStatus(GLhandleARB hObj, GLenum type);
|
||||
GLuint Create(GLenum iShaderType, const char *szWhat, const char *szShader);
|
||||
void DumpInfoLog(const char *szWhat, GLuint hShader, bool forProgram);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
@ -186,35 +185,35 @@ public:
|
|||
// something could be done about it.
|
||||
void SetUniform1i(int iUniform, int iX) const {
|
||||
if (pShader->HaveUniform(iUniform))
|
||||
glUniform1iARB(pShader->GetUniform(iUniform), iX);
|
||||
glUniform1i(pShader->GetUniform(iUniform), iX);
|
||||
}
|
||||
void SetUniform1f(int iUniform, float gX) const {
|
||||
if (pShader->HaveUniform(iUniform))
|
||||
glUniform1fARB(pShader->GetUniform(iUniform), gX);
|
||||
glUniform1f(pShader->GetUniform(iUniform), gX);
|
||||
}
|
||||
void SetUniform2f(int iUniform, float gX, float gY) const {
|
||||
if (pShader->HaveUniform(iUniform))
|
||||
glUniform2fARB(pShader->GetUniform(iUniform), gX, gY);
|
||||
glUniform2f(pShader->GetUniform(iUniform), gX, gY);
|
||||
}
|
||||
void SetUniform1iv(int iUniform, int iLength, const int *pVals) const {
|
||||
if (pShader->HaveUniform(iUniform))
|
||||
glUniform1ivARB(pShader->GetUniform(iUniform), iLength, pVals);
|
||||
glUniform1iv(pShader->GetUniform(iUniform), iLength, pVals);
|
||||
}
|
||||
void SetUniform1fv(int iUniform, int iLength, const float *pVals) const {
|
||||
if (pShader->HaveUniform(iUniform))
|
||||
glUniform1fvARB(pShader->GetUniform(iUniform), iLength, pVals);
|
||||
glUniform1fv(pShader->GetUniform(iUniform), iLength, pVals);
|
||||
}
|
||||
void SetUniform2fv(int iUniform, int iLength, const float *pVals) const {
|
||||
if (pShader->HaveUniform(iUniform))
|
||||
glUniform2fvARB(pShader->GetUniform(iUniform), iLength, pVals);
|
||||
glUniform2fv(pShader->GetUniform(iUniform), iLength, pVals);
|
||||
}
|
||||
void SetUniform3fv(int iUniform, int iLength, const float *pVals) const {
|
||||
if (pShader->HaveUniform(iUniform))
|
||||
glUniform3fvARB(pShader->GetUniform(iUniform), iLength, pVals);
|
||||
glUniform3fv(pShader->GetUniform(iUniform), iLength, pVals);
|
||||
}
|
||||
void SetUniform4fv(int iUniform, int iLength, const float *pVals) const {
|
||||
if (pShader->HaveUniform(iUniform))
|
||||
glUniform4fvARB(pShader->GetUniform(iUniform), iLength, pVals);
|
||||
glUniform4fv(pShader->GetUniform(iUniform), iLength, pVals);
|
||||
}
|
||||
|
||||
// Matrices are in row-major order
|
||||
|
@ -235,7 +234,7 @@ public:
|
|||
|
||||
void SetUniformMatrix4x4fv(int iUniform, int iLength, const float* pVals) const {
|
||||
if (pShader->HaveUniform(iUniform))
|
||||
glUniformMatrix4fvARB(pShader->GetUniform(iUniform), iLength, GL_TRUE, pVals);
|
||||
glUniformMatrix4fv(pShader->GetUniform(iUniform), iLength, GL_TRUE, pVals);
|
||||
}
|
||||
|
||||
void SetUniformMatrix3x3(int iUniform, const StdMeshMatrix& matrix)
|
||||
|
@ -267,14 +266,14 @@ public:
|
|||
if (pShader->HaveUniform(iUniform))
|
||||
{
|
||||
const float mat[16] = { matrix(0, 0), matrix(1, 0), matrix(2, 0), 0.0f, matrix(0, 1), matrix(1, 1), matrix(2, 1), 0.0f, matrix(0, 2), matrix(1, 2), matrix(2, 2), 0.0f, matrix(0, 3), matrix(1, 3), matrix(2, 3), 1.0f };
|
||||
glUniformMatrix4fvARB(pShader->GetUniform(iUniform), 1, GL_FALSE, mat);
|
||||
glUniformMatrix4fv(pShader->GetUniform(iUniform), 1, GL_FALSE, mat);
|
||||
}
|
||||
}
|
||||
|
||||
void SetUniformMatrix4x4(int iUniform, const StdProjectionMatrix& matrix)
|
||||
{
|
||||
if (pShader->HaveUniform(iUniform))
|
||||
glUniformMatrix4fvARB(pShader->GetUniform(iUniform), 1, GL_TRUE, matrix.data());
|
||||
glUniformMatrix4fv(pShader->GetUniform(iUniform), 1, GL_TRUE, matrix.data());
|
||||
}
|
||||
|
||||
void Start();
|
||||
|
|
Loading…
Reference in New Issue