ShaderProgramControlFiles.hh 8.55 KB
Newer Older
1 2 3 4 5
/***********************************************************************
 * Copyright 2011-2012 Computer Graphics Group RWTH Aachen University. *
 * All rights reserved.                                                *
 * Distributed under the terms of the MIT License (see LICENSE.TXT).   *
 **********************************************************************/
6 7 8 9

#ifndef ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLFILES_HH
#define ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLFILES_HH

10
/**
11 12 13 14 15 16 17 18 19
 * 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>

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

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

namespace ACGL{
namespace OpenGL{

32
class ShaderProgramControlFiles : public Resource::MultiFileController<ShaderProgram>
33 34 35 36 37
{
    // ========================================================================================================= \/
    // ============================================================================================ CONSTRUCTORS \/
    // ========================================================================================================= \/
public:
38
    //! The filenames (sorted and concatenated) will also be the name of the resource (can be changed by setResourceName() below).
39 40 41
    //! 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 )
42
        :   Resource::MultiFileController<ShaderProgram>(),
43
        mShaderType(),
44
        mAttributeLocations(new LocationMappings),
45 46
        mFragmentDataLocations(new LocationMappings),
        mUniformBufferLocations(new LocationMappings)
47
    {
48 49 50 51
        // 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();

52 53 54 55
        if ( _type != GL_INVALID_VALUE ) {
            andFile( _fileName, _type );
            return;
        }
56
        // only add the first name if it is a valid file name
57
        if ( _fileName.find( "." ) != std::string::npos ) {
58
            andFile( _fileName );
59 60 61
        } else {
            autoFiles( _fileName );
        }
62
    }
63

64 65 66 67 68 69
    virtual ~ShaderProgramControlFiles(void) {}

    // ==================================================================================================== \/
    // ============================================================================================ METHODS \/
    // ==================================================================================================== \/
public:
70 71 72
    //
    // Adding files:
    //
73
    //! adds a single file, the shader type will be guessed by the ending:
74
    inline ShaderProgramControlFiles& andFile              (const std::string &_fileName)               { addFile( _fileName ); mShaderType.push_back( GL_INVALID_VALUE ); return *this; }
75 76

    //! adds a single file, the shader type is explicitly given and must be one of:
77
    //! GL_VERTEX_SHADER, GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER, GL_GEOMETRY_SHADER, GL_FRAGMENT_SHADER, GL_COMPUTE_SHADER
78
    inline ShaderProgramControlFiles& andFile              (const std::string &_fileName, GLenum _type) { addFile( _fileName ); mShaderType.push_back( _type ); return *this; }
79 80 81 82

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

83
    //
84
    // Adding attribute locations:
85 86 87 88 89 90 91
    //
    //! 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; }

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

95 96 97 98
    //! 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; }

99 100 101
    //
    // Adding fragment output locations:
    //
102 103 104 105 106 107 108
    //! 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
109 110
    inline ShaderProgramControlFiles& fragmentDataLocations(const SharedLocationMappings &_mapping) { mFragmentDataLocations->addLocations(_mapping); return *this; }

111 112 113 114
    //! 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; }

115 116 117 118 119 120 121 122
    //
    // 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; }
123 124

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

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

129 130 131 132 133 134 135
    //
    // 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; }

136 137 138 139 140 141 142 143 144 145 146 147 148

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

    // =================================================================================================== \/
    // ============================================================================================ FIELDS \/
    // =================================================================================================== \/
protected:
    std::vector<GLenum>      mShaderType;
149 150 151

    SharedLocationMappings mAttributeLocations;
    SharedLocationMappings mFragmentDataLocations;
152
    SharedLocationMappings mUniformBufferLocations;
153 154

private:
Robert Menzel's avatar
Robert Menzel committed
155 156
    // set attribute, UBO & fragdata locations and links the program
    bool setBindings(SharedShaderProgram &_shaderProgram);
157 158 159 160 161 162
};

} // OpenGL
} // ACGL

#endif // ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLFILES_HH