ProgramPipeline.hh 3.97 KB
Newer Older
1
2
3
4
5
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
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2012, Computer Graphics Group RWTH Aachen University         //
// All rights reserved.                                                       //
////////////////////////////////////////////////////////////////////////////////

#ifndef ACGL_OPENGL_OBJECTS_PROGRAMPIPELINE_HH
#define ACGL_OPENGL_OBJECTS_PROGRAMPIPELINE_HH

#include <ACGL/ACGL.hh>

#include <ACGL/Base/Macros.hh>
#include <ACGL/OpenGL/GL.hh>
#include <ACGL/OpenGL/Tools.hh>

#include <ACGL/OpenGL/Objects/ShaderProgram.hh>

namespace ACGL{
namespace OpenGL{

/**
 * OpenGL ProgramPipeline Objects
 *
 * Multiple ShaderPrograms that are set to be separable can be attached to one ProgramPipeline.
 * Uniforms are still a ShaderProgram (not ProgramPipeline) state, so to update them you either have to
 * select the correct ShaderProgram first (glActiveShaderProgram) or use the setProgramUniform variants.
 *
 * When using multiple ShaderPrograms in one ProgramPipeline the varyings don't just match based on
 * the names any more, look up "Shader Interface Matching", cry, and rethink whether you still want to
 * play around with ProgramPipeline Objects.
 */

#if (ACGL_OPENGL_VERSION >= 41)

class ProgramPipeline {
    ACGL_NOT_COPYABLE(ProgramPipeline)
public:
    ProgramPipeline();
    ~ProgramPipeline(void);

    // ==================================================================================================== \/
    // ============================================================================================ GETTERS \/
    // ==================================================================================================== \/
public:
    inline GLuint operator()   (void) const { return mObjectName; }
    inline GLuint getObjectName(void) const { return mObjectName; }

    // ===================================================================================================== \/
    // ============================================================================================ WRAPPERS \/
    // ===================================================================================================== \/
    //! Set this ProgramPipeline active, will override active ShaderPrograms!
    inline void bind() const
    {
        glBindProgramPipeline( mObjectName );
        openGLRareError();
    }

    //! unbinds the ProgramPipeline (if there is one bound), after that, ShaderPrograms can be used again directly
    inline static void unBind() { glBindProgramPipeline( 0 ); }

    //! Sets the given ShaderProgram (that should be part of the ProgramPipeline, which should be active) as target
    //! for setUniform() calls. Alternatively use the setProgramUniform calls!
    inline void setActiveShaderProgram( GLuint _shaderProgram ) { glActiveShaderProgram( mObjectName, _shaderProgram ); }

    //! Sets the given ShaderProgram (that should be part of the ProgramPipeline, which should be active) as target
    //! for setUniform() calls. Alternatively use the setProgramUniform calls!
    inline void setActiveShaderProgram( const SharedShaderProgram &_shaderProgram ) { glActiveShaderProgram( mObjectName, _shaderProgram->getObjectName() ); }

    //! _stages is a bitwise OR of GL_TESS_CONTROL_SHADER_BIT, GL_TESS_EVALUATION_SHADER_BIT, GL_VERTEX_SHADER_BIT, GL_GEOMETRY_SHADER_BIT,
    //! and/or GL_FRAGMENT_SHADER_BIT _or_ GL_ALL_SHADER_BITS
    void useProgramStages( GLbitfield _stages, SharedShaderProgram _shaderProgram ) {
        if (_shaderProgram) {
            glUseProgramStages( mObjectName, _stages, _shaderProgram->getObjectName() );
        } else {
            glUseProgramStages( mObjectName, _stages, 0 ); // deactivates that part of the pipeline (defined by _stages)
        }
    }

private:
    // TODO: save 5 SharedPointer to the 5 ShaderPrograms for the individual stages
    GLuint mObjectName;
};

ACGL_SMARTPOINTER_TYPEDEFS(ProgramPipeline)
#endif // OpenGL >= 4.1

} // OpenGL
} // ACGL

#endif // ACGL_OPENGL_OBJECTS_PROGRAMPIPELINE_HH