-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathframebuffer.cpp
More file actions
86 lines (68 loc) · 2.74 KB
/
Copy pathframebuffer.cpp
File metadata and controls
86 lines (68 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Copyright 2017-2025 the openage authors. See copying.md for legal info.
#include "framebuffer.h"
#include "log/log.h"
#include "renderer/opengl/context.h"
#include "renderer/opengl/texture.h"
namespace openage::renderer::opengl {
GlFramebuffer::GlFramebuffer(const std::shared_ptr<GlContext> &context) :
GlSimpleObject(context,
[](GLuint /*handle*/) {}),
type{gl_framebuffer_t::display} {
log::log(MSG(dbg) << "Created OpenGL framebuffer with display target");
}
// TODO the validity of this object is contingent
// on its texture existing. use shared_ptr?
GlFramebuffer::GlFramebuffer(const std::shared_ptr<GlContext> &context,
std::vector<std::shared_ptr<GlTexture2d>> const &textures) :
GlSimpleObject(context,
[](GLuint handle) { glDeleteFramebuffers(1, &handle); }),
type{gl_framebuffer_t::textures} {
GLuint handle;
glGenFramebuffers(1, &handle);
this->handle = handle;
glBindFramebuffer(GL_FRAMEBUFFER, handle);
std::vector<GLenum> drawBuffers;
if (textures.empty()) {
throw Error{ERR << "At least 1 texture must be assigned to texture framebuffer."};
}
size_t colorTextureCount = 0;
for (auto const &texture : textures) {
// TODO figure out attachment points from pixel formats
if (texture->get_info().get_format() == resources::pixel_format::depth24) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture->get_handle(), 0);
}
else if (texture->get_info().get_format() == resources::pixel_format::depth24_stencil8) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture->get_handle(), 0);
}
else {
auto attachmentPoint = GL_COLOR_ATTACHMENT0 + colorTextureCount++;
glFramebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_2D, texture->get_handle(), 0);
drawBuffers.push_back(attachmentPoint);
}
}
glDrawBuffers(drawBuffers.size(), drawBuffers.data());
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
throw Error(MSG(err) << "Could not create OpenGL framebuffer.");
}
log::log(MSG(dbg) << "Created OpenGL framebuffer with texture targets");
}
gl_framebuffer_t GlFramebuffer::get_type() const {
return this->type;
}
void GlFramebuffer::bind_read() const {
if (this->type == gl_framebuffer_t::textures) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, *this->handle);
}
else {
glBindFramebuffer(GL_READ_FRAMEBUFFER, this->context->get_default_framebuffer_id());
}
}
void GlFramebuffer::bind_write() const {
if (this->type == gl_framebuffer_t::textures) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, *this->handle);
}
else {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->context->get_default_framebuffer_id());
}
}
} // namespace openage::renderer::opengl