55 if (this->
glid != 0) {
56 glDeleteShader(this->
glid);
71 if (this->
glid != 0) {
72 glDeleteProgram(this->
glid);
88 status(
"Initialising shaders...");
109 cripter.
build(
GfxMan.isGL3(), vertexStringFinal, fragmentStringFinal);
125 vertexStringFinal.
clear();
126 fragmentStringFinal.
clear();
127 cripter.
build(
GfxMan.isGL3(), vertexStringFinal, fragmentStringFinal);
143 vertexStringFinal.
clear();
144 fragmentStringFinal.
clear();
145 cripter.
build(
GfxMan.isGL3(), vertexStringFinal, fragmentStringFinal);
157 vertexStringFinal.
clear();
158 fragmentStringFinal.
clear();
159 cripter.
build(
GfxMan.isGL3(), vertexStringFinal, fragmentStringFinal);
166 status(
"Cleaning up shaders...");
176 if (iter->second->glid) {
177 glDeleteShader(iter->second->glid);
189 std::map<Common::UString, Shader::ShaderObject *>::iterator it =
_shaderObjectMap.find(name);
201 std::map<Common::UString, Shader::ShaderObject *>::iterator it =
_shaderObjectMap.find(name);
208 shaderObject->
type = type;
209 shaderObject->
glid = 0;
214 _shaderObjectMap.insert(std::pair<Common::UString, ShaderObject *>(name, shaderObject));
230 case SHADER_FLOAT: glUniform1fv(loc, var.
count, static_cast<const float *>(data));
break;
231 case SHADER_VEC2: glUniform2fv(loc, var.
count, static_cast<const float *>(data));
break;
232 case SHADER_VEC3: glUniform3fv(loc, var.
count, static_cast<const float *>(data));
break;
233 case SHADER_VEC4: glUniform4fv(loc, var.
count, static_cast<const float *>(data));
break;
234 case SHADER_INT: glUniform1iv(loc, var.
count, static_cast<const GLint *>(data));
break;
235 case SHADER_IVEC2: glUniform2iv(loc, var.
count, static_cast<const GLint *>(data));
break;
236 case SHADER_IVEC3: glUniform3iv(loc, var.
count, static_cast<const GLint *>(data));
break;
237 case SHADER_IVEC4: glUniform4iv(loc, var.
count, static_cast<const GLint *>(data));
break;
247 case SHADER_MAT2: glUniformMatrix2fv(loc, var.
count, 0, static_cast<const float *>(data));
break;
248 case SHADER_MAT3: glUniformMatrix3fv(loc, var.
count, 0, static_cast<const float *>(data));
break;
249 case SHADER_MAT4: glUniformMatrix4fv(loc, var.
count, 0, static_cast<const float *>(data));
break;
251 glUniform1i(loc, static_cast<const ShaderSampler *>(data)->unit);
252 glActiveTexture(GL_TEXTURE0 + static_cast<const ShaderSampler *>(data)->unit);
253 glBindTexture(GL_TEXTURE_1D, static_cast<const ShaderSampler *>(data)->handle.getTexture().getID());
256 glUniform1i(loc, static_cast<const ShaderSampler *>(data)->unit);
257 glActiveTexture(GL_TEXTURE0 + static_cast<const ShaderSampler *>(data)->unit);
258 glBindTexture(GL_TEXTURE_2D, static_cast<const ShaderSampler *>(data)->handle.getTexture().getID());
261 glUniform1i(loc, static_cast<const ShaderSampler *>(data)->unit);
262 glActiveTexture(GL_TEXTURE0 + static_cast<const ShaderSampler *>(data)->unit);
263 glBindTexture(GL_TEXTURE_3D, static_cast<const ShaderSampler *>(data)->handle.getTexture().getID());
266 glUniform1i(loc, static_cast<const ShaderSampler *>(data)->unit);
267 glActiveTexture(GL_TEXTURE0 + static_cast<const ShaderSampler *>(data)->unit);
268 glBindTexture(GL_TEXTURE_CUBE_MAP, static_cast<const ShaderSampler *>(data)->handle.getTexture().getID());
271 glUniform1i(loc, static_cast<const ShaderSampler *>(data)->unit);
272 glActiveTexture(GL_TEXTURE0 + static_cast<const ShaderSampler *>(data)->unit);
273 glBindTexture(GL_TEXTURE_1D_ARRAY, static_cast<const ShaderSampler *>(data)->handle.getTexture().getID());
276 glUniform1i(loc, static_cast<const ShaderSampler *>(data)->unit);
277 glActiveTexture(GL_TEXTURE0 + static_cast<const ShaderSampler *>(data)->unit);
278 glBindTexture(GL_TEXTURE_2D, static_cast<const ShaderSampler *>(data)->handle.getTexture().getID());
281 glUniform1i(loc, static_cast<const ShaderSampler *>(data)->unit);
282 glActiveTexture(GL_TEXTURE0 + static_cast<const ShaderSampler *>(data)->unit);
283 glBindTexture(GL_TEXTURE_1D_ARRAY, static_cast<const ShaderSampler *>(data)->handle.getTexture().getID());
286 glUniform1i(loc, static_cast<const ShaderSampler *>(data)->unit);
287 glActiveTexture(GL_TEXTURE0 + static_cast<const ShaderSampler *>(data)->unit);
288 glBindTexture(GL_TEXTURE_2D_ARRAY, static_cast<const ShaderSampler *>(data)->handle.getTexture().getID());
291 glUniform1i(loc, static_cast<const ShaderSampler *>(data)->unit);
292 glActiveTexture(GL_TEXTURE0 + static_cast<const ShaderSampler *>(data)->unit);
293 glBindTexture(GL_TEXTURE_1D_ARRAY, static_cast<const ShaderSampler *>(data)->handle.getTexture().getID());
296 glUniform1i(loc, static_cast<const ShaderSampler *>(data)->unit);
297 glActiveTexture(GL_TEXTURE0 + static_cast<const ShaderSampler *>(data)->unit);
298 glBindTexture(GL_TEXTURE_2D_ARRAY, static_cast<const ShaderSampler *>(data)->handle.getTexture().getID());
301 glUniform1i(loc, static_cast<const ShaderSampler *>(data)->unit);
302 glActiveTexture(GL_TEXTURE0 + static_cast<const ShaderSampler *>(data)->unit);
303 glBindTexture(GL_TEXTURE_BUFFER, static_cast<const ShaderSampler *>(data)->handle.getTexture().getID());
318 glBindBufferBase(GL_UNIFORM_BUFFER, static_cast<const ShaderUBO *>(data)->index, static_cast<const ShaderUBO *>(data)->glid);
325 glUseProgram(prog->
glid);
348 while (search_high >= search_low) {
351 search_low = search_high+1;
354 search_low = search_mid+1;
355 search_mid = (search_high + search_low) >> 1;
358 search_high = search_mid-1;
359 search_mid = (search_high + search_low) >> 1;
367 glAttachShader(progid, obj->
glid);
377 else if (vertexObject->
id == 0 || fragmentObject->
id == 0)
413 std::vector<ShaderObject *> shaderObjectStack;
414 std::map<Common::UString, uint32> shaderNameMap;
418 shaderObjectStack.push_back(obj->
subObjects[i]);
422 if (shaderNameMap.find(obj->
variablesSelf[i].name) == shaderNameMap.end()) {
423 shaderNameMap.insert(std::pair<Common::UString, uint32>(obj->
variablesSelf[i].name, i));
427 if (shaderObjectStack.size() > 0) {
428 obj = shaderObjectStack.back();
429 shaderObjectStack.pop_back();
435 vars.resize(vars.size());
442 std::string searchString = shaderString.
c_str();
443 std::string sword, snum;
444 std::string::size_type pos, posEnd;
445 std::string::size_type posi, posEndi;
446 unsigned int parseState = 0;
450 pos = searchString.find_first_not_of(
"\t\r\n\f\v ", 0);
451 posEnd = searchString.find_first_of(
"\t\r\n\f\v ", pos);
452 while (pos != std::string::npos && posEnd != std::string::npos) {
453 sword = searchString.substr(pos, posEnd - pos);
454 switch (parseState) {
456 if (sword.find(
"//") != std::string::npos) {
458 posEnd = searchString.find_first_of(
"\n", pos);
459 }
else if (sword.find(
"/*") != std::string::npos) {
461 posEnd = searchString.find(
"*/", pos);
462 if (posEnd != std::string::npos)
464 }
else if (sword ==
"uniform") {
468 pos = searchString.find_first_not_of(
"\t\r\n\f\v ", posEnd);
469 posEnd = searchString.find_first_of(
"\t\r\n\f\v ", pos);
498 pos = searchString.find_first_not_of(
"\t\r\n\f\v ", posEnd);
499 posEnd = searchString.find_first_of(
",;", pos);
504 posEndi = sword.length();
505 posi = sword.find(
'=');
506 if (posi != std::string::npos) {
507 sword.erase(posi, posEndi - posi);
511 posi = sword.find(
'[');
512 if (posi != std::string::npos) {
513 posEndi = sword.find(
']');
514 snum = sword.substr(posi+1, posEndi - posi - 1);
515 num = atoi(snum.c_str());
516 sword.erase(posi, sword.length() - posi);
519 sword.erase(sword.find_last_not_of(
"\t\r\n\f\v ")+1);
524 if (searchString.at(posEnd) ==
';') {
528 pos = searchString.find_first_not_of(
"\t\r\n\f\v ", posEnd);
529 posEnd = searchString.find_first_of(
"\t\r\n\f\v ", pos);
532 pos = searchString.find_first_not_of(
"\t\r\n\f\v ", posEnd);
533 posEnd = searchString.find_first_of(
"\t\r\n\v\f ,;", pos);
537 default: parseState = 0;
break;
541 varList.resize(varList.size());
545 if (object->
glid != 0) {
549 object->glid = glCreateShader(object->
type ==
SHADER_VERTEX ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);
550 const char *text =
object->shaderString.c_str();
551 glShaderSource(object->
glid, 1, (
const GLchar **)(&text), 0);
552 glCompileShader(object->
glid);
555 glGetShaderiv(object->
glid, GL_COMPILE_STATUS, &gl_status);
556 if (gl_status == GL_FALSE) {
559 glGetShaderInfoLog(object->
glid, 4095, &logolength, logorama);
560 error(
"Shader compile failure! Driver output: %s", logorama);
565 if (program->
glid != 0) {
569 GLuint glid = glCreateProgram();
584 glBindAttribLocation(glid, (GLuint)(
VERTEX_LOCATION),
"inputPosition0");
586 glBindAttribLocation(glid, (GLuint)(
VERTEX_NORMAL),
"inputNormal0");
588 glBindAttribLocation(glid, (GLuint)(
VERTEX_COLOR),
"inputColour");
594 glGetProgramiv(glid, GL_LINK_STATUS, &linkStatus);
595 if (linkStatus == GL_FALSE) {
598 glGetProgramInfoLog(glid, 4095, &logolength, logorama);
599 error(
"Shader link failure! Driver output: %s", logorama);
601 glDeleteProgram(glid);
606 program->
glid = glid;
611 location = glGetUniformLocation(glid, vertexObject->
variablesCombined[i].name.c_str());
613 location = glGetUniformBlockIndex(glid, vertexObject->
variablesCombined[i].name.c_str());
620 location = glGetUniformLocation(glid, fragmentObject->
variablesCombined[i].name.c_str());
622 location = glGetUniformBlockIndex(glid, fragmentObject->
variablesCombined[i].name.c_str());
629 ubo_index = glGetUniformBlockIndex(glid,
"engine_ubo_view");
630 if (ubo_index != GL_INVALID_INDEX) {
633 ubo_index = glGetUniformBlockIndex(glid,
"engine_ubo_screen");
634 if (ubo_index != GL_INVALID_INDEX) {
637 ubo_index = glGetUniformBlockIndex(glid,
"boneBlock");
638 if (ubo_index != GL_INVALID_INDEX) {
683 "sampler1DArrayShadow",
684 "sampler2DArrayShadow",
698 "uniformBufferInvalid" void parseShaderVariables(const Common::UString &shaderString, std::vector< ShaderObject::ShaderObjectVariable > &variableList)
Parses a given string, representing a GLSL shader, and extracts uniform variable information from it...
void build(bool isGL3, Common::UString &v_string, Common::UString &f_string)
ShaderProgram * getShaderProgram(ShaderObject *vertexObject, ShaderObject *fragmentObject)
The global graphics manager.
A class holding an UTF-8 string.
std::vector< ShaderObject::ShaderObjectVariable > variablesSelf
ShaderProgram * registerShaderProgram(ShaderObject *vertexObject, ShaderObject *fragmentObject)
void declareSampler(ShaderDescriptor::Sampler sampler, ShaderDescriptor::SamplerType type)
Common::UString shaderString
void bindShaderVariable(ShaderObject::ShaderObjectVariable &var, GLint loc, const void *data)
Common::Mutex _programMutex
void connect(ShaderDescriptor::Sampler sampler, ShaderDescriptor::Input input, ShaderDescriptor::Action action)
Connect an input to a sampler and an action.
ShaderObject * fragmentObject
ShaderObject * getShaderObject(const Common::UString &name, ShaderType type)
const char * c_str() const
Return the (utf8 encoded) string data.
void clear()
Clear shader descriptor information.
The global shader manager.
ShaderVariableType shaderstringToEnum(const Common::UString &stype)
Utility templates and functions.
ShaderVariableType
Enum of all supported shader variable parsing and automatic binding.
#define DECLARE_SINGLETON(T)
Note that you need to use this macro from the global namespace.
void genGLShader(ShaderObject *object)
Generate GL ids for, and compile a shader object.
Not really blending, but component-wise multiply.
std::vector< GLint > fragmentVariableLocations
void declareUniform(ShaderDescriptor::Uniform uniform)
ShaderObject * vertexObject
std::vector< Shader::ShaderProgram * > _shaderProgramArray
void deinit()
Deinitialise shader subsystem.
void registerShaderAttachment(GLuint progid, ShaderObject *obj)
Recursively attaches shader objects to a given program.
void genShaderVariableList(ShaderObject *obj, std::vector< ShaderObject::ShaderObjectVariable > &vars)
Same as INPUT_UV0, but specifies input matrix too.
std::vector< ShaderObject * > subObjects
void genGLProgram(ShaderProgram *program)
Generate GL id for, and link, a shader program.
Uniform variable colour information.
A texture as used in the Aurora engines.
void init()
Initialise shader management, including default shader set creation.
#define ShaderMan
Shortcut for accessing the shader manager.
std::map< Common::UString, Shader::ShaderObject * > _shaderObjectMap
void status(const char *s,...)
std::vector< GLint > vertexVariableLocations
void addPass(ShaderDescriptor::Action action, ShaderDescriptor::Blend blend)
A container of OpenGL elements.
static const char * shaderTypeChararray[]
void declareInput(ShaderDescriptor::Input input)
void bindShaderInstance(ShaderProgram *program, const void **vertexVariables, const void **fragmentVariables)
void NORETURN_PRE error(const char *s,...)
void clear()
Clear the string's contents.
Common::Mutex _shaderMutex
#define GfxMan
Shortcut for accessing the graphics manager.
std::vector< ShaderObject::ShaderObjectVariable > variablesCombined
Per-vertex colour information.