Otclient  14/8/2020
framebuffer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "framebuffer.h"
24 #include "graphics.h"
25 #include "texture.h"
26 
29 
30 uint FrameBuffer::boundFbo = 0;
31 
33 {
34  internalCreate();
35 }
36 
37 void FrameBuffer::internalCreate()
38 {
39  m_prevBoundFbo = 0;
40  m_fbo = 0;
41  if(g_graphics.canUseFBO()) {
42  glGenFramebuffers(1, &m_fbo);
43  if(!m_fbo)
44  g_logger.fatal("Unable to create framebuffer object");
45  }
46 }
47 
49 {
50 #ifndef NDEBUG
51  assert(!g_app.isTerminated());
52 #endif
53  if(g_graphics.ok() && m_fbo != 0)
54  glDeleteFramebuffers(1, &m_fbo);
55 }
56 
57 void FrameBuffer::resize(const Size& size)
58 {
59  assert(size.isValid());
60 
61  if(m_texture && m_texture->getSize() == size)
62  return;
63 
64  m_texture = TexturePtr(new Texture(size));
65  m_texture->setSmooth(m_smooth);
66  m_texture->setUpsideDown(true);
67 
68  if(m_fbo) {
69  internalBind();
70  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->getId(), 0);
71 
72  GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
73  if(status != GL_FRAMEBUFFER_COMPLETE)
74  g_logger.fatal("Unable to setup framebuffer object");
75  internalRelease();
76  } else {
77  if(m_backuping) {
78  m_screenBackup = TexturePtr(new Texture(size));
79  m_screenBackup->setUpsideDown(true);
80  }
81  }
82 }
83 
85 {
87  internalBind();
88  g_painter->setResolution(m_texture->getSize());
89 }
90 
92 {
93  internalRelease();
95 }
96 
98 {
99  Rect rect(0,0, getSize());
100  g_painter->drawTexturedRect(rect, m_texture, rect);
101 }
102 
103 void FrameBuffer::draw(const Rect& dest, const Rect& src)
104 {
105  g_painter->drawTexturedRect(dest, m_texture, src);
106 }
107 
108 void FrameBuffer::draw(const Rect& dest)
109 {
110  g_painter->drawTexturedRect(dest, m_texture, Rect(0,0, getSize()));
111 }
112 
113 void FrameBuffer::internalBind()
114 {
115  if(m_fbo) {
116  assert(boundFbo != m_fbo);
117  glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
118  m_prevBoundFbo = boundFbo;
119  boundFbo = m_fbo;
120  } else if(m_backuping) {
121  // backup screen color buffer into a texture
122  m_screenBackup->copyFromScreen(Rect(0, 0, getSize()));
123  }
124 }
125 
126 void FrameBuffer::internalRelease()
127 {
128  if(m_fbo) {
129  assert(boundFbo == m_fbo);
130  glBindFramebuffer(GL_FRAMEBUFFER, m_prevBoundFbo);
131  boundFbo = m_prevBoundFbo;
132  } else {
133  Rect screenRect(0, 0, getSize());
134 
135  // copy the drawn color buffer into the framebuffer texture
136  m_texture->copyFromScreen(screenRect);
137 
138  // restore screen original content
139  if(m_backuping) {
140  glDisable(GL_BLEND);
142  g_painter->drawTexturedRect(screenRect, m_screenBackup, screenRect);
143  glEnable(GL_BLEND);
144  }
145  }
146 }
147 
149 {
150  if(m_fbo == 0) {
151  // the buffer size is limited by the window size
152  return Size(std::min<int>(m_texture->getWidth(), g_window.getWidth()),
153  std::min<int>(m_texture->getHeight(), g_window.getHeight()));
154  }
155  return m_texture->getSize();
156 }
Painter::setColor
virtual void setColor(const Color &color)
Definition: painter.h:77
Painter::restoreSavedState
virtual void restoreSavedState()=0
graphics.h
Graphics::ok
bool ok()
Definition: graphics.h:65
platformwindow.h
Painter::saveAndResetState
virtual void saveAndResetState()=0
TRect< int >
Texture::getSize
const Size & getSize()
Definition: texture.h:50
Texture::setUpsideDown
void setUpsideDown(bool upsideDown)
Definition: texture.cpp:150
Texture
Definition: texture.h:28
PlatformWindow::getWidth
int getWidth()
Definition: platformwindow.h:77
FrameBuffer::FrameBuffer
FrameBuffer()
Definition: framebuffer.cpp:32
Texture::getWidth
int getWidth()
Definition: texture.h:48
Texture::getHeight
int getHeight()
Definition: texture.h:49
PlatformWindow::getHeight
int getHeight()
Definition: platformwindow.h:78
Logger::fatal
void fatal(const std::string &what)
Definition: logger.h:55
FrameBuffer::draw
void draw()
Definition: framebuffer.cpp:97
g_window
PlatformWindow & g_window
Definition: platformwindow.cpp:37
uint
unsigned int uint
Definition: types.h:31
FrameBuffer::release
void release()
Definition: framebuffer.cpp:91
g_logger
Logger g_logger
Definition: logger.cpp:35
Graphics::canUseFBO
bool canUseFBO()
Definition: graphics.cpp:293
Color::white
static const Color white
Definition: color.h:101
Size
TSize< int > Size
Definition: size.h:107
g_graphics
Graphics g_graphics
Definition: graphics.cpp:44
TexturePtr
stdext::shared_object_ptr< Texture > TexturePtr
Definition: declarations.h:49
Texture::copyFromScreen
void copyFromScreen(const Rect &screenRect)
Definition: texture.cpp:105
Texture::getId
uint getId()
Definition: texture.h:46
g_app
ConsoleApplication g_app
Definition: consoleapplication.cpp:32
Rect
TRect< int > Rect
Definition: rect.h:319
FrameBuffer::bind
void bind()
Definition: framebuffer.cpp:84
texture.h
Texture::setSmooth
virtual void setSmooth(bool smooth)
Definition: texture.cpp:127
FrameBuffer::~FrameBuffer
virtual ~FrameBuffer()
Definition: framebuffer.cpp:48
Application::isTerminated
bool isTerminated()
Definition: application.h:50
g_painter
Painter * g_painter
Definition: painter.cpp:28
FrameBuffer::resize
void resize(const Size &size)
Definition: framebuffer.cpp:57
framebuffer.h
FrameBuffer::getSize
Size getSize()
Definition: framebuffer.cpp:148
Painter::setResolution
virtual void setResolution(const Size &resolution)
Definition: painter.h:92
TSize< int >
TSize::isValid
bool isValid() const
Definition: size.h:41
Painter::drawTexturedRect
virtual void drawTexturedRect(const Rect &dest, const TexturePtr &texture, const Rect &src)=0
application.h