10 #include <ThirdParty/glm/glm/gtc/type_ptr.hpp> 18 bool CompileShader(GLuint* shader, GLenum type,
const GLchar* source)
28 *shader = glCreateShader(type);
29 glShaderSource(*shader, 1, &source,
nullptr);
31 glCompileShader(*shader);
34 glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
37 GLchar *log =
static_cast<GLchar *
>(malloc(logLength));
38 glGetShaderInfoLog(*shader, logLength, &logLength, log);
39 eastl::string logInfo = log;
40 debug_info(
"OpenGLShader",
"CompileShader", eastl::string(
"Shader compile log: \n " + logInfo));
44 glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
47 glDeleteShader(*shader);
59 bool LinkProgram(GLuint prog)
66 glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
69 GLchar *log =
static_cast<GLchar *
>(malloc(logLength));
70 glGetProgramInfoLog(prog, logLength, &logLength, log);
71 eastl::string logInfo = log;
72 debug_info(
"OpenGLShader",
"LinkProgram", eastl::string(
"Program link log: \n " + logInfo));
76 glGetProgramiv(prog, GL_LINK_STATUS, &status);
86 bool ValidateProgram(GLuint prog)
91 glValidateProgram(prog);
92 glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
95 GLchar *log =
static_cast<GLchar *
>(malloc(logLength));
96 glGetProgramInfoLog(prog, logLength, &logLength, log);
101 glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
115 void ShaderParameter::SetValue(
float val)
const 121 assert(_type == GL_FLOAT);
122 glUniform1f(_location, val);
126 void ShaderParameter::SetValue(
int val)
const 131 assert(_type == GL_INT);
132 glUniform1i(_location, val);
136 void ShaderParameter::SetValue(
bool val)
const 141 assert(_type == GL_BOOL);
142 glUniform1i(_location, val);
146 void ShaderParameter::SetValue(
const glm::vec2& vec)
const 151 assert(_type == GL_FLOAT_VEC2);
152 glUniform2fv(_location, 1, &vec.x);
156 void ShaderParameter::SetValue(
const glm::vec3& vec)
const 161 assert(_type == GL_FLOAT_VEC3);
162 glUniform3fv(_location, 1, glm::value_ptr(vec));
166 void ShaderParameter::SetValue(
const glm::vec4& vec)
const 171 assert(_type == GL_FLOAT_VEC4);
172 glUniform4fv(_location, 1, &vec.x);
176 void ShaderParameter::SetValue(
const glm::mat4x4& mtx,
bool transpose)
const 181 assert(_type == GL_FLOAT_MAT4);
182 glUniformMatrix4fv(_location, 1, transpose, glm::value_ptr(mtx));
186 void ShaderParameter::SetValue(Texture &texture_)
const 191 assert(_type == GL_SAMPLER_2D);
193 glActiveTexture(GL_TEXTURE0 + _sampler);
196 glBindTexture(GL_TEXTURE_2D, GLuint(texture_.GetTexture()));
199 glUniform1i(_location, _sampler);
209 void ShaderAttribute::SetAttributePointer(GLint size,
211 GLboolean normalized,
213 const GLvoid *pointer)
const 218 glVertexAttribPointer(
228 glEnableVertexAttribArray(_location);
232 void ShaderAttribute::DisableAttributePointer()
const 237 glDisableVertexAttribArray(_location);
247 GLuint LoadShader(eastl::string filePath,
int shaderType)
250 CompileShader(&shader, shaderType, reinterpret_cast<char const *const>(
Utility::ReadFile(filePath, std::ios::binary).data()));
254 OpenGLShader::OpenGLShader(
const eastl::string& vertexFileName,
const eastl::string& fragmentFileName) :
255 OpenGLShader(vertexFileName, fragmentFileName,
"")
258 OpenGLShader::OpenGLShader(
const eastl::string& vertexFileName,
259 const eastl::string& fragmentFileName,
260 const eastl::string& geometryFileName)
262 if (!LoadSource(vertexFileName, fragmentFileName, geometryFileName))
266 bool OpenGLShader::LoadSource(
const eastl::string& vertexShader,
const eastl::string& fragmentShader,
267 const eastl::string& geometryShader)
269 program = glCreateProgram();
271 eastl::string shaderPath =
"Resources/Shaders/";
272 GLuint vertShader = LoadShader(shaderPath + vertexShader, GL_VERTEX_SHADER);
273 GLuint fragShader = LoadShader(shaderPath + fragmentShader, GL_FRAGMENT_SHADER);
274 GLuint geomShader = 0;
276 if (geometryShader.length() > 0)
277 geomShader = LoadShader(shaderPath + geometryShader, GL_GEOMETRY_SHADER);
280 glAttachShader(program, vertShader);
285 glAttachShader(program, geomShader);
288 glAttachShader(program, fragShader);
292 if (!LinkProgram(program))
296 glDeleteShader(vertShader);
301 glDeleteShader(fragShader);
306 glDeleteShader(geomShader);
311 glDeleteProgram(program);
324 glDeleteShader(vertShader);
327 glDeleteShader(geomShader);
330 glDeleteShader(fragShader);
338 eastl::weak_ptr<ShaderParameter> OpenGLShader::GetParameter(
const eastl::string& name)
341 auto itr = parameters.find(name);
342 if (itr != parameters.end())
347 parameters[name] = eastl::shared_ptr<ShaderParameter>();
348 return parameters[name];
351 eastl::weak_ptr<ShaderAttribute> OpenGLShader::GetAttribute(
const eastl::string& name)
354 auto itr = attributes.find(name);
355 if (itr != attributes.end())
360 attributes[name] = eastl::shared_ptr<ShaderAttribute>();
361 return attributes[name];
364 GLuint OpenGLShader::GetProgram()
const 369 void OpenGLShader::Activate()
371 glUseProgram(program);
375 void OpenGLShader::Deactivate()
377 for (
auto& a : attributes)
378 a.second->DisableAttributePointer();
381 void OpenGLShader::LoadParameters()
385 for (
auto& itr : parameters)
386 itr.second->Invalidate();
389 GLint numActiveUniforms = 0;
390 glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numActiveUniforms);
394 GLint maxUniformNameLength = 0;
395 glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformNameLength);
396 eastl::vector<GLchar> uniformNameData(maxUniformNameLength);
399 int samplerCount = 0;
400 for (
int uniform = 0; uniform < numActiveUniforms; uniform++)
404 GLsizei actualLength = 0;
408 maxUniformNameLength,
412 &uniformNameData[0]);
413 eastl::string name(&uniformNameData[0], actualLength);
414 GLint location = glGetUniformLocation(program, name.c_str());
416 auto itr = parameters.find(name);
417 if (itr != parameters.end())
419 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE)
420 itr->second->Reset(
this, name, type, location, samplerCount++);
422 itr->second->Reset(
this, name, type, location);
426 eastl::shared_ptr<ShaderParameter> param;
427 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE)
428 param = eastl::shared_ptr<ShaderParameter>(
new ShaderParameter(
this, name, type, location, samplerCount++));
430 param = eastl::shared_ptr<ShaderParameter>(
new ShaderParameter(
this, name, type, location));
431 parameters[name] = param;
436 GLint numActiveAttribs = 0;
437 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numActiveAttribs);
440 GLint maxAttribNameLength = 0;
441 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttribNameLength);
442 eastl::vector<GLchar> attribNameData(maxAttribNameLength);
445 for (
int attrib = 0; attrib < numActiveAttribs; ++attrib)
449 GLsizei actualLength = 0;
450 glGetActiveAttrib(program,
452 GLsizei(attribNameData.size()),
457 eastl::string name(static_cast<char*>(&attribNameData[0]));
458 GLint location = glGetAttribLocation(program, name.c_str());
460 auto itr = attributes.find(name);
461 if (itr != attributes.end())
463 itr->second->Reset(
this, name, type, location);
467 attributes[name] = eastl::shared_ptr<ShaderAttribute>(
new ShaderAttribute(
this, name, type, location));
472 bool OpenGLShader::Validate()
const 474 if (!ValidateProgram(program))
#define debug_info(debug_class, function, value)
This functions logs a debug info to the log and console. Use this for useless information.
static eastl::vector< char > ReadFile(const eastl::string &fileName, int fileOpenMode=1)