1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     demo_FrameBuffer.cpp
4 
5   Copyright (C)2009-2012 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 46365 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "demo/Render/demo_FrameBuffer.h"
17 
18 namespace demo
19 {
20 
21   /* ------------------------------------------------------------------------
22         RenderBuffersDescription class  member function
23         ------------------------------------------------------------------------ */
24 
RenderBufferDescription(void)25     RenderBufferDescription::RenderBufferDescription(void) :
26     m_Format(GL_RGBA8_OES),
27     m_Width(nn::gx::DISPLAY0_WIDTH), m_Height(nn::gx::DISPLAY0_HEIGHT),
28     m_Area(NN_GX_MEM_FCRAM), m_Attachment(GL_COLOR_ATTACHMENT0)
29     {
30     }
31 
~RenderBufferDescription(void)32     RenderBufferDescription::~RenderBufferDescription(void)
33     {
34     }
35 
GetDefaultDisplay0ColorDescription(void)36     RenderBufferDescription RenderBufferDescription::GetDefaultDisplay0ColorDescription(void)
37     {
38         RenderBufferDescription renderBufferDesc;
39         renderBufferDesc.m_Format = GL_RGBA8_OES;
40         renderBufferDesc.m_Width = nn::gx::DISPLAY0_WIDTH;
41         renderBufferDesc.m_Height = nn::gx::DISPLAY0_HEIGHT;
42         renderBufferDesc.m_Area = NN_GX_MEM_VRAMA;
43         renderBufferDesc.m_Attachment = GL_COLOR_ATTACHMENT0;
44 
45         return renderBufferDesc;
46     }
47 
GetDefaultDisplay0DepthStencilDescription(void)48     RenderBufferDescription RenderBufferDescription::GetDefaultDisplay0DepthStencilDescription(void)
49     {
50         RenderBufferDescription renderBufferDesc;
51         renderBufferDesc.m_Format = GL_DEPTH24_STENCIL8_EXT;
52         renderBufferDesc.m_Width = nn::gx::DISPLAY0_WIDTH;
53         renderBufferDesc.m_Height = nn::gx::DISPLAY0_HEIGHT;
54         renderBufferDesc.m_Area = NN_GX_MEM_VRAMB;
55         renderBufferDesc.m_Attachment = GL_DEPTH_STENCIL_ATTACHMENT;
56 
57         return renderBufferDesc;
58     }
59 
GetDefaultDisplay1ColorDescription(void)60     RenderBufferDescription RenderBufferDescription::GetDefaultDisplay1ColorDescription(void)
61     {
62         RenderBufferDescription renderBufferDesc;
63         renderBufferDesc.m_Format = GL_RGBA8_OES;
64         renderBufferDesc.m_Width = nn::gx::DISPLAY1_WIDTH;
65         renderBufferDesc.m_Height = nn::gx::DISPLAY1_HEIGHT;
66         renderBufferDesc.m_Area = NN_GX_MEM_VRAMA;
67         renderBufferDesc.m_Attachment = GL_COLOR_ATTACHMENT0;
68 
69         return renderBufferDesc;
70     }
71 
GetDefaultDisplay1DepthStencilDescription(void)72     RenderBufferDescription RenderBufferDescription::GetDefaultDisplay1DepthStencilDescription(void)
73     {
74         RenderBufferDescription renderBufferDesc;
75         renderBufferDesc.m_Format = GL_DEPTH24_STENCIL8_EXT;
76         renderBufferDesc.m_Width = nn::gx::DISPLAY1_WIDTH;
77         renderBufferDesc.m_Height = nn::gx::DISPLAY1_HEIGHT;
78         renderBufferDesc.m_Area = NN_GX_MEM_VRAMB;
79         renderBufferDesc.m_Attachment = GL_DEPTH_STENCIL_ATTACHMENT;
80 
81         return renderBufferDesc;
82     }
83 
84   /* ------------------------------------------------------------------------
85         FrameBuffersDescription class  member function
86         ------------------------------------------------------------------------ */
87 
FrameBufferDescription(void)88     FrameBufferDescription::FrameBufferDescription(void)
89     {
90         Initialize();
91     }
92 
~FrameBufferDescription(void)93     FrameBufferDescription::~FrameBufferDescription(void)
94     {
95         Finalize();
96     }
97 
FrameBufferDescription(const FrameBufferDescription & rhs)98     FrameBufferDescription::FrameBufferDescription(const FrameBufferDescription& rhs)
99     {
100         Initialize();
101 
102         for (u32 index = 0; index < DEMO_RENDER_BUFFER_NUM; index++)
103         {
104             m_RenderBufferDescriptionArray[index] = rhs.m_RenderBufferDescriptionArray[index];
105         }
106     }
107 
operator =(const FrameBufferDescription & rhs)108     FrameBufferDescription& FrameBufferDescription::operator=(const FrameBufferDescription& rhs)
109     {
110         Finalize();
111         Initialize();
112 
113         for (u32 index = 0; index < DEMO_RENDER_BUFFER_NUM; index++)
114         {
115             m_RenderBufferDescriptionArray[index] = rhs.m_RenderBufferDescriptionArray[index];
116         }
117 
118         return (*this);
119     }
120 
Initialize(void)121     void FrameBufferDescription::Initialize(void)
122     {
123     }
124 
Finalize(void)125     void FrameBufferDescription::Finalize(void)
126     {
127     }
128 
GetDefaultDisplay0FrameBufferDescription(void)129     FrameBufferDescription FrameBufferDescription::GetDefaultDisplay0FrameBufferDescription(void)
130     {
131         FrameBufferDescription frameBufferDesc;
132         frameBufferDesc.m_RenderBufferDescriptionArray[DEMO_COLOR_BUFFER_INDEX] = RenderBufferDescription::GetDefaultDisplay0ColorDescription();
133         frameBufferDesc.m_RenderBufferDescriptionArray[DEMO_DEPTH_STENCIL_BUFFER_INDEX] = RenderBufferDescription::GetDefaultDisplay0DepthStencilDescription();
134 
135         return frameBufferDesc;
136     }
137 
GetDefaultDisplay1FrameBufferDescription(void)138     FrameBufferDescription FrameBufferDescription::GetDefaultDisplay1FrameBufferDescription(void)
139     {
140         FrameBufferDescription frameBufferDesc;
141         frameBufferDesc.m_RenderBufferDescriptionArray[DEMO_COLOR_BUFFER_INDEX] = RenderBufferDescription::GetDefaultDisplay1ColorDescription();
142         frameBufferDesc.m_RenderBufferDescriptionArray[DEMO_DEPTH_STENCIL_BUFFER_INDEX] = RenderBufferDescription::GetDefaultDisplay1DepthStencilDescription();
143 
144         return frameBufferDesc;
145     }
146 
147   /* ------------------------------------------------------------------------
148         FrameBuffer class  member function
149         ------------------------------------------------------------------------ */
150 
FrameBuffer(void)151    FrameBuffer::FrameBuffer(void) :
152    m_InitializeFlag(false),
153    m_FrameBufferId(0),
154    m_RenderBufferNum(DEMO_RENDER_BUFFER_NUM),
155    m_Width(nn::gx::DISPLAY0_WIDTH), m_Height(nn::gx::DISPLAY0_HEIGHT)
156    {
157    }
158 
~FrameBuffer(void)159    FrameBuffer::~FrameBuffer(void)
160    {
161        Finalize();
162    }
163 
Initialize(const FrameBufferDescription & frameBufferDesc)164    void FrameBuffer::Initialize(const FrameBufferDescription& frameBufferDesc)
165    {
166        if ( ! m_InitializeFlag )
167        {
168            DEMO_ASSERT_GL_ERROR();
169 
170            glGenFramebuffers(1, &m_FrameBufferId);
171            DEMO_ASSERT_GL_ERROR();
172 
173            glGenRenderbuffers(m_RenderBufferNum, m_RenderBufferIdArray);
174            DEMO_ASSERT_GL_ERROR();
175 
176            glBindFramebuffer(GL_FRAMEBUFFER, m_FrameBufferId);
177            DEMO_ASSERT_GL_ERROR();
178 
179            bool colorBufferAttached = false;
180            bool depthStencilBufferAttached = false;
181            bool depthBufferAttached = false;
182            bool stencilBufferAttached = false;
183 
184            for (u32 bufferIndex = 0; bufferIndex < DEMO_RENDER_BUFFER_NUM; bufferIndex++)
185            {
186                const RenderBufferDescription& bufferDesc =
187                    frameBufferDesc.m_RenderBufferDescriptionArray[bufferIndex];
188                GLuint& bufferId = m_RenderBufferIdArray[bufferIndex];
189 
190                glBindRenderbuffer(GL_RENDERBUFFER, bufferId);
191                glRenderbufferStorage(GL_RENDERBUFFER | bufferDesc.m_Area, bufferDesc.m_Format,
192                    bufferDesc.m_Width, bufferDesc.m_Height);
193                m_Width = bufferDesc.m_Width;
194                m_Height = bufferDesc.m_Height;
195                DEMO_ASSERT_GL_ERROR();
196 
197                glFramebufferRenderbuffer(GL_FRAMEBUFFER, bufferDesc.m_Attachment,
198                    GL_RENDERBUFFER, m_RenderBufferIdArray[bufferIndex]);
199                DEMO_ASSERT_GL_ERROR();
200 
201                if ( bufferDesc.m_Attachment == GL_COLOR_ATTACHMENT0 )
202                {
203                    if ( colorBufferAttached )
204                    {
205                        NN_TPANIC_("Color buffer is attached twice.\n");
206                    }
207                    else
208                    {
209                        colorBufferAttached = true;
210                    }
211                }
212 
213                if ( bufferDesc.m_Attachment == GL_DEPTH_STENCIL_ATTACHMENT )
214                {
215                    if ( depthStencilBufferAttached )
216                    {
217                        NN_TPANIC_("Depth-Stencil buffer is attached twice.\n");
218                    }
219                    else
220                    {
221                        depthStencilBufferAttached = true;
222                    }
223                }
224 
225                if ( bufferDesc.m_Attachment == GL_DEPTH_ATTACHMENT )
226                {
227                     if ( depthBufferAttached )
228                    {
229                        NN_TPANIC_("Depth buffer is attached twice.\n");
230                    }
231                    else
232                    {
233                        depthBufferAttached = true;
234                    }
235                }
236 
237                if ( bufferDesc.m_Attachment == GL_STENCIL_ATTACHMENT )
238                {
239                    if ( stencilBufferAttached )
240                    {
241                        NN_TPANIC_("Stencil buffer is attached twice.\n");
242                    }
243                    else
244                    {
245                        stencilBufferAttached = true;
246                    }
247                }
248            }
249 
250            m_InitializeFlag = true;
251        }
252    }
253 
Finalize(void)254    void FrameBuffer::Finalize(void)
255    {
256        if ( m_InitializeFlag )
257        {
258            DEMO_ASSERT_GL_ERROR();
259 
260            glBindFramebuffer(GL_FRAMEBUFFER, 0);
261            glDeleteFramebuffers(1, &m_FrameBufferId);
262            DEMO_ASSERT_GL_ERROR();
263            m_FrameBufferId = 0;
264 
265            glDeleteRenderbuffers(m_RenderBufferNum, m_RenderBufferIdArray);
266            DEMO_ASSERT_GL_ERROR();
267 
268            m_InitializeFlag = false;
269        }
270    }
271 
Create(const FrameBufferDescription & frameBufferDesc,FrameBuffer & frameBuffer)272    void FrameBuffer::Create(const FrameBufferDescription& frameBufferDesc,
273        FrameBuffer& frameBuffer)
274    {
275        frameBuffer.Initialize(frameBufferDesc);
276        DEMO_ASSERT_GL_ERROR();
277    }
278 
Destroy(FrameBuffer & frameBuffer)279    void FrameBuffer::Destroy(FrameBuffer& frameBuffer)
280    {
281        frameBuffer.Finalize();
282        DEMO_ASSERT_GL_ERROR();
283    }
284 
Bind(void)285    void FrameBuffer::Bind(void)
286    {
287        if (! this->m_InitializeFlag)
288        {
289            NN_TPANIC_("Not initialized.\n");
290        }
291 
292        glBindFramebuffer(GL_FRAMEBUFFER, m_FrameBufferId);
293    }
294 
295 
SetViewport(void)296    void FrameBuffer::SetViewport(void)
297    {
298        SetViewport(0, 0, GetWidth(), GetHeight());
299    }
300 
301 
SetViewport(const GLint x,const GLint y,const GLsizei width,const GLsizei height)302    void FrameBuffer::SetViewport(const GLint x, const GLint y, const GLsizei width, const GLsizei height)
303    {
304         if (! this->m_InitializeFlag)
305         {
306            NN_TPANIC_("Not initialized.\n");
307         }
308 
309         glViewport(x, y, width, height);
310    }
311 
GetWidth(void)312    GLsizei FrameBuffer::GetWidth(void)
313    {
314        return m_Width;
315    }
316 
GetHeight(void)317    GLsizei FrameBuffer::GetHeight(void)
318    {
319        return m_Height;
320    }
321 
ClearBuffer(const GLbitfield mask)322    void FrameBuffer::ClearBuffer(const GLbitfield mask)
323    {
324        Bind();
325        glClear(mask);
326    }
327 
ClearColorDepthStencilBuffer(const GLclampf red,const GLclampf green,const GLclampf blue,const GLclampf alpha,const GLclampf depth,const GLclampf stencil)328    void FrameBuffer::ClearColorDepthStencilBuffer(const GLclampf red, const GLclampf green,
329        const GLclampf blue, const GLclampf alpha, const GLclampf depth, const GLclampf stencil)
330    {
331        Bind();
332        glClearColor(red, green, blue, alpha);
333        glClearDepthf(depth);
334        glClearStencil(stencil);
335        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
336    }
337 
ClearColorDepthBuffer(const GLclampf red,const GLclampf green,const GLclampf blue,const GLclampf alpha,const GLclampf depth)338    void FrameBuffer::ClearColorDepthBuffer(const GLclampf red, const GLclampf green,
339        const GLclampf blue, const GLclampf alpha, const GLclampf depth)
340    {
341        Bind();
342        glClearColor(red, green, blue, alpha);
343        glClearDepthf(depth);
344        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
345    }
346 
ClearColorBuffer(const GLclampf red,const GLclampf green,const GLclampf blue,const GLclampf alpha)347    void FrameBuffer::ClearColorBuffer(const GLclampf red, const GLclampf green,
348        const GLclampf blue, const GLclampf alpha)
349    {
350        Bind();
351        glClearColor(red, green, blue, alpha);
352        glClear(GL_COLOR_BUFFER_BIT);
353    }
354 
ClearDepthStencilBuffer(const GLclampf depth,const GLclampf stencil)355    void FrameBuffer::ClearDepthStencilBuffer(const GLclampf depth, const GLclampf stencil)
356    {
357        Bind();
358        glClearDepthf(depth);
359        glClearStencil(stencil);
360        glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
361    }
362 
ClearDepthBuffer(const GLclampf depth)363    void FrameBuffer::ClearDepthBuffer(const GLclampf depth)
364    {
365        Bind();
366        glClearDepthf(depth);
367        glClear(GL_DEPTH_BUFFER_BIT);
368    }
369 
ClearStencilBuffer(const GLclampf stencil)370    void FrameBuffer::ClearStencilBuffer(const GLclampf stencil)
371    {
372        Bind();
373        glClearStencil(stencil);
374        glClear(GL_STENCIL_BUFFER_BIT);
375    }
376 
Transfer(const GLuint displayBufferId,const GLenum mode,const GLboolean yflip,const GLint colorX,const GLint colorY)377    void FrameBuffer::Transfer(const GLuint displayBufferId, const GLenum mode,
378        const GLboolean yflip, const GLint colorX, const GLint colorY)
379    {
380        nngxTransferRenderImage(displayBufferId, mode, yflip, colorX, colorY);
381        DEMO_ASSERT_GL_ERROR();
382    }
383 
GetFrameBufferId(void)384    GLuint FrameBuffer::GetFrameBufferId(void)
385    {
386        if (! this->m_InitializeFlag)
387        {
388            NN_TPANIC_("Not initialized.\n");
389        }
390 
391        return m_FrameBufferId;
392    }
393 
GetRenderBufferId(const u32 bufferIndex)394    GLuint FrameBuffer::GetRenderBufferId(const u32 bufferIndex)
395    {
396         if (! this->m_InitializeFlag)
397         {
398            NN_TPANIC_("Not initialized.\n");
399 
400            return 0;
401         }
402 
403         if ( bufferIndex < m_RenderBufferNum )
404         {
405             return m_RenderBufferIdArray[bufferIndex];
406         }
407         else
408         {
409             NN_TPANIC_("Invalid bufferIndex = %d.\n", bufferIndex);
410 
411             return 0;
412         }
413    }
414 
415 }
416