17 GLenum error = glGetError();
18 if (error != GL_NO_ERROR) {
21 std::cerr <<
"GL error: " << prefix <<
": " << int(error) <<
'\n';
29 Texture::Texture(
bool interpolation,
bool wrap)
32 setInterpolation(interpolation);
36 void Texture::allocate()
38 glGenTextures(1, &textureId);
43 glDeleteTextures(1, &textureId);
47 void Texture::setInterpolation(
bool interpolation)
50 int mode = interpolation ? GL_LINEAR : GL_NEAREST;
51 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mode);
52 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mode);
55 void Texture::setWrapMode(
bool wrap)
58 int mode = wrap ? GL_REPEAT : GL_CLAMP_TO_EDGE;
59 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, mode);
60 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, mode);
66 ColorTexture::ColorTexture(GLsizei width_, GLsizei height_)
68 resize(width_, height_);
71 void ColorTexture::resize(GLsizei width_, GLsizei height_)
91 FrameBufferObject::FrameBufferObject(
Texture& texture)
93 glGenFramebuffers(1, &bufferId);
95 glFramebufferTexture2D(GL_FRAMEBUFFER,
98 bool success = glCheckFramebufferStatus(GL_FRAMEBUFFER) ==
99 GL_FRAMEBUFFER_COMPLETE;
103 "Your OpenGL implementation support for "
104 "framebuffer objects is too limited.");
108 FrameBufferObject::~FrameBufferObject()
111 glDeleteFramebuffers(1, &bufferId);
114 void FrameBufferObject::push()
116 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &previousId);
117 glBindFramebuffer(GL_FRAMEBUFFER, bufferId);
120 void FrameBufferObject::pop()
122 glBindFramebuffer(GL_FRAMEBUFFER, GLuint(previousId));
128 void Shader::init(GLenum type, std::string_view header, std::string_view
filename)
133 source +=
"#version 100\n";
134 if (type == GL_FRAGMENT_SHADER) {
135 source +=
"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
136 " precision highp float;\n"
138 " precision mediump float;\n"
142 source +=
"#version 110\n";
147 auto mmap = file.mmap();
148 source.append(
reinterpret_cast<const char*
>(mmap.data()),
151 std::cerr <<
"Cannot find shader: " <<
e.getMessage() <<
'\n';
157 handle = glCreateShader(type);
159 std::cerr <<
"Failed to allocate shader\n";
164 const char* sourcePtr = source.c_str();
165 glShaderSource(handle, 1, &sourcePtr,
nullptr);
168 glCompileShader(handle);
169 const bool ok = isOK();
170 GLint infoLogLength = 0;
171 glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &infoLogLength);
174 VLA(GLchar, infoLog, infoLogLength);
175 glGetShaderInfoLog(handle, infoLogLength,
nullptr, infoLog);
176 std::cerr << (ok ?
"Warning" :
"Error") <<
"(s) compiling shader \""
178 << (infoLogLength > 1 ? infoLog :
"(no details available)\n");
184 glDeleteShader(handle);
187 bool Shader::isOK()
const
189 if (handle == 0)
return false;
190 GLint compileStatus = GL_FALSE;
191 glGetShaderiv(handle, GL_COMPILE_STATUS, &compileStatus);
192 return compileStatus == GL_TRUE;
198 void ShaderProgram::allocate()
200 handle = glCreateProgram();
202 std::cerr <<
"Failed to allocate program\n";
206 void ShaderProgram::reset()
208 glDeleteProgram(handle);
212 bool ShaderProgram::isOK()
const
214 if (handle == 0)
return false;
215 GLint linkStatus = GL_FALSE;
216 glGetProgramiv(handle, GL_LINK_STATUS, &linkStatus);
217 return linkStatus == GL_TRUE;
220 void ShaderProgram::attach(
const Shader& shader)
223 if (handle == 0)
return;
226 if (!shader.
isOK())
return;
229 glAttachShader(handle, shader.handle);
232 void ShaderProgram::link()
235 if (handle == 0)
return;
238 glLinkProgram(handle);
239 const bool ok = isOK();
240 GLint infoLogLength = 0;
241 glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &infoLogLength);
244 VLA(GLchar, infoLog, infoLogLength);
245 glGetProgramInfoLog(handle, infoLogLength,
nullptr, infoLog);
246 fprintf(stderr,
"%s(s) linking shader program:\n%s\n",
247 ok ?
"Warning" :
"Error",
248 infoLogLength > 1 ? infoLog :
"(no details available)\n");
252 void ShaderProgram::bindAttribLocation(
unsigned index,
const char* name)
254 glBindAttribLocation(handle, index, name);
257 GLint ShaderProgram::getUniformLocation(
const char* name)
const
260 if (!isOK())
return -1;
262 return glGetUniformLocation(handle, name);
265 void ShaderProgram::activate()
const
267 glUseProgram(handle);
271 void ShaderProgram::validate()
const
273 glValidateProgram(handle);
274 GLint validateStatus = GL_FALSE;
275 glGetProgramiv(handle, GL_VALIDATE_STATUS, &validateStatus);
276 GLint infoLogLength = 0;
277 glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &infoLogLength);
279 VLA(GLchar, infoLog, infoLogLength);
280 glGetProgramInfoLog(handle, infoLogLength,
nullptr, infoLog);
281 std::cout <<
"Validate "
282 << ((validateStatus == GL_TRUE) ?
"OK" :
"FAIL")
283 <<
": " << infoLog <<
'\n';
289 BufferObject::BufferObject()
291 glGenBuffers(1, &bufferId);
294 BufferObject::~BufferObject()
296 glDeleteBuffers(1, &bufferId);
Wrapper around an OpenGL shader: a program executed on the GPU.
bool isOK() const
Returns true iff this shader is loaded and compiled without errors.
Most basic/generic texture: only contains a texture ID.
Thrown when a subsystem initialisation fails.
static const bool RELEASE
void checkGLError(std::string_view prefix)
This file implemented 3 utility functions:
const FileContext & systemFileContext()
constexpr const char *const filename
TemporaryString tmpStrCat(Ts &&... ts)
#define VLA(TYPE, NAME, LENGTH)