SuperTuxKart
Loading...
Searching...
No Matches
frame_buffer.hpp
1// SuperTuxKart - a fun racing game with go-kart
2// Copyright (C) 2018 SuperTuxKart-Team
3//
4// This program is free software; you can redistribute it and/or
5// modify it under the terms of the GNU General Public License
6// as published by the Free Software Foundation; either version 3
7// of the License, or (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#ifndef SERVER_ONLY
19
20#ifndef HEADER_FRAME_BUFFER_HPP
21#define HEADER_FRAME_BUFFER_HPP
22
23#include "graphics/gl_headers.hpp"
24#include "graphics/irr_driver.hpp"
25#include "utils/log.hpp"
26#include "utils/leak_check.hpp"
27#include "utils/no_copy.hpp"
28
29#include <cassert>
30#include <vector>
31
32class FrameBuffer : public NoCopy
33{
34protected:
35 GLuint m_fbo = 0;
36
37 std::vector<GLuint> m_render_targets;
38
39 GLuint m_depth_texture = 0;
40
41 unsigned m_width = 0;
42
43 unsigned m_height = 0;
44
45public:
46 LEAK_CHECK()
47 // ------------------------------------------------------------------------
48 FrameBuffer() {}
49 // ------------------------------------------------------------------------
50 FrameBuffer(const std::vector<GLuint> &rtts, unsigned w, unsigned h)
51 {
52 m_render_targets = rtts;
53 m_width = w;
54 m_height = h;
55
56 glGenFramebuffers(1, &m_fbo);
57 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
58 for (unsigned i = 0; i < rtts.size(); i++)
59 {
60 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
61 GL_TEXTURE_2D, rtts[i], 0);
62 }
63 assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) ==
64 GL_FRAMEBUFFER_COMPLETE_EXT);
65 }
66 // ------------------------------------------------------------------------
67 FrameBuffer(const std::vector<GLuint> &rtts, GLuint depth_stencil,
68 unsigned w, unsigned h)
69 {
70 m_render_targets = rtts;
71 m_depth_texture = depth_stencil;
72 m_width = w;
73 m_height = h;
74
75 glGenFramebuffers(1, &m_fbo);
76 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
77 for (unsigned i = 0; i < rtts.size(); i++)
78 {
79 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
80 GL_TEXTURE_2D, rtts[i], 0);
81 }
82 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
83 GL_TEXTURE_2D, depth_stencil, 0);
84 assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) ==
85 GL_FRAMEBUFFER_COMPLETE_EXT);
86 }
87 // ------------------------------------------------------------------------
89 {
90 if (m_fbo != 0)
91 {
92 glDeleteFramebuffers(1, &m_fbo);
93 }
94 }
95 // ------------------------------------------------------------------------
96 void bind() const
97 {
98 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
99 glViewport(0, 0, (int)m_width, (int)m_height);
100 GLenum bufs[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
101 GL_COLOR_ATTACHMENT2 };
102 glDrawBuffers((int)m_render_targets.size(), bufs);
103 }
104 // ------------------------------------------------------------------------
105 void bindDepthOnly() const
106 {
107 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
108 glViewport(0, 0, (int)m_width, (int)m_height);
109 GLenum bufs[] = { GL_NONE, GL_NONE, GL_NONE };
110 glDrawBuffers((int)m_render_targets.size(), bufs);
111 }
112 // ------------------------------------------------------------------------
113 const std::vector<GLuint>& getRTT() const { return m_render_targets; }
114 // ------------------------------------------------------------------------
115 GLuint getDepthTexture() const
116 {
117 assert(m_depth_texture != 0);
118 return m_depth_texture;
119 }
120 // ------------------------------------------------------------------------
121 unsigned int getWidth() const { return m_width; }
122 // ------------------------------------------------------------------------
123 unsigned int getHeight() const { return m_height; }
124 // ------------------------------------------------------------------------
125 static void blit(const FrameBuffer &src, const FrameBuffer &dst,
126 GLbitfield mask = GL_COLOR_BUFFER_BIT,
127 GLenum filter = GL_NEAREST)
128 {
129 glBindFramebuffer(GL_READ_FRAMEBUFFER, src.m_fbo);
130 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst.m_fbo);
131 glBlitFramebuffer(0, 0, (int)src.m_width, (int)src.m_height, 0, 0,
132 (int)dst.m_width, (int)dst.m_height, mask, filter);
133 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
134 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
135 }
136 // ------------------------------------------------------------------------
137 void blitToDefault(size_t x0, size_t y0, size_t x1, size_t y1)
138 {
139 if (m_fbo == 0)
140 {
141 Log::warn("FrameBuffer", "Don't blit layered framebuffer");
142 return;
143 }
144 glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
145 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, irr_driver->getDefaultFramebuffer());
146 glBlitFramebuffer(0, 0, (int)m_width, (int)m_height, (int)x0, (int)y0,
147 (int)x1, (int)y1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
148 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
149 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, irr_driver->getDefaultFramebuffer());
150 }
151
152};
153
154
155#endif
156
157#endif
Definition: frame_buffer.hpp:33
Utility class, you can inherit from this class to disallow the assignment operator and copy construct...
Definition: no_copy.hpp:26