ShaderProgramControlFiles.hh 8.75 KB
Newer Older
1
////////////////////////////////////////////////////////////////////////////////
2
// Copyright (c) 2011, 2012 Computer Graphics Group RWTH Aachen University    //
3 4 5 6 7 8
// All rights reserved.                                                       //
////////////////////////////////////////////////////////////////////////////////

#ifndef ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLFILES_HH
#define ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLFILES_HH

9
/**
10 11 12 13 14 15 16 17 18
 * Used to create a ShaderProgram from a given set of file names:
 * e.g.:
 *      SharedShaderProgram prog = ShaderProgramControlFiles("file.vsh").andFile("foobar.fsh").create();
 *
 * The shadertype will be guessed by the extensions.
 */

#include <ACGL/ACGL.hh>

19
#include <ACGL/Resource/MultiFileController.hh>
20 21 22
#include <ACGL/Resource/FileController.hh>
#include <ACGL/OpenGL/Objects/ShaderProgram.hh>
#include <ACGL/OpenGL/GL.hh>
23
#include <ACGL/Base/Settings.hh>
24 25

#include <vector>
26
#include <ACGL/OpenGL/Data/LocationMappings.hh>
27 28 29 30

namespace ACGL{
namespace OpenGL{

31
class ShaderProgramControlFiles : public Resource::MultiFileController<ShaderProgram>
32
{
33 34 35 36 37 38 39 40
    struct ShaderEndings
    {
        const char *ending;
        GLenum      type;
    };
    static const unsigned int  sShaderEndingsSize; // size of the array sShaderEndings
    static const ShaderEndings sShaderEndings[];   // all supported endings (see .cc file)

41 42 43 44
    // ========================================================================================================= \/
    // ============================================================================================ CONSTRUCTORS \/
    // ========================================================================================================= \/
public:
45
    //! The filenames (sorted and concatenated) will also be the name of the resource (can be changed by setResourceName() below).
46 47 48
    //! If the filename has a dot in it (or _type is set), it will be treated as a single file, otherwise all
    //! files starting with that string will be used.
    ShaderProgramControlFiles(const std::string& _fileName, GLenum _type = GL_INVALID_VALUE )
49
        :   Resource::MultiFileController<ShaderProgram>(),
50
        mShaderType(),
51
        mAttributeLocations(new LocationMappings),
52 53
        mFragmentDataLocations(new LocationMappings),
        mUniformBufferLocations(new LocationMappings)
54
    {
55 56 57 58
        // the base path is only needed for updating the time stamps, as the shaders itself get loaded via ShaderControlFiles
        // which itself will add the base path! (read: mFileNames will _NOT_ store the base path!)
        mBasePath = Base::Settings::the()->getFullShaderPath();

59 60 61 62
        if ( _type != GL_INVALID_VALUE ) {
            andFile( _fileName, _type );
            return;
        }
63
        // only add the first name if it is a valid file name
64
        if ( _fileName.find( "." ) != std::string::npos ) {
65
            andFile( _fileName );
66 67 68
        } else {
            autoFiles( _fileName );
        }
69
    }
70

71 72 73 74 75 76
    virtual ~ShaderProgramControlFiles(void) {}

    // ==================================================================================================== \/
    // ============================================================================================ METHODS \/
    // ==================================================================================================== \/
public:
77 78 79
    //
    // Adding files:
    //
80
    //! adds a single file, the shader type will be guessed by the ending:
81
    inline ShaderProgramControlFiles& andFile              (const std::string &_fileName)               { addFile( _fileName ); mShaderType.push_back( GL_INVALID_VALUE ); return *this; }
82 83 84

    //! adds a single file, the shader type is explicitly given and must be one of:
    //! GL_VERTEX_SHADER, GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER, GL_GEOMETRY_SHADER, GL_FRAGMENT_SHADER
85
    inline ShaderProgramControlFiles& andFile              (const std::string &_fileName, GLenum _type) { addFile( _fileName ); mShaderType.push_back( _type ); return *this; }
86 87 88 89

    //! adds all files begining with the given name, the shader type will be guessed by the ending:
           ShaderProgramControlFiles& autoFiles            (const std::string &_fileName);

90
    //
91
    // Adding attribute locations:
92 93 94 95 96 97 98
    //
    //! adds an attribute location to the next free location number:
    inline ShaderProgramControlFiles& attributeLocation    (const std::string &_attributeName)                      { mAttributeLocations->setLocation(_attributeName);                 return *this; }

    //! adds an attribute location to the given location number:
    inline ShaderProgramControlFiles& attributeLocation    (const std::string &_attributeName, GLuint _location)    { mAttributeLocations->setLocation(_attributeName,_location);       return *this; }

99 100 101
    //! adds a whole list of mappings
    inline ShaderProgramControlFiles& attributeLocations   (const SharedLocationMappings &_mapping) { mAttributeLocations->addLocations(_mapping);    return *this; }

102 103 104 105
    //! links to the external mapping object, earlyer mapping definitions get ignored, following
    //! mappings will also change the external object!
    inline ShaderProgramControlFiles& externAttributeLocations   (SharedLocationMappings _mapping) { mAttributeLocations = _mapping; return *this; }

106 107 108
    //
    // Adding fragment output locations:
    //
109 110 111 112 113 114 115
    //! adds a fragment output location to the next free location number:
    inline ShaderProgramControlFiles& fragmentDataLocation (const std::string &_fragmentDataName)                   { mFragmentDataLocations->setLocation(_fragmentDataName);           return *this; }

    //! adds a fragment output location to the given location number:
    inline ShaderProgramControlFiles& fragmentDataLocation (const std::string &_fragmentDataName, GLuint _location) { mFragmentDataLocations->setLocation(_fragmentDataName,_location); return *this; }

    //! adds a whole list of mappings
116 117
    inline ShaderProgramControlFiles& fragmentDataLocations(const SharedLocationMappings &_mapping) { mFragmentDataLocations->addLocations(_mapping); return *this; }

118 119 120 121
    //! links to the external mapping object, earlyer mapping definitions get ignored, following
    //! mappings will also change the external object!
    inline ShaderProgramControlFiles& externFragmentDataLocations (SharedLocationMappings _mapping) { mFragmentDataLocations = _mapping; return *this; }

122 123 124 125 126 127 128 129
    //
    // Adding uniform buffer locations:
    //
    //! adds an attribute location to the next free location number:
    inline ShaderProgramControlFiles& uniformBufferLocation(const std::string &_uniformBufferName)                  { mUniformBufferLocations->setLocation(_uniformBufferName);         return *this; }

    //! adds an attribute location to the given location number:
    inline ShaderProgramControlFiles& uniformBufferLocation(const std::string &_uniformBufferName, GLuint _location){ mUniformBufferLocations->setLocation(_uniformBufferName,_location);return *this; }
130 131

    //! adds a whole list of mappings
132
    inline ShaderProgramControlFiles& uniformBufferLocations(SharedLocationMappings _mapping) { mUniformBufferLocations->addLocations(_mapping);return *this; }
133

134 135
    inline ShaderProgramControlFiles& externUniformBufferLocations(SharedLocationMappings _mapping) { mUniformBufferLocations = _mapping; return *this; }

136 137 138 139 140 141 142
    //
    // Modifying the resource name:
    // A ShaderProgram consists of multiple shader files, so associating the ShaderProgram with just one of those file names
    // is often not useful.
    //
    inline ShaderProgramControlFiles& setResourceName(const std::string &_resourceName) { mResourceName = _resourceName; return *this; }

143 144 145 146 147 148 149 150 151 152 153 154 155

    // ===================================================================================================== \/
    // ============================================================================================ OVERRIDE \/
    // ===================================================================================================== \/
public:
    virtual SharedShaderProgram create(void);
    virtual bool update(SharedShaderProgram &_shaderProgram);

    // =================================================================================================== \/
    // ============================================================================================ FIELDS \/
    // =================================================================================================== \/
protected:
    std::vector<GLenum>      mShaderType;
156 157 158

    SharedLocationMappings mAttributeLocations;
    SharedLocationMappings mFragmentDataLocations;
159
    SharedLocationMappings mUniformBufferLocations;
160 161

private:
Robert Menzel's avatar
Robert Menzel committed
162 163
    // set attribute, UBO & fragdata locations and links the program
    bool setBindings(SharedShaderProgram &_shaderProgram);
164 165 166 167 168 169
};

} // OpenGL
} // ACGL

#endif // ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLFILES_HH