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/framebuffer.h"
#include "backends/graphics/opengl/texture.h" #include "backends/graphics/opengl/texture.h"
#include "backends/graphics/opengl/pipelines/pipeline.h" #include "backends/graphics/opengl/pipelines/pipeline.h"
#include "graphics/opengl/debug.h"
namespace OpenGL { namespace OpenGL {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -31,6 +31,7 @@ MODULE_OBJS := \
managed_surface.o \ managed_surface.o \
nine_patch.o \ nine_patch.o \
opengl/context.o \ opengl/context.o \
opengl/debug.o \
opengl/shader.o \ opengl/shader.o \
pixelformat.o \ pixelformat.o \
primitives.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/str.h"
#include "common/textconsole.h" #include "common/textconsole.h"
#include "graphics/opengl/system_headers.h" #include "graphics/opengl/system_headers.h"
#if defined(USE_OPENGL)
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
namespace OpenGL { namespace OpenGL {
@ -65,3 +67,5 @@ void checkGLError(const char *expr, const char *file, int line) {
} // End of namespace OpenGL } // End of namespace OpenGL
#endif #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) { static GLuint createDirectShader(const char *shaderSource, GLenum shaderType, const Common::String &name) {
GLuint shader = glCreateShader(shaderType); GLuint shader;
glShaderSource(shader, 1, &shaderSource, NULL); GL_ASSIGN(shader, glCreateShader(shaderType));
glCompileShader(shader); GL_CALL(glShaderSource(shader, 1, &shaderSource, NULL));
GL_CALL(glCompileShader(shader));
GLint status; GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status); GL_CALL(glGetShaderiv(shader, GL_COMPILE_STATUS, &status));
if (status != GL_TRUE) { if (status != GL_TRUE) {
GLint logSize; GLint logSize;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize); GL_CALL(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize));
GLchar *log = new GLchar[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); 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 shaderSource
}; };
GLuint shader = glCreateShader(shaderType); GLuint shader;
glShaderSource(shader, 4, shaderSources, NULL); GL_ASSIGN(shader, glCreateShader(shaderType));
glCompileShader(shader); GL_CALL(glShaderSource(shader, 4, shaderSources, NULL));
GL_CALL(glCompileShader(shader));
GLint status; GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status); GL_CALL(glGetShaderiv(shader, GL_COMPILE_STATUS, &status));
if (status != GL_TRUE) { if (status != GL_TRUE) {
GLint logSize; GLint logSize;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize); GL_CALL(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize));
GLchar *log = new GLchar[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); 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 { struct SharedPtrProgramDeleter {
void operator()(GLuint *ptr) { void operator()(GLuint *ptr) {
if (ptr) { if (ptr) {
glDeleteProgram(*ptr); GL_CALL(glDeleteProgram(*ptr));
} }
delete 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) Shader::Shader(const Common::String &name, GLuint vertexShader, GLuint fragmentShader, const char *const *attributes)
: _name(name) { : _name(name) {
assert(attributes); assert(attributes);
GLuint shaderProgram = glCreateProgram(); GLuint shaderProgram;
glAttachShader(shaderProgram, vertexShader); GL_ASSIGN(shaderProgram, glCreateProgram());
glAttachShader(shaderProgram, fragmentShader); GL_CALL(glAttachShader(shaderProgram, vertexShader));
GL_CALL(glAttachShader(shaderProgram, fragmentShader));
for (int idx = 0; attributes[idx]; ++idx) { 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])); _attributes.push_back(VertexAttrib(idx, attributes[idx]));
} }
glLinkProgram(shaderProgram); GL_CALL(glLinkProgram(shaderProgram));
GLint status; GLint status;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status); GL_CALL(glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status));
if (status != GL_TRUE) { if (status != GL_TRUE) {
GLint logSize; GLint logSize;
glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &logSize); GL_CALL(glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &logSize));
GLchar *log = new GLchar[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); error("Could not link shader %s: %s", name.c_str(), log);
} }
glDetachShader(shaderProgram, vertexShader); GL_CALL(glDetachShader(shaderProgram, vertexShader));
glDetachShader(shaderProgram, fragmentShader); GL_CALL(glDetachShader(shaderProgram, fragmentShader));
glDeleteShader(vertexShader); GL_CALL(glDeleteShader(vertexShader));
glDeleteShader(fragmentShader); GL_CALL(glDeleteShader(fragmentShader));
_shaderNo = Common::SharedPtr<GLuint>(new GLuint(shaderProgram), SharedPtrProgramDeleter()); _shaderNo = Common::SharedPtr<GLuint>(new GLuint(shaderProgram), SharedPtrProgramDeleter());
_uniforms = Common::SharedPtr<UniformsMap>(new UniformsMap()); _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. // The previous shader might have had more attributes. Disable any extra ones.
if (_attributes.size() < previousNumAttributes) { if (_attributes.size() < previousNumAttributes) {
for (uint32 i = _attributes.size(); i < previousNumAttributes; ++i) { for (uint32 i = _attributes.size(); i < previousNumAttributes; ++i) {
glDisableVertexAttribArray(i); GL_CALL(glDisableVertexAttribArray(i));
} }
} }
_previousShader = this; _previousShader = this;
previousNumAttributes = _attributes.size(); previousNumAttributes = _attributes.size();
glUseProgram(*_shaderNo); GL_CALL(glUseProgram(*_shaderNo));
for (uint32 i = 0; i < _attributes.size(); ++i) { for (uint32 i = 0; i < _attributes.size(); ++i) {
VertexAttrib &attrib = _attributes[i]; VertexAttrib &attrib = _attributes[i];
if (attrib._enabled) { if (attrib._enabled) {
glEnableVertexAttribArray(i); GL_CALL(glEnableVertexAttribArray(i));
glBindBuffer(GL_ARRAY_BUFFER, attrib._vbo); GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, attrib._vbo));
glVertexAttribPointer(i, attrib._size, attrib._type, attrib._normalized, attrib._stride, attrib._pointer); GL_CALL(glVertexAttribPointer(i, attrib._size, attrib._type, attrib._normalized, attrib._stride, attrib._pointer));
} else { } else {
glDisableVertexAttribArray(i); GL_CALL(glDisableVertexAttribArray(i));
switch (attrib._size) { switch (attrib._size) {
case 2: case 2:
glVertexAttrib2fv(i, attrib._const); GL_CALL(glVertexAttrib2fv(i, attrib._const));
break; break;
case 3: case 3:
glVertexAttrib3fv(i, attrib._const); GL_CALL(glVertexAttrib3fv(i, attrib._const));
break; break;
case 4: case 4:
glVertexAttrib4fv(i, attrib._const); GL_CALL(glVertexAttrib4fv(i, attrib._const));
break; 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 Shader::createBuffer(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) {
GLuint vbo; GLuint vbo;
glGenBuffers(1, &vbo); GL_CALL(glGenBuffers(1, &vbo));
glBindBuffer(target, vbo); GL_CALL(glBindBuffer(target, vbo));
glBufferData(target, size, data, usage); GL_CALL(glBufferData(target, size, data, usage));
glBindBuffer(GL_ARRAY_BUFFER, 0); GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
return vbo; return vbo;
} }
void Shader::freeBuffer(GLuint vbo) { void Shader::freeBuffer(GLuint vbo) {
glDeleteBuffers(1, &vbo); GL_CALL(glDeleteBuffers(1, &vbo));
} }
VertexAttrib &Shader::getAttributeAt(uint32 idx) { VertexAttrib &Shader::getAttributeAt(uint32 idx) {
@ -372,12 +375,12 @@ void Shader::disableVertexAttribute(const char *attrib, int size, const float *d
} }
void Shader::unbind() { void Shader::unbind() {
glUseProgram(0); GL_CALL(glUseProgram(0));
_previousShader = nullptr; _previousShader = nullptr;
// Disable all vertex attributes as well // Disable all vertex attributes as well
for (uint32 i = 0; i < previousNumAttributes; ++i) { for (uint32 i = 0; i < previousNumAttributes; ++i) {
glDisableVertexAttribArray(i); GL_CALL(glDisableVertexAttribArray(i));
} }
previousNumAttributes = 0; previousNumAttributes = 0;
} }

View file

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