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 #ifndef _SO_SHADER_PROGRAM_H_
00026 #define _SO_SHADER_PROGRAM_H_
00027
00028 #include <Inventor/SbBasic.h>
00029 #include <Inventor/nodes/SoNode.h>
00030 #include <Inventor/nodes/SoNode.h>
00031 #include <Inventor/fields/SoMFNode.h>
00032 #include <Inventor/nodes/SoShaderParameter.h>
00033 #include <Inventor/nodes/SoFragmentShader.h>
00034 #include <Inventor/nodes/SoVertexShader.h>
00035 #include <Inventor/nodes/SoTessellationControlShader.h>
00036 #include <Inventor/nodes/SoTessellationEvaluationShader.h>
00037 #include <Inventor/nodes/SoTexture.h>
00038 #include <Inventor/nodes/SoGeometryShader.h>
00039 #include <Inventor/STL/vector>
00040 #include <Inventor/STL/cassert>
00041 #include <Inventor/helpers/SbConstCharMap.h>
00042 #include <Inventor/elements/SoEnvironmentElement.h>
00043 #include <memory>
00044 #include <unordered_map>
00045 #include <Inventor/renderer/RendererResourceMacro.h>
00046 #include <Inventor/sensors/SoFileSensor.h>
00047
00048
00049 #ifdef _WIN32
00050 #pragma warning(push)
00051 #pragma warning(disable:4251)
00052 #endif
00053
00054 class SoGLRenderAction;
00055 class SoGLShaderProgram ;
00056 class SoGLShaderObject;
00057 class SoFieldSensor ;
00058 class SoLight;
00059 class SoCache;
00060 class SoShaderParameterBufferObject;
00061
00062 namespace inventor { namespace helper { class ShaderLibrary; } }
00063 namespace inventor { namespace renderer { class ShaderStateUniforms; } }
00064
00065
00066
00231 class SoShaderProgram : public SoNode
00232 {
00233
00234 SO_NODE_HEADER( SoShaderProgram );
00235 RENDERER_RESOURCE(SoShaderProgram);
00236
00237 public:
00239 enum GeometryInputType
00240 {
00247 POINTS_INPUT = GL_POINTS,
00248
00257 LINES_INPUT = GL_LINES,
00258
00267 TRIANGLES_INPUT = GL_TRIANGLES
00268 };
00269
00273 enum GeometryOutputType
00274 {
00275 POINTS_OUTPUT = GL_POINTS,
00276 LINE_STRIP_OUTPUT = GL_LINE_STRIP,
00280 TRIANGLE_STRIP_OUTPUT = GL_TRIANGLE_STRIP
00281 };
00282
00289 SoMFNode shaderObject;
00290
00297 SoSFEnum geometryInputType;
00298
00305 SoSFEnum geometryOutputType;
00306
00313 SoSFBool vertexProgramTwoSide;
00314
00332 SoSFBool shadowShader;
00333
00340 SoSFInt32 maxGeometryOutputVertices;
00341
00342
00353 SoSFBool generateTransparency;
00354
00361 SoSFInt32 patchLength;
00362
00368 SoMFNode bufferObjects;
00369
00373 SoShaderProgram();
00374
00378 inline SoFragmentShader* getFragmentShader(int pos) const;
00379
00383 inline SoVertexShader* getVertexShader(int pos) const;
00384
00389 inline SoGeometryShader* getGeometryShader(int pos) const;
00390
00395 virtual SoFragmentShader* setFragmentShader(int pos, const SbString& filenameOrSource,
00396 SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME);
00397
00402 virtual SoVertexShader* setVertexShader(int pos, const SbString& filenameOrSource,
00403 SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME);
00404
00410 virtual SoGeometryShader* setGeometryShader(int pos, const SbString& filenameOrSource,
00411 SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME);
00412
00417 static unsigned int getNumReservedTextures();
00418
00422 inline SoTessellationControlShader* getTessellationControlShader(int pos) const;
00423
00427 inline SoTessellationEvaluationShader* getTessellationEvaluationShader(int pos) const;
00428
00433 virtual SoTessellationControlShader* setTessellationControlShader(int pos, const SbString& filenameOrSource,
00434 SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME);
00435
00440 virtual SoTessellationEvaluationShader* setTessellationEvaluationShader(int pos, const SbString& filenameOrSource,
00441 SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME);
00442
00443
00444
00445 private:
00446
00447
00448 virtual void doAction(SoAction *action);
00449 virtual void GLRender( SoGLRenderAction *action );
00450 virtual void getBoundingBox( SoGetBoundingBoxAction *action );
00451 virtual void pick( SoPickAction *action );
00452
00453 private:
00455 enum GPUVendorType
00456 {
00457 GPU_TYPE_NOT_INITIALIZED = -1,
00458 GPU_NVIDIA = 0,
00459 GPU_ATI = 1,
00460 GPU_INTEL = 2,
00461 GPU_FIREPRO_MAC = 3
00462 };
00463
00464
00465 enum { MAX_IMG_UNITS = 8 };
00466
00470 struct TextureImageProperties
00471 {
00472 uint32_t unit;
00473 SoRef<SoTexture> texture;
00474
00475 int32_t mipmap;
00476 bool layered;
00477 int32_t layer;
00478 SbEnums::BufferAccess access;
00479
00483 TextureImageProperties()
00484 {
00485 unit = 0;
00486 mipmap = 0;
00487 layered = false;
00488 layer = 0;
00489 access = SbEnums::READ;
00490 }
00491
00495 bool operator==(const TextureImageProperties& other) const
00496 {
00497 return (unit == other.unit
00498 && texture.ptr() == other.texture.ptr()
00499 && mipmap == other.mipmap
00500 && layered == other.layered
00501 && layer == other.layer
00502 && access == other.access);
00503 }
00504 };
00505
00507 bool hasMainShaderType(SbEnums::ShaderType shaderType) const;
00508
00510 void getAllParameters(SoState* state, std::vector<SoUniformShaderParameter*>& shaderParameters);
00511
00513 void getShaderObjects(std::vector<SoShaderObject*>& shaderObjectsList) const;
00514
00516 SbString getLinkedShaderFileNames(SbEnums::ShaderType shaderType) const;
00517
00519 void displayLinkedFileNames() const;
00520
00521
00522 static bool isOivReservedName(const std::string ¶mName);
00523
00525 virtual void notify(SoNotList *list);
00526
00528 void setDefine(const char* name, const char* value);
00529 void setDefine(const char* name, const SbString& value)
00530 { setDefine(name,value.toLatin1()); }
00531
00535 bool getDefine(const char* name, SbString& value) const;
00536
00538 void removeDefine(const char* name);
00539
00541 void setHeader(const SbString& filename);
00542
00544 void removeHeader(const SbString& name);
00545
00549 static GLint offsetToGLTextureUnit(SoGLRenderAction* action, const char* offset);
00550
00554 static int offsetToTextureUnit(SoGLRenderAction* action, const char* offset);
00555
00556
00557 static void initClass();
00558 static void exitClass();
00559
00561 void invalidate();
00562
00564 void setTextureImageProperties(const TextureImageProperties& properties);
00565
00566 TextureImageProperties getTextureImageProperties(size_t unit) const { return m_textureImageProperties[unit]; }
00567
00568 void resetTextureImageProperties(size_t unit);
00569
00571 bool isGlslProgram() const;
00572
00574 bool isShadowShader() const;
00575
00577 SoShaderProgram* getShadowPassShader() const;
00578
00580 void setShadowShader(bool flag);
00581
00584 void setHiddenShaderObject(const char* objName, SoShaderObject* obj);
00585
00587 SoVertexShader* setHiddenVertexShader(const char* objName, const SbString& filenameOrSource,
00588 SoShaderObject::SourceType sourceType);
00589
00591 SoFragmentShader* setHiddenFragmentShader(const char* objName, const SbString& filenameOrSource,
00592 SoShaderObject::SourceType sourceType);
00593
00595 void removeHiddenShaderObject(const char* objName);
00596
00598 SoShaderObject* getHiddenShaderObject(const char* objName) const;
00599
00601 const SbConstCharMap<SoShaderObject*>& getHiddenShaderObjects() const;
00602
00604 static GPUVendorType getGPUVendorType();
00605
00606
00610 template<typename T>
00611 T* setupPrivateShaderStage(const char* hiddenName, const SbString& shaderSource)
00612 {
00613
00614 T* fp = (T*)getHiddenShaderObject(hiddenName);
00615 if (!fp || (fp->sourceProgram.getValue() != shaderSource))
00616 {
00617 fp = new T;
00618 fp->sourceProgram.setValue(shaderSource);
00619 setHiddenShaderObject(hiddenName, fp);
00620 }
00621 return fp;
00622 }
00623
00625 void removeAllPrivateShaderType(SbEnums::ShaderType shaderType);
00626
00628 enum ShaderLibraryState
00629 {
00630 LIBRARY_NOT_INSTALLED,
00631 LIBRARY_INSTALLED_EMPTY,
00632 LIBRARY_INSTALLED,
00633 };
00634
00636 ShaderLibraryState getLibraryState( inventor::helper::ShaderLibrary* library ) const;
00637
00639 void setLibraryState( inventor::helper::ShaderLibrary* library, ShaderLibraryState libraryState );
00640
00641 private:
00642 typedef std::vector<SoShaderObject*> ShaderObjectVector;
00643 typedef SbConstCharMap<SoShaderObject*> ShaderObjectMap;
00645 typedef SoShaderObject::DefineMap DefineMap;
00646 typedef SoShaderObject::HeaderSet HeaderSet;
00647
00649 struct Members
00650 {
00651 Members();
00652 ~Members();
00653 void unref();
00654
00656 bool m_isShadowShader;
00657
00659 ShaderObjectMap m_hiddenShaderObjects;
00660
00661
00662
00663
00664 std::vector<SoShaderObject*> m_prevShaderObject;
00665 std::vector< SoNode * > m_toUnrefShaderObjects;
00666
00668 SoShaderProgram* m_shadowPassShader;
00669
00671 DefineMap m_defineMap;
00672
00674 HeaderSet m_headerMap;
00675
00677 bool m_isValid;
00678 };
00679 SbThreadStorage<Members*> m_members;
00680
00681
00682 virtual ~SoShaderProgram();
00683
00684
00685 SbBool isValidShaderObjects() const;
00686
00687
00688
00689 SbBool isOneShaderObjectActive();
00690
00692 static SoShaderProgram::Members* getMembers(const SoShaderProgram* prog);
00693
00694 private:
00695
00696 SoMFNode prevShaderObject;
00697
00699 void addDefines(SoShaderObject* obj);
00700
00702 void addHeaders(SoShaderObject* obj);
00703
00705 void addHiddenShaderObjects(ShaderObjectVector& shaderObjectsList);
00706
00708 static bool lessVersion(SoShaderObject* obj1, SoShaderObject* obj2);
00709
00711 static SbString getMaxVersion(const ShaderObjectVector& objList);
00712
00714 static bool lessProfile(SoShaderObject* obj1, SoShaderObject* obj2);
00715
00718 static SbString getLoosestProfile(const ShaderObjectVector& objList);
00719
00721 bool hasShaderObjectsChanged() const;
00722
00724 void updatePrevShaderObject();
00725
00727 static void invalidate(ShaderObjectMap::value_type& p);
00728
00730 void addGPUVendorDefine();
00731
00733 void setShaderBufferObject(SoGLRenderAction* action);
00734
00736 private:
00741 void notifyAddedShaderObject(const char* hiddenShaderObjectName);
00742
00744 static void fileSensorCB(void *data, SoSensor *) ;
00745
00747 void updateFileSensor();
00748
00750 std::auto_ptr<SoFileSensor> m_fileSensor;
00751
00753 int m_previousTransparencyType;
00754
00755 typedef std::unordered_map<inventor::helper::ShaderLibrary*, ShaderLibraryState> ShaderLibraryStateMap;
00756 ShaderLibraryStateMap m_shaderLibrariesStates;
00757
00759 static GPUVendorType s_gpuVendorType;
00760
00762 static int s_firstUsedTextureUnit;
00763
00765 static bool s_debugCache;
00766
00767
00768 SoShaderProgram::TextureImageProperties m_textureImageProperties[MAX_IMG_UNITS];
00769
00770 friend class SoUniformShaderParameter;
00771 };
00772
00773
00774
00775 SoFragmentShader*
00776 SoShaderProgram::getFragmentShader(int pos) const
00777 {
00778 assert(pos >= 0 && pos < shaderObject.getNum());
00779 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00780
00781 if ( !obj )
00782 return NULL;
00783
00784 assert(obj->getTypeId() == SoFragmentShader::getClassTypeId());
00785
00786 return static_cast<SoFragmentShader*>(obj);
00787 }
00788
00789
00790 SoVertexShader*
00791 SoShaderProgram::getVertexShader(int pos) const
00792 {
00793 assert(pos >= 0 && pos < shaderObject.getNum());
00794 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00795
00796 if ( !obj )
00797 return NULL;
00798
00799 assert(obj->getTypeId() == SoVertexShader::getClassTypeId());
00800
00801 return static_cast<SoVertexShader*>(obj);
00802 }
00803
00804
00805 SoGeometryShader*
00806 SoShaderProgram::getGeometryShader(int pos) const
00807 {
00808 assert(pos >= 0 && pos < shaderObject.getNum());
00809 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00810
00811 if ( !obj )
00812 return NULL;
00813
00814 assert(obj->getTypeId() == SoGeometryShader::getClassTypeId());
00815
00816 return static_cast<SoGeometryShader*>(obj);
00817 }
00818
00819
00820 SoTessellationControlShader*
00821 SoShaderProgram::getTessellationControlShader(int pos) const
00822 {
00823 assert(pos >= 0 && pos < shaderObject.getNum());
00824 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00825
00826 if ( !obj )
00827 return NULL;
00828
00829 assert(obj->getTypeId() == SoTessellationControlShader::getClassTypeId());
00830
00831 return static_cast<SoTessellationControlShader*>(obj);
00832 }
00833
00834
00835 SoTessellationEvaluationShader*
00836 SoShaderProgram::getTessellationEvaluationShader(int pos) const
00837 {
00838 assert(pos >= 0 && pos < shaderObject.getNum());
00839 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00840
00841 if ( !obj )
00842 return NULL;
00843
00844 assert(obj->getTypeId() == SoTessellationEvaluationShader::getClassTypeId());
00845
00846 return static_cast<SoTessellationEvaluationShader*>(obj);
00847 }
00848
00849 #ifdef _WIN32
00850 #pragma warning(pop)
00851 #endif
00852
00853 #endif
00854
00855
00856