summaryrefslogtreecommitdiff
path: root/LayerManagerBase/src/Shader.cpp
blob: c4a12c545fef7a4ef752f88bda580748181b79b5 (plain)
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
90
91
92
93
94
95
96
97
98
99
100
/***************************************************************************
*
* Copyright 2010,2011 BMW Car IT GmbH
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*        http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
****************************************************************************/

#include <Shader.h>

unsigned int Shader::m_nextUniqueShaderId = 1;

Shader* Shader::createShader(const string& vertFileName, const string& fragFileName)
{
    Shader* shader = 0;
    ShaderProgram* program = 0;

    // Obtain shader program. If a shader program of the same name already exists,
    // its instance will be returned. If it doesn't exist, a new program is returned.
    program = ShaderProgram::obtain(vertFileName, fragFileName);

    if (program)
    {
        // create shader instance
        shader = new Shader(*program);
    }
    else
    {
        // failed to load, compile or link the program
    }

    return shader;
}

Shader::Shader(ShaderProgram& program)
    : m_uniqueShaderId(m_nextUniqueShaderId++)
    , m_program(program)
    , m_uniformMap()
{
    // increase program reference counter
    m_program.ref();
}

Shader::~Shader()
{
    // decrease program reference counter.
    // This might destroy the program if no longer in use.
    m_program.unref();

    UniformMapIterator iter = m_uniformMap.begin();
    UniformMapIterator iterEnd = m_uniformMap.end();

    for (; iter != iterEnd; ++iter)
    {
        ShaderUniform* shaderUniform = (*iter).second;
        delete shaderUniform;
    }

    m_uniformMap.clear();
}

void Shader::setUniform(const ShaderUniform& uniform)
{
    const string& name = uniform.getName();

    if (0 == m_uniformMap.count(name))
    {
        // add new uniform
        int location = m_program.getUniformLocation(name.c_str());
        ShaderUniform* pNewUniform = new ShaderUniform(name, location);
        m_uniformMap[name] = pNewUniform;
    }

    // update uniform data
    m_uniformMap[name]->setData(uniform);
}

void Shader::loadUniforms(void)
{
    UniformMapConstIterator iter = m_uniformMap.begin();
    UniformMapConstIterator iterEnd = m_uniformMap.end();

    for (; iter != iterEnd; ++iter)
    {
        ShaderUniform* uniform = (*iter).second;
        uniform->load(m_program);
    }
}