00001
00002
00003
00004
00005 #pragma once
00006
00007 #include "../base/Setup.h"
00008
00009 #ifdef MPMA_COMPILE_GFX
00010
00011 #include "../base/Types.h"
00012 #include "../base/ReferenceCount.h"
00013 #include "../base/File.h"
00014 #include "../gfxsetup/GL.h"
00015 #include "../gfxsetup/Extensions.h"
00016 #include <string>
00017 #include <vector>
00018
00019 #ifdef MPMA_COMPILE_GEO
00020 #include "../geo/Geo.h"
00021 #endif
00022
00023 namespace GFX
00024 {
00026 class UniformVariable
00027 {
00028 public:
00030 inline operator GLint() const { return location; }
00031
00033 inline bool Exists() const { return location!=-1; }
00034
00035 inline void SetFloat1(float f0) { glUniform1fARB(*this, f0); }
00036 inline void SetFloat2(float f0, float f1) { glUniform2fARB(*this, f0, f1); }
00037 inline void SetFloat3(float f0, float f1, float f2) { glUniform3fARB(*this, f0, f1, f2); }
00038 inline void SetFloat4(float f0, float f1, float f2, float f3) { glUniform4fARB(*this, f0, f1, f2, f3); }
00039
00040 inline void SetFloat1(const float *f, GLsizei arrayCount=1) { glUniform1fvARB(*this, arrayCount, f); }
00041 inline void SetFloat2(const float *f, GLsizei arrayCount=1) { glUniform2fvARB(*this, arrayCount, f); }
00042 inline void SetFloat3(const float *f, GLsizei arrayCount=1) { glUniform3fvARB(*this, arrayCount, f); }
00043 inline void SetFloat4(const float *f, GLsizei arrayCount=1) { glUniform4fvARB(*this, arrayCount, f); }
00044
00045 inline void SetInt1(int i0) { glUniform1iARB(*this, i0); }
00046 inline void SetInt2(int i0, int i1) { glUniform2iARB(*this, i0, i1); }
00047 inline void SetInt3(int i0, int i1, int i2) { glUniform3iARB(*this, i0, i1, i2); }
00048 inline void SetInt4(int i0, int i1, int i2, int i3) { glUniform4iARB(*this, i0, i1, i2, i3); }
00049
00050 inline void SetInt1(const int *i, GLsizei arrayCount=1) { glUniform1ivARB(*this, arrayCount, i); }
00051 inline void SetInt2(const int *i, GLsizei arrayCount=1) { glUniform2ivARB(*this, arrayCount, i); }
00052 inline void SetInt3(const int *i, GLsizei arrayCount=1) { glUniform3ivARB(*this, arrayCount, i); }
00053 inline void SetInt4(const int *i, GLsizei arrayCount=1) { glUniform4ivARB(*this, arrayCount, i); }
00054
00055 inline void SetMatrix2x2(const float *m, bool transpose=false, GLsizei arrayCount=1) { glUniformMatrix2fvARB(*this, arrayCount, transpose, m); }
00056
00057
00058
00059 inline void SetMatrix3x3(const float *m, bool transpose=false, GLsizei arrayCount=1) { glUniformMatrix3fvARB(*this, arrayCount, transpose, m); }
00060
00061
00062
00063 inline void SetMatrix4x4(const float *m, bool transpose=false, GLsizei arrayCount=1) { glUniformMatrix4fvARB(*this, arrayCount, transpose, m); }
00064
00066 inline void SetTextureStage(int stage) { SetInt1(stage); }
00067
00068 #ifdef MPMA_COMPILE_GEO
00069 inline void SetVector2(const GEO::Vector2 &v) { SetFloat2(&v[0]); }
00070 inline void SetVector3(const GEO::Vector3 &v) { SetFloat3(&v[0]); }
00071 inline void SetVector4(const GEO::Vector4 &v) { SetFloat4(&v[0]); }
00072
00073 inline void SetMatrix2x2(const GEO::Matrix2 &m, bool transpose=false) { SetMatrix2x2(&m[0][0], transpose); }
00074 inline void SetMatrix3x3(const GEO::Matrix3 &m, bool transpose=false) { SetMatrix3x3(&m[0][0], transpose); }
00075 inline void SetMatrix4x4(const GEO::Matrix4 &m, bool transpose=false) { SetMatrix4x4(&m[0][0], transpose); }
00076 #endif
00077
00078 private:
00079 inline UniformVariable(GLint loc): location(loc) {}
00080
00081 GLint location;
00082 friend class ShaderProgram;
00083 };
00084
00085
00086
00087 struct ShaderCodeData
00088 {
00089 GLuint object;
00090 std::vector<MPMA::Filename> origFilenames;
00091 std::string compileMessages;
00092
00093 inline ShaderCodeData(): object(0)
00094 {}
00095 };
00096
00098 class ShaderCode: public MPMA::ReferenceCountedData<ShaderCodeData>
00099 {
00100 public:
00101 virtual ~ShaderCode();
00102
00104 bool Create(GLenum shaderType);
00105
00107 void Free();
00108
00110 bool Compile(GLenum shaderType, const std::string &code);
00112 bool Compile(GLenum shaderType, const std::vector<std::string> &codes);
00113
00115 bool CompileFile(GLenum shaderType, const MPMA::Filename &file);
00117 bool CompileFiles(GLenum shaderType, const std::vector<MPMA::Filename> &files);
00118
00120 inline const std::string& GetCompileMessages() const { return Data().compileMessages; }
00121
00123 inline operator GLuint() const { return Data().object; }
00124
00125 private:
00126 bool CompileInternal(const std::vector<std::string> &codes);
00127 };
00128
00129
00130
00131 struct ShaderProgramData
00132 {
00133 GLuint object;
00134 std::string linkMessages;
00135
00136 inline ShaderProgramData(): object(0)
00137 {}
00138 };
00139
00141 class ShaderProgram: public MPMA::ReferenceCountedData<ShaderProgramData>
00142 {
00143 public:
00144 virtual ~ShaderProgram();
00145
00147 bool Create();
00149 void Free();
00150
00152 void AttachShader(const ShaderCode &code);
00154 void DetatchShader(const ShaderCode &code);
00156 bool Link();
00157
00159 bool CreateAndLink(const std::vector<ShaderCode> &codes);
00161 bool CreateAndLink(const ShaderCode *codes, nuint count);
00162
00164 inline const std::string& GetLinkMessages() const { return Data().linkMessages; }
00165
00167 inline void Bind()
00168 {
00169 glUseProgram(*this);
00170 }
00171
00173 inline void Unbind()
00174 {
00175 glUseProgram(0);
00176 }
00177
00179 inline UniformVariable FindVariable(const std::string &name)
00180 {
00181 return UniformVariable(glGetUniformLocationARB(*this, name.c_str()));
00182 }
00183
00185 inline operator GLuint() const { return Data().object; }
00186 };
00187
00189 class AutoBindShaderProgram
00190 {
00191 public:
00193 inline AutoBindShaderProgram(ShaderProgram &shaderToBind): prog(shaderToBind) { prog.Bind(); }
00195 inline ~AutoBindShaderProgram() { prog.Unbind(); }
00196
00197 private:
00198 ShaderProgram &prog;
00199
00200
00201 AutoBindShaderProgram(const AutoBindShaderProgram &o);
00202 bool operator=(const AutoBindShaderProgram &o);
00203 };
00204 }
00205
00206 #endif //#ifdef MPMA_COMPILE_GFX