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

Revision 3007, 8.6 KB checked in by mattausch, 16 years ago (diff)

improving performance

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;
96                components = GL_RGB;
97                break;
98        case RGBA_UBYTE:
99                mGlFormat = GL_UNSIGNED_BYTE; mInternalFormat = GL_RGBA8; break;
100        case RGBA_FLOAT_16:
101                mGlFormat = GL_FLOAT; mInternalFormat = GL_RGBA16F_ARB; break;
102        case RGB_FLOAT_32:
103                mGlFormat = GL_FLOAT; mInternalFormat = GL_RGB32F_ARB;
104                components = GL_RGB;
105                break;
106        case RGBA_FLOAT_32:
107                mGlFormat = GL_FLOAT; mInternalFormat = GL_RGBA32F_ARB; break;
108        default:
109                mGlFormat = GL_UNSIGNED_BYTE; mInternalFormat = GL_RGBA8;
110                cerr << "should not come here" << endl;
111        }
112
113
114        glGenRenderbuffersEXT(1, &mId);
115        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mId);
116       
117        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, mInternalFormat, w, h);
118        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, mrt[attachment_idx], GL_RENDERBUFFER_EXT, mId);
119
120
121        glGenTextures(1, &mTexId);
122        glBindTexture(GL_TEXTURE_2D, mTexId);
123        glTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, w, h, 0, components, mGlFormat, NULL);
124
125        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, mrt[attachment_idx], GL_TEXTURE_2D, mTexId, 0);
126
127        GLuint minfilterParam;
128        GLuint magfilterParam;
129
130        if (filterType == FILTER_NEAREST)
131                magfilterParam = GL_NEAREST;
132        else // FILTER_LINEAR
133                magfilterParam = GL_LINEAR;
134
135        if (!useMipMap)
136        {
137                if (filterType == FILTER_NEAREST)
138                        minfilterParam = GL_NEAREST;
139                else // FILTER_LINEAR
140                        minfilterParam = GL_LINEAR;
141        }
142        else
143        {
144                if (filterType == FILTER_NEAREST)
145                {
146                        if (filterTypeMipMap == FILTER_NEAREST)
147                                minfilterParam = GL_NEAREST_MIPMAP_NEAREST;
148                        else // FILTER_LINEAR
149                                minfilterParam = GL_NEAREST_MIPMAP_LINEAR;
150                }
151                else // FILTER_LINEAR
152                {
153                        if (filterTypeMipMap == FILTER_NEAREST)
154                                minfilterParam = GL_LINEAR_MIPMAP_NEAREST;
155                        else // FILTER_LINEAR
156                                minfilterParam = GL_LINEAR_MIPMAP_LINEAR;
157                }
158        }
159
160        GLuint wrapParam;
161
162        switch (wrapType)
163        {
164        case WRAP_REPEAT:
165                wrapParam = GL_REPEAT; break;
166        case WRAP_CLAMP_TO_EDGE:
167                wrapParam = GL_CLAMP_TO_EDGE; break;
168        }
169
170        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilterParam);
171        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilterParam);
172
173        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapParam);
174        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapParam);
175
176        if (useMipMap)
177        {
178                glGenerateMipmapEXT(GL_TEXTURE_2D);
179        }
180
181        // print status
182        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
183}
184
185
186
187void *ColorBufferObject::ReadTexture() const
188{
189        int bytes = 0;
190
191        switch (mInternalFormat)
192        {
193        case GL_RGB8:
194                bytes = 3; break;
195        case GL_RGBA8:
196                bytes = 4; break;
197        case GL_RGBA16F_ARB:
198                bytes = 16; break;
199        case GL_RGB32F_ARB:
200                bytes = 24; break;
201        case GL_RGBA32F_ARB:
202                bytes = 32; break;
203        default:
204                cerr << "should not come here" << endl;
205        }
206
207       
208        glBindTexture(GL_TEXTURE_2D, mTexId);
209       
210        /*GLint width, height;
211        glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
212        glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
213        cout << "w: " << width << "h: " << height << endl;
214        */
215
216        unsigned char *data = new unsigned char[bytes * 4 * mWidth * mHeight];
217
218        glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, data);
219
220        glBindTexture(GL_TEXTURE_2D, 0);
221        glDisable(GL_TEXTURE_2D);
222
223        return data;
224}
225
226
227/*****************************************************************/
228/*                 FrameBufferObject implementation              */
229/*****************************************************************/
230
231
232FrameBufferObject::FrameBufferObject(int w, int h, DEPTH_FORMAT d, bool useDepthTex)
233: mWidth(w), mHeight(h), mDepthTexId(0)
234{
235        glGenFramebuffersEXT(1, &mId);
236       
237        Bind();
238        ///////////
239        //-- create depth buffer
240
241        if (d != DEPTH_NONE)
242        {
243                glGenRenderbuffersEXT(1, &mDepthId);   
244                glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepthId);
245
246                GLuint depthFormat;
247
248                switch (d)
249                {
250                case DEPTH_16:
251                        depthFormat = GL_DEPTH_COMPONENT16; break;
252                case DEPTH_24:
253                        depthFormat = GL_DEPTH_COMPONENT24; break;
254                case DEPTH_32:
255                        depthFormat = GL_DEPTH_COMPONENT32; break;
256                default:       
257                        cerr << "should not come here" << endl;
258                }
259
260                glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, depthFormat, w, h);
261               
262
263                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepthId);
264
265                if (useDepthTex)
266                {
267                        glGenTextures(1, &mDepthTexId);
268                        glBindTexture(GL_TEXTURE_2D, mDepthTexId);
269
270                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
271                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
272                       
273                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
274                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
275
276                        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
277
278                        glTexImage2D(GL_TEXTURE_2D, 0, depthFormat, mWidth, mHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
279
280                        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, mDepthTexId, 0);
281                }
282        }
283
284        Release();
285}
286
287
288FrameBufferObject::~FrameBufferObject()
289{
290        glDeleteFramebuffersEXT(1, &mId);
291        glDeleteRenderbuffersEXT(1, &mDepthId);
292
293        if (mDepthTexId) glDeleteTextures(1, &mDepthTexId);
294
295        CLEAR_CONTAINER(mColorBuffers);
296}
297
298
299int FrameBufferObject::AddColorBuffer(ColorBufferObject::FORMAT col,
300                                                                          ColorBufferObject::WRAP_TYPE wrapType,
301                                                                          ColorBufferObject::FILTER_TYPE filterType,
302                                                                          ColorBufferObject::FILTER_TYPE filterTypeMipMap)
303{
304        Bind();
305
306        const int idx = (int)mColorBuffers.size();
307
308        ColorBufferObject *colorBuf =
309                new ColorBufferObject(mWidth, mHeight, idx, col, wrapType, filterType, filterTypeMipMap);
310
311        mColorBuffers.push_back(colorBuf);
312
313        Release();
314
315        return idx;
316}
317
318
319
320int FrameBufferObject::AddColorBuffer(ColorBufferObject::FORMAT col,
321                                                                          ColorBufferObject::WRAP_TYPE wrapType,
322                                                                          ColorBufferObject::FILTER_TYPE filterType)
323{
324        Bind();
325
326        const int idx = (int)mColorBuffers.size();
327
328        ColorBufferObject *colorBuf =
329                new ColorBufferObject(mWidth, mHeight, idx, col, wrapType, filterType);
330
331        mColorBuffers.push_back(colorBuf);
332
333        Release();
334
335        return idx;
336}
337
338
339void FrameBufferObject::Bind() const
340{
341        if (sCurrentFbo != mId)
342        {
343                sCurrentFbo = mId;
344                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mId);
345        }
346}
347
348
349void FrameBufferObject::Release()
350{
351        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
352        sCurrentFbo = -1;
353}
354
355
356} // namespace
Note: See TracBrowser for help on using the repository browser.