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 SoVertexShader* setHiddenVertexShader(const char* objName, const SbString& filenameOrSource,
00585 SoShaderObject::SourceType sourceType);
00586
00588 SoFragmentShader* setHiddenFragmentShader(const char* objName, const SbString& filenameOrSource,
00589 SoShaderObject::SourceType sourceType);
00590
00592 void removeHiddenShaderObject(const char* objName);
00593
00595 SoShaderObject* getHiddenShaderObject(const char* objName) const;
00596
00598 const SbConstCharMap<SoShaderObject*>& getHiddenShaderObjects() const;
00599
00601 static GPUVendorType getGPUVendorType();
00602
00603
00607 template<typename T>
00608 T* setupPrivateShaderStage(const char* hiddenName, const SbString& shaderSource)
00609 {
00610
00611 T* fp = (T*)getHiddenShaderObject(hiddenName);
00612 if (!fp || (fp->sourceProgram.getValue() != shaderSource))
00613 {
00614 fp = new T;
00615 fp->sourceProgram.setValue(shaderSource);
00616 setHiddenShaderObject(hiddenName, fp);
00617 }
00618 return fp;
00619 }
00620
00622 void removeAllPrivateShaderType(SbEnums::ShaderType shaderType);
00623
00625 enum ShaderLibraryState
00626 {
00627 LIBRARY_NOT_INSTALLED,
00628 LIBRARY_INSTALLED_EMPTY,
00629 LIBRARY_INSTALLED,
00630 };
00631
00633 ShaderLibraryState getLibraryState( inventor::helper::ShaderLibrary* library ) const;
00634
00636 void setLibraryState( inventor::helper::ShaderLibrary* library, ShaderLibraryState libraryState );
00637
00638 void addInternalTextureImage(SoShaderParameterImage* textureImage);
00639
00640 void removeInternalTextureImage(SoShaderParameterImage* textureImage);
00641
00642 bool getPreviousNeedDepthPeelingLibrary() const
00643 {
00644 return m_previousNeedDepthPeelingLibrary;
00645 }
00646
00648 void setIsFixedPipeline(bool isFixedPipelineShader)
00649 {
00650 m_isFixedPipelineShader = isFixedPipelineShader;
00651 }
00652
00654 bool isFixedPipeline() const
00655 {
00656 return m_isFixedPipelineShader;
00657 }
00658
00659 private:
00660 typedef std::vector<SoShaderObject*> ShaderObjectVector;
00661 typedef SbConstCharMap<SoShaderObject*> ShaderObjectMap;
00663 typedef SoShaderObject::DefineMap DefineMap;
00664 typedef SoShaderObject::HeaderSet HeaderSet;
00665
00667 struct Members
00668 {
00669 Members();
00670 ~Members();
00671 void unref();
00672
00674 bool m_isShadowShader;
00675
00677 ShaderObjectMap m_hiddenShaderObjects;
00678
00679
00680
00681
00682 std::vector<SoShaderObject*> m_prevShaderObject;
00683 std::vector< SoNode * > m_toUnrefShaderObjects;
00684
00686 SoShaderProgram* m_shadowPassShader;
00687
00689 DefineMap m_defineMap;
00690
00692 HeaderSet m_headerMap;
00693
00695 bool m_isValid;
00696 };
00697 Members m_members;
00698
00699
00700 virtual ~SoShaderProgram();
00701
00702
00703 SbBool isValidShaderObjects() const;
00704
00705
00706
00707 SbBool isOneShaderObjectActive();
00708
00710 static SoShaderProgram::Members* getMembers(const SoShaderProgram* prog);
00711
00712 private:
00713
00714 SoMFNode prevShaderObject;
00715
00717 void addDefines(SoShaderObject* obj);
00718
00720 void addHeaders(SoShaderObject* obj);
00721
00723 void addHiddenShaderObjects(ShaderObjectVector& shaderObjectsList);
00724
00726 static bool lessVersion(SoShaderObject* obj1, SoShaderObject* obj2);
00727
00729 static SbString getMaxVersion(const ShaderObjectVector& objList);
00730
00732 static bool lessProfile(SoShaderObject* obj1, SoShaderObject* obj2);
00733
00736 static SbString getLoosestProfile(const ShaderObjectVector& objList);
00737
00739 bool hasShaderObjectsChanged() const;
00740
00742 void updatePrevShaderObject();
00743
00745 static void invalidate(ShaderObjectMap::value_type& p);
00746
00748 void addGPUVendorDefine();
00749
00751 void setShaderBufferObject(SoGLRenderAction* action);
00752
00754 void setShaderTextureImages(SoGLRenderAction* action) const;
00755
00757 private:
00762 void notifyAddedShaderObject(const char* hiddenShaderObjectName);
00763
00765 static void fileSensorCB(void *data, SoSensor *) ;
00766
00768 void updateFileSensor();
00769
00771 std::unique_ptr<SoFileSensor> m_fileSensor;
00772
00774 bool m_previousNeedDepthPeelingLibrary;
00775
00776 std::set<SoShaderParameterImage*> m_internalTextureImages;
00777
00778 typedef std::unordered_map<inventor::helper::ShaderLibrary*, ShaderLibraryState> ShaderLibraryStateMap;
00779 ShaderLibraryStateMap m_shaderLibrariesStates;
00780
00782 static GPUVendorType s_gpuVendorType;
00783
00785 static int s_firstUsedTextureUnit;
00786
00788 static bool s_debugCache;
00789
00790
00791 bool m_isFixedPipelineShader;
00792
00793 friend class SoUniformShaderParameter;
00794 };
00795
00796
00797
00798 SoFragmentShader*
00799 SoShaderProgram::getFragmentShader(int pos) const
00800 {
00801 assert(pos >= 0 && pos < shaderObject.getNum());
00802 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00803
00804 if ( !obj )
00805 return NULL;
00806
00807 assert(obj->getTypeId() == SoFragmentShader::getClassTypeId());
00808
00809 return static_cast<SoFragmentShader*>(obj);
00810 }
00811
00812
00813 SoVertexShader*
00814 SoShaderProgram::getVertexShader(int pos) const
00815 {
00816 assert(pos >= 0 && pos < shaderObject.getNum());
00817 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00818
00819 if ( !obj )
00820 return NULL;
00821
00822 assert(obj->getTypeId() == SoVertexShader::getClassTypeId());
00823
00824 return static_cast<SoVertexShader*>(obj);
00825 }
00826
00827
00828 SoGeometryShader*
00829 SoShaderProgram::getGeometryShader(int pos) const
00830 {
00831 assert(pos >= 0 && pos < shaderObject.getNum());
00832 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00833
00834 if ( !obj )
00835 return NULL;
00836
00837 assert(obj->getTypeId() == SoGeometryShader::getClassTypeId());
00838
00839 return static_cast<SoGeometryShader*>(obj);
00840 }
00841
00842
00843 SoTessellationControlShader*
00844 SoShaderProgram::getTessellationControlShader(int pos) const
00845 {
00846 assert(pos >= 0 && pos < shaderObject.getNum());
00847 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00848
00849 if ( !obj )
00850 return NULL;
00851
00852 assert(obj->getTypeId() == SoTessellationControlShader::getClassTypeId());
00853
00854 return static_cast<SoTessellationControlShader*>(obj);
00855 }
00856
00857
00858 SoTessellationEvaluationShader*
00859 SoShaderProgram::getTessellationEvaluationShader(int pos) const
00860 {
00861 assert(pos >= 0 && pos < shaderObject.getNum());
00862 SoShaderObject* obj = static_cast<SoShaderObject*>(shaderObject[pos]);
00863
00864 if ( !obj )
00865 return NULL;
00866
00867 assert(obj->getTypeId() == SoTessellationEvaluationShader::getClassTypeId());
00868
00869 return static_cast<SoTessellationEvaluationShader*>(obj);
00870 }
00871
00872 #ifdef _WIN32
00873 #pragma warning(pop)
00874 #endif
00875
00876 #endif
00877
00878
00879