source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.cpp @ 3017

Revision 3017, 8.7 KB checked in by mattausch, 16 years ago (diff)
Line 
1#include <iostream>
2#include "FrameBufferObject.h"
3#include "glInterface.h"
4
5using namespace std;
6
7
8namespace CHCDemoEngine
9{
10
11int FrameBufferObject::sCurrentFbo = -1;
12
13
14void PrintFBOStatus(GLenum status)
15{
16        switch(status)
17        {
18        case GL_FRAMEBUFFER_COMPLETE_EXT:
19                //cout << "frame buffer object complete" << endl;
20                break;
21        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
22                cerr << "incomplete attachment" << endl;
23                break;
24        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
25                cerr << "missing attachment" << endl;
26                break;
27        case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
28                cerr << "incomplete dimensions" << endl;
29                break;
30        case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
31                cerr << "incomplete formats" << endl;
32                break;
33        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
34                cerr << "incomplete draw buffer" << endl;
35                break;
36        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
37                cerr << "incomplete read buffer" << endl;
38                break;
39        case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
40                cerr << "framebuffer unsupported" << endl;
41                break;
42        default:
43                cerr << "unknown status code " << status << endl;
44        }
45}
46
47
48ColorBufferObject::ColorBufferObject(int w, int h,
49                                                                         int attachment_idx,
50                                                                         FORMAT format,
51                                                                         WRAP_TYPE wrapType,
52                                                                         FILTER_TYPE filterType,
53                                                                         FILTER_TYPE filterTypeMipMap
54                                                                         )
55{
56        Init(w, h, attachment_idx, format, wrapType, filterType, true, filterTypeMipMap);
57}
58
59
60ColorBufferObject::ColorBufferObject(int w, int h,
61                                                                         int attachment_idx,
62                                                                         FORMAT format,
63                                                                         WRAP_TYPE wrapType,
64                                                                         FILTER_TYPE filterType
65                                                                         )
66{
67        Init(w, h, attachment_idx, format, wrapType, filterType, false, FILTER_NEAREST);
68}
69
70
71ColorBufferObject::~ColorBufferObject()
72{
73        glDeleteRenderbuffersEXT(1, &mId);
74        glDeleteTextures(1, &mTexId);
75}
76
77
78void ColorBufferObject::Init(int w, int h,
79                                                         int attachment_idx,
80                                                         FORMAT format,
81                                                         WRAP_TYPE wrapType,
82                                                         FILTER_TYPE filterType,
83                                                         bool useMipMap,
84                                                         FILTER_TYPE filterTypeMipMap
85                                                         )
86{
87        mWidth = w;
88        mHeight = h;
89
90        int components = GL_RGBA;
91
92        switch (format)
93        {
94        case RGB_UBYTE:
95                mGlFormat = GL_UNSIGNED_BYTE; mInternalFormat = GL_RGB8; components = GL_RGB; break;
96        case RGBA_UBYTE:
97                mGlFormat = GL_UNSIGNED_BYTE; mInternalFormat = GL_RGBA8; break;
98        case RGB_FLOAT_32:
99                mGlFormat = GL_FLOAT; mInternalFormat = GL_RGB16F_ARB; components = GL_RGB;     break;
100        case RGBA_FLOAT_16:
101                mGlFormat = GL_FLOAT; mInternalFormat = GL_RGBA16F_ARB; break;
102        case RGB_FLOAT_16:
103                mGlFormat = GL_FLOAT; mInternalFormat = GL_RGB32F_ARB; components = GL_RGB;     break;
104        case RGBA_FLOAT_32:
105                mGlFormat = GL_FLOAT; mInternalFormat = GL_RGBA32F_ARB; break;
106        default:
107                mGlFormat = GL_UNSIGNED_BYTE; mInternalFormat = GL_RGBA8;
108                cerr << "should not come here" << endl;
109        }
110
111
112        glGenRenderbuffersEXT(1, &mId);
113        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mId);
114       
115        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, mInternalFormat, w, h);
116        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, mrt[attachment_idx], GL_RENDERBUFFER_EXT, mId);
117
118
119        glGenTextures(1, &mTexId);
120        glBindTexture(GL_TEXTURE_2D, mTexId);
121        glTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, w, h, 0, components, mGlFormat, NULL);
122
123        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, mrt[attachment_idx], GL_TEXTURE_2D, mTexId, 0);
124
125        GLuint minfilterParam;
126        GLuint magfilterParam;
127
128        if (filterType == FILTER_NEAREST)
129                magfilterParam = GL_NEAREST;
130        else // FILTER_LINEAR
131                magfilterParam = GL_LINEAR;
132
133        if (!useMipMap)
134        {
135                if (filterType == FILTER_NEAREST)
136                        minfilterParam = GL_NEAREST;
137                else // FILTER_LINEAR
138                        minfilterParam = GL_LINEAR;
139        }
140        else
141        {
142                if (filterType == FILTER_NEAREST)
143                {
144                        if (filterTypeMipMap == FILTER_NEAREST)
145                                minfilterParam = GL_NEAREST_MIPMAP_NEAREST;
146                        else // FILTER_LINEAR
147                                minfilterParam = GL_NEAREST_MIPMAP_LINEAR;
148                }
149                else // FILTER_LINEAR
150                {
151                        if (filterTypeMipMap == FILTER_NEAREST)
152                                minfilterParam = GL_LINEAR_MIPMAP_NEAREST;
153                        else // FILTER_LINEAR
154                                minfilterParam = GL_LINEAR_MIPMAP_LINEAR;
155                }
156        }
157
158        GLuint wrapParam;
159
160        switch (wrapType)
161        {
162        case WRAP_REPEAT:
163                wrapParam = GL_REPEAT; break;
164        case WRAP_CLAMP_TO_EDGE:
165                wrapParam = GL_CLAMP_TO_EDGE; break;
166        }
167
168        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilterParam);
169        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilterParam);
170
171        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapParam);
172        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapParam);
173
174        if (useMipMap)
175        {
176                glGenerateMipmapEXT(GL_TEXTURE_2D);
177        }
178
179        // print status
180        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
181}
182
183
184
185void *ColorBufferObject::ReadTexture() const
186{
187        int bytes = 0;
188
189        switch (mInternalFormat)
190        {
191        case GL_RGB8:
192                bytes = 3; break;
193        case GL_RGBA8:
194                bytes = 4; break;
195        case GL_RGBA16F_ARB:
196                bytes = 16; break;
197        case GL_RGB32F_ARB:
198                bytes = 24; break;
199        case GL_RGBA32F_ARB:
200                bytes = 32; break;
201        default:
202                cerr << "should not come here" << endl;
203        }
204
205       
206        glBindTexture(GL_TEXTURE_2D, mTexId);
207       
208        /*GLint width, height;
209        glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
210        glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
211        cout << "w: " << width << "h: " << height << endl;
212        */
213
214        unsigned char *data = new unsigned char[bytes * 4 * mWidth * mHeight];
215
216        glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, data);
217
218        glBindTexture(GL_TEXTURE_2D, 0);
219        glDisable(GL_TEXTURE_2D);
220
221        return data;
222}
223
224
225/*****************************************************************/
226/*                 FrameBufferObject implementation              */
227/*****************************************************************/
228
229
230FrameBufferObject::FrameBufferObject(int w, int h, DEPTH_FORMAT d, bool useDepthTex)
231: mWidth(w), mHeight(h), mDepthTexId(0)
232{
233        glGenFramebuffersEXT(1, &mId);
234       
235        Bind();
236        ///////////
237        //-- create depth buffer
238
239        if (d != DEPTH_NONE)
240        {
241                glGenRenderbuffersEXT(1, &mDepthId);   
242                glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepthId);
243
244                GLuint depthFormat;
245
246                switch (d)
247                {
248                case DEPTH_16:
249                        depthFormat = GL_DEPTH_COMPONENT16; break;
250                case DEPTH_24:
251                        depthFormat = GL_DEPTH_COMPONENT24; break;
252                case DEPTH_32:
253                        depthFormat = GL_DEPTH_COMPONENT32; break;
254                default:       
255                        cerr << "should not come here" << endl;
256                }
257
258                glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, depthFormat, w, h);
259               
260
261                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepthId);
262
263                if (useDepthTex)
264                {
265                        glGenTextures(1, &mDepthTexId);
266                        glBindTexture(GL_TEXTURE_2D, mDepthTexId);
267
268                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
269                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
270                       
271                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
272                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
273
274                        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
275
276                        glTexImage2D(GL_TEXTURE_2D, 0, depthFormat, mWidth, mHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
277
278                        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, mDepthTexId, 0);
279                }
280        }
281
282        Release();
283}
284
285
286FrameBufferObject::~FrameBufferObject()
287{
288        glDeleteFramebuffersEXT(1, &mId);
289        glDeleteRenderbuffersEXT(1, &mDepthId);
290
291        if (mDepthTexId) glDeleteTextures(1, &mDepthTexId);
292
293        CLEAR_CONTAINER(mColorBuffers);
294}
295
296
297int FrameBufferObject::AddColorBuffer(ColorBufferObject::FORMAT col,
298                                                                          ColorBufferObject::WRAP_TYPE wrapType,
299                                                                          ColorBufferObject::FILTER_TYPE filterType,
300                                                                          ColorBufferObject::FILTER_TYPE filterTypeMipMap)
301{
302        Bind();
303
304        const int idx = (int)mColorBuffers.size();
305
306        ColorBufferObject *colorBuf =
307                new ColorBufferObject(mWidth, mHeight, idx, col, wrapType, filterType, filterTypeMipMap);
308
309        mColorBuffers.push_back(colorBuf);
310
311        Release();
312
313        return idx;
314}
315
316
317
318int FrameBufferObject::AddColorBuffer(ColorBufferObject::FORMAT col,
319                                                                          ColorBufferObject::WRAP_TYPE wrapType,
320                                                                          ColorBufferObject::FILTER_TYPE filterType)
321{
322        Bind();
323
324        const int idx = (int)mColorBuffers.size();
325
326        ColorBufferObject *colorBuf =
327                new ColorBufferObject(mWidth, mHeight, idx, col, wrapType, filterType);
328
329        mColorBuffers.push_back(colorBuf);
330
331        Release();
332
333        return idx;
334}
335
336
337void FrameBufferObject::Bind() const
338{
339        if (sCurrentFbo != mId)
340        {
341                sCurrentFbo = mId;
342                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mId);
343        }
344}
345
346
347void FrameBufferObject::Release()
348{
349        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
350        sCurrentFbo = -1;
351}
352
353
354} // namespace
Note: See TracBrowser for help on using the repository browser.