ManaPlus
shadersmanager.cpp
Go to the documentation of this file.
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 
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__
36 #endif // __native_client__
37 
38 #include "render/shaders/shader.h"
40 
42 
43 #include "debug.h"
44 
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*>(
77  if (vertexShader == nullptr)
78  return nullptr;
79 
80  Shader *const fragmentShader = static_cast<Shader*>(
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 
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 
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
#define CAST_SIZE
Definition: cast.h:34
std::string getStringValue(const std::string &key) const
void log(const char *const log_text,...)
Definition: logger.cpp:269
std::string mIdPath
Definition: resource.h:84
virtual void decRef()
Definition: resource.cpp:50
Definition: shader.h:30
unsigned int getShaderId() const
Definition: shader.h:38
ShaderProgram * getGles2Program()
ShaderProgram * createProgram(const std::string &vertex, const std::string &fragment, const bool isNewShader)
ShaderProgram * getSimpleProgram()
Shader * createShader(const unsigned int type, const std::string &fileName)
Configuration paths
Logger * logger
Definition: logger.cpp:89
#define GL_FRAGMENT_SHADER
Definition: mgldefines.h:95
#define GL_VALIDATE_STATUS
Definition: mgldefines.h:99
#define GL_COMPILE_STATUS
Definition: mgldefines.h:97
#define GL_VERTEX_SHADER
Definition: mgldefines.h:96
#define GL_LINK_STATUS
Definition: mgldefines.h:98
#define GL_INFO_LOG_LENGTH
Definition: mgldefines.h:100
Resource * getShader(const unsigned int type, const std::string &name)
std::string loadTextFileString(const std::string &fileName)
Definition: tools.cpp:122
ShadersManager shaders
std::string fileName
Definition: testmain.cpp:39