1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 #include "FrameBufferObject.h"
10
11 #include "ServiceBroker.h"
12 #include "rendering/RenderSystem.h"
13 #include "utils/GLUtils.h"
14 #include "utils/log.h"
15
16 //////////////////////////////////////////////////////////////////////
17 // CFrameBufferObject
18 //////////////////////////////////////////////////////////////////////
19
CFrameBufferObject()20 CFrameBufferObject::CFrameBufferObject()
21 {
22 m_fbo = 0;
23 m_valid = false;
24 m_supported = false;
25 m_bound = false;
26 m_texid = 0;
27 }
28
IsSupported()29 bool CFrameBufferObject::IsSupported()
30 {
31 if(CServiceBroker::GetRenderSystem()->IsExtSupported("GL_EXT_framebuffer_object"))
32 m_supported = true;
33 else
34 m_supported = false;
35 return m_supported;
36 }
37
Initialize()38 bool CFrameBufferObject::Initialize()
39 {
40 if (!IsSupported())
41 return false;
42
43 Cleanup();
44
45 glGenFramebuffers(1, &m_fbo);
46 VerifyGLState();
47
48 if (!m_fbo)
49 return false;
50
51 m_valid = true;
52 return true;
53 }
54
Cleanup()55 void CFrameBufferObject::Cleanup()
56 {
57 if (!IsValid())
58 return;
59
60 if (m_fbo)
61 glDeleteFramebuffers(1, &m_fbo);
62
63 if (m_texid)
64 glDeleteTextures(1, &m_texid);
65
66 m_texid = 0;
67 m_fbo = 0;
68 m_valid = false;
69 m_bound = false;
70 }
71
CreateAndBindToTexture(GLenum target,int width,int height,GLenum format,GLenum type,GLenum filter,GLenum clampmode)72 bool CFrameBufferObject::CreateAndBindToTexture(GLenum target, int width, int height, GLenum format, GLenum type,
73 GLenum filter, GLenum clampmode)
74 {
75 if (!IsValid())
76 return false;
77
78 if (m_texid)
79 glDeleteTextures(1, &m_texid);
80
81 glGenTextures(1, &m_texid);
82 glBindTexture(target, m_texid);
83 glTexImage2D(target, 0, format, width, height, 0, GL_RGBA, type, NULL);
84 glTexParameteri(target, GL_TEXTURE_WRAP_S, clampmode);
85 glTexParameteri(target, GL_TEXTURE_WRAP_T, clampmode);
86 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
87 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
88 VerifyGLState();
89
90 m_bound = false;
91 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
92 glBindTexture(target, m_texid);
93 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_texid, 0);
94 VerifyGLState();
95 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
96 glBindFramebuffer(GL_FRAMEBUFFER, 0);
97 if (status != GL_FRAMEBUFFER_COMPLETE)
98 {
99 VerifyGLState();
100 return false;
101 }
102 m_bound = true;
103 return true;
104 }
105
SetFiltering(GLenum target,GLenum mode)106 void CFrameBufferObject::SetFiltering(GLenum target, GLenum mode)
107 {
108 glBindTexture(target, m_texid);
109 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, mode);
110 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, mode);
111 }
112
113 // Begin rendering to FBO
BeginRender()114 bool CFrameBufferObject::BeginRender()
115 {
116 if (IsValid() && IsBound())
117 {
118 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
119 return true;
120 }
121 return false;
122 }
123
124 // Finish rendering to FBO
EndRender() const125 void CFrameBufferObject::EndRender() const
126 {
127 if (IsValid())
128 glBindFramebuffer(GL_FRAMEBUFFER, 0);
129 }
130