SuperTuxKart
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 
32 class FrameBuffer : public NoCopy
33 {
34 protected:
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 
45 public:
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  // ------------------------------------------------------------------------
88  ~FrameBuffer()
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:32
Utility class, you can inherit from this class to disallow the assignment operator and copy construct...
Definition: no_copy.hpp:25