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