ultimatepp/rainbow/CoreGl/Shaders.cpp
cxl f0e42f8693 reorganizing repo
git-svn-id: svn://ultimatepp.org/upp/trunk@9214 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2015-11-22 19:53:58 +00:00

387 lines
No EOL
7.5 KiB
C++

#if defined(flagWINGL) || defined(flagLINUXGL)
#include "Shaders.h"
NAMESPACE_UPP
void Shader::PrintShaderInfoLog(GLuint obj, const char* fileName)
{
int infoLength = 0;
int charsWritten = 0;
glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infoLength);
if(infoLength > 0)
{
char* info = new char[infoLength];
glGetShaderInfoLog(obj, infoLength, &charsWritten, info);
if(charsWritten > 0)
{
compileError = info;
FileOut f(fileName);
f.Put(info);
}
delete[] info;
}
}
void Shader::PrintProgramInfoLog(GLuint obj, const char* fileName)
{
int infoLength = 0;
int charsWritten = 0;
glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &infoLength);
if(infoLength > 0)
{
char* info = new char[infoLength];
glGetShaderInfoLog(obj, infoLength, &charsWritten, info);
if(charsWritten > 0)
{
FileOut f(fileName);
f.Put(info);
}
delete[] info;
}
}
void Shader::PrintProgramValidationLog(GLuint obj, const char* fileName)
{
char log[1024];
int len = 0;
glValidateProgram(obj);
glGetProgramInfoLog(obj, 1024, &len, log);
if(len > 0)
{
FileOut f(fileName);
f.Put(log);
}
}
bool Shader::CheckGLError()
{
unsigned int lastError = glGetError();
if(GL_NO_ERROR != lastError)
{
error = (const char*) gluErrorString(lastError);
return false;
}
return true;
}
bool Shader::IsProgramCompiled(int program)
{
GLint result = GL_FALSE;
glGetShaderiv(program, GL_COMPILE_STATUS, &result);
return result == GL_TRUE;
}
bool Shader::IsProgramLinked(int program)
{
GLint result = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &result);
return result == GL_TRUE;
}
int Shader::CompileProgram(const char* vs, const char* fs, const char* gs)
{
vertSrc = vs;
fragSrc = fs;
geomSrc = gs;
const GLchar* vertexShaderSrc = (const GLchar*) vertSrc;
const GLchar* fragmentShaderSrc = (const GLchar*) fragSrc;
const GLchar* geometryShaderSrc = (const GLchar*) geomSrc;
DeleteFile("shader_vertex.log");
DeleteFile("shader_fragment.log");
DeleteFile("shader_geometry.log");
DeleteFile("shader_link.log");
DeleteFile("shader_validation.log");
GLenum vertexShader = 0;
GLenum fragmentShader = 0;
GLenum geometryShader = 0;
if(!vertSrc.IsEmpty())
{
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSrc, NULL);
glCompileShader(vertexShader);
if(!IsProgramCompiled(vertexShader))
{
PrintShaderInfoLog(vertexShader, "shader_vertex.log");
error = "Vertex shader compilation error:\n\n" + compileError;
glDeleteShader(vertexShader);
return -1;
}
}
if(!fragSrc.IsEmpty())
{
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSrc, NULL);
glCompileShader(fragmentShader);
if(!IsProgramCompiled(fragmentShader))
{
PrintShaderInfoLog(fragmentShader, "shader_fragment.log");
error = "Fragment shader compilation error:\n\n" + compileError;
glDeleteShader(fragmentShader);
return -1;
}
}
if(!geomSrc.IsEmpty())
{
geometryShader = glCreateShader(GL_GEOMETRY_SHADER);
glShaderSource(geometryShader, 1, &geometryShaderSrc, NULL);
glCompileShader(geometryShader);
if(!IsProgramCompiled(geometryShader))
{
PrintShaderInfoLog(geometryShader, "shader_geometry.log");
error = "Geometry shader compilation error:\n\n" + compileError;
glDeleteShader(geometryShader);
return -1;
}
}
program = glCreateProgram();
if(program > 0)
{
if(vertexShader > 0)
glAttachShader(program, vertexShader);
if(fragmentShader > 0)
glAttachShader(program, fragmentShader);
if(geometryShader > 0)
glAttachShader(program, geometryShader);
glLinkProgram(program);
if(!IsProgramLinked(program))
{
PrintProgramInfoLog(program, "shader_link.log");
PrintProgramValidationLog(program, "shader_validation.log");
glDeleteProgram(program);
program = -1;
}
}
else
program = -1;
return program;
}
int Shader::CompileProgram(const byte* vs, const byte* fs, const byte* gs)
{
return CompileProgram((const char*) vs, (const char*) fs, (const char*) gs);
}
int Shader::GetProgram()
{
return program;
}
String Shader::GetError()
{
return error;
}
int Shader::GetUniformId(const char* var)
{
int n = uniforms.Find(var);
if(n < 0)
{
int id = glGetUniformLocation(program, var);
CheckGLError();
if(id >= 0)
uniforms.Add(var, id);
return id;
}
else
return uniforms[n];
}
int Shader::GetAttributeId(const char* var)
{
int n = attributes.Find(var);
if(n < 0)
{
int id = glGetAttribLocation(program, var);
CheckGLError();
if(id >= 0)
attributes.Add(var, id);
return id;
}
else
return attributes[n];
}
void Shader::SetUniform(const char* var, float v)
{
int id = GetUniformId(var);
if(id >= 0)
glUniform1f(id, v);
}
void Shader::SetUniform(const char* var, bool v)
{
int id = GetUniformId(var);
if(id >= 0)
glUniform1i(id, int(v));
}
void Shader::SetUniform(const char* var, int v)
{
int id = GetUniformId(var);
if(id >= 0)
glUniform1i(id, v);
}
void Shader::SetUniform(const char* var, float v0, float v1)
{
int id = GetUniformId(var);
if(id >= 0)
glUniform2f(id, v0, v1);
}
void Shader::SetUniform(const char* var, float v0, float v1, float v2)
{
int id = GetUniformId(var);
if(id >= 0)
glUniform3f(id, v0, v1, v2);
}
void Shader::SetUniform(const char* var, float v0, float v1, float v2, float v3)
{
int id = GetUniformId(var);
if(id >= 0)
glUniform4f(id, v0, v1, v2, v3);
}
void Shader::SetUniform(const char* var, float* v, int size, int count)
{
int id = GetUniformId(var);
if(id >= 0)
{
if(size == 2)
glUniform2fv(id, count, v);
else if(size == 3)
glUniform3fv(id, count, v);
else if(size == 4)
glUniform4fv(id, count, v);
else if(size == 16)
glUniformMatrix4fv(id, count, GL_FALSE, v);
}
}
void Shader::SetMatrixUniform(const char* var, float* v, int size, int count)
{
int id = GetUniformId(var);
if(id >= 0)
{
if(size == 2)
glUniform2fv(id, count, v);
else if(size == 3)
glUniform3fv(id, count, v);
else if(size == 4)
glUniform4fv(id, count, v);
else if(size == 16)
glUniformMatrix4fv(id, count, GL_FALSE, v);
}
}
void Shader::EnableAttribute(const char* var, bool b)
{
int id = GetAttributeId(var);
if(id >= 0)
{
if(b)
glEnableVertexAttribArray(id);
else
glDisableVertexAttribArray(id);
}
}
void Shader::DisableAttribute(const char* var)
{
EnableAttribute(var, false);
}
void Shader::DisableAllAtrributes()
{
for(int i = 0; i < attributes.GetCount(); i++)
{
int id = attributes[i];
if(id >= 0)
glDisableVertexAttribArray(id);
}
}
void Shader::SetAttribute(const char* var, float v)
{
int id = GetAttributeId(var);
if(id >= 0)
glVertexAttrib1f(id, v);
}
void Shader::SetAttribute(const char* var, float v0, float v1)
{
int id = GetAttributeId(var);
if(id >= 0)
glVertexAttrib2f(id, v0, v1);
}
void Shader::SetAttribute(const char* var, float v0, float v1, float v2)
{
int id = GetAttributeId(var);
if(id >= 0)
glVertexAttrib3f(id, v0, v1, v2);
}
void Shader::SetAttribute(const char* var, float v0, float v1, float v2, float v3)
{
int id = GetAttributeId(var);
if(id >= 0)
glVertexAttrib4f(id, v0, v1, v2, v3);
}
void Shader::SetAttribute(const char* var, float* v, int size)
{
int id = GetAttributeId(var);
if(id >= 0)
{
if(size == 2)
glVertexAttrib2fv(id, v);
else if(size == 3)
glVertexAttrib3fv(id, v);
else if(size == 4)
glVertexAttrib4fv(id, v);
}
}
void Shader::Start()
{
glUseProgram(program);
CheckGLError();
}
void Shader::Stop()
{
glUseProgram(0);
}
void Shader::Release()
{
if(program >= 0)
glDeleteProgram(program);
}
Shader::Shader() : program(-1)
{}
END_UPP_NAMESPACE
#endif