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/glsl_math.hpp>
00037 #include <vlGraphics/RenderState.hpp>
00038 #include <vlCore/String.hpp>
00039
00040 namespace vl
00041 {
00042 class Uniform;
00043
00044
00045
00046
00048 struct UniformInfo: public Object
00049 {
00050 UniformInfo(const char* name, EUniformType type, int size, int location)
00051 :Name(name), Type(type), Size(size), Location(location) {}
00052
00053 std::string Name;
00054 EUniformType Type;
00055 int Size;
00056 int Location;
00057 };
00058
00059
00060
00061
00063 struct AttribInfo: public Object
00064 {
00065 AttribInfo(const char* name, EAttributeType type, int size, int location)
00066 :Name(name), Type(type), Size(size), Location(location) {}
00067
00068 std::string Name;
00069 EAttributeType Type;
00070 int Size;
00071 int Location;
00072 };
00073
00074
00075
00076
00080 class VLGRAPHICS_EXPORT GLSLShader: public Object
00081 {
00082 VL_INSTRUMENT_CLASS(vl::GLSLShader, Object)
00083
00084 public:
00085 GLSLShader();
00086
00087 GLSLShader(EShaderType type, const String& source_or_path);
00088
00089 ~GLSLShader();
00090
00091 void setType(EShaderType type) { mType = type; }
00092
00093 EShaderType type() const { return mType; }
00094
00096 void setSource( const String& source_or_path );
00097
00099 const std::string& source() const { return mSource; }
00100
00102 void setPath(const char* path) { mPath = path; }
00103
00105 const std::string& path() const { return mPath; }
00106
00108 std::string getShaderSource() const;
00109
00112 bool compile();
00113
00116 bool compileStatus() const;
00117
00119 String infoLog() const;
00120
00122 void createShader();
00123
00125 void deleteShader();
00126
00128 unsigned int handle() const { return mHandle; }
00129
00130 protected:
00131 EShaderType mType;
00132 std::string mSource;
00133 std::string mPath;
00134 unsigned int mHandle;
00135 bool mCompiled;
00136 };
00137
00141 class GLSLVertexShader: public GLSLShader
00142 {
00143 VL_INSTRUMENT_CLASS(vl::GLSLVertexShader, GLSLShader)
00144
00145 public:
00148 GLSLVertexShader(const String& source=String()): GLSLShader(ST_VERTEX_SHADER, source)
00149 {
00150 #ifndef NDEBUG
00151 if (mObjectName.empty())
00152 mObjectName = className();
00153 #endif
00154 }
00155 };
00156
00160 class GLSLFragmentShader: public GLSLShader
00161 {
00162 VL_INSTRUMENT_CLASS(vl::GLSLFragmentShader, GLSLShader)
00163
00164 public:
00166 GLSLFragmentShader(const String& source=String()): GLSLShader(ST_FRAGMENT_SHADER, source)
00167 {
00168 #ifndef NDEBUG
00169 if (mObjectName.empty())
00170 mObjectName = className();
00171 #endif
00172 }
00173 };
00174
00178 class GLSLGeometryShader: public GLSLShader
00179 {
00180 VL_INSTRUMENT_CLASS(vl::GLSLGeometryShader, GLSLShader)
00181
00182 public:
00184 GLSLGeometryShader(const String& source=String()): GLSLShader(ST_GEOMETRY_SHADER, source)
00185 {
00186 #ifndef NDEBUG
00187 if (mObjectName.empty())
00188 mObjectName = className();
00189 #endif
00190 }
00191 };
00192
00196 class GLSLTessControlShader: public GLSLShader
00197 {
00198 VL_INSTRUMENT_CLASS(vl::GLSLTessControlShader, GLSLShader)
00199
00200 public:
00202 GLSLTessControlShader(const String& source=String()): GLSLShader(ST_TESS_CONTROL_SHADER, source)
00203 {
00204 #ifndef NDEBUG
00205 if (mObjectName.empty())
00206 mObjectName = className();
00207 #endif
00208 }
00209 };
00210
00214 class GLSLTessEvaluationShader: public GLSLShader
00215 {
00216 VL_INSTRUMENT_CLASS(vl::GLSLTessEvaluationShader, GLSLShader)
00217
00218 public:
00220 GLSLTessEvaluationShader(const String& source=String()): GLSLShader(ST_TESS_EVALUATION_SHADER, source)
00221 {
00222 #ifndef NDEBUG
00223 if (mObjectName.empty())
00224 mObjectName = className();
00225 #endif
00226 }
00227 };
00228
00229
00230
00264 class VLGRAPHICS_EXPORT GLSLProgram: public RenderStateNonIndexed
00265 {
00266 VL_INSTRUMENT_CLASS(vl::GLSLProgram, RenderStateNonIndexed)
00267
00268
00269 friend class Renderer;
00270 public:
00272 GLSLProgram();
00273
00275 ~GLSLProgram();
00276
00278 virtual ERenderState type() const { return RS_GLSLProgram; }
00279
00280 virtual ref<RenderState> clone() const
00281 {
00282 ref<GLSLProgram> rs = new GLSLProgram;
00283 *rs = *this;
00284 return rs;
00285 }
00286
00287 GLSLProgram& operator=(const GLSLProgram& other);
00288
00292 void createProgram();
00293
00296 void deleteProgram();
00297
00303 unsigned int handle() const { return mHandle; }
00304
00306 bool useProgram() const;
00307
00309 void apply(int index, const Camera*, OpenGLContext* ctx) const;
00310
00316 bool linkProgram(bool force_relink = false);
00317
00318 bool linkStatus() const;
00319
00321 bool linked() const { return mHandle && !mScheduleLink; }
00322
00324 void scheduleRelinking() { mScheduleLink = true; }
00325
00331 bool attachShader(GLSLShader* shader);
00332
00334 bool detachShader(GLSLShader* shader);
00335
00339 void discardAllShaders();
00340
00342 String infoLog() const;
00343
00345 bool validateProgram() const;
00346
00351 void bindAttribLocation(unsigned int index, const char* name);
00352
00356 void addAutoAttribLocation(int attr_index, const char* attr_name) { mAutoAttribLocation[attr_name] = attr_index; mScheduleLink = true; }
00357
00361 void removeAutoAttribLocation(const char* attr_name) { mAutoAttribLocation.erase(attr_name); mScheduleLink = true; }
00362
00366 void setAutoAttribLocations(const std::map<std::string, int>& attrib_bindings) { mAutoAttribLocation = attrib_bindings; mScheduleLink = true; }
00367
00371 const std::map<std::string, int>& autoAttribLocations() const { return mAutoAttribLocation; }
00372
00376 void clearAutoAttribLocations() { mAutoAttribLocation.clear(); }
00377
00380 int getAttribLocation(const char* name) const
00381 {
00382 VL_CHECK( Has_GLSL )
00383 if( !Has_GLSL )
00384 return -1;
00385 VL_CHECK(handle())
00386 VL_CHECK(linked())
00387 int location = glGetAttribLocation(handle(), name);
00388 return location;
00389 }
00390
00392 int shaderCount() const { return (int)mShaders.size(); }
00393
00395 const GLSLShader* shader(int i) const { return mShaders[i].get(); }
00396
00398 GLSLShader* shader(int i) { return mShaders[i].get(); }
00399
00401 void detachAllShaders();
00402
00403
00404
00405 void bindFragDataLocation(int color_number, const char* name);
00406
00407 void unbindFragDataLocation(const char* name);
00408
00409 int fragDataLocation(const char* name) const;
00410
00411 const std::map<std::string, int>& fragDataLocations() const { return mFragDataLocation; }
00412
00413
00414
00416 void setGeometryVerticesOut(int vertex_count)
00417 {
00418 if (mGeometryVerticesOut != vertex_count)
00419 {
00420 scheduleRelinking();
00421 mGeometryVerticesOut = vertex_count;
00422 }
00423 }
00424
00426 int geometryVerticesOut() const { return mGeometryVerticesOut; }
00427
00429 void setGeometryInputType(EGeometryInputType type)
00430 {
00431 if (mGeometryInputType != type)
00432 {
00433 scheduleRelinking();
00434 mGeometryInputType = type;
00435 }
00436 }
00438 EGeometryInputType geometryInputType() const { return mGeometryInputType; }
00439
00441 void setGeometryOutputType(EGeometryOutputType type)
00442 {
00443 if (mGeometryOutputType != type)
00444 {
00445 scheduleRelinking();
00446 mGeometryOutputType = type;
00447 }
00448 }
00449
00451 EGeometryOutputType geometryOutputType() const { return mGeometryOutputType; }
00452
00453
00454
00458 void setProgramBinaryRetrievableHint(bool hint) { mProgramBinaryRetrievableHint = hint; }
00459
00463 bool programBinaryRetrievableHint() const { return mProgramBinaryRetrievableHint; }
00464
00467 void setProgramSeparable(bool separable)
00468 {
00469 if (mProgramSeparable != separable)
00470 {
00471 scheduleRelinking();
00472 mProgramSeparable = separable;
00473 }
00474 }
00475
00477 bool programSeparable() const { return mProgramSeparable; }
00478
00480 bool getProgramBinary(GLenum& binary_format, std::vector<unsigned char>& binary) const;
00481
00483 bool programBinary(GLenum binary_format, const std::vector<unsigned char>& binary) { return programBinary(binary_format, &binary[0], (int)binary.size()); }
00484
00486 bool programBinary(GLenum binary_format, const void* binary, int length);
00487
00488
00489
00494 bool applyUniformSet(const UniformSet* uniforms) const;
00495
00499 int getUniformLocation(const char* name) const
00500 {
00501 VL_CHECK( Has_GLSL )
00502 if( !Has_GLSL )
00503 return -1;
00504 VL_CHECK(linked())
00505
00506 int location = glGetUniformLocation(handle(), name);
00507 return location;
00508 }
00509
00510
00511
00512
00513
00514
00516 void getUniformfv(int location, float* params) const
00517 {
00518 VL_CHECK( Has_GLSL )
00519 if( !Has_GLSL )
00520 return;
00521 VL_CHECK(linked())
00522 VL_CHECK(handle())
00523 glGetUniformfv(handle(), location, params); VL_CHECK_OGL()
00524 }
00526 void getUniformfv(const char* name, float* params) const { getUniformfv(getUniformLocation(name), params); }
00528 void getUniformiv(int location, int* params) const
00529 {
00530 VL_CHECK( Has_GLSL )
00531 if( !Has_GLSL )
00532 return;
00533 VL_CHECK(linked())
00534 VL_CHECK(handle())
00535 glGetUniformiv(handle(), location, params); VL_CHECK_OGL()
00536 }
00538 void getUniformiv(const char* name, int* params) const { getUniformiv(getUniformLocation(name), params); }
00539
00540
00541
00542 void getUniform(int location, fvec2& vec) const { getUniformfv(location, vec.ptr()); }
00543 void getUniform(int location, fvec3& vec) const { getUniformfv(location, vec.ptr()); }
00544 void getUniform(int location, fvec4& vec) const { getUniformfv(location, vec.ptr()); }
00545 void getUniform(int location, fmat2& mat) const { getUniformfv(location, mat.ptr()); }
00546 void getUniform(int location, fmat3& mat) const { getUniformfv(location, mat.ptr()); }
00547 void getUniform(int location, fmat4& mat) const { getUniformfv(location, mat.ptr()); }
00548 void getUniform(int location, ivec2& vec) const { getUniformiv(location, vec.ptr()); }
00549 void getUniform(int location, ivec3& vec) const { getUniformiv(location, vec.ptr()); }
00550 void getUniform(int location, ivec4& vec) const { getUniformiv(location, vec.ptr()); }
00551 void getUniform(const char* name, fvec2& vec) const { getUniform(getUniformLocation(name), vec); }
00552 void getUniform(const char* name, fvec3& vec) const { getUniform(getUniformLocation(name), vec); }
00553 void getUniform(const char* name, fvec4& vec) const { getUniform(getUniformLocation(name), vec); }
00554 void getUniform(const char* name, fmat2& mat) const { getUniform(getUniformLocation(name), mat); }
00555 void getUniform(const char* name, fmat3& mat) const { getUniform(getUniformLocation(name), mat); }
00556 void getUniform(const char* name, fmat4& mat) const { getUniform(getUniformLocation(name), mat); }
00557 void getUniform(const char* name, ivec2& vec) const { getUniform(getUniformLocation(name), vec); }
00558 void getUniform(const char* name, ivec3& vec) const { getUniform(getUniformLocation(name), vec); }
00559 void getUniform(const char* name, ivec4& vec) const { getUniform(getUniformLocation(name), vec); }
00560
00562 UniformSet* getUniformSet() { return mUniformSet.get(); }
00564 const UniformSet* getUniformSet() const { return mUniformSet.get(); }
00566 void setUniformSet(UniformSet* uniforms) { mUniformSet = uniforms; }
00568 void setUniform(Uniform* uniform) { if (!getUniformSet()) setUniformSet(new UniformSet); getUniformSet()->setUniform(uniform); }
00570 Uniform* getUniform(const char* name) { if (!getUniformSet()) return NULL; return getUniformSet()->getUniform(name); }
00572 Uniform* gocUniform(const char* name) { if (!getUniformSet()) setUniformSet(new UniformSet); return getUniformSet()->gocUniform(name); }
00574 void eraseUniform(const char* name) { if(getUniformSet()) getUniformSet()->eraseUniform(name); }
00576 void eraseUniform(const Uniform* uniform) { if(getUniformSet()) getUniformSet()->eraseUniform(uniform); }
00578 void eraseAllUniforms() { if(getUniformSet()) getUniformSet()->eraseAllUniforms(); }
00579
00582 const std::map<std::string, ref<UniformInfo> >& activeUniforms() const { return mActiveUniforms; }
00583
00586 const UniformInfo* activeUniformInfo(const char* name) const
00587 {
00588 std::map<std::string, ref<UniformInfo> >::const_iterator it = mActiveUniforms.find(name);
00589 if (it == mActiveUniforms.end())
00590 return NULL;
00591 else
00592 return it->second.get();
00593 }
00594
00597 const std::map<std::string, ref<AttribInfo> >& activeAttribs() const { return mActiveAttribs; }
00598
00601 const AttribInfo* activeAttribInfo(const char* name) const
00602 {
00603 std::map<std::string, ref<AttribInfo> >::const_iterator it = mActiveAttribs.find(name);
00604 if (it == mActiveAttribs.end())
00605 return NULL;
00606 else
00607 return it->second.get();
00608 }
00609
00611 int vl_ModelViewMatrix() const { return m_vl_ModelViewMatrix; }
00612
00614 int vl_ProjectionMatrix() const { return m_vl_ProjectionMatrix; }
00615
00617 int vl_ModelViewProjectionMatrix() const { return m_vl_ModelViewProjectionMatrix; }
00618
00620 int vl_NormalMatrix() const { return m_vl_NormalMatrix; }
00621
00622 private:
00623 void preLink();
00624 void postLink();
00625
00626 protected:
00627 std::vector< ref<GLSLShader> > mShaders;
00628 std::map<std::string, int> mFragDataLocation;
00629 std::map<std::string, ref<UniformInfo> > mActiveUniforms;
00630 std::map<std::string, ref<AttribInfo> > mActiveAttribs;
00631 std::map<std::string, int> mAutoAttribLocation;
00632 ref<UniformSet> mUniformSet;
00633 unsigned int mHandle;
00634 bool mScheduleLink;
00635
00636
00637 int mGeometryVerticesOut;
00638 EGeometryInputType mGeometryInputType;
00639 EGeometryOutputType mGeometryOutputType;
00640 bool mProgramBinaryRetrievableHint;
00641 bool mProgramSeparable;
00642
00643 int m_vl_ModelViewMatrix;
00644 int m_vl_ProjectionMatrix;
00645 int m_vl_ModelViewProjectionMatrix;
00646 int m_vl_NormalMatrix;
00647 };
00648 }
00649
00650 #endif