1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer 16 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105. 17 18 #include "Framebuffer.h" 19 20 #include "main.h" 21 #include "Renderbuffer.h" 22 #include "Texture.h" 23 #include "utilities.h" 24 25 #include <algorithm> 26 27 namespace es2 28 { 29 30 bool Framebuffer::IsRenderbuffer(GLenum type) 31 { 32 return type == GL_RENDERBUFFER || type == GL_FRAMEBUFFER_DEFAULT; 33 } 34 35 Framebuffer::Framebuffer() 36 { 37 readBuffer = GL_COLOR_ATTACHMENT0; 38 drawBuffer[0] = GL_COLOR_ATTACHMENT0; 39 for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++) 40 { 41 drawBuffer[i] = GL_NONE; 42 } 43 44 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 45 { 46 mColorbufferType[i] = GL_NONE; 47 mColorbufferLayer[i] = 0; 48 } 49 50 mDepthbufferType = GL_NONE; 51 mDepthbufferLayer = 0; 52 mStencilbufferType = GL_NONE; 53 mStencilbufferLayer = 0; 54 } 55 56 Framebuffer::~Framebuffer() 57 { 58 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 59 { 60 mColorbufferPointer[i] = nullptr; 61 } 62 mDepthbufferPointer = nullptr; 63 mStencilbufferPointer = nullptr; 64 } 65 66 Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level) const 67 { 68 Context *context = getContextLocked(); 69 Renderbuffer *buffer = nullptr; 70 71 if(type == GL_NONE) 72 { 73 buffer = nullptr; 74 } 75 else if(IsRenderbuffer(type)) 76 { 77 buffer = context->getRenderbuffer(handle); 78 } 79 else if(IsTextureTarget(type)) 80 { 81 buffer = context->getTexture(handle)->getRenderbuffer(type, level); 82 } 83 else UNREACHABLE(type); 84 85 return buffer; 86 } 87 88 void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level, GLint layer) 89 { 90 mColorbufferType[index] = (colorbuffer != 0) ? type : GL_NONE; 91 mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer, level); 92 mColorbufferLayer[index] = layer; 93 } 94 95 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer) 96 { 97 mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE; 98 mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer, level); 99 mDepthbufferLayer = layer; 100 } 101 102 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer) 103 { 104 mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE; 105 mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer, level); 106 mStencilbufferLayer = layer; 107 } 108 109 void Framebuffer::setReadBuffer(GLenum buf) 110 { 111 readBuffer = buf; 112 } 113 114 void Framebuffer::setDrawBuffer(GLuint index, GLenum buf) 115 { 116 drawBuffer[index] = buf; 117 } 118 119 GLenum Framebuffer::getReadBuffer() const 120 { 121 return readBuffer; 122 } 123 124 GLenum Framebuffer::getDrawBuffer(GLuint index) const 125 { 126 return drawBuffer[index]; 127 } 128 129 void Framebuffer::detachTexture(GLuint texture) 130 { 131 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 132 { 133 if(mColorbufferPointer[i].name() == texture && IsTextureTarget(mColorbufferType[i])) 134 { 135 mColorbufferType[i] = GL_NONE; 136 mColorbufferPointer[i] = nullptr; 137 } 138 } 139 140 if(mDepthbufferPointer.name() == texture && IsTextureTarget(mDepthbufferType)) 141 { 142 mDepthbufferType = GL_NONE; 143 mDepthbufferPointer = nullptr; 144 } 145 146 if(mStencilbufferPointer.name() == texture && IsTextureTarget(mStencilbufferType)) 147 { 148 mStencilbufferType = GL_NONE; 149 mStencilbufferPointer = nullptr; 150 } 151 } 152 153 void Framebuffer::detachRenderbuffer(GLuint renderbuffer) 154 { 155 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 156 { 157 if(mColorbufferPointer[i].name() == renderbuffer && IsRenderbuffer(mColorbufferType[i])) 158 { 159 mColorbufferType[i] = GL_NONE; 160 mColorbufferPointer[i] = nullptr; 161 } 162 } 163 164 if(mDepthbufferPointer.name() == renderbuffer && IsRenderbuffer(mDepthbufferType)) 165 { 166 mDepthbufferType = GL_NONE; 167 mDepthbufferPointer = nullptr; 168 } 169 170 if(mStencilbufferPointer.name() == renderbuffer && IsRenderbuffer(mStencilbufferType)) 171 { 172 mStencilbufferType = GL_NONE; 173 mStencilbufferPointer = nullptr; 174 } 175 } 176 177 // Increments refcount on surface. 178 // caller must Release() the returned surface 179 egl::Image *Framebuffer::getRenderTarget(GLuint index) 180 { 181 if(index < MAX_COLOR_ATTACHMENTS) 182 { 183 Renderbuffer *colorbuffer = mColorbufferPointer[index]; 184 185 if(colorbuffer) 186 { 187 return colorbuffer->getRenderTarget(); 188 } 189 } 190 191 return nullptr; 192 } 193 194 egl::Image *Framebuffer::getReadRenderTarget() 195 { 196 return getRenderTarget(getReadBufferIndex()); 197 } 198 199 // Increments refcount on surface. 200 // caller must Release() the returned surface 201 egl::Image *Framebuffer::getDepthBuffer() 202 { 203 Renderbuffer *depthbuffer = mDepthbufferPointer; 204 205 if(depthbuffer) 206 { 207 return depthbuffer->getRenderTarget(); 208 } 209 210 return nullptr; 211 } 212 213 // Increments refcount on surface. 214 // caller must Release() the returned surface 215 egl::Image *Framebuffer::getStencilBuffer() 216 { 217 Renderbuffer *stencilbuffer = mStencilbufferPointer; 218 219 if(stencilbuffer) 220 { 221 return stencilbuffer->getRenderTarget(); 222 } 223 224 return nullptr; 225 } 226 227 Renderbuffer *Framebuffer::getColorbuffer(GLuint index) const 228 { 229 return (index < MAX_COLOR_ATTACHMENTS) ? mColorbufferPointer[index] : (Renderbuffer*)nullptr; 230 } 231 232 Renderbuffer *Framebuffer::getReadColorbuffer() const 233 { 234 return getColorbuffer(getReadBufferIndex()); 235 } 236 237 Renderbuffer *Framebuffer::getDepthbuffer() const 238 { 239 return mDepthbufferPointer; 240 } 241 242 Renderbuffer *Framebuffer::getStencilbuffer() const 243 { 244 return mStencilbufferPointer; 245 } 246 247 GLenum Framebuffer::getReadBufferType() 248 { 249 if(readBuffer == GL_NONE) 250 { 251 return GL_NONE; 252 } 253 254 return mColorbufferType[getReadBufferIndex()]; 255 } 256 257 GLenum Framebuffer::getColorbufferType(GLuint index) 258 { 259 return mColorbufferType[index]; 260 } 261 262 GLenum Framebuffer::getDepthbufferType() 263 { 264 return mDepthbufferType; 265 } 266 267 GLenum Framebuffer::getStencilbufferType() 268 { 269 return mStencilbufferType; 270 } 271 272 GLuint Framebuffer::getColorbufferName(GLuint index) 273 { 274 return mColorbufferPointer[index].name(); 275 } 276 277 GLuint Framebuffer::getDepthbufferName() 278 { 279 return mDepthbufferPointer.name(); 280 } 281 282 GLuint Framebuffer::getStencilbufferName() 283 { 284 return mStencilbufferPointer.name(); 285 } 286 287 GLint Framebuffer::getColorbufferLayer(GLuint index) 288 { 289 return mColorbufferLayer[index]; 290 } 291 292 GLint Framebuffer::getDepthbufferLayer() 293 { 294 return mDepthbufferLayer; 295 } 296 297 GLint Framebuffer::getStencilbufferLayer() 298 { 299 return mStencilbufferLayer; 300 } 301 302 bool Framebuffer::hasStencil() 303 { 304 if(mStencilbufferType != GL_NONE) 305 { 306 Renderbuffer *stencilbufferObject = getStencilbuffer(); 307 308 if(stencilbufferObject) 309 { 310 return stencilbufferObject->getStencilSize() > 0; 311 } 312 } 313 314 return false; 315 } 316 317 GLenum Framebuffer::completeness() 318 { 319 int width; 320 int height; 321 int samples; 322 323 return completeness(width, height, samples); 324 } 325 326 GLenum Framebuffer::completeness(int &width, int &height, int &samples) 327 { 328 width = -1; 329 height = -1; 330 samples = -1; 331 332 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 333 { 334 if(mColorbufferType[i] != GL_NONE) 335 { 336 Renderbuffer *colorbuffer = getColorbuffer(i); 337 338 if(!colorbuffer) 339 { 340 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 341 } 342 343 if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0 || (colorbuffer->getDepth() <= mColorbufferLayer[i])) 344 { 345 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 346 } 347 348 if(IsRenderbuffer(mColorbufferType[i])) 349 { 350 if(!IsColorRenderable(colorbuffer->getFormat())) 351 { 352 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 353 } 354 } 355 else if(IsTextureTarget(mColorbufferType[i])) 356 { 357 GLint format = colorbuffer->getFormat(); 358 359 if(!IsColorRenderable(format)) 360 { 361 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 362 } 363 364 if(IsDepthTexture(format) || IsStencilTexture(format)) 365 { 366 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 367 } 368 } 369 else 370 { 371 UNREACHABLE(mColorbufferType[i]); 372 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 373 } 374 375 if(width == -1 || height == -1) 376 { 377 width = colorbuffer->getWidth(); 378 height = colorbuffer->getHeight(); 379 samples = colorbuffer->getSamples(); 380 } 381 else 382 { 383 if(samples != colorbuffer->getSamples()) 384 { 385 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 386 } 387 388 width = std::min(width, colorbuffer->getWidth()); 389 height = std::min(height, colorbuffer->getHeight()); 390 } 391 } 392 } 393 394 Renderbuffer *depthbuffer = nullptr; 395 Renderbuffer *stencilbuffer = nullptr; 396 397 if(mDepthbufferType != GL_NONE) 398 { 399 depthbuffer = getDepthbuffer(); 400 401 if(!depthbuffer) 402 { 403 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 404 } 405 406 if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0 || (depthbuffer->getDepth() <= mDepthbufferLayer)) 407 { 408 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 409 } 410 411 if(IsRenderbuffer(mDepthbufferType)) 412 { 413 if(!es2::IsDepthRenderable(depthbuffer->getFormat())) 414 { 415 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 416 } 417 } 418 else if(IsTextureTarget(mDepthbufferType)) 419 { 420 if(!es2::IsDepthTexture(depthbuffer->getFormat())) 421 { 422 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 423 } 424 } 425 else 426 { 427 UNREACHABLE(mDepthbufferType); 428 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 429 } 430 431 if(width == -1 || height == -1) 432 { 433 width = depthbuffer->getWidth(); 434 height = depthbuffer->getHeight(); 435 samples = depthbuffer->getSamples(); 436 } 437 else 438 { 439 if(samples != depthbuffer->getSamples()) 440 { 441 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 442 } 443 444 width = std::min(width, depthbuffer->getWidth()); 445 height = std::min(height, depthbuffer->getHeight()); 446 } 447 } 448 449 if(mStencilbufferType != GL_NONE) 450 { 451 stencilbuffer = getStencilbuffer(); 452 453 if(!stencilbuffer) 454 { 455 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 456 } 457 458 if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0 || (stencilbuffer->getDepth() <= mStencilbufferLayer)) 459 { 460 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 461 } 462 463 if(IsRenderbuffer(mStencilbufferType)) 464 { 465 if(!es2::IsStencilRenderable(stencilbuffer->getFormat())) 466 { 467 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 468 } 469 } 470 else if(IsTextureTarget(mStencilbufferType)) 471 { 472 GLenum internalformat = stencilbuffer->getFormat(); 473 474 if(!es2::IsStencilTexture(internalformat)) 475 { 476 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 477 } 478 } 479 else 480 { 481 UNREACHABLE(mStencilbufferType); 482 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 483 } 484 485 if(width == -1 || height == -1) 486 { 487 width = stencilbuffer->getWidth(); 488 height = stencilbuffer->getHeight(); 489 samples = stencilbuffer->getSamples(); 490 } 491 else 492 { 493 if(samples != stencilbuffer->getSamples()) 494 { 495 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 496 } 497 498 width = std::min(width, stencilbuffer->getWidth()); 499 height = std::min(height, stencilbuffer->getHeight()); 500 } 501 } 502 503 if(depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer)) 504 { 505 // In the GLES 3.0 spec, section 4.4.4, Framebuffer Completeness: 506 // "The framebuffer object target is said to be framebuffer complete if all the following conditions are true: 507 // [...] 508 // Depth and stencil attachments, if present, are the same image. 509 // { FRAMEBUFFER_UNSUPPORTED }" 510 return GL_FRAMEBUFFER_UNSUPPORTED; 511 } 512 513 // We need to have at least one attachment to be complete 514 if(width == -1 || height == -1) 515 { 516 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; 517 } 518 519 return GL_FRAMEBUFFER_COMPLETE; 520 } 521 522 GLenum Framebuffer::getImplementationColorReadFormat() const 523 { 524 Renderbuffer *colorbuffer = getReadColorbuffer(); 525 526 if(colorbuffer) 527 { 528 switch(colorbuffer->getFormat()) 529 { 530 case GL_BGRA8_EXT: return GL_BGRA_EXT; 531 case GL_RGBA4: return GL_RGBA; 532 case GL_RGB5_A1: return GL_RGBA; 533 case GL_RGBA8: return GL_RGBA; 534 case GL_RGB565: return GL_RGBA; 535 case GL_RGB8: return GL_RGB; 536 case GL_R8: return GL_RED; 537 case GL_RG8: return GL_RG; 538 case GL_R8I: return GL_RED_INTEGER; 539 case GL_RG8I: return GL_RG_INTEGER; 540 case GL_RGB8I: return GL_RGB_INTEGER; 541 case GL_RGBA8I: return GL_RGBA_INTEGER; 542 case GL_R8UI: return GL_RED_INTEGER; 543 case GL_RG8UI: return GL_RG_INTEGER; 544 case GL_RGB8UI: return GL_RGB_INTEGER; 545 case GL_RGBA8UI: return GL_RGBA_INTEGER; 546 case GL_R16I: return GL_RED_INTEGER; 547 case GL_RG16I: return GL_RG_INTEGER; 548 case GL_RGB16I: return GL_RGB_INTEGER; 549 case GL_RGBA16I: return GL_RGBA_INTEGER; 550 case GL_R16UI: return GL_RED_INTEGER; 551 case GL_RG16UI: return GL_RG_INTEGER; 552 case GL_RGB16UI: return GL_RGB_INTEGER; 553 case GL_RGB10_A2UI: return GL_RGBA_INTEGER; 554 case GL_RGBA16UI: return GL_RGBA_INTEGER; 555 case GL_R32I: return GL_RED_INTEGER; 556 case GL_RG32I: return GL_RG_INTEGER; 557 case GL_RGB32I: return GL_RGB_INTEGER; 558 case GL_RGBA32I: return GL_RGBA_INTEGER; 559 case GL_R32UI: return GL_RED_INTEGER; 560 case GL_RG32UI: return GL_RG_INTEGER; 561 case GL_RGB32UI: return GL_RGB_INTEGER; 562 case GL_RGBA32UI: return GL_RGBA_INTEGER; 563 case GL_R16F: return GL_RED; 564 case GL_RG16F: return GL_RG; 565 case GL_R11F_G11F_B10F: return GL_RGB; 566 case GL_RGB16F: return GL_RGB; 567 case GL_RGBA16F: return GL_RGBA; 568 case GL_R32F: return GL_RED; 569 case GL_RG32F: return GL_RG; 570 case GL_RGB32F: return GL_RGB; 571 case GL_RGBA32F: return GL_RGBA; 572 case GL_RGB10_A2: return GL_RGBA; 573 case GL_SRGB8: return GL_RGB; 574 case GL_SRGB8_ALPHA8: return GL_RGBA; 575 default: 576 UNREACHABLE(colorbuffer->getFormat()); 577 } 578 } 579 580 return GL_RGBA; 581 } 582 583 GLenum Framebuffer::getImplementationColorReadType() const 584 { 585 Renderbuffer *colorbuffer = getReadColorbuffer(); 586 587 if(colorbuffer) 588 { 589 switch(colorbuffer->getFormat()) 590 { 591 case GL_BGRA8_EXT: return GL_UNSIGNED_BYTE; 592 case GL_RGBA4: return GL_UNSIGNED_SHORT_4_4_4_4; 593 case GL_RGB5_A1: return GL_UNSIGNED_SHORT_5_5_5_1; 594 case GL_RGBA8: return GL_UNSIGNED_BYTE; 595 case GL_RGB565: return GL_UNSIGNED_SHORT_5_6_5; 596 case GL_RGB8: return GL_UNSIGNED_BYTE; 597 case GL_R8: return GL_UNSIGNED_BYTE; 598 case GL_RG8: return GL_UNSIGNED_BYTE; 599 case GL_R8I: return GL_INT; 600 case GL_RG8I: return GL_INT; 601 case GL_RGB8I: return GL_INT; 602 case GL_RGBA8I: return GL_INT; 603 case GL_R8UI: return GL_UNSIGNED_BYTE; 604 case GL_RG8UI: return GL_UNSIGNED_BYTE; 605 case GL_RGB8UI: return GL_UNSIGNED_BYTE; 606 case GL_RGBA8UI: return GL_UNSIGNED_BYTE; 607 case GL_R16I: return GL_INT; 608 case GL_RG16I: return GL_INT; 609 case GL_RGB16I: return GL_INT; 610 case GL_RGBA16I: return GL_INT; 611 case GL_R16UI: return GL_UNSIGNED_INT; 612 case GL_RG16UI: return GL_UNSIGNED_INT; 613 case GL_RGB16UI: return GL_UNSIGNED_INT; 614 case GL_RGB10_A2UI: return GL_UNSIGNED_INT_2_10_10_10_REV; 615 case GL_RGBA16UI: return GL_UNSIGNED_INT; 616 case GL_R32I: return GL_INT; 617 case GL_RG32I: return GL_INT; 618 case GL_RGB32I: return GL_INT; 619 case GL_RGBA32I: return GL_INT; 620 case GL_R32UI: return GL_UNSIGNED_INT; 621 case GL_RG32UI: return GL_UNSIGNED_INT; 622 case GL_RGB32UI: return GL_UNSIGNED_INT; 623 case GL_RGBA32UI: return GL_UNSIGNED_INT; 624 case GL_R16F: return GL_HALF_FLOAT; 625 case GL_RG16F: return GL_HALF_FLOAT; 626 case GL_R11F_G11F_B10F: return GL_HALF_FLOAT; 627 case GL_RGB16F: return GL_HALF_FLOAT; 628 case GL_RGBA16F: return GL_HALF_FLOAT; 629 case GL_R32F: return GL_FLOAT; 630 case GL_RG32F: return GL_FLOAT; 631 case GL_RGB32F: return GL_FLOAT; 632 case GL_RGBA32F: return GL_FLOAT; 633 case GL_RGB10_A2: return GL_UNSIGNED_INT_2_10_10_10_REV; 634 case GL_SRGB8: return GL_UNSIGNED_BYTE; 635 case GL_SRGB8_ALPHA8: return GL_UNSIGNED_BYTE; 636 default: 637 UNREACHABLE(colorbuffer->getFormat()); 638 } 639 } 640 641 return GL_UNSIGNED_BYTE; 642 } 643 644 GLenum Framebuffer::getDepthReadFormat() const 645 { 646 Renderbuffer *depthbuffer = getDepthbuffer(); 647 648 if(depthbuffer) 649 { 650 // There is only one depth read format. 651 return GL_DEPTH_COMPONENT; 652 } 653 654 // If there is no depth buffer, GL_INVALID_OPERATION occurs. 655 return GL_NONE; 656 } 657 658 GLenum Framebuffer::getDepthReadType() const 659 { 660 Renderbuffer *depthbuffer = getDepthbuffer(); 661 662 if(depthbuffer) 663 { 664 switch(depthbuffer->getFormat()) 665 { 666 case GL_DEPTH_COMPONENT16: return GL_UNSIGNED_SHORT; 667 case GL_DEPTH_COMPONENT24: return GL_UNSIGNED_INT; 668 case GL_DEPTH_COMPONENT32_OES: return GL_UNSIGNED_INT; 669 case GL_DEPTH_COMPONENT32F: return GL_FLOAT; 670 case GL_DEPTH24_STENCIL8: return GL_UNSIGNED_INT_24_8_OES; 671 case GL_DEPTH32F_STENCIL8: return GL_FLOAT_32_UNSIGNED_INT_24_8_REV; 672 default: 673 UNREACHABLE(depthbuffer->getFormat()); 674 } 675 } 676 677 // If there is no depth buffer, GL_INVALID_OPERATION occurs. 678 return GL_NONE; 679 } 680 681 GLuint Framebuffer::getReadBufferIndex() const 682 { 683 switch(readBuffer) 684 { 685 case GL_BACK: 686 return 0; 687 case GL_NONE: 688 return GL_INVALID_INDEX; 689 default: 690 return readBuffer - GL_COLOR_ATTACHMENT0; 691 } 692 } 693 694 DefaultFramebuffer::DefaultFramebuffer() 695 { 696 readBuffer = GL_BACK; 697 drawBuffer[0] = GL_BACK; 698 } 699 700 DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil) 701 { 702 GLenum defaultRenderbufferType = GL_FRAMEBUFFER_DEFAULT; 703 mColorbufferPointer[0] = new Renderbuffer(0, colorbuffer); 704 mColorbufferType[0] = defaultRenderbufferType; 705 706 readBuffer = GL_BACK; 707 drawBuffer[0] = GL_BACK; 708 for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++) 709 { 710 mColorbufferPointer[i] = nullptr; 711 mColorbufferType[i] = GL_NONE; 712 } 713 714 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil); 715 mDepthbufferPointer = depthStencilRenderbuffer; 716 mStencilbufferPointer = depthStencilRenderbuffer; 717 718 mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_FRAMEBUFFER_DEFAULT : GL_NONE; 719 mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_FRAMEBUFFER_DEFAULT : GL_NONE; 720 } 721 722 } 723