mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-29 17:02:57 +02:00
146 lines
3.6 KiB
C++
146 lines
3.6 KiB
C++
#ifndef __interface__OpenGlSupport__
|
|
#define __interface__OpenGlSupport__
|
|
|
|
#include "InterfaceConfig.h"
|
|
#include "Log.h"
|
|
|
|
//
|
|
// Macro to log OpenGl errors.
|
|
// Example: oglLog( glPushMatrix() );
|
|
//
|
|
#define oGlLog(stmt) \
|
|
stmt; \
|
|
{ \
|
|
GLenum e = glGetError(); \
|
|
if (e != GL_NO_ERROR) { \
|
|
printLog(__FILE__ ":" oGlLog_stringize(__LINE__) \
|
|
" [OpenGL] %s\n", gluErrorString(e)); \
|
|
} \
|
|
} \
|
|
(void) 0
|
|
|
|
#define oGlLog_stringize(x) oGlLog_stringize_i(x)
|
|
#define oGlLog_stringize_i(x) # x
|
|
|
|
//
|
|
// Encapsulation of the otherwise lengthy call sequence to compile
|
|
// and link shading pipelines.
|
|
//
|
|
class OGlProgram {
|
|
|
|
GLuint _hndProg;
|
|
|
|
public:
|
|
|
|
OGlProgram() : _hndProg(0) { }
|
|
|
|
~OGlProgram() { if (_hndProg != 0u) { glDeleteProgram(_hndProg); } }
|
|
|
|
// no copy/assign
|
|
OGlProgram(OGlProgram const&); // = delete;
|
|
OGlProgram& operator=(OGlProgram const&); // = delete;
|
|
|
|
#if 0 // let's keep this commented, for now (C++11)
|
|
|
|
OGlProgram(OGlProgram&& disposable) : _hndProg(disposable._hndProg) {
|
|
|
|
disposable._hndProg = 0;
|
|
}
|
|
|
|
OGlProgram& operator=(OGlProgram&& disposable) {
|
|
|
|
GLuint tmp = _hndProg;
|
|
_hndProg = disposable._hndProg;
|
|
disposable._hndProg = tmp;
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Activates the executable for rendering.
|
|
// Shaders must be added and linked before this will work.
|
|
//
|
|
void activate() const {
|
|
|
|
if (_hndProg != 0u) {
|
|
|
|
oGlLog( glUseProgram(_hndProg) );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Adds a shader to the program.
|
|
//
|
|
bool addShader(GLenum type, GLchar const* cString) {
|
|
|
|
return addShader(type, 1, & cString);
|
|
}
|
|
|
|
//
|
|
// Adds a shader to the program and logs to stderr.
|
|
//
|
|
bool addShader(GLenum type, GLsizei nStrings, GLchar const** strings) {
|
|
|
|
if (! _hndProg && !! glCreateProgram) {
|
|
|
|
_hndProg = glCreateProgram();
|
|
}
|
|
if (! _hndProg) { return false; }
|
|
|
|
GLuint s = glCreateShader(type);
|
|
glShaderSource(s, nStrings, strings, 0l);
|
|
glCompileShader(s);
|
|
GLint status;
|
|
glGetShaderiv(s, GL_COMPILE_STATUS, & status);
|
|
if (status != 0)
|
|
glAttachShader(_hndProg, s);
|
|
#ifdef NDEBUG // always fetch log in debug mode
|
|
else
|
|
#endif
|
|
fetchLog(s, glGetShaderiv, glGetShaderInfoLog);
|
|
glDeleteShader(s);
|
|
return !! status;
|
|
}
|
|
|
|
//
|
|
// Links the program and logs to stderr.
|
|
//
|
|
bool link() {
|
|
|
|
if (! _hndProg) { return false; }
|
|
|
|
glLinkProgram(_hndProg);
|
|
GLint status;
|
|
glGetProgramiv(_hndProg, GL_LINK_STATUS, & status);
|
|
#ifndef NDEBUG // always fetch log in debug mode
|
|
fetchLog(_hndProg, glGetProgramiv, glGetProgramInfoLog);
|
|
#endif
|
|
if (status == 0) {
|
|
#ifdef NDEBUG // only on error in release mode
|
|
fetchLog(_hndProg, glGetProgramiv, glGetProgramInfoLog);
|
|
#endif
|
|
glDeleteProgram(_hndProg);
|
|
_hndProg = 0u;
|
|
return false;
|
|
|
|
} else {
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private:
|
|
|
|
template< typename ParamFunc, typename GetLogFunc >
|
|
void fetchLog(GLint handle, ParamFunc getParam, GetLogFunc getLog) {
|
|
GLint logLength = 0;
|
|
getParam(handle, GL_INFO_LOG_LENGTH, &logLength);
|
|
if (!! logLength) {
|
|
GLchar* message = new GLchar[logLength];
|
|
getLog(handle, logLength, 0l, message);
|
|
printLog("%s\n", message);
|
|
delete[] message;
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif
|