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

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

debug / performance stuff

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