GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/render/shaders/shadersmanager.cpp Lines: 0 61 0.0 %
Date: 2017-11-29 Branches: 0 74 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2014-2017  The ManaPlus Developers
4
 *
5
 *  This file is part of The ManaPlus Client.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "render/shaders/shadersmanager.h"
22
23
#ifdef USE_OPENGL
24
25
#include "configuration.h"
26
#include "logger.h"
27
28
#include "fs/virtfs/tools.h"
29
30
#include "utils/cast.h"
31
32
#include "render/opengl/mgl.h"
33
#ifdef __native_client__
34
#include "render/opengl/naclglfunctions.h"
35
#endif  // __native_client__
36
37
#include "render/shaders/shader.h"
38
#include "render/shaders/shaderprogram.h"
39
40
#include "resources/loaders/shaderloader.h"
41
42
#include "debug.h"
43
44
ShadersManager shaders;
45
46
Shader *ShadersManager::createShader(const unsigned int type,
47
                                     const std::string &fileName)
48
{
49
    const std::string str = VirtFs::loadTextFileString(fileName);
50
    const char *ptrStr = str.c_str();
51
    GLuint shaderId = mglCreateShader(type);
52
    mglShaderSource(shaderId, 1, &ptrStr, nullptr);
53
    mglCompileShader(shaderId);
54
55
    GLint isCompiled = 0;
56
    mglGetShaderiv(shaderId, GL_COMPILE_STATUS, &isCompiled);
57
    if (isCompiled == GL_TRUE)
58
        return new Shader(shaderId);
59
    GLint len = 0;
60
    mglGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &len);
61
    char *buf = new char[CAST_SIZE(len) + 1];
62
    mglGetShaderInfoLog(shaderId, len, &len, buf);
63
    buf[len] = 0;
64
    logger->log("Shader '%s' compilation error: %s", fileName.c_str(), buf);
65
    delete [] buf;
66
    mglDeleteShader(shaderId);
67
    return nullptr;
68
}
69
70
ShaderProgram *ShadersManager::createProgram(const std::string &vertex,
71
                                             const std::string &fragment,
72
                                             const bool isNewShader)
73
{
74
    Shader *const vertexShader = static_cast<Shader*>(
75
        Loader::getShader(GL_VERTEX_SHADER, vertex));
76
    if (vertexShader == nullptr)
77
        return nullptr;
78
79
    Shader *const fragmentShader = static_cast<Shader*>(
80
        Loader::getShader(GL_FRAGMENT_SHADER, fragment));
81
82
    if (fragmentShader == nullptr)
83
    {
84
        vertexShader->decRef();
85
        return nullptr;
86
    }
87
88
    GLuint programId = mglCreateProgram();
89
    if (programId == 0u)
90
    {
91
        vertexShader->decRef();
92
        fragmentShader->decRef();
93
        return nullptr;
94
    }
95
96
    mglAttachShader(programId, vertexShader->getShaderId());
97
    mglAttachShader(programId, fragmentShader->getShaderId());
98
    if (isNewShader)
99
        mglBindFragDataLocation(programId, 0, "outColor");
100
    else
101
        mglBindAttribLocation(programId, 0, "position");
102
    mglLinkProgram(programId);
103
    GLint isLinked = 0;
104
    mglGetProgramiv(programId, GL_LINK_STATUS, &isLinked);
105
    if (isLinked == GL_TRUE)
106
    {
107
        mglValidateProgram(programId);
108
        GLint isValidated = 0;
109
        mglGetProgramiv(programId,  GL_VALIDATE_STATUS, &isValidated);
110
        if (isValidated == GL_TRUE)
111
            return new ShaderProgram(programId, vertexShader, fragmentShader);
112
        mglDeleteProgram(programId);
113
        return nullptr;
114
    }
115
116
    GLint len = 0;
117
    mglGetProgramiv(programId, GL_INFO_LOG_LENGTH, &len);
118
    char *buf = new char[CAST_SIZE(len) + 1];
119
    mglGetProgramInfoLog(programId, len, &len, buf);
120
    buf[len] = 0;
121
    logger->log("Program '%s, %s' compilation error: %s",
122
        vertexShader->mIdPath.c_str(),
123
        fragmentShader->mIdPath.c_str(),
124
        buf);
125
    delete [] buf;
126
    mglDeleteProgram(programId);
127
    return nullptr;
128
}
129
130
ShaderProgram *ShadersManager::getSimpleProgram()
131
{
132
    const std::string dir = paths.getStringValue("shaders");
133
    return createProgram(dir + paths.getStringValue("simpleVertexShader"),
134
        dir + paths.getStringValue("simpleFragmentShader"),
135
        true);
136
}
137
138
ShaderProgram *ShadersManager::getGles2Program()
139
{
140
    const std::string dir = paths.getStringValue("shaders");
141
    return createProgram(dir + paths.getStringValue("gles2VertexShader"),
142
        dir + paths.getStringValue("gles2FragmentShader"),
143
        false);
144
}
145
146
#endif  // USE_OPENGL