summaryrefslogtreecommitdiff
path: root/source/modules/asura-core/graphics/shader.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-04-02 21:45:33 +0800
committerchai <chaifix@163.com>2019-04-02 21:45:33 +0800
commitaf7bdaa10ee71a319dc55c3c7556fa43a95c9dc9 (patch)
tree58611985001b78c5a76b78ae146fdb07dde31c1d /source/modules/asura-core/graphics/shader.cpp
parent250e30d73f09e9da2b5a81d0fbae63744ae12a73 (diff)
*misc
Diffstat (limited to 'source/modules/asura-core/graphics/shader.cpp')
-rw-r--r--source/modules/asura-core/graphics/shader.cpp136
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