Celestia

Форк
0
/
framebuffer.cpp 
229 строк · 5.7 Кб
1
// frambuffer.cpp
2
//
3
// Copyright (C) 2010-2020, the Celestia Development Team
4
// Original version by Chris Laurel <claurel@gmail.com>
5
//
6
// This program is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU General Public License
8
// as published by the Free Software Foundation; either version 2
9
// of the License, or (at your option) any later version.
10

11
#include "framebuffer.h"
12

13
FramebufferObject::FramebufferObject(GLuint width, GLuint height, unsigned int attachments) :
14
    m_width(width),
15
    m_height(height),
16
    m_colorTexId(0),
17
    m_depthTexId(0),
18
    m_fboId(0),
19
    m_status(GL_FRAMEBUFFER_UNSUPPORTED)
20
{
21
    if (attachments != 0)
22
    {
23
        generateFbo(attachments);
24
    }
25
}
26

27
FramebufferObject::FramebufferObject(FramebufferObject &&other) noexcept:
28
    m_width(other.m_width),
29
    m_height(other.m_height),
30
    m_colorTexId(other.m_colorTexId),
31
    m_depthTexId(other.m_depthTexId),
32
    m_fboId(other.m_fboId),
33
    m_status(other.m_status)
34
{
35
    other.m_fboId  = 0;
36
    other.m_status = GL_FRAMEBUFFER_UNSUPPORTED;
37
}
38

39
FramebufferObject& FramebufferObject::operator=(FramebufferObject &&other) noexcept
40
{
41
    m_width        = other.m_width;
42
    m_height       = other.m_height;
43
    m_colorTexId   = other.m_colorTexId;
44
    m_depthTexId   = other.m_depthTexId;
45
    m_fboId        = other.m_fboId;
46
    m_status       = other.m_status;
47

48
    other.m_fboId  = 0;
49
    other.m_status = GL_FRAMEBUFFER_UNSUPPORTED;
50
    return *this;
51
}
52

53
FramebufferObject::~FramebufferObject()
54
{
55
    cleanup();
56
}
57

58
bool
59
FramebufferObject::isValid() const
60
{
61
    return m_status == GL_FRAMEBUFFER_COMPLETE;
62
}
63

64
GLuint
65
FramebufferObject::colorTexture() const
66
{
67
    return m_colorTexId;
68
}
69

70
GLuint
71
FramebufferObject::depthTexture() const
72
{
73
    return m_depthTexId;
74
}
75

76
void
77
FramebufferObject::generateColorTexture()
78
{
79
    // Create and bind the texture
80
    glGenTextures(1, &m_colorTexId);
81
    glBindTexture(GL_TEXTURE_2D, m_colorTexId);
82

83
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
84
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
85

86
    // Clamp to edge
87
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
88
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
89

90
    // Set the texture dimensions
91
    // Do we need to set GL_DEPTH_COMPONENT24 here?
92
#ifdef GL_ES
93
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
94
#else
95
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
96
#endif
97

98
    // Unbind the texture
99
    glBindTexture(GL_TEXTURE_2D, 0);
100
}
101

102
#ifdef GL_ES
103
#define CEL_DEPTH_FORMAT GL_UNSIGNED_INT
104
#else
105
#define CEL_DEPTH_FORMAT GL_UNSIGNED_BYTE
106
#endif
107

108
void
109
FramebufferObject::generateDepthTexture()
110
{
111
    // Create and bind the texture
112
    glGenTextures(1, &m_depthTexId);
113
    glBindTexture(GL_TEXTURE_2D, m_depthTexId);
114

115
#ifndef GL_ES
116
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
117
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
118
#endif
119

120
    // Only nearest sampling is appropriate for depth textures
121
    // But we can use linear to decrease aliasing
122
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
123
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
124

125
    // Clamp to edge
126
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
127
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
128

129
    // Set the texture dimensions
130
    // Do we need to set GL_DEPTH_COMPONENT24 here?
131

132
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_width, m_height, 0, GL_DEPTH_COMPONENT, CEL_DEPTH_FORMAT, nullptr);
133

134
    // Unbind the texture
135
    glBindTexture(GL_TEXTURE_2D, 0);
136
}
137

138
void
139
FramebufferObject::generateFbo(unsigned int attachments)
140
{
141
    // Create the FBO
142
    glGenFramebuffers(1, &m_fboId);
143
    GLint oldFboId;
144
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFboId);
145
    glBindFramebuffer(GL_FRAMEBUFFER, m_fboId);
146

147
#ifndef GL_ES
148
    glReadBuffer(GL_NONE);
149
#endif
150

151
    if ((attachments & ColorAttachment) != 0)
152
    {
153
        generateColorTexture();
154
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorTexId, 0);
155
        m_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
156
        if (m_status != GL_FRAMEBUFFER_COMPLETE)
157
        {
158
            glBindFramebuffer(GL_FRAMEBUFFER, oldFboId);
159
            cleanup();
160
            return;
161
        }
162
    }
163
#ifndef GL_ES
164
    else
165
    {
166
        // Depth-only rendering; no color buffer.
167
        glDrawBuffer(GL_NONE);
168
    }
169
#endif
170

171
    if ((attachments & DepthAttachment) != 0)
172
    {
173
        generateDepthTexture();
174
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexId, 0);
175
        m_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
176
        if (m_status != GL_FRAMEBUFFER_COMPLETE)
177
        {
178
            glBindFramebuffer(GL_FRAMEBUFFER, oldFboId);
179
            cleanup();
180
            return;
181
        }
182
    }
183
    else
184
    {
185
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
186
    }
187

188
    // Restore default frame buffer
189
    glBindFramebuffer(GL_FRAMEBUFFER, oldFboId);
190
}
191

192
// Delete all GL objects associated with this framebuffer object
193
void
194
FramebufferObject::cleanup()
195
{
196
    if (m_fboId != 0)
197
    {
198
        glDeleteFramebuffers(1, &m_fboId);
199
    }
200

201
    if (m_colorTexId != 0)
202
    {
203
        glDeleteTextures(1, &m_colorTexId);
204
    }
205

206
    if (m_depthTexId != 0)
207
    {
208
        glDeleteTextures(1, &m_depthTexId);
209
    }
210
}
211

212
bool
213
FramebufferObject::bind()
214
{
215
    if (isValid())
216
    {
217
        glBindFramebuffer(GL_FRAMEBUFFER, m_fboId);
218
        return true;
219
    }
220

221
    return false;
222
}
223

224
bool
225
FramebufferObject::unbind(GLint oldfboId)
226
{
227
    glBindFramebuffer(GL_FRAMEBUFFER, oldfboId);
228
    return true;
229
}
230

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.