Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2010, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 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 // UniformInfo 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 // AttribInfo 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 // GLSLShader 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 // GLSLProgram 00230 //------------------------------------------------------------------------------ 00264 class VLGRAPHICS_EXPORT GLSLProgram: public RenderStateNonIndexed 00265 { 00266 VL_INSTRUMENT_CLASS(vl::GLSLProgram, RenderStateNonIndexed) 00267 00268 // applyUniform 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 // --------------- bind frag data location --------------- 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 // --------------- geometry shader --------------- 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 // --------------- GLSL 4.x --------------- 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 // --------------- uniform variables --------------- 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 // --------------- uniform variables: getters --------------- 00511 00512 // general uniform getters: use these to access to all the types supported by your GLSL implementation, 00513 // and not only the ordinary fvec2, fvec3, fvec4, ivec2, ivec3, ivec4, fmat2, fmat3, fmat4 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 // utility functions for fvec2, fvec3, fvec4, ivec2, ivec3, ivec4, fmat2, fmat3, fmat4 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 // glProgramParameter 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