GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/render/shaders/shadersmanager.cpp Lines: 0 62 0.0 %
Date: 2021-03-17 Branches: 0 74 0.0 %

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