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

RevLine 
[2855]1#include <iostream>
2#include "FrameBufferObject.h"
3#include "glInterface.h"
4
5using namespace std;
6
7
8namespace CHCDemoEngine
9{
10
[3007]11int FrameBufferObject::sCurrentFbo = -1;
[2855]12
[3007]13
[2855]14void PrintFBOStatus(GLenum status)
15{
16        switch(status)
17        {
18        case GL_FRAMEBUFFER_COMPLETE_EXT:
[2879]19                //cout << "frame buffer object complete" << endl;
[2855]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,
[2965]49                                                                         int attachment_idx,
[2861]50                                                                         FORMAT format,
[2856]51                                                                         WRAP_TYPE wrapType,
52                                                                         FILTER_TYPE filterType,
[2965]53                                                                         FILTER_TYPE filterTypeMipMap
54                                                                         )
[2855]55{
[2965]56        Init(w, h, attachment_idx, format, wrapType, filterType, true, filterTypeMipMap);
57}
[2861]58
59
[2965]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
[3005]90        int components = GL_RGBA;
[2999]91
[2861]92        switch (format)
93        {
[3005]94        case RGB_UBYTE:
95                mGlFormat = GL_UNSIGNED_BYTE; mInternalFormat = GL_RGB8;
96                components = GL_RGB;
97                break;
98        case RGBA_UBYTE:
[2965]99                mGlFormat = GL_UNSIGNED_BYTE; mInternalFormat = GL_RGBA8; break;
[3005]100        case RGBA_FLOAT_16:
[2965]101                mGlFormat = GL_FLOAT; mInternalFormat = GL_RGBA16F_ARB; break;
[3005]102        case RGB_FLOAT_32:
103                mGlFormat = GL_FLOAT; mInternalFormat = GL_RGB32F_ARB;
104                components = GL_RGB;
105                break;
106        case RGBA_FLOAT_32:
[2965]107                mGlFormat = GL_FLOAT; mInternalFormat = GL_RGBA32F_ARB; break;
[2861]108        default:
[2965]109                mGlFormat = GL_UNSIGNED_BYTE; mInternalFormat = GL_RGBA8;
[2861]110                cerr << "should not come here" << endl;
111        }
112
[2879]113
[2856]114        glGenRenderbuffersEXT(1, &mId);
115        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mId);
[2855]116       
[2965]117        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, mInternalFormat, w, h);
[2899]118        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, mrt[attachment_idx], GL_RENDERBUFFER_EXT, mId);
[2855]119
[2879]120
[2856]121        glGenTextures(1, &mTexId);
122        glBindTexture(GL_TEXTURE_2D, mTexId);
[3005]123        glTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, w, h, 0, components, mGlFormat, NULL);
[2862]124
[2899]125        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, mrt[attachment_idx], GL_TEXTURE_2D, mTexId, 0);
[2855]126
[2867]127        GLuint minfilterParam;
128        GLuint magfilterParam;
[2855]129
[2965]130        if (filterType == FILTER_NEAREST)
[2867]131                magfilterParam = GL_NEAREST;
[2965]132        else // FILTER_LINEAR
133                magfilterParam = GL_LINEAR;
[2867]134
[2965]135        if (!useMipMap)
136        {
137                if (filterType == FILTER_NEAREST)
138                        minfilterParam = GL_NEAREST;
139                else // FILTER_LINEAR
140                        minfilterParam = GL_LINEAR;
[2856]141        }
[2965]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        }
[2855]159
[2856]160        GLuint wrapParam;
161
162        switch (wrapType)
163        {
[2857]164        case WRAP_REPEAT:
165                wrapParam = GL_REPEAT; break;
166        case WRAP_CLAMP_TO_EDGE:
167                wrapParam = GL_CLAMP_TO_EDGE; break;
[2856]168        }
169
[2867]170        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilterParam);
171        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilterParam);
[2856]172
173        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapParam);
174        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapParam);
175
[2976]176        if (useMipMap)
177        {
178                glGenerateMipmapEXT(GL_TEXTURE_2D);
179        }
[2867]180
[2857]181        // print status
[2855]182        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
183}
184
185
[2965]186
187void *ColorBufferObject::ReadTexture() const
[2878]188{
[2965]189        int bytes = 0;
190
191        switch (mInternalFormat)
192        {
[3005]193        case GL_RGB8:
194                bytes = 3; break;
[2965]195        case GL_RGBA8:
[3005]196                bytes = 4; break;
[2965]197        case GL_RGBA16F_ARB:
198                bytes = 16; break;
[3005]199        case GL_RGB32F_ARB:
200                bytes = 24; break;
[2965]201        case GL_RGBA32F_ARB:
202                bytes = 32; break;
203        default:
204                cerr << "should not come here" << endl;
205        }
206
[2979]207       
[2965]208        glBindTexture(GL_TEXTURE_2D, mTexId);
[2979]209       
[3005]210        /*GLint width, height;
[2979]211        glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
[2976]212        glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
[3005]213        cout << "w: " << width << "h: " << height << endl;
214        */
[2976]215
[3005]216        unsigned char *data = new unsigned char[bytes * 4 * mWidth * mHeight];
[2979]217
218        glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, data);
[2976]219
[2965]220        glBindTexture(GL_TEXTURE_2D, 0);
221        glDisable(GL_TEXTURE_2D);
222
223        return data;
[2878]224}
225
226
[2965]227/*****************************************************************/
228/*                 FrameBufferObject implementation              */
229/*****************************************************************/
230
231
[2862]232FrameBufferObject::FrameBufferObject(int w, int h, DEPTH_FORMAT d, bool useDepthTex)
233: mWidth(w), mHeight(h), mDepthTexId(0)
[2855]234{
235        glGenFramebuffersEXT(1, &mId);
[2862]236       
237        Bind();
[2855]238        ///////////
239        //-- create depth buffer
240
[2861]241        if (d != DEPTH_NONE)
[2855]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;
[2861]256                default:       
257                        cerr << "should not come here" << endl;
[2855]258                }
259
[2879]260                glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, depthFormat, w, h);
261               
262
[2855]263                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepthId);
[2862]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);
[2965]275
[2862]276                        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
277
[2866]278                        glTexImage2D(GL_TEXTURE_2D, 0, depthFormat, mWidth, mHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
[2862]279
280                        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, mDepthTexId, 0);
281                }
[2857]282        }
[2862]283
284        Release();
[2855]285}
286
287
[2878]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
[2867]299int FrameBufferObject::AddColorBuffer(ColorBufferObject::FORMAT col,
[2859]300                                                                          ColorBufferObject::WRAP_TYPE wrapType,
301                                                                          ColorBufferObject::FILTER_TYPE filterType,
[2965]302                                                                          ColorBufferObject::FILTER_TYPE filterTypeMipMap)
[2857]303{
[2862]304        Bind();
[2861]305
[2867]306        const int idx = (int)mColorBuffers.size();
307
[2857]308        ColorBufferObject *colorBuf =
[2965]309                new ColorBufferObject(mWidth, mHeight, idx, col, wrapType, filterType, filterTypeMipMap);
[2861]310
[2857]311        mColorBuffers.push_back(colorBuf);
312
[2862]313        Release();
[2861]314
315        return idx;
[2857]316}
317
[2859]318
[2965]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
[2861]339void FrameBufferObject::Bind() const
340{
[3007]341        if (sCurrentFbo != mId)
342        {
343                sCurrentFbo = mId;
344                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mId);
345        }
[2861]346}
347
348
349void FrameBufferObject::Release()
350{
351        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
[3007]352        sCurrentFbo = -1;
[2861]353}
354
355
[2855]356} // namespace
Note: See TracBrowser for help on using the repository browser.