00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef GLSL_INCLUDE_ONCE
00033 #define GLSL_INCLUDE_ONCE
00034
00035 #include <vlGraphics/UniformSet.hpp>
00036 #include <vlCore/GLSLmath.hpp>
00037 #include <vlGraphics/RenderState.hpp>
00038 #include <vlCore/String.hpp>
00039
00040 namespace vl
00041 {
00042 class Uniform;
00043
00044
00045
00046
00050 class VLGRAPHICS_EXPORT GLSLShader: public Object
00051 {
00052 public:
00053 GLSLShader(EShaderType type, const String& source=String());
00054
00055 ~GLSLShader();
00056
00057 virtual const char* className() { return "vl::Unnamed GLSLShader"; }
00058
00059 EShaderType type() const { return mType; }
00060
00062 void setSource( const String& source );
00063
00065 const std::string& source() const { return mSource; }
00066
00069 bool compile();
00070
00073 bool compileStatus() const;
00074
00076 String infoLog() const;
00077
00079 void createShader();
00080
00082 void deleteShader();
00083
00085 unsigned int handle() const { return mHandle; }
00086
00087 protected:
00088 EShaderType mType;
00089 std::string mSource;
00090 unsigned int mHandle;
00091 bool mCompiled;
00092 };
00093
00097 class GLSLVertexShader: public GLSLShader
00098 {
00099 public:
00102 GLSLVertexShader(const String& source=String()): GLSLShader(ST_VERTEX_SHADER, source)
00103 {
00104 #ifndef NDEBUG
00105 if (mObjectName.empty())
00106 mObjectName = className();
00107 #endif
00108 }
00109 virtual const char* className() { return "vl::GLSLVertexShader"; }
00110 };
00111
00115 class GLSLFragmentShader: public GLSLShader
00116 {
00117 public:
00119 GLSLFragmentShader(const String& source=String()): GLSLShader(ST_FRAGMENT_SHADER, source)
00120 {
00121 #ifndef NDEBUG
00122 if (mObjectName.empty())
00123 mObjectName = className();
00124 #endif
00125 }
00126 virtual const char* className() { return "vl::GLSLFragmentShader"; }
00127 };
00128
00132 class GLSLGeometryShader: public GLSLShader
00133 {
00134 public:
00136 GLSLGeometryShader(const String& source=String()): GLSLShader(ST_GEOMETRY_SHADER, source)
00137 {
00138 #ifndef NDEBUG
00139 if (mObjectName.empty())
00140 mObjectName = className();
00141 #endif
00142 }
00143 virtual const char* className() { return "vl::GLSLGeometryShader"; }
00144 };
00145
00149 class GLSLTessControlShader: public GLSLShader
00150 {
00151 public:
00153 GLSLTessControlShader(const String& source=String()): GLSLShader(ST_TESS_CONTROL_SHADER, source)
00154 {
00155 #ifndef NDEBUG
00156 if (mObjectName.empty())
00157 mObjectName = className();
00158 #endif
00159 }
00160 virtual const char* className() { return "vl::GLSLTessControlShader"; }
00161 };
00162
00166 class GLSLTessEvaluationShader: public GLSLShader
00167 {
00168 public:
00170 GLSLTessEvaluationShader(const String& source=String()): GLSLShader(ST_TESS_EVALUATION_SHADER, source)
00171 {
00172 #ifndef NDEBUG
00173 if (mObjectName.empty())
00174 mObjectName = className();
00175 #endif
00176 }
00177 virtual const char* className() { return "vl::GLSLTessEvaluationShader"; }
00178 };
00179
00180
00181
00215 class VLGRAPHICS_EXPORT GLSLProgram: public RenderState
00216 {
00217
00218 friend class Renderer;
00219 public:
00221 GLSLProgram();
00222
00224 ~GLSLProgram();
00225
00226 virtual const char* className() { return "vl::GLSLProgram"; }
00227
00229 virtual ERenderState type() const { return RS_GLSLProgram; }
00230
00234 void createProgram();
00235
00238 void deleteProgram();
00239
00245 unsigned int handle() const { return mHandle; }
00246
00248 bool useProgram() const;
00249
00251 void apply(const Camera*, OpenGLContext* ctx) const;
00252
00258 bool linkProgram(bool force_relink = false);
00259
00260 bool linkStatus() const;
00261
00263 bool linked() const { return mHandle && !mScheduleLink; }
00264
00266 void scheduleRelinking() { mScheduleLink = true; }
00267
00273 bool attachShader(GLSLShader* shader);
00274
00276 bool detachShader(GLSLShader* shader);
00277
00281 void discardAllShaders();
00282
00284 String infoLog() const;
00285
00287 bool validateProgram() const;
00288
00293 void bindAttribLocation(unsigned int index, const std::string& name);
00294
00298 void addAutoAttribLocation(const char* attr_name, int attr_index) { mAutoAttribLocation[attr_name] = attr_index; mScheduleLink = true; }
00299
00303 void removeAutoAttribLocation(const char* attr_name) { mAutoAttribLocation.erase(attr_name); mScheduleLink = true; }
00304
00308 void setAutoAttribLocations(const std::map<std::string, int>& attrib_bindings) { mAutoAttribLocation = attrib_bindings; mScheduleLink = true; }
00309
00313 const std::map<std::string, int>& autoAttribLocations() const { return mAutoAttribLocation; }
00314
00318 void clearAutoAttribLocations() { mAutoAttribLocation.clear(); }
00319
00322 int getAttribLocation(const char* name) const
00323 {
00324 VL_CHECK( GLEW_Has_Shading_Language_20 )
00325 if( !GLEW_Has_Shading_Language_20 )
00326 return -1;
00327 VL_CHECK(handle())
00328 VL_CHECK(linked())
00329 int location = glGetAttribLocation(handle(), name);
00330 return location;
00331 }
00332
00334 static int maxVertexAttribs();
00335
00337 int shaderCount() const { return (int)mShaders.size(); }
00339 const GLSLShader* shader(int i) const { return mShaders[i].get(); }
00341 GLSLShader* shader(int i) { return mShaders[i].get(); }
00343 void detachAllShaders();
00344
00345
00346
00347 void bindFragDataLocation(int color_number, const std::string& name);
00348 void unbindFragDataLocation(const std::string& name);
00349 int fragDataLocationBinding(const std::string& name) const;
00350
00351
00352
00354 void setGeometryVerticesOut(int vertex_count)
00355 {
00356 if (mGeometryVerticesOut != vertex_count)
00357 {
00358 scheduleRelinking();
00359 mGeometryVerticesOut = vertex_count;
00360 }
00361 }
00362
00364 int geometryVerticesOut() const { return mGeometryVerticesOut; }
00365
00367 void setGeometryInputType(EGeometryInputType type)
00368 {
00369 if (mGeometryInputType != type)
00370 {
00371 scheduleRelinking();
00372 mGeometryInputType = type;
00373 }
00374 }
00376 EGeometryInputType geometryInputType() const { return mGeometryInputType; }
00377
00379 void setGeometryOutputType(EGeometryOutputType type)
00380 {
00381 if (mGeometryOutputType != type)
00382 {
00383 scheduleRelinking();
00384 mGeometryOutputType = type;
00385 }
00386 }
00387
00389 EGeometryOutputType geometryOutputType() const { return mGeometryOutputType; }
00390
00391
00392
00396 void setProgramBinaryRetrievableHint(bool hint) { mProgramBinaryRetrievableHint = hint; }
00397
00401 bool programBinaryRetrievableHint() const { return mProgramBinaryRetrievableHint; }
00402
00405 void setProgramSeparable(bool separable)
00406 {
00407 if (mProgramSeparable != separable)
00408 {
00409 scheduleRelinking();
00410 mProgramSeparable = separable;
00411 }
00412 }
00413
00415 bool programSeparable() const { return mProgramSeparable; }
00416
00418 bool getProgramBinary(GLenum& binary_format, std::vector<unsigned char>& binary) const;
00419
00421 bool programBinary(GLenum binary_format, const std::vector<unsigned char>& binary) { return programBinary(binary_format, &binary[0], (int)binary.size()); }
00422
00424 bool programBinary(GLenum binary_format, const void* binary, int length);
00425
00426
00427
00432 bool applyUniformSet(const UniformSet* uniforms) const;
00433
00437 int getUniformLocation(const std::string& name) const
00438 {
00439 VL_CHECK( GLEW_Has_Shading_Language_20 )
00440 if( !GLEW_Has_Shading_Language_20 )
00441 return -1;
00442 VL_CHECK(linked())
00443
00444 int location = glGetUniformLocation(handle(), name.c_str());
00445 return location;
00446 }
00447
00451 int getUniformLocation(const char* name) const
00452 {
00453 VL_CHECK( GLEW_Has_Shading_Language_20 )
00454 if( !GLEW_Has_Shading_Language_20 )
00455 return -1;
00456 VL_CHECK(linked())
00457
00458 int location = glGetUniformLocation(handle(), name);
00459 return location;
00460 }
00461
00462
00463
00464
00465
00466
00468 void getUniformfv(int location, float* params) const
00469 {
00470 VL_CHECK( GLEW_Has_Shading_Language_20 )
00471 if( !GLEW_Has_Shading_Language_20 )
00472 return;
00473 VL_CHECK(linked())
00474 VL_CHECK(handle())
00475 glGetUniformfv(handle(), location, params); VL_CHECK_OGL()
00476 }
00478 void getUniformfv(const std::string& name, float* params) const { getUniformfv(getUniformLocation(name), params); }
00480 void getUniformiv(int location, int* params) const
00481 {
00482 VL_CHECK( GLEW_Has_Shading_Language_20 )
00483 if( !GLEW_Has_Shading_Language_20 )
00484 return;
00485 VL_CHECK(linked())
00486 VL_CHECK(handle())
00487 glGetUniformiv(handle(), location, params); VL_CHECK_OGL()
00488 }
00490 void getUniformiv(const std::string& name, int* params) const { getUniformiv(getUniformLocation(name), params); }
00491
00492
00493
00494 void getUniform(int location, fvec2& vec) const { getUniformfv(location, vec.ptr()); }
00495 void getUniform(int location, fvec3& vec) const { getUniformfv(location, vec.ptr()); }
00496 void getUniform(int location, fvec4& vec) const { getUniformfv(location, vec.ptr()); }
00497 void getUniform(int location, fmat2& mat) const { getUniformfv(location, mat.ptr()); }
00498 void getUniform(int location, fmat3& mat) const { getUniformfv(location, mat.ptr()); }
00499 void getUniform(int location, fmat4& mat) const { getUniformfv(location, mat.ptr()); }
00500 void getUniform(int location, ivec2& vec) const { getUniformiv(location, vec.ptr()); }
00501 void getUniform(int location, ivec3& vec) const { getUniformiv(location, vec.ptr()); }
00502 void getUniform(int location, ivec4& vec) const { getUniformiv(location, vec.ptr()); }
00503 void getUniform(const std::string& name, fvec2& vec) const { getUniform(getUniformLocation(name), vec); }
00504 void getUniform(const std::string& name, fvec3& vec) const { getUniform(getUniformLocation(name), vec); }
00505 void getUniform(const std::string& name, fvec4& vec) const { getUniform(getUniformLocation(name), vec); }
00506 void getUniform(const std::string& name, fmat2& mat) const { getUniform(getUniformLocation(name), mat); }
00507 void getUniform(const std::string& name, fmat3& mat) const { getUniform(getUniformLocation(name), mat); }
00508 void getUniform(const std::string& name, fmat4& mat) const { getUniform(getUniformLocation(name), mat); }
00509 void getUniform(const std::string& name, ivec2& vec) const { getUniform(getUniformLocation(name), vec); }
00510 void getUniform(const std::string& name, ivec3& vec) const { getUniform(getUniformLocation(name), vec); }
00511 void getUniform(const std::string& name, ivec4& vec) const { getUniform(getUniformLocation(name), vec); }
00512
00513
00514
00516 UniformSet* uniformSet() { return mUniformSet.get(); }
00518 const UniformSet* uniformSet() const { return mUniformSet.get(); }
00520 void setUniformSet(UniformSet* uniforms) { mUniformSet = uniforms; }
00522 void setUniform(Uniform* uniform) { if (!uniformSet()) setUniformSet(new UniformSet); uniformSet()->setUniform(uniform); }
00524 Uniform* getUniform(const std::string& name) { if (!uniformSet()) return NULL; return uniformSet()->getUniform(name); }
00526 Uniform* gocUniform(const std::string& name) { if (!uniformSet()) setUniformSet(new UniformSet); return uniformSet()->gocUniform(name); }
00528 void eraseUniform(const std::string& name) { if(uniformSet()) uniformSet()->eraseUniform(name); }
00530 void eraseUniform(const Uniform* uniform) { if(uniformSet()) uniformSet()->eraseUniform(uniform); }
00532 void eraseAllUniforms() { if(uniformSet()) uniformSet()->eraseAllUniforms(); }
00533
00535 const std::map<std::string, int>& activeUniformLocations() const { return mActiveUniformLocation; }
00536
00538 int vl_ModelViewMatrix() const { return m_vl_ModelViewMatrix; }
00539
00541 int vl_ProjectionMatrix() const { return m_vl_ProjectionMatrix; }
00542
00544 int vl_ModelViewProjectionMatrix() const { return m_vl_ModelViewProjectionMatrix; }
00545
00547 int vl_NormalMatrix() const { return m_vl_NormalMatrix; }
00548
00549 private:
00550 void preLink();
00551 void postLink();
00552
00553 protected:
00554 std::vector< ref<GLSLShader> > mShaders;
00555 std::map<std::string, int> mFragDataLocation;
00556 std::map<std::string, int> mActiveUniformLocation;
00557 std::map<std::string, int> mAutoAttribLocation;
00558 ref<UniformSet> mUniformSet;
00559 unsigned int mHandle;
00560 bool mScheduleLink;
00561
00562 int mGeometryVerticesOut;
00563 EGeometryInputType mGeometryInputType;
00564 EGeometryOutputType mGeometryOutputType;
00565 bool mProgramBinaryRetrievableHint;
00566 bool mProgramSeparable;
00567 int m_vl_ModelViewMatrix;
00568 int m_vl_ProjectionMatrix;
00569 int m_vl_ModelViewProjectionMatrix;
00570 int m_vl_NormalMatrix;
00571 };
00572 }
00573
00574 #endif