/*========================================================================= Program: Visualization Toolkit Module: vtkFramebufferPass.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkFramebufferPass.h" #include "vtkObjectFactory.h" #include // #include "vtkCamera.h" #include "vtkRenderState.h" #include "vtkRenderer.h" #include "vtkOpenGLFramebufferObject.h" #include "vtkTextureObject.h" #include "vtkOpenGLRenderWindow.h" #include "vtkOpenGLError.h" // #include "vtkShaderProgram.h" // #include "vtkOpenGLShaderCache.h" // #include "vtkOpenGLRenderWindow.h" // #include "vtkOpenGLVertexArrayObject.h" #include "vtkOpenGLHelper.h" vtkStandardNewMacro(vtkFramebufferPass); // ---------------------------------------------------------------------------- vtkFramebufferPass::vtkFramebufferPass() { this->FrameBufferObject=nullptr; this->ColorTexture = vtkTextureObject::New(); this->DepthTexture = vtkTextureObject::New(); this->DepthFormat = vtkTextureObject::Float32; this->ColorFormat = vtkTextureObject::Fixed8; } // ---------------------------------------------------------------------------- vtkFramebufferPass::~vtkFramebufferPass() { if(this->FrameBufferObject!=nullptr) { vtkErrorMacro(<<"FrameBufferObject should have been deleted in ReleaseGraphicsResources()."); } if(this->ColorTexture!=nullptr) { this->ColorTexture->Delete(); this->ColorTexture = nullptr; } if(this->DepthTexture !=nullptr) { this->DepthTexture->Delete(); this->DepthTexture = nullptr; } } // ---------------------------------------------------------------------------- void vtkFramebufferPass::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); } // ---------------------------------------------------------------------------- // Description: // Perform rendering according to a render state \p s. // \pre s_exists: s!=0 void vtkFramebufferPass::Render(const vtkRenderState *s) { assert("pre: s_exists" && s!=nullptr); vtkOpenGLClearErrorMacro(); this->NumberOfRenderedProps=0; vtkRenderer *r=s->GetRenderer(); vtkOpenGLRenderWindow *renWin = static_cast(r->GetRenderWindow()); if(this->DelegatePass == nullptr) { vtkWarningMacro(<<" no delegate."); return; } // 1. Create a new render state with an FO. if(s->GetFrameBuffer()==nullptr) { // get the viewport dimensions r->GetTiledSizeAndOrigin(&this->ViewportWidth,&this->ViewportHeight, &this->ViewportX,&this->ViewportY); } else { int size[2]; s->GetWindowSize(size); this->ViewportWidth=size[0]; this->ViewportHeight=size[1]; this->ViewportX=0; this->ViewportY=0; } this->ColorTexture->SetContext(renWin); if (!this->ColorTexture->GetHandle()) { if (this->ColorFormat == vtkTextureObject::Float16) { this->ColorTexture->SetInternalFormat(GL_RGBA16F); this->ColorTexture->SetDataType(GL_FLOAT); } if (this->ColorFormat == vtkTextureObject::Float32) { this->ColorTexture->SetInternalFormat(GL_RGBA32F); this->ColorTexture->SetDataType(GL_FLOAT); } this->ColorTexture->Create2D( this->ViewportWidth, this->ViewportHeight, 4, VTK_UNSIGNED_CHAR, false); } this->ColorTexture->Resize(this->ViewportWidth, this->ViewportHeight); // Depth texture this->DepthTexture->SetContext(renWin); if (!this->DepthTexture->GetHandle()) { this->DepthTexture->AllocateDepth( this->ViewportWidth, this->ViewportHeight, this->DepthFormat); } this->DepthTexture->Resize(this->ViewportWidth, this->ViewportHeight); if(this->FrameBufferObject==nullptr) { this->FrameBufferObject=vtkOpenGLFramebufferObject::New(); this->FrameBufferObject->SetContext(renWin); } this->FrameBufferObject->SaveCurrentBindingsAndBuffers(); this->RenderDelegate(s, this->ViewportWidth, this->ViewportHeight, this->ViewportWidth, this->ViewportHeight, this->FrameBufferObject, this->ColorTexture, this->DepthTexture); this->FrameBufferObject->RestorePreviousBindingsAndBuffers(); // now copy the result to the outer FO this->FrameBufferObject->SaveCurrentBindingsAndBuffers( this->FrameBufferObject->GetReadMode()); this->FrameBufferObject->Bind( this->FrameBufferObject->GetReadMode()); glViewport(this->ViewportX, this->ViewportY, this->ViewportWidth, this->ViewportHeight); glScissor(this->ViewportX, this->ViewportY, this->ViewportWidth, this->ViewportHeight); glBlitFramebuffer( 0, 0, this->ViewportWidth, this->ViewportHeight, this->ViewportX, this->ViewportY, this->ViewportX + this->ViewportWidth, this->ViewportY + this->ViewportHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); this->FrameBufferObject->RestorePreviousBindingsAndBuffers( this->FrameBufferObject->GetReadMode()); vtkOpenGLCheckErrorMacro("failed after Render"); } // ---------------------------------------------------------------------------- // Description: // Release graphics resources and ask components to release their own // resources. // \pre w_exists: w!=0 void vtkFramebufferPass::ReleaseGraphicsResources(vtkWindow *w) { assert("pre: w_exists" && w!=nullptr); this->Superclass::ReleaseGraphicsResources(w); if(this->FrameBufferObject!=nullptr) { this->FrameBufferObject->Delete(); this->FrameBufferObject=nullptr; } if(this->ColorTexture!=nullptr) { this->ColorTexture->ReleaseGraphicsResources(w); } if(this->DepthTexture!=nullptr) { this->DepthTexture->ReleaseGraphicsResources(w); } }