[nostalgia/glutils] Add FrameBuffer type

This commit is contained in:
Gary Talent 2021-08-03 21:49:28 -05:00
parent c7499f4241
commit 1bf882c674
2 changed files with 70 additions and 5 deletions

View File

@ -17,6 +17,14 @@ void deleteBuffer(GLuint b) noexcept {
glDeleteBuffers(1, &b); glDeleteBuffers(1, &b);
} }
void deleteFrameBuffer(GLuint b) noexcept {
glDeleteFramebuffers(1, &b);
}
void deleteRenderBuffer(GLuint b) noexcept {
glDeleteRenderbuffers(1, &b);
}
void deleteTexture(GLuint t) noexcept { void deleteTexture(GLuint t) noexcept {
glDeleteTextures(1, &t); glDeleteTextures(1, &t);
} }
@ -26,6 +34,8 @@ void deleteVertexArray(GLuint v) noexcept {
} }
template struct GLObject<deleteBuffer>; template struct GLObject<deleteBuffer>;
template struct GLObject<deleteFrameBuffer>;
template struct GLObject<deleteRenderBuffer>;
template struct GLObject<deleteTexture, TextureBase>; template struct GLObject<deleteTexture, TextureBase>;
template struct GLObject<deleteVertexArray>; template struct GLObject<deleteVertexArray>;
template struct GLObject<glDeleteProgram>; template struct GLObject<glDeleteProgram>;
@ -44,10 +54,9 @@ static ox::Result<GLShader> buildShader(GLuint shaderType, const GLchar *src, co
oxErrorf("shader compile error in {}: {}", shaderName, errMsg); oxErrorf("shader compile error in {}: {}", shaderName, errMsg);
return OxError(1, "shader compile error"); return OxError(1, "shader compile error");
} }
return ox::move(shader); return shader;
} }
[[nodiscard]]
ox::Result<GLProgram> buildShaderProgram(const GLchar *vert, const GLchar *frag) noexcept { ox::Result<GLProgram> buildShaderProgram(const GLchar *vert, const GLchar *frag) noexcept {
oxRequire(vs, buildShader(GL_VERTEX_SHADER, vert, "vshad")); oxRequire(vs, buildShader(GL_VERTEX_SHADER, vert, "vshad"));
oxRequire(fs, buildShader(GL_FRAGMENT_SHADER, frag, "fshad")); oxRequire(fs, buildShader(GL_FRAGMENT_SHADER, frag, "fshad"));
@ -55,7 +64,30 @@ ox::Result<GLProgram> buildShaderProgram(const GLchar *vert, const GLchar *frag)
glAttachShader(prgm, vs); glAttachShader(prgm, vs);
glAttachShader(prgm, fs); glAttachShader(prgm, fs);
glLinkProgram(prgm); glLinkProgram(prgm);
return ox::move(prgm); return prgm;
}
FrameBuffer generateFrameBuffer(int width, int height) noexcept {
FrameBuffer fb;
glGenFramebuffers(1, &fb.fbo.id);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
// color texture
glGenTextures(1, &fb.color.id);
glBindTexture(GL_TEXTURE_2D, fb.color);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.color, 0);
// depth texture
glGenRenderbuffers(1, &fb.depth.id);
glBindRenderbuffer(GL_RENDERBUFFER, fb.depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb.depth, 0);
// verify FBO
oxAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame Buffer is incomplete");
// restore primary FB
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return fb;
} }
} }

View File

@ -6,11 +6,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#pragma once
#include <ox/std/defines.hpp> #include <ox/std/defines.hpp>
#define GL_GLEXT_PROTOTYPES 1 #define GL_GLEXT_PROTOTYPES 1
#ifdef OX_OS_Darwin #ifdef OX_OS_Darwin
#ifndef GL_SILENCE_DEPRECATION
#define GL_SILENCE_DEPRECATION #define GL_SILENCE_DEPRECATION
#endif
#include <OpenGL/gl3.h> #include <OpenGL/gl3.h>
#else #else
#include <GLES3/gl3.h> #include <GLES3/gl3.h>
@ -63,7 +67,7 @@ struct GLObject: public Base {
o.id = 0; o.id = 0;
} }
~GLObject() { ~GLObject() noexcept {
del(id); del(id);
} }
@ -94,22 +98,51 @@ struct GLObject: public Base {
}; };
void deleteBuffer(GLuint b) noexcept; void deleteBuffer(GLuint b) noexcept;
void deleteFrameBuffer(GLuint b) noexcept;
void deleteRenderBuffer(GLuint b) noexcept;
void deleteTexture(GLuint t) noexcept; void deleteTexture(GLuint t) noexcept;
void deleteVertexArray(GLuint v) noexcept; void deleteVertexArray(GLuint v) noexcept;
extern template struct GLObject<deleteBuffer>; extern template struct GLObject<deleteBuffer>;
extern template struct GLObject<deleteFrameBuffer>;
extern template struct GLObject<deleteRenderBuffer>;
extern template struct GLObject<deleteTexture, TextureBase>; extern template struct GLObject<deleteTexture, TextureBase>;
extern template struct GLObject<deleteVertexArray>; extern template struct GLObject<deleteVertexArray>;
extern template struct GLObject<glDeleteProgram>; extern template struct GLObject<glDeleteProgram>;
extern template struct GLObject<glDeleteShader>; extern template struct GLObject<glDeleteShader>;
using GLBuffer = GLObject<deleteBuffer>; using GLBuffer = GLObject<deleteBuffer>;
using GLFrameBuffer = GLObject<deleteBuffer>;
using GLRenderBuffer = GLObject<deleteRenderBuffer>;
using GLShader = GLObject<glDeleteShader>; using GLShader = GLObject<glDeleteShader>;
using GLProgram = GLObject<glDeleteProgram>; using GLProgram = GLObject<glDeleteProgram>;
using GLTexture = GLObject<deleteTexture, TextureBase>; using GLTexture = GLObject<deleteTexture, TextureBase>;
using GLVertexArray = GLObject<deleteVertexArray>; using GLVertexArray = GLObject<deleteVertexArray>;
/**
* FrameBuffer holds everything needed for a usable frame buffer to exist.
* It differs from GLFrameBuffer in that GLFrameBuffer only manages the FBO
* and not its dependencies.
*/
struct FrameBuffer {
GLFrameBuffer fbo;
GLTexture color;
GLRenderBuffer depth;
constexpr operator GLuint&() noexcept {
return fbo.id;
}
constexpr operator const GLuint&() const noexcept {
return fbo.id;
}
};
[[nodiscard]] [[nodiscard]]
ox::Result<GLProgram> buildShaderProgram(const GLchar *vert, const GLchar *frag) noexcept; ox::Result<GLProgram> buildShaderProgram(const GLchar *vert, const GLchar *frag) noexcept;
} [[nodiscard]]
FrameBuffer generateFrameBuffer(int width, int height) noexcept;
}