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/nodes/SoShaderParameterImage.h>
00040 #include <Inventor/STL/vector>
00041 #include <Inventor/STL/cassert>
00042 #include <Inventor/helpers/SbConstCharMap.h>
00043 #include <Inventor/elements/SoEnvironmentElement.h>
00044 #include <memory>
00045 #include <unordered_map>
00046 #include <Inventor/renderer/RendererResourceMacro.h>
00047 #include <Inventor/sensors/SoFileSensor.h>
00048
00049
00050 #ifdef _WIN32
00051 #pragma warning(push)
00052 #pragma warning(disable:4251)
00053 #endif
00054
00055 class SoGLRenderAction;
00056 class SoGLShaderProgram ;
00057 class SoGLShaderObject;
00058 class SoFieldSensor ;
00059 class SoLight;
00060 class SoCache;
00061 class SoShaderParameterBufferObject;
00062 class SoComputeShader;
00063
00065 namespace inventor { namespace helper { class ShaderLibrary; } }
00066 namespace inventor { namespace renderer { class ShaderStateUniforms; } }
00069
00070
00235 class SoShaderProgram : public SoNode
00236 {
00237
00238 SO_NODE_HEADER( SoShaderProgram );
00239 RENDERER_RESOURCE(SoShaderProgram);
00240
00241 public:
00243 enum GeometryInputType
00244 {
00251 POINTS_INPUT = GL_POINTS,
00252
00261 LINES_INPUT = GL_LINES,
00262
00271 TRIANGLES_INPUT = GL_TRIANGLES
00272 };
00273
00277 enum GeometryOutputType
00278 {
00279 POINTS_OUTPUT = GL_POINTS,
00280 LINE_STRIP_OUTPUT = GL_LINE_STRIP,
00284 TRIANGLE_STRIP_OUTPUT = GL_TRIANGLE_STRIP
00285 };
00286
00293 SoMFNode shaderObject;
00294
00301 SoSFEnum geometryInputType;
00302
00309 SoSFEnum geometryOutputType;
00310
00317 SoSFBool vertexProgramTwoSide;
00318
00336 SoSFBool shadowShader;
00337
00344 SoSFInt32 maxGeometryOutputVertices;
00345
00346
00357 SoSFBool generateTransparency;
00358
00365 SoSFInt32 patchLength;
00366
00372 SoMFNode bufferObjects;
00373
00379 SoMFNode images;
00380
00384 SoShaderProgram();
00385
00389 inline SoFragmentShader* getFragmentShader(int pos) const;
00390
00394 inline SoVertexShader* getVertexShader(int pos) const;
00395
00400 inline SoGeometryShader* getGeometryShader(int pos) const;
00401
00406 virtual SoFragmentShader* setFragmentShader(int pos, const SbString& filenameOrSource,
00407 SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME);
00408
00413 virtual SoVertexShader* setVertexShader(int pos, const SbString& filenameOrSource,
00414 SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME);
00415
00421 virtual SoGeometryShader* setGeometryShader(int pos, const SbString& filenameOrSource,
00422 SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME);
00423
00428 virtual SoComputeShader* setComputeShader(int pos, const SbString& filenameOrSource,
00429 SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME);
00430
00435 static unsigned int getNumReservedTextures();
00436
00440 inline SoTessellationControlShader* getTessellationControlShader(int pos) const;
00441
00445 inline SoTessellationEvaluationShader* getTessellationEvaluationShader(int pos) const;
00446
00451 virtual SoTessellationControlShader* setTessellationControlShader(int pos, const SbString& filenameOrSource,
00452 SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME);
00453
00458 virtual SoTessellationEvaluationShader* setTessellationEvaluationShader(int pos, const SbString& filenameOrSource,
00459 SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME);
00460
00461
00462
00467 SoShaderParameterImage* addShaderParameterImage(const SbString& name, SoTexture* tex);
00468
00469 private:
00470
00471
00472 virtual void doAction(SoAction *action);
00473 virtual void GLRender( SoGLRenderAction *action );
00474 virtual void getBoundingBox( SoGetBoundingBoxAction *action );
00475 virtual void pick( SoPickAction *action );
00476
00477 private:
00479 enum GPUVendorType
00480 {
00481 GPU_TYPE_NOT_INITIALIZED = -1,
00482 GPU_NVIDIA = 0,
00483 GPU_ATI = 1,
00484 GPU_INTEL = 2,
00485 GPU_FIREPRO_MAC = 3,
00486 GPU_MESA = 4
00487 };
00488
00489
00490 enum { MAX_IMG_UNITS = 8 };
00491
00493 static const char* getMainSlotName(SbEnums::ShaderType shaderType);
00494
00496 bool hasPrivateMainShaderType(SbEnums::ShaderType shaderType) const;
00497
00499 bool hasPublicMainShaderType(SbEnums::ShaderType shaderType) const;
00500
00502 bool hasMainShaderType(SbEnums::ShaderType shaderType) const;
00503
00505 bool hasFixedPipelineMainShaderType(SbEnums::ShaderType shaderType) const;
00506
00508 bool hasFixedPipelineMain() const;
00509
00511 void getAllParameters(SoState* state, std::vector<SoUniformShaderParameter*>& shaderParameters);
00512
00514 void getShaderObjects(std::vector<SoShaderObject*>& shaderObjectsList) const;
00515
00517 SbString getLinkedShaderFileNames(SbEnums::ShaderType shaderType) const;
00518
00520 void displayLinkedFileNames() const;
00521
00522
00523 static bool isOivReservedName(const std::string ¶mName);
00524
00526 virtual void notify(SoNotList *list);
00527
00529 void setDefine(const char* name, const char* value);
00530 void setDefine(const char* name, const SbString& value)
00531 { setDefine(name,value.toLatin1()); }
00532
00536 bool getDefine(const char* name, SbString& value) const;
00537
00539 void removeDefine(const char* name);
00540
00542 void setHeader(const SbString& filename);
00543
00545 void removeHeader(const SbString& name);
00546
00550 static GLint offsetToGLTextureUnit(SoGLRenderAction* action, const char* offset);
00551
00555 static int offsetToTextureUnit(SoGLRenderAction* action, const char* offset);
00556
00557
00558 static void initClass();
00559 static void exitClass();
00560
00562 void invalidate();
00563
00565 bool isGlslProgram() const;
00566
00568 bool isComputeShader() const;
00569
00571 bool isShadowShader() const;
00572
00574 SoShaderProgram* getShadowPassShader() const;
00575
00577 void setShadowShader(bool flag);
00578
00581 void setHiddenShaderObject(const char* objName, SoShaderObject* obj);
00582
00584 void removeHiddenShaderObject(const char* objName);
00585
00587 SoShaderObject* getHiddenShaderObject(const char* objName) const;
00588
00590 const SbConstCharMap<SoShaderObject*>& getHiddenShaderObjects() const;
00591
00593 static GPUVendorType getGPUVendorType();
00594
00595
00599 template<typename T>
00600 T* setupPrivateShaderStage(const char* hiddenName, const SbString& shaderSource, SoShaderObject::SourceType sourceType = SoShaderObject::FILENAME)
00601 {
00602
00603 T* fp = (T*)getHiddenShaderObject(hiddenName);
00604 if (!fp || (fp->sourceProgram.getValue() != shaderSource))
00605 {
00606 fp = new T;
00607 fp->sourceProgram.setValue(shaderSource);
00608 fp->sourceType = sourceType;
00609 setHiddenShaderObject(hiddenName, fp);
00610 }
00611 return fp;
00612 }
00613
00615 void removeAllPrivateShaderType(SbEnums::ShaderType shaderType);
00616
00618 enum ShaderLibraryState
00619 {
00620 LIBRARY_NOT_INSTALLED,
00621 LIBRARY_INSTALLED_EMPTY,
00622 LIBRARY_INSTALLED,
00623 };
00624
00626 ShaderLibraryState getLibraryState( inventor::helper::ShaderLibrary* library ) const;
00627
00629 void setLibraryState( inventor::helper::ShaderLibrary* library, ShaderLibraryState libraryState );
00630
00631 bool getPreviousNeedDepthPeelingLibrary() const
00632 {
00633 return m_previousNeedDepthPeelingLibrary;
00634 }
00635
00637 void setIsFixedPipeline(bool isFixedPipelineShader)
00638 {
00639 m_isFixedPipelineShader = isFixedPipelineShader;
00640 }
00641
00643 bool isFixedPipeline() const
00644 {
00645 return m_isFixedPipelineShader;
00646 }
00647
00648 private:
00649 typedef std::vector<SoShaderObject*> ShaderObjectVector;
00650 typedef SbConstCharMap<SoShaderObject*> ShaderObjectMap;
00652 typedef SoShaderObject::DefineMap DefineMap;
00653 typedef SoShaderObject::HeaderSet HeaderSet;
00654
00656 struct Members
00657 {
00658 Members();
00659 ~Members();
00660 void unref();
00661
00663 bool m_isShadowShader;
00664
00666 ShaderObjectMap m_hiddenShaderObjects;
00667
00668
00669
00670
00671 std::vector<SoShaderObject*> m_prevShaderObject;
00672 std::vector< SoNode * > m_toUnrefShaderObjects;
00673
00675 SoShaderProgram* m_shadowPassShader;
00676
00678 DefineMap m_defineMap;
00679
00681 HeaderSet m_headerMap;
00682
00684 bool m_isValid;
00685 };
00686 Members m_members;
00687
00688
00689 virtual ~SoShaderProgram();
00690
00691
00692 SbBool isValidShaderObjects() const;
00693
00694
00695
00696 SbBool isOneShaderObjectActive();
00697
00699 static SoShaderProgram::Members* getMembers(const SoShaderProgram* prog);
00700
00701 private:
00702
00703 SoMFNode prevShaderObject;
00704
00706 void addDefines(SoShaderObject* obj);
00707
00709 void addHeaders(SoShaderObject* obj);
00710
00712 void addHiddenShaderObjects(ShaderObjectVector& shaderObjectsList);
00713
00715 static bool lessVersion(SoShaderObject* obj1, SoShaderObject* obj2);
00716
00718 static SbString getMaxVersion(const ShaderObjectVector& objList);
00719
00721 static bool lessProfile(SoShaderObject* obj1, SoShaderObject* obj2);
00722
00725 static SbString getLoosestProfile(const ShaderObjectVector& objList);
00726
00728 bool hasShaderObjectsChanged() const;
00729
00731 void updatePrevShaderObject();
00732
00734 static void invalidate(ShaderObjectMap::value_type& p);
00735
00737 void addGPUVendorDefine();
00738
00740 void setShaderBufferObject(SoGLRenderAction* action);
00741
00743 void setShaderTextureImages(SoGLRenderAction* action) const;
00744
00746 private:
00751 void notifyAddedShaderObject(const char* hiddenShaderObjectName);
00752
00754 static void fileSensorCB(void *data, SoSensor *) ;
00755
00757 void updateFileSensor();
00758
00760 std::unique_ptr<SoFileSensor> m_fileSensor;
00761
00763 bool m_previousNeedDepthPeelingLibrary;
00764
00765 typedef std::unordered_map<inventor::helper::ShaderLibrary*, ShaderLibraryState> ShaderLibraryStateMap;
00766 ShaderLibraryStateMap m_shaderLibrariesStates;
00767
00769 static GPUVendorType s_gpuVendorType;
00770
00772 static int s_firstUsedTextureUnit;
00773
00775 static bool s_debugCache;
00776
00777
00778 bool m_isFixedPipelineShader;
00779
00780 friend class SoUniformShaderParameter;
00781 };
00782
00783
00784
00785 SoFragmentShader*
00786 SoShaderProgram::getFragmentShader(int pos) const
00787 {
00788 assert(pos >= 0 && pos < shaderObject.getNum());
00789 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00790
00791 if ( !obj )
00792 return NULL;
00793
00794 assert(obj->getTypeId() == SoFragmentShader::getClassTypeId());
00795
00796 return static_cast<SoFragmentShader*>(obj);
00797 }
00798
00799
00800 SoVertexShader*
00801 SoShaderProgram::getVertexShader(int pos) const
00802 {
00803 assert(pos >= 0 && pos < shaderObject.getNum());
00804 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00805
00806 if ( !obj )
00807 return NULL;
00808
00809 assert(obj->getTypeId() == SoVertexShader::getClassTypeId());
00810
00811 return static_cast<SoVertexShader*>(obj);
00812 }
00813
00814
00815 SoGeometryShader*
00816 SoShaderProgram::getGeometryShader(int pos) const
00817 {
00818 assert(pos >= 0 && pos < shaderObject.getNum());
00819 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00820
00821 if ( !obj )
00822 return NULL;
00823
00824 assert(obj->getTypeId() == SoGeometryShader::getClassTypeId());
00825
00826 return static_cast<SoGeometryShader*>(obj);
00827 }
00828
00829
00830 SoTessellationControlShader*
00831 SoShaderProgram::getTessellationControlShader(int pos) const
00832 {
00833 assert(pos >= 0 && pos < shaderObject.getNum());
00834 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00835
00836 if ( !obj )
00837 return NULL;
00838
00839 assert(obj->getTypeId() == SoTessellationControlShader::getClassTypeId());
00840
00841 return static_cast<SoTessellationControlShader*>(obj);
00842 }
00843
00844
00845 SoTessellationEvaluationShader*
00846 SoShaderProgram::getTessellationEvaluationShader(int pos) const
00847 {
00848 assert(pos >= 0 && pos < shaderObject.getNum());
00849 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00850
00851 if ( !obj )
00852 return NULL;
00853
00854 assert(obj->getTypeId() == SoTessellationEvaluationShader::getClassTypeId());
00855
00856 return static_cast<SoTessellationEvaluationShader*>(obj);
00857 }
00858
00859 #ifdef _WIN32
00860 #pragma warning(pop)
00861 #endif
00862
00863 #endif
00864
00865
00866