OPENGL: Add proper error checking to the Shader class

This commit is contained in:
Cameron Cawley 2022-06-29 21:08:20 +01:00
parent cf73da0409
commit 863988fee4
13 changed files with 68 additions and 59 deletions

View file

@ -19,10 +19,10 @@
*
*/
#include "backends/graphics/opengl/debug.h"
#include "backends/graphics/opengl/framebuffer.h"
#include "backends/graphics/opengl/texture.h"
#include "backends/graphics/opengl/pipelines/pipeline.h"
#include "graphics/opengl/debug.h"
namespace OpenGL {

View file

@ -21,12 +21,12 @@
#include "backends/graphics/opengl/opengl-graphics.h"
#include "backends/graphics/opengl/debug.h"
#include "backends/graphics/opengl/texture.h"
#include "backends/graphics/opengl/pipelines/pipeline.h"
#include "backends/graphics/opengl/pipelines/fixed.h"
#include "backends/graphics/opengl/pipelines/shader.h"
#include "backends/graphics/opengl/shader.h"
#include "graphics/opengl/debug.h"
#include "common/array.h"
#include "common/textconsole.h"

View file

@ -20,9 +20,9 @@
*/
#include "backends/graphics/opengl/pipelines/clut8.h"
#include "backends/graphics/opengl/debug.h"
#include "backends/graphics/opengl/shader.h"
#include "backends/graphics/opengl/framebuffer.h"
#include "graphics/opengl/debug.h"
namespace OpenGL {

View file

@ -20,7 +20,7 @@
*/
#include "backends/graphics/opengl/pipelines/fixed.h"
#include "backends/graphics/opengl/debug.h"
#include "graphics/opengl/debug.h"
namespace OpenGL {

View file

@ -20,9 +20,9 @@
*/
#include "backends/graphics/opengl/pipelines/shader.h"
#include "backends/graphics/opengl/debug.h"
#include "backends/graphics/opengl/shader.h"
#include "backends/graphics/opengl/framebuffer.h"
#include "graphics/opengl/debug.h"
namespace OpenGL {

View file

@ -20,7 +20,7 @@
*/
#include "backends/graphics/opengl/shader.h"
#include "backends/graphics/opengl/debug.h"
#include "graphics/opengl/debug.h"
#if !USE_FORCED_GLES

View file

@ -20,11 +20,11 @@
*/
#include "backends/graphics/opengl/texture.h"
#include "backends/graphics/opengl/debug.h"
#include "backends/graphics/opengl/shader.h"
#include "backends/graphics/opengl/pipelines/pipeline.h"
#include "backends/graphics/opengl/pipelines/clut8.h"
#include "backends/graphics/opengl/framebuffer.h"
#include "graphics/opengl/debug.h"
#include "common/algorithm.h"
#include "common/endian.h"

View file

@ -123,7 +123,6 @@ endif
# OpenGL specific source files.
ifdef USE_OPENGL
MODULE_OBJS += \
graphics/opengl/debug.o \
graphics/opengl/framebuffer.o \
graphics/opengl/opengl-graphics.o \
graphics/opengl/shader.o \

View file

@ -31,6 +31,7 @@ MODULE_OBJS := \
managed_surface.o \
nine_patch.o \
opengl/context.o \
opengl/debug.o \
opengl/shader.o \
pixelformat.o \
primitives.o \

View file

@ -19,13 +19,15 @@
*
*/
#include "backends/graphics/opengl/debug.h"
#include "graphics/opengl/debug.h"
#include "common/str.h"
#include "common/textconsole.h"
#include "graphics/opengl/system_headers.h"
#if defined(USE_OPENGL)
#ifdef OPENGL_DEBUG
namespace OpenGL {
@ -65,3 +67,5 @@ void checkGLError(const char *expr, const char *file, int line) {
} // End of namespace OpenGL
#endif
#endif

View file

@ -117,17 +117,18 @@ static const GLchar *readFile(const Common::String &filename) {
}
static GLuint createDirectShader(const char *shaderSource, GLenum shaderType, const Common::String &name) {
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &shaderSource, NULL);
glCompileShader(shader);
GLuint shader;
GL_ASSIGN(shader, glCreateShader(shaderType));
GL_CALL(glShaderSource(shader, 1, &shaderSource, NULL));
GL_CALL(glCompileShader(shader));
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
GL_CALL(glGetShaderiv(shader, GL_COMPILE_STATUS, &status));
if (status != GL_TRUE) {
GLint logSize;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
GL_CALL(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize));
GLchar *log = new GLchar[logSize];
glGetShaderInfoLog(shader, logSize, nullptr, log);
GL_CALL(glGetShaderInfoLog(shader, logSize, nullptr, log));
error("Could not compile shader %s: %s", name.c_str(), log);
}
@ -173,17 +174,18 @@ static GLuint createCompatShader(const char *shaderSource, GLenum shaderType, co
shaderSource
};
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 4, shaderSources, NULL);
glCompileShader(shader);
GLuint shader;
GL_ASSIGN(shader, glCreateShader(shaderType));
GL_CALL(glShaderSource(shader, 4, shaderSources, NULL));
GL_CALL(glCompileShader(shader));
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
GL_CALL(glGetShaderiv(shader, GL_COMPILE_STATUS, &status));
if (status != GL_TRUE) {
GLint logSize;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
GL_CALL(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize));
GLchar *log = new GLchar[logSize];
glGetShaderInfoLog(shader, logSize, nullptr, log);
GL_CALL(glGetShaderInfoLog(shader, logSize, nullptr, log));
error("Could not compile shader %s: %s", name.c_str(), log);
}
@ -212,7 +214,7 @@ static GLuint loadShaderFromFile(const char *base, const char *extension, GLenum
struct SharedPtrProgramDeleter {
void operator()(GLuint *ptr) {
if (ptr) {
glDeleteProgram(*ptr);
GL_CALL(glDeleteProgram(*ptr));
}
delete ptr;
}
@ -225,31 +227,32 @@ uint32 Shader::previousNumAttributes = 0;
Shader::Shader(const Common::String &name, GLuint vertexShader, GLuint fragmentShader, const char *const *attributes)
: _name(name) {
assert(attributes);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
GLuint shaderProgram;
GL_ASSIGN(shaderProgram, glCreateProgram());
GL_CALL(glAttachShader(shaderProgram, vertexShader));
GL_CALL(glAttachShader(shaderProgram, fragmentShader));
for (int idx = 0; attributes[idx]; ++idx) {
glBindAttribLocation(shaderProgram, idx, attributes[idx]);
GL_CALL(glBindAttribLocation(shaderProgram, idx, attributes[idx]));
_attributes.push_back(VertexAttrib(idx, attributes[idx]));
}
glLinkProgram(shaderProgram);
GL_CALL(glLinkProgram(shaderProgram));
GLint status;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);
GL_CALL(glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status));
if (status != GL_TRUE) {
GLint logSize;
glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &logSize);
GL_CALL(glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &logSize));
GLchar *log = new GLchar[logSize];
glGetProgramInfoLog(shaderProgram, logSize, nullptr, log);
GL_CALL(glGetProgramInfoLog(shaderProgram, logSize, nullptr, log));
error("Could not link shader %s: %s", name.c_str(), log);
}
glDetachShader(shaderProgram, vertexShader);
glDetachShader(shaderProgram, fragmentShader);
GL_CALL(glDetachShader(shaderProgram, vertexShader));
GL_CALL(glDetachShader(shaderProgram, fragmentShader));
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
GL_CALL(glDeleteShader(vertexShader));
GL_CALL(glDeleteShader(fragmentShader));
_shaderNo = Common::SharedPtr<GLuint>(new GLuint(shaderProgram), SharedPtrProgramDeleter());
_uniforms = Common::SharedPtr<UniformsMap>(new UniformsMap());
@ -283,49 +286,49 @@ void Shader::use(bool forceReload) {
// The previous shader might have had more attributes. Disable any extra ones.
if (_attributes.size() < previousNumAttributes) {
for (uint32 i = _attributes.size(); i < previousNumAttributes; ++i) {
glDisableVertexAttribArray(i);
GL_CALL(glDisableVertexAttribArray(i));
}
}
_previousShader = this;
previousNumAttributes = _attributes.size();
glUseProgram(*_shaderNo);
GL_CALL(glUseProgram(*_shaderNo));
for (uint32 i = 0; i < _attributes.size(); ++i) {
VertexAttrib &attrib = _attributes[i];
if (attrib._enabled) {
glEnableVertexAttribArray(i);
glBindBuffer(GL_ARRAY_BUFFER, attrib._vbo);
glVertexAttribPointer(i, attrib._size, attrib._type, attrib._normalized, attrib._stride, attrib._pointer);
GL_CALL(glEnableVertexAttribArray(i));
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, attrib._vbo));
GL_CALL(glVertexAttribPointer(i, attrib._size, attrib._type, attrib._normalized, attrib._stride, attrib._pointer));
} else {
glDisableVertexAttribArray(i);
GL_CALL(glDisableVertexAttribArray(i));
switch (attrib._size) {
case 2:
glVertexAttrib2fv(i, attrib._const);
GL_CALL(glVertexAttrib2fv(i, attrib._const));
break;
case 3:
glVertexAttrib3fv(i, attrib._const);
GL_CALL(glVertexAttrib3fv(i, attrib._const));
break;
case 4:
glVertexAttrib4fv(i, attrib._const);
GL_CALL(glVertexAttrib4fv(i, attrib._const));
break;
}
}
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
GLuint Shader::createBuffer(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) {
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(target, vbo);
glBufferData(target, size, data, usage);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GL_CALL(glGenBuffers(1, &vbo));
GL_CALL(glBindBuffer(target, vbo));
GL_CALL(glBufferData(target, size, data, usage));
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
return vbo;
}
void Shader::freeBuffer(GLuint vbo) {
glDeleteBuffers(1, &vbo);
GL_CALL(glDeleteBuffers(1, &vbo));
}
VertexAttrib &Shader::getAttributeAt(uint32 idx) {
@ -372,12 +375,12 @@ void Shader::disableVertexAttribute(const char *attrib, int size, const float *d
}
void Shader::unbind() {
glUseProgram(0);
GL_CALL(glUseProgram(0));
_previousShader = nullptr;
// Disable all vertex attributes as well
for (uint32 i = 0; i < previousNumAttributes; ++i) {
glDisableVertexAttribArray(i);
GL_CALL(glDisableVertexAttribArray(i));
}
previousNumAttributes = 0;
}

View file

@ -32,6 +32,7 @@
#include "math/vector3d.h"
#include "math/vector4d.h"
#include "graphics/opengl/debug.h"
#include "graphics/opengl/system_headers.h"
namespace OpenGL {
@ -67,7 +68,7 @@ public:
GLint pos = getUniformLocation(uniform);
if (pos != -1) {
use();
glUniformMatrix4fv(pos, 1, GL_FALSE, m.getData());
GL_CALL(glUniformMatrix4fv(pos, 1, GL_FALSE, m.getData()));
return true;
} else {
return false;
@ -78,7 +79,7 @@ public:
GLint pos = getUniformLocation(uniform);
if (pos != -1) {
use();
glUniformMatrix3fv(pos, 1, GL_FALSE, m.getData());
GL_CALL(glUniformMatrix3fv(pos, 1, GL_FALSE, m.getData()));
return true;
} else {
return false;
@ -89,7 +90,7 @@ public:
GLint pos = getUniformLocation(uniform);
if (pos != -1) {
use();
glUniform4fv(pos, 1, v.getData());
GL_CALL(glUniform4fv(pos, 1, v.getData()));
return true;
} else {
return false;
@ -100,7 +101,7 @@ public:
GLint pos = getUniformLocation(uniform);
if (pos != -1) {
use();
glUniform3fv(pos, 1, v.getData());
GL_CALL(glUniform3fv(pos, 1, v.getData()));
return true;
} else {
return false;
@ -111,7 +112,7 @@ public:
GLint pos = getUniformLocation(uniform);
if (pos != -1) {
use();
glUniform2fv(pos, 1, v.getData());
GL_CALL(glUniform2fv(pos, 1, v.getData()));
return true;
} else {
return false;
@ -122,7 +123,7 @@ public:
GLint pos = getUniformLocation(uniform);
if (pos != -1) {
use();
glUniform1i(pos, x);
GL_CALL(glUniform1i(pos, x));
return true;
} else {
return false;
@ -134,7 +135,7 @@ public:
GLint pos = getUniformLocation(uniform);
if (pos != -1) {
use();
glUniform1f(pos, f);
GL_CALL(glUniform1f(pos, f));
return true;
} else {
return false;
@ -144,7 +145,8 @@ public:
GLint getUniformLocation(const Common::String &uniform) const {
UniformsMap::iterator kv = _uniforms->find(uniform);
if (kv == _uniforms->end()) {
GLint ret = glGetUniformLocation(*_shaderNo, uniform.c_str());
GLint ret;
GL_ASSIGN(ret, glGetUniformLocation(*_shaderNo, uniform.c_str()));
_uniforms->setVal(uniform, ret);
return ret;
} else {