diff options
author | chai <chaifix@163.com> | 2019-04-02 21:45:33 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-04-02 21:45:33 +0800 |
commit | af7bdaa10ee71a319dc55c3c7556fa43a95c9dc9 (patch) | |
tree | 58611985001b78c5a76b78ae146fdb07dde31c1d /source/modules/asura-core/graphics/shader.cpp | |
parent | 250e30d73f09e9da2b5a81d0fbae63744ae12a73 (diff) |
*misc
Diffstat (limited to 'source/modules/asura-core/graphics/shader.cpp')
-rw-r--r-- | source/modules/asura-core/graphics/shader.cpp | 136 |
1 files changed, 124 insertions, 12 deletions
diff --git a/source/modules/asura-core/graphics/shader.cpp b/source/modules/asura-core/graphics/shader.cpp index f33fd1a..a4738cd 100644 --- a/source/modules/asura-core/graphics/shader.cpp +++ b/source/modules/asura-core/graphics/shader.cpp @@ -1,4 +1,9 @@ -#include "Shader.h" +#include <asura-utils/exceptions/exception.h> + +#include "shader_source.h" +#include "shader.h" + +using namespace std; namespace AsuraEngine { @@ -7,17 +12,76 @@ namespace AsuraEngine Shader::Shader() { - + mProgram = glCreateProgram(); + if (mProgram == 0) + throw Exception("Cannot create OpenGL shader program."); + + mVertShader = glCreateShader(GL_VERTEX_SHADER); + if (mVertShader == 0) + { + glDeleteProgram(mProgram); + throw Exception("Cannot create OpenGL vertex shader."); + } + + mFragShader = glCreateShader(GL_FRAGMENT_SHADER); + if (mFragShader == 0) + { + glDeleteProgram(mProgram); + glDeleteShader(mVertShader); + throw Exception("Cannot create OpenGL fragment shader."); + } } Shader::~Shader() { - + glDeleteShader(mVertShader); + glDeleteShader(mFragShader); + glDeleteProgram(mProgram); } - bool Shader::Refresh(AEIO::DecodedData* db) + bool Shader::Renew(AEIO::DecodedData* db) { - return false; + if (!db) return false; + ShaderSouce* shaderSource = static_cast<ShaderSouce*>(db); + if (!shaderSource) return false; + + GLenum err = GL_NO_ERROR; + const GLchar* source; + GLint success; + string warnning = ""; + + // Compile vertex shader. + source = shaderSource->mVert.c_str(); + glShaderSource(mVertShader, 1, &source, NULL); + glCompileShader(mVertShader); + glGetShaderiv(mVertShader, GL_COMPILE_STATUS, &success); + if (success == GL_FALSE) + { + warnning = GetShaderWarnings(mVertShader); + throw Exception("Compile vertex shader failed:\n%s", warnning.c_str()); + } + + // Compile fragment shader. + source = shaderSource->mFrag.c_str(); + glShaderSource(mFragShader, 1, &source, NULL); + glCompileShader(mFragShader); + glGetShaderiv(mFragShader, GL_COMPILE_STATUS, &success); + if (success == GL_FALSE) + { + warnning = GetShaderWarnings(mFragShader); + throw Exception("Compile fragment shader failed:\n%s", warnning.c_str()); + } + + // Link program. + glAttachShader(mProgram, mVertShader); + glAttachShader(mProgram, mFragShader); + glLinkProgram(mProgram); + glGetProgramiv(mProgram, GL_LINK_STATUS, &success); + if (success == GL_FALSE) + { + warnning = GetProgramWarnings(); + throw Exception("Link shader program failed:\n%s", warnning.c_str()); + } } uint Shader::GetUniformLocation(const std::string& uniform) @@ -32,37 +96,45 @@ namespace AsuraEngine void Shader::Use() { - + if (mProgram != 0) + { + gl.UseShader(this); + } } void Shader::Unuse() { - + gl.UnuseShader(); } void Shader::SetUniformFloat(uint loc, float value) { - + if(gl.state.shader == this) + glUniform1f(loc, value); } void Shader::SetUniformTexture(uint loc, const Texture& texture) { - + if (gl.state.shader == this) + glUniform1i(loc, texture.GetGLTextureHandle()); } void Shader::SetUniformVector2(uint loc, const Math::Vector2f& vec2) { - + if (gl.state.shader == this) + glUniform2f(loc, vec2.x, vec2.y); } void Shader::SetUniformVector3(uint loc, const Math::Vector3f& vec3) { - + if (gl.state.shader == this) + glUniform3f(loc, vec3.x, vec3.y, vec3.z); } void Shader::SetUniformVector4(uint loc, const Math::Vector4f& vec4) { - + if (gl.state.shader == this) + glUniform4f(loc, vec4.x, vec4.y, vec4.z, vec4.w); } uint Shader::GetGLTextureUnitCount() @@ -72,5 +144,45 @@ namespace AsuraEngine return (uint)maxTextureUnits; } + std::string Shader::GetProgramWarnings() + { + GLint strsize, nullpos; + glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &strsize); + + if (strsize == 0) + return ""; + + char *tempstr = new char[strsize]; + + memset(tempstr, '\0', strsize); + glGetProgramInfoLog(mProgram, strsize, &nullpos, tempstr); + tempstr[nullpos] = '\0'; + + std::string warnings(tempstr); + delete[] tempstr; + + return warnings; + } + + std::string Shader::GetShaderWarnings(GLuint shader) + { + GLint strsize, nullpos; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &strsize); + + if (strsize == 0) + return ""; + + char *tempstr = new char[strsize]; + + memset(tempstr, '\0', strsize); + glGetShaderInfoLog(shader, strsize, &nullpos, tempstr); + tempstr[nullpos] = '\0'; + + std::string warnings(tempstr); + delete[] tempstr; + + return warnings; + } + } }
\ No newline at end of file |