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

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