Otclient  14/8/2020
shaderprogram.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "shaderprogram.h"
24 #include "graphics.h"
25 
27 
28 uint ShaderProgram::m_currentProgram = 0;
29 
31 {
32  m_linked = false;
33  m_programId = glCreateProgram();
34  m_uniformLocations.fill(-1);
35  if(!m_programId)
36  g_logger.fatal("Unable to create GL shader program");
37 }
38 
40 {
41 #ifndef NDEBUG
42  assert(!g_app.isTerminated());
43 #endif
44  if(g_graphics.ok())
45  glDeleteProgram(m_programId);
46 }
47 
48 bool ShaderProgram::addShader(const ShaderPtr& shader) {
49  glAttachShader(m_programId, shader->getShaderId());
50  m_linked = false;
51  m_shaders.push_back(shader);
52  return true;
53 }
54 
55 bool ShaderProgram::addShaderFromSourceCode(Shader::ShaderType shaderType, const std::string& sourceCode) {
56  ShaderPtr shader(new Shader(shaderType));
57  if(!shader->compileSourceCode(sourceCode)) {
58  g_logger.error(stdext::format("failed to compile shader: %s", shader->log()));
59  return false;
60  }
61  return addShader(shader);
62 }
63 
64 bool ShaderProgram::addShaderFromSourceFile(Shader::ShaderType shaderType, const std::string& sourceFile) {
65  ShaderPtr shader(new Shader(shaderType));
66  if(!shader->compileSourceFile(sourceFile)) {
67  g_logger.error(stdext::format("failed to compile shader: %s", shader->log()));
68  return false;
69  }
70  return addShader(shader);
71 }
72 
74 {
75  auto it = std::find(m_shaders.begin(), m_shaders.end(), shader);
76  if(it == m_shaders.end())
77  return;
78 
79  glDetachShader(m_programId, shader->getShaderId());
80  m_shaders.erase(it);
81  m_linked = false;
82 }
83 
85 {
86  while(!m_shaders.empty())
87  removeShader(m_shaders.front());
88 }
89 
91 {
92  if(m_linked)
93  return true;
94 
95  glLinkProgram(m_programId);
96 
97  int value = GL_FALSE;
98  glGetProgramiv(m_programId, GL_LINK_STATUS, &value);
99  m_linked = (value != GL_FALSE);
100 
101  if(!m_linked)
102  g_logger.traceWarning(log());
103  return m_linked;
104 }
105 
107 {
108  if(m_currentProgram != m_programId) {
109  if(!m_linked && !link())
110  return false;
111  glUseProgram(m_programId);
112  m_currentProgram = m_programId;
113  }
114  return true;
115 }
116 
118 {
119  if(m_currentProgram != 0) {
120  m_currentProgram = 0;
121  glUseProgram(0);
122  }
123 }
124 
125 std::string ShaderProgram::log()
126 {
127  std::string infoLog;
128  int infoLogLength = 0;
129  glGetProgramiv(m_programId, GL_INFO_LOG_LENGTH, &infoLogLength);
130  if(infoLogLength > 1) {
131  std::vector<char> buf(infoLogLength);
132  glGetShaderInfoLog(m_programId, infoLogLength-1, nullptr, &buf[0]);
133  infoLog = &buf[0];
134  }
135  return infoLog;
136 }
137 
139 {
140  return glGetAttribLocation(m_programId, name);
141 }
142 
143 void ShaderProgram::bindAttributeLocation(int location, const char* name)
144 {
145  return glBindAttribLocation(m_programId, location, name);
146 }
147 
148 void ShaderProgram::bindUniformLocation(int location, const char* name)
149 {
150  assert(m_linked);
151  assert(location >= 0 && location < MAX_UNIFORM_LOCATIONS);
152  m_uniformLocations[location] = glGetUniformLocation(m_programId, name);
153 }
ShaderProgram::~ShaderProgram
~ShaderProgram()
Definition: shaderprogram.cpp:39
graphics.h
Graphics::ok
bool ok()
Definition: graphics.h:65
ShaderProgram::addShaderFromSourceFile
bool addShaderFromSourceFile(Shader::ShaderType shaderType, const std::string &sourceFile)
Definition: shaderprogram.cpp:64
ShaderProgram::release
static void release()
Definition: shaderprogram.cpp:117
Logger::error
void error(const std::string &what)
Definition: logger.h:54
ShaderProgram::addShader
bool addShader(const ShaderPtr &shader)
Definition: shaderprogram.cpp:48
Shader::ShaderType
ShaderType
Definition: shader.h:31
stdext::format
std::string format()
Definition: format.h:82
Logger::fatal
void fatal(const std::string &what)
Definition: logger.h:55
ShaderProgram::link
virtual bool link()
Definition: shaderprogram.cpp:90
uint
unsigned int uint
Definition: types.h:31
g_logger
Logger g_logger
Definition: logger.cpp:35
ShaderProgram::bind
bool bind()
Definition: shaderprogram.cpp:106
ShaderProgram::removeAllShaders
void removeAllShaders()
Definition: shaderprogram.cpp:84
g_graphics
Graphics g_graphics
Definition: graphics.cpp:44
g_app
ConsoleApplication g_app
Definition: consoleapplication.cpp:32
ShaderProgram::bindAttributeLocation
void bindAttributeLocation(int location, const char *name)
Definition: shaderprogram.cpp:143
ShaderProgram::log
std::string log()
Definition: shaderprogram.cpp:125
shaderprogram.h
stdext::shared_object_ptr
Definition: shared_object.h:39
Application::isTerminated
bool isTerminated()
Definition: application.h:50
Shader
Definition: shader.h:28
ShaderProgram::bindUniformLocation
void bindUniformLocation(int location, const char *name)
Definition: shaderprogram.cpp:148
ShaderProgram::getAttributeLocation
int getAttributeLocation(const char *name)
Definition: shaderprogram.cpp:138
ShaderProgram::addShaderFromSourceCode
bool addShaderFromSourceCode(Shader::ShaderType shaderType, const std::string &sourceCode)
Definition: shaderprogram.cpp:55
ShaderProgram::removeShader
void removeShader(const ShaderPtr &shader)
Definition: shaderprogram.cpp:73
ShaderProgram::ShaderProgram
ShaderProgram()
Definition: shaderprogram.cpp:30
application.h