ShaderProgram.hh 7.09 KB
Newer Older
1
2
3
4
5
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University         //
// All rights reserved.                                                       //
////////////////////////////////////////////////////////////////////////////////

Robert Menzel's avatar
Robert Menzel committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#ifndef ACGL_RESOURCE_SHADERPROGRAM_HH
#define ACGL_RESOURCE_SHADERPROGRAM_HH

#include "ResourceTypes.hh"
#include "Shader.hh"
#include "Texture.hh"
#include <ACGL/Math/Math.hh>
#include <ACGL/Types.hh>
#include <ACGL/GL.hh>

#include <vector>

namespace ACGL{
namespace Resource{

class ShaderProgram
{
    // ===================================================================================================== \/
    // ============================================================================================ TYPEDEFS \/
    // ===================================================================================================== \/
public:
    typedef std::vector< SharedShader > SharedShaderVec;

    // ========================================================================================================= \/
    // ============================================================================================ CONSTRUCTORS \/
    // ========================================================================================================= \/
public:
    ShaderProgram(void)
    :   mContext(0),
        mShaders()
    {
        mContext = glCreateProgram();
    }

    virtual ~ShaderProgram(void)
    {
        for(SharedShaderVec::size_type i = 0; i < mShaders.size(); ++i) {
            if(mShaders[i]) {
                // we have to detach all shaders, otherwise the attached shaders will get deleted by
                // OpenGL: "When a program object is deleted, all shader objects attached to it are detached"
                //  - GL Spec
                glDetachShader(mContext, mShaders[i]->getContext());
            }
        }

        // "DeleteProgram will silently ignore the value zero." - GL Spec
        glDeleteProgram(mContext);
    }

    // ==================================================================================================== \/
    // ============================================================================================ GETTERS \/
    // ==================================================================================================== \/
public:
    inline       GLuint           getContext (void) const { return mContext; }
    inline const SharedShaderVec& getShaders (void) const { return mShaders; }

    // ===================================================================================================== \/
    // ============================================================================================ WRAPPERS \/
    // ===================================================================================================== \/
public:
    inline GLint getUniformLocation (const std::string& _nameInShader) const { return glGetUniformLocation(mContext, _nameInShader.c_str()); }
    inline GLint getAttribLocation  (const std::string& _nameInShader) const { return glGetAttribLocation (mContext, _nameInShader.c_str()); }

    inline void attachShader(const SharedShader& _shader)
    {
        mShaders.push_back(_shader);
        glAttachShader(mContext, _shader->getContext());
    }

    bool link (void) const;

    inline void setUniform (GLint _location, GLint _v)            const { glUniform1i (_location, _v); }
    inline void setUniform (GLint _location, GLfloat _v)          const { glUniform1f (_location, _v); }
    inline void setUniform (GLint _location, const glm::vec2& _v) const { glUniform2fv(_location, 1, glm::value_ptr(_v)); }
    inline void setUniform (GLint _location, const glm::vec3& _v) const { glUniform3fv(_location, 1, glm::value_ptr(_v)); }
    inline void setUniform (GLint _location, const glm::vec4& _v) const { glUniform4fv(_location, 1, glm::value_ptr(_v)); }
    inline void setUniform (GLint _location, const glm::mat2& _v) const { glUniformMatrix2fv(_location, 1, GL_FALSE, glm::value_ptr(_v)); }
    inline void setUniform (GLint _location, const glm::mat3& _v) const { glUniformMatrix3fv(_location, 1, GL_FALSE, glm::value_ptr(_v)); }
    inline void setUniform (GLint _location, const glm::mat4& _v) const { glUniformMatrix4fv(_location, 1, GL_FALSE, glm::value_ptr(_v)); }

    inline void setTexture (GLint _location, const SharedTexture& _texture, GLenum _unit = 0) const { glUniform1i(_location, _unit); _texture->bind(_unit); }

    inline void use (void) const { glUseProgram(mContext); }

    inline GLint getUniformLocation( const char *_name ) const { return glGetUniformLocation( mContext, _name ); }

    // =================================================================================================== \/
    // ============================================================================== HIGH LEVEL FUNCTIONS \/
    // =================================================================================================== \/

    inline void setUniform (const std::string& _nameInShader, GLint _v)            const { glUniform1i (getUniformLocation(_nameInShader), _v); }
    inline void setUniform (const std::string& _nameInShader, GLfloat _v)          const { glUniform1f (getUniformLocation(_nameInShader), _v); }
    inline void setUniform (const std::string& _nameInShader, const glm::vec2& _v) const { glUniform2fv(getUniformLocation(_nameInShader), 1, glm::value_ptr(_v)); }
    inline void setUniform (const std::string& _nameInShader, const glm::vec3& _v) const { glUniform3fv(getUniformLocation(_nameInShader), 1, glm::value_ptr(_v)); }
    inline void setUniform (const std::string& _nameInShader, const glm::vec4& _v) const { glUniform4fv(getUniformLocation(_nameInShader), 1, glm::value_ptr(_v)); }
    inline void setUniform (const std::string& _nameInShader, const glm::mat2& _v) const { glUniformMatrix2fv(getUniformLocation(_nameInShader), 1, GL_FALSE, glm::value_ptr(_v)); }
    inline void setUniform (const std::string& _nameInShader, const glm::mat3& _v) const { glUniformMatrix3fv(getUniformLocation(_nameInShader), 1, GL_FALSE, glm::value_ptr(_v)); }
    inline void setUniform (const std::string& _nameInShader, const glm::mat4& _v) const { glUniformMatrix4fv(getUniformLocation(_nameInShader), 1, GL_FALSE, glm::value_ptr(_v)); }

    inline void setTexture (const std::string& _nameInShader, const SharedTexture& _texture, GLenum _unit = 0) const { glUniform1i(getUniformLocation(_nameInShader), _unit); _texture->bind(_unit); }

    // =================================================================================================== \/
    // ============================================================================================ FIELDS \/
    // =================================================================================================== \/
protected:
111
112
    void bindAttributeLocations() const;

Robert Menzel's avatar
Robert Menzel committed
113
114
115
116
117
118
119
120
    GLuint          mContext;
    SharedShaderVec mShaders;
};

} // Resource
} // ACGL

#endif // ACGL_RESOURCE_SHADERPROGRAM_HH