Commit 91595233 authored by Ken Martin's avatar Ken Martin Committed by Kitware Robot

Merge topic 'always_framebuffer'

426d5d8d Some fixes to framebuffer resorce management
f161cf55 fix srystal eves buffers and add errro checking
b75bc715 Update VTK to always use a framebuffer for rendering
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !6229
parents 3388ac80 426d5d8d
Pipeline #153199 running with stage
2d6863bfba4da904385c8d571a99fc6855c92382d869ab3d2000f9967a7a7b9afdc26654e47da4253244bbee136749b09a9a207139d4849009710b29f941c703
63d03f2145de7797b4c4d01989be4854468ccdefb237f68c96b054c5425ddb0f4ccaa932bba8e1488998f4f036c39e874c4ee0cd42d13d1f2b268ddaa35a45db
c5b3b918f705c39b103c8b3da0f1d59c9648b08c67b798861c1061cb2d8ed53cd2f54664e2ef767ddc84144818f72d748d9191ec913a2f9d2bb1f90b50ff3da2
319073d7ed4258c838ad64d88afebe8e925a111ee878edc83c76c3b811e6258aadd78f060bdc953f19d28f99117bd01bbd78575296eaa97311c082eb909c221b
......@@ -29,7 +29,6 @@
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkTestUtilities.h"
#include "vtkUnsignedCharArray.h"
int TestEdgeFlags(int argc, char* argv[])
......
......@@ -109,6 +109,22 @@ vtkRenderWindow::~vtkRenderWindow()
}
}
void vtkRenderWindow::SetMultiSamples(int val)
{
if (val == 1)
{
val = 0;
}
if (val == this->MultiSamples)
{
return;
}
this->MultiSamples = val;
this->Modified();
}
//----------------------------------------------------------------------------
// Create an interactor that will work with this renderer.
vtkRenderWindowInteractor* vtkRenderWindow::MakeRenderWindowInteractor()
......@@ -275,15 +291,18 @@ void vtkRenderWindow::Render()
this->Interactor->Initialize();
}
this->Start(); // Ensure context exists
vtkRenderTimerLog::ScopedEventLogger event;
if (this->RenderTimer->GetLoggingEnabled())
{
this->Start(); // Ensure context exists
this->RenderTimer->MarkFrame();
event = this->RenderTimer->StartScopedEvent("vtkRenderWindow::Render");
}
this->DoStereoRender();
this->End(); // restores original bindings
this->CopyResultFrame();
// reset the buffer size without freeing any memory.
......@@ -302,7 +321,6 @@ void vtkRenderWindow::DoStereoRender()
{
vtkCollectionSimpleIterator rsit;
this->Start();
this->StereoUpdate();
if (!this->StereoRender || (this->StereoType != VTK_STEREO_RIGHT))
......
......@@ -156,6 +156,11 @@ public:
*/
virtual void Start() = 0;
/**
* Update the system, if needed, at end of render process
*/
virtual void End(){};
/**
* Finalize the rendering process.
*/
......@@ -644,8 +649,9 @@ public:
//@{
/**
* Set / Get the number of multisamples to use for hardware antialiasing.
* A value of 1 will be set to 0.
*/
vtkSetMacro(MultiSamples, int);
virtual void SetMultiSamples(int);
vtkGetMacro(MultiSamples, int);
//@}
......
......@@ -35,105 +35,6 @@ vtkExternalOpenGLCamera::vtkExternalOpenGLCamera()
this->UserProvidedViewTransform = false;
}
//----------------------------------------------------------------------------
// Implement base class method.
void vtkExternalOpenGLCamera::Render(vtkRenderer* ren)
{
vtkOpenGLClearErrorMacro();
int lowerLeft[2];
int usize, vsize;
vtkOpenGLRenderWindow* win = vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow());
vtkOpenGLState* ostate = win->GetState();
// find out if we should stereo render
this->Stereo = (ren->GetRenderWindow())->GetStereoRender();
ren->GetTiledSizeAndOrigin(&usize, &vsize, lowerLeft, lowerLeft + 1);
// Take the window position into account
for (int i = 0; i < 2; ++i)
{
lowerLeft[i] = lowerLeft[i] + ren->GetRenderWindow()->GetPosition()[i];
}
// if were on a stereo renderer draw to special parts of screen
if (this->Stereo)
{
switch ((ren->GetRenderWindow())->GetStereoType())
{
case VTK_STEREO_CRYSTAL_EYES:
if (this->LeftEye)
{
if (ren->GetRenderWindow()->GetDoubleBuffer())
{
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetBackLeftBuffer()));
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetBackLeftBuffer()));
}
else
{
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetFrontLeftBuffer()));
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetFrontLeftBuffer()));
}
}
else
{
if (ren->GetRenderWindow()->GetDoubleBuffer())
{
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetBackRightBuffer()));
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetBackRightBuffer()));
}
else
{
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetFrontRightBuffer()));
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetFrontRightBuffer()));
}
}
break;
case VTK_STEREO_LEFT:
this->LeftEye = 1;
break;
case VTK_STEREO_RIGHT:
this->LeftEye = 0;
break;
default:
break;
}
}
else
{
if (ren->GetRenderWindow()->GetDoubleBuffer())
{
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetBackLeftBuffer()));
// Reading back buffer means back left. see OpenGL spec.
// because one can write to two buffers at a time but can only read from
// one buffer at a time.
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetBackLeftBuffer()));
}
else
{
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetFrontLeftBuffer()));
// Reading front buffer means front left. see OpenGL spec.
// because one can write to two buffers at a time but can only read from
// one buffer at a time.
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetFrontLeftBuffer()));
}
}
ostate->vtkglViewport(lowerLeft[0], lowerLeft[1], usize, vsize);
ostate->vtkglEnable(GL_SCISSOR_TEST);
ostate->vtkglScissor(lowerLeft[0], lowerLeft[1], usize, vsize);
if ((ren->GetRenderWindow())->GetErase() && ren->GetErase())
{
ren->Clear();
}
vtkOpenGLCheckErrorMacro("failed after Render");
}
//----------------------------------------------------------------------------
void vtkExternalOpenGLCamera::SetViewTransformMatrix(const double elements[16])
{
......
......@@ -35,11 +35,6 @@ public:
vtkTypeMacro(vtkExternalOpenGLCamera, vtkOpenGLCamera);
void PrintSelf(ostream& os, vtkIndent indent) override;
/**
* Implement base class method.
*/
void Render(vtkRenderer* ren) override;
/**
* Set the view transform matrix
*/
......
......@@ -17,6 +17,8 @@
#include "vtkExternalOpenGLRenderWindow.h"
#include "vtkObjectFactory.h"
#include "vtkOpenGLFramebufferObject.h"
#include "vtkOpenGLState.h"
#include "vtkRenderer.h"
#include "vtkRendererCollection.h"
......@@ -26,6 +28,7 @@ vtkStandardNewMacro(vtkExternalOpenGLRenderWindow);
vtkExternalOpenGLRenderWindow::vtkExternalOpenGLRenderWindow()
{
this->AutomaticWindowPositionAndResize = 1;
this->UseExternalContent = true;
}
//----------------------------------------------------------------------------
......@@ -40,17 +43,24 @@ void vtkExternalOpenGLRenderWindow::Start(void)
// Use hardware acceleration
this->SetIsDirect(1);
auto ostate = this->GetState();
if (this->AutomaticWindowPositionAndResize)
{
int info[4];
glGetIntegerv(GL_VIEWPORT, info);
ostate->vtkglGetIntegerv(GL_VIEWPORT, info);
this->SetPosition(info[0], info[1]);
this->SetSize(info[2], info[3]);
}
// creates or resizes the framebuffer
this->Size[0] = (this->Size[0] > 0 ? this->Size[0] : 300);
this->Size[1] = (this->Size[1] > 0 ? this->Size[1] : 300);
this->CreateOffScreenFramebuffer(this->Size[0], this->Size[1]);
// For stereo, render the correct eye based on the OpenGL buffer mode
GLint bufferType;
glGetIntegerv(GL_DRAW_BUFFER, &bufferType);
ostate->vtkglGetIntegerv(GL_DRAW_BUFFER, &bufferType);
vtkCollectionSimpleIterator sit;
vtkRenderer* renderer;
for (this->GetRenderers()->InitTraversal(sit);
......@@ -66,6 +76,20 @@ void vtkExternalOpenGLRenderWindow::Start(void)
this->SetStereoTypeToLeft();
}
}
ostate->PushFramebufferBindings();
if (this->UseExternalContent)
{
const int destExtents[4] = { 0, this->Size[0], 0, this->Size[1] };
this->OffScreenFramebuffer->Bind(GL_DRAW_FRAMEBUFFER);
this->GetState()->vtkglViewport(0, 0, this->Size[0], this->Size[1]);
this->GetState()->vtkglScissor(0, 0, this->Size[0], this->Size[1]);
vtkOpenGLFramebufferObject::Blit(
destExtents, destExtents, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
}
this->OffScreenFramebuffer->Bind();
}
//----------------------------------------------------------------------------
......@@ -77,5 +101,6 @@ bool vtkExternalOpenGLRenderWindow::IsCurrent(void)
//----------------------------------------------------------------------------
void vtkExternalOpenGLRenderWindow::PrintSelf(ostream& os, vtkIndent indent)
{
os << indent << "UseExternalContent: " << this->UseExternalContent << endl;
this->Superclass::PrintSelf(os, indent);
}
......@@ -80,11 +80,23 @@ public:
vtkBooleanMacro(AutomaticWindowPositionAndResize, int);
//@}
//@{
/**
* Turn on/off a flag which enables/disables using the content from an
* outside applicaiton. When on the active read buffer is first blitted
* into VTK and becomes the starting poiint for VTK's rendering.
*/
vtkGetMacro(UseExternalContent, bool);
vtkSetMacro(UseExternalContent, bool);
vtkBooleanMacro(UseExternalContent, bool);
//@}
protected:
vtkExternalOpenGLRenderWindow();
~vtkExternalOpenGLRenderWindow() override;
int AutomaticWindowPositionAndResize;
bool UseExternalContent;
private:
vtkExternalOpenGLRenderWindow(const vtkExternalOpenGLRenderWindow&) = delete;
......
......@@ -335,7 +335,6 @@ void vtkAndroidRenderWindowInteractor::HandleCommand(int32_t cmd)
{
LOGW("Creating Window");
this->RenderWindow->SetWindowId(this->AndroidApplication->window);
this->RenderWindow->Start();
LOGW("Done Creating Window start");
this->RenderWindow->Render();
LOGW("Done first render");
......
......@@ -937,15 +937,6 @@ void vtkCocoaRenderWindow::CreateGLContext()
attribs[i++] = NSOpenGLPFADepthSize;
attribs[i++] = (NSOpenGLPixelFormatAttribute)32;
if (this->MultiSamples != 0)
{
attribs[i++] = NSOpenGLPFASampleBuffers;
attribs[i++] = (NSOpenGLPixelFormatAttribute)1;
attribs[i++] = NSOpenGLPFASamples;
attribs[i++] = (NSOpenGLPixelFormatAttribute)(this->MultiSamples);
attribs[i++] = NSOpenGLPFAMultisample;
}
if (this->DoubleBuffer != 0)
{
attribs[i++] = NSOpenGLPFADoubleBuffer;
......@@ -980,21 +971,11 @@ void vtkCocoaRenderWindow::CreateGLContext()
// Try falling back to the software renderer
hardware = 0;
}
else if (this->MultiSamples == 0)
else
{
// after trying with no multisamples, we are done
vtkWarningMacro(<< "No OpenGL context whatsoever could be created!");
break;
}
else if (this->MultiSamples < 4)
{
// next time try with no multisamples
this->MultiSamples = 0;
}
else
{
this->MultiSamples /= 2;
}
}
}
......@@ -1273,7 +1254,6 @@ void vtkCocoaRenderWindow::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "MultiSamples: " << this->MultiSamples << endl;
os << indent << "CocoaManager: " << this->GetCocoaManager() << endl;
os << indent << "RootWindow (NSWindow): " << this->GetRootWindow() << endl;
os << indent << "WindowId (NSView): " << this->GetWindowId() << endl;
......
......@@ -435,7 +435,6 @@ void vtkIOSRenderWindow::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "MultiSamples: " << this->MultiSamples << endl;
os << indent << "RootWindow (UIWindow): " << this->GetRootWindow() << endl;
os << indent << "WindowId (UIView): " << this->GetWindowId() << endl;
os << indent << "ParentId: " << this->GetParentId() << endl;
......
......@@ -212,6 +212,19 @@ public:
this->Attachment = attachment;
}
int GetSamples()
{
if (this->Texture)
{
return this->Texture->GetSamples();
}
if (this->Renderbuffer)
{
return this->Renderbuffer->GetSamples();
}
return 0;
}
void GetSize(int (&size)[2])
{
if (this->Texture)
......@@ -286,6 +299,7 @@ vtkOpenGLFramebufferObject::~vtkOpenGLFramebufferObject()
delete i->second;
}
this->ColorBuffers.clear();
this->Context = nullptr;
}
//-----------------------------------------------------------------------------
......@@ -333,22 +347,21 @@ unsigned int vtkOpenGLFramebufferObject::GetBothMode()
//----------------------------------------------------------------------------
void vtkOpenGLFramebufferObject::CreateFBO()
{
this->FBOIndex = 0;
GLuint temp;
glGenFramebuffers(1, &temp);
vtkOpenGLCheckErrorMacro("failed at glGenFramebuffers");
this->FBOIndex = temp;
if (!this->FBOIndex)
{
this->ResourceCallback->RegisterGraphicsResources(this->Context);
this->FBOIndex = 0;
GLuint temp;
glGenFramebuffers(1, &temp);
vtkOpenGLCheckErrorMacro("failed at glGenFramebuffers");
this->FBOIndex = temp;
}
}
//----------------------------------------------------------------------------
void vtkOpenGLFramebufferObject::DestroyFBO()
{
// because we don't hold a reference to the render
// context we don't have any control on when it is
// destroyed. In fact it may be destroyed before
// we are(eg smart pointers), in which case we should
// do nothing.
if (this->Context && (this->FBOIndex != 0))
if (this->FBOIndex != 0)
{
GLuint fbo = static_cast<GLuint>(this->FBOIndex);
glDeleteFramebuffers(1, &fbo);
......@@ -369,7 +382,6 @@ void vtkOpenGLFramebufferObject::ReleaseGraphicsResources(vtkWindow* win)
this->DestroyDepthBuffer(win);
this->DestroyColorBuffers(win);
this->DestroyFBO();
this->Context = nullptr;
this->Modified();
}
......@@ -384,8 +396,6 @@ void vtkOpenGLFramebufferObject::SetContext(vtkRenderWindow* rw)
return;
}
this->ResourceCallback->RegisterGraphicsResources(renWin);
// all done if assigned null
if (!renWin)
{
......@@ -399,8 +409,6 @@ void vtkOpenGLFramebufferObject::SetContext(vtkRenderWindow* rw)
}
// initialize
this->Context = renWin;
this->Context->MakeCurrent();
this->CreateFBO();
}
//----------------------------------------------------------------------------
......@@ -562,6 +570,7 @@ bool vtkOpenGLFramebufferObject::Start(int width, int height)
void vtkOpenGLFramebufferObject::ActivateBuffers()
{
GLint maxbuffers;
// todo move to cache
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxbuffers);
GLenum* buffers = new GLenum[maxbuffers];
......@@ -672,6 +681,11 @@ void vtkOpenGLFramebufferObject::SaveCurrentBindingsAndBuffers()
void vtkOpenGLFramebufferObject::SaveCurrentBindingsAndBuffers(unsigned int mode)
{
if (!this->Context)
{
vtkErrorMacro("Attempt to save bindings without a context");
return;
}
if (mode == GL_FRAMEBUFFER || mode == GL_DRAW_FRAMEBUFFER)
{
this->Context->GetState()->PushDrawFramebufferBinding();
......@@ -691,6 +705,11 @@ void vtkOpenGLFramebufferObject::RestorePreviousBindingsAndBuffers()
void vtkOpenGLFramebufferObject::RestorePreviousBindingsAndBuffers(unsigned int mode)
{
if (!this->Context)
{
vtkErrorMacro("Attempt to restore bindings without a context");
return;
}
if ((mode == GL_FRAMEBUFFER || mode == GL_DRAW_FRAMEBUFFER) && this->DrawBindingSaved)
{
this->Context->GetState()->PopDrawFramebufferBinding();
......@@ -713,6 +732,13 @@ void vtkOpenGLFramebufferObject::Bind()
void vtkOpenGLFramebufferObject::Bind(unsigned int mode)
{
if (!this->Context)
{
vtkErrorMacro("Attempt to bind framebuffer without a context");
return;
}
this->Context->MakeCurrent();
this->CreateFBO();
if (this->FBOIndex != 0)
{
// note this also changes the draw/read buffers as they are
......@@ -1438,6 +1464,12 @@ void vtkOpenGLFramebufferObject::Download(
pbo->UnBind();
}
int vtkOpenGLFramebufferObject::GetMultiSamples()
{
int abuff = this->ActiveBuffers[0];
return this->ColorBuffers[abuff]->GetSamples();
}
bool vtkOpenGLFramebufferObject::PopulateFramebuffer(int width, int height)
{
return this->PopulateFramebuffer(width, height, true, 1, VTK_UNSIGNED_CHAR, true, 24, 0);
......@@ -1489,7 +1521,7 @@ bool vtkOpenGLFramebufferObject::PopulateFramebuffer(int width, int height, bool
depth->AllocateDepth(this->LastSize[0], this->LastSize[1], vtkTextureObject::Fixed16);
break;
case 32:
depth->AllocateDepth(this->LastSize[0], this->LastSize[1], vtkTextureObject::Float32);
depth->AllocateDepth(this->LastSize[0], this->LastSize[1], vtkTextureObject::Fixed32);
break;
case 24:
default:
......
......@@ -164,7 +164,6 @@
#include "vtkFrameBufferObjectBase.h"
#include "vtkRenderingOpenGL2Module.h" // For export macro
#include "vtkWeakPointer.h" // needed for vtkWeakPointer.
#include <map> // for the maps
#include <vector> // for the lists of logical buffers.
......@@ -425,6 +424,8 @@ public:
*/
void Resize(int width, int height);
int GetMultiSamples();
protected:
/**
* Attach a specific buffer
......@@ -488,7 +489,7 @@ protected:
vtkOpenGLFramebufferObject();
~vtkOpenGLFramebufferObject() override;
vtkWeakPointer<vtkOpenGLRenderWindow> Context;
vtkOpenGLRenderWindow* Context;
unsigned int FBOIndex;
......
This diff is collapsed.
......@@ -258,15 +258,6 @@ public:
vtkGetObjectMacro(OffScreenFramebuffer, vtkOpenGLFramebufferObject);
//@}
//@{
/**
* Render to an offscreen destination such as a framebuffer.
* All four combinations of ShowWindow and UseOffScreenBuffers
* should work for most rendering backends.
*/
void SetUseOffScreenBuffers(bool) override;
//@}
/**
* Returns its texture unit manager object. A new one will be created if one
* hasn't already been set up.
......@@ -419,24 +410,23 @@ public:
int GetNoiseTextureUnit();
/**
* Update the system, if needed, due to stereo rendering. For some stereo
* methods, subclasses might need to switch some hardware settings here.
* Update the system, if needed, at end of render process
*/
void StereoUpdate() override;
void End() override;
/**
* Intermediate method performs operations required between the rendering
* of the left and right eye.
* Handle opengl specific code and calls superclass
*/
void StereoMidpoint() override;
void Render() override;
/**
* Handle opengl specific code and calls superclass
* Intermediate method performs operations required between the rendering
* of the left and right eye.
*/
void Render() override;
void StereoMidpoint() override;
// does the current read buffer require resolving for reading pixels
bool GetCurrentBufferNeedsResolving();
// does VTKs framebuffer require resolving for reading pixels
bool GetBufferNeedsResolving();
protected:
vtkOpenGLRenderWindow();
......@@ -520,6 +510,9 @@ protected:
double FirstRenderTime;
// keep track of in case we need to recreate the framebuffer
int LastMultiSamples;
private:
vtkOpenGLRenderWindow(const vtkOpenGLRenderWindow&) = delete;
void operator=(const vtkOpenGLRenderWindow&) = delete;
......
......@@ -28,6 +28,8 @@
#include <cmath>
#include "vtksys/SystemInformation.hxx"
// If you define NO_CACHE then all state->vtkgl* calls
// will get passed down to OpenGL regardless of the current
// state. This basically bypasses the caching mechanism
......@@ -44,8 +46,8 @@
// printed.
// 3) All methods check the cache state to see if anything is out of sync
//
// #undef VTK_REPORT_OPENGL_ERRORS
#ifdef VTK_REPORT_OPENGL_ERRORS
#include "vtksys/SystemInformation.hxx"
// this method checks all the cached state to make sure
// nothing is out of sync. It can be slow.
......@@ -548,6 +550,8 @@ void vtkOpenGLState::vtkglDrawBuffer(unsigned int val)
// todo get rid of the && and make this always an error if FO is set
vtkGenericWarningMacro(
"A vtkOpenGLFramebufferObject is currently bound but a hardware draw buffer was requested.");
std::string msg = vtksys::SystemInformation::GetProgramStack(0, 0);
vtkGenericWarningMacro("at stack loc\n" << msg);
}
#ifndef NO_CACHE
......@@ -585,7 +589,7 @@ void vtkOpenGLState::vtkglDrawBuffers(unsigned int count, unsigned int* vals)
{
// todo get rid of the && and make this always an error if FO is set
vtkGenericWarningMacro(
"A vtkOpenGLFramebufferObject is currently bound but a hardware draw bufer was requested.");
"A vtkOpenGLFramebufferObject is currently bound but hardware draw buffers were requested.");
}
#ifndef NO_CACHE
......@@ -681,7 +685,7 @@ void vtkOpenGLState::vtkglReadBuffer(unsigned int val)
val < GL_COLOR_ATTACHMENT0 && val != GL_NONE)
{
vtkGenericWarningMacro(
"A vtkOpenGLFramebufferObject is currently bound but a hardware draw bufer was requested.");
"A vtkOpenGLFramebufferObject is currently bound but a hardware read buffer was requested.");
}
#ifndef NO_CACHE
......@@ -1542,6 +1546,7 @@ void vtkOpenGLState::PopDrawFramebufferBinding()
else
{
vtkGenericWarningMacro("Attempt to pop framebuffer beyond beginning of the stack.");
abort();
}
}
......@@ -1557,6 +1562,7 @@ void vtkOpenGLState::PopReadFramebufferBinding()
else
{
vtkGenericWarningMacro("Attempt to pop framebuffer beyond beginning of the stack.");
abort();
}
}
......
......@@ -241,7 +241,7 @@ void vtkOrderIndependentTranslucentPass::Render(const vtkRenderState* s)
if (dbits == 32)
{
this->TranslucentZTexture->AllocateDepth(
this->ViewportWidth, this->ViewportHeight, vtkTextureObject::Float32);
this->ViewportWidth, this->ViewportHeight, vtkTextureObject::Fixed32);
}
else
{
......
......@@ -148,8 +148,13 @@ void vtkPanoramicProjectionPass::InitOpenGLResources(vtkOpenGLRenderWindow* renW
if (this->FrameBufferObject == nullptr)
{
this->FrameBufferObject = vtkOpenGLFramebufferObject::New();
}
if (!this->FrameBufferObject->GetFBOIndex())
{
this->FrameBufferObject->SetContext(renWin);
renWin->GetState()->PushFramebufferBindings();
this->FrameBufferObject->Bind();
this->FrameBufferObject->Resize(this->CubeResolution, this->CubeResolution);
this->FrameBufferObject->AddDepthAttachment();
renWin->GetState()->PopFramebufferBindings();
......
......@@ -21,6 +21,7 @@
#include "vtkNew.h"
#include "vtkOpenGLBufferObject.h"
#include "vtkOpenGLError.h"
#include "vtkOpenGLFramebufferObject.h"
#include "vtkOpenGLRenderUtilities.h"
#include "vtkOpenGLRenderWindow.h"
#include "vtkOpenGLResourceFreeCallback.h"
......@@ -1836,11 +1837,57 @@ void vtkTextureObject::CopyFromFrameBuffer(
{
assert("pre: is2D" && this->GetNumberOfDimensions() == 2);
// Todo: if the framebuffer is multisampled we need to resolve first
// as the CopyTexImage will not work.
this->Activate();
// make assumption on the need to resolve
// based on MultiSample setting
if (this->Context->GetMultiSamples())
{
vtkNew<vtkOpenGLFramebufferObject> resolvedFBO;
resolvedFBO->SetContext(this->Context);
this->Context->GetState()->PushFramebufferBindings();
resolvedFBO->PopulateFramebuffer(width, height,
/* useTextures = */ true,
/* numberOfColorAttachments = */ 1,
/* colorDataType = */ VTK_UNSIGNED_CHAR,
/* wantDepthAttachment = */ true,
/* depthBitplanes = */ 24,
/* multisamples = */ 0);
// PopulateFramebuffer changes active read/write buffer bindings,
// hence we restore the read buffer bindings to read from the original
// frame buffer.
this->Context->GetState()->PopReadFramebufferBinding();