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

Revision 2991, 8.1 KB checked in by mattausch, 16 years ago (diff)

what todo with tone mapping: manually donwsample??
or manually downsample ssao?? or use smaller rendertarget for ssao solution??

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