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

Revision 3117, 9.1 KB checked in by mattausch, 16 years ago (diff)

strange errors

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