Commit 837e899d authored by Ken Martin's avatar Ken Martin

Track framebuffer state in OpenGLState class

Keep track of framebuffer state in OpenGL
This includes both vtk framebuffers as well as
other use of framebuffers. Supports pushing and popping
the draw and read framebuffers. Also some bug fixes
and changes to account for the fact that buffer state
is actually stored with framebuffer objects.
parent 8ac3a222
......@@ -235,6 +235,7 @@ public:
else
{
this->FBO->bind();
this->RenderWindow->GetState()->ResetFramebufferBindings();
}
}
......@@ -325,7 +326,7 @@ public:
}
}
bool blit(unsigned int targetId, int targetAttachement, const QRect& targetRect, bool left)
bool blit(unsigned int targetId, int targetAttachment, const QRect& targetRect, bool left)
{
QVTKInternalsDebugMacro("blit");
if (!this->Context || !this->FBO)
......@@ -339,12 +340,14 @@ public:
}
f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetId);
f->glDrawBuffer(targetAttachement);
f->glDrawBuffer(targetAttachment);
f->glBindFramebuffer(GL_READ_FRAMEBUFFER, this->FBO->handle());
f->glReadBuffer(
left ? this->RenderWindow->GetFrontLeftBuffer() : this->RenderWindow->GetFrontRightBuffer());
this->RenderWindow->GetState()->ResetFramebufferBindings();
GLboolean scissorTest = f->glIsEnabled(GL_SCISSOR_TEST);
if (scissorTest == GL_TRUE)
{
......@@ -576,9 +579,10 @@ void QVTKRenderWindowAdapter::QVTKInternals::recreateFBO()
renWin->SetFrontRightBuffer(GL_COLOR_ATTACHMENT0 + attachmentIncrement);
renWin->SetBackRightBuffer(GL_COLOR_ATTACHMENT0 + attachmentIncrement);
}
renWin->OpenGLInitState();
this->FBO->bind();
renWin->SetDefaultFrameBufferId(this->FBO->handle());
renWin->OpenGLInitState();
renWin->GetState()->ResetFramebufferBindings();
}
//-----------------------------------------------------------------------------
......
......@@ -15,6 +15,7 @@
#include "vtkObjectFactory.h"
#include "vtkOpenGLRenderWindow.h"
#include "vtkOpenGLError.h"
#include "vtkOpenGLResourceFreeCallback.h"
#include "vtkOpenGLState.h"
......@@ -27,6 +28,7 @@
#include <QtWidgets/QWidget>
//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkQWidgetTexture);
......@@ -44,6 +46,9 @@ vtkQWidgetTexture::vtkQWidgetTexture()
[this] () {
if (this->Framebuffer)
{
this->Context->MakeCurrent();
auto state = this->Context->GetState();
state->PushFramebufferBindings();
this->Framebuffer->bind();
QOpenGLPaintDevice *device = new QOpenGLPaintDevice( this->Framebuffer->size() );
......@@ -59,7 +64,7 @@ vtkQWidgetTexture::vtkQWidgetTexture()
delete device;
// bring vtk state back in sync with Qt state
auto state = this->Context->GetState();
state->PopFramebufferBindings();
state->ResetEnumState(GL_BLEND);
state->ResetEnumState(GL_DEPTH_TEST);
state->ResetEnumState(GL_SCISSOR_TEST);
......@@ -67,9 +72,11 @@ vtkQWidgetTexture::vtkQWidgetTexture()
state->ResetEnumState(GL_MULTISAMPLE);
#endif
state->ResetGLScissorState();
state->ResetGLClearColorState();
state->ResetGLViewportState();
state->ResetGLDepthFuncState();
state->ResetGLBlendFuncState();
state->ResetFramebufferBindings();
// reset the depth test to LEQUAL as all vtk classes
// expect this to be the case when called
state->vtkglDepthFunc(GL_LEQUAL);
......
......@@ -151,7 +151,7 @@ vtkIdType vtkOpenGLContextBufferId::GetPickedItem(int x, int y)
if(savedDrawBuffer!=GL_BACK_LEFT)
{
glDrawBuffer(GL_BACK_LEFT);
ostate->vtkglDrawBuffer(GL_BACK_LEFT);
}
ostate->vtkglDisable(GL_DEPTH_TEST);
ostate->vtkglDisable(GL_STENCIL_TEST);
......@@ -163,7 +163,7 @@ vtkIdType vtkOpenGLContextBufferId::GetPickedItem(int x, int y)
GLint savedReadBuffer;
glGetIntegerv(GL_READ_BUFFER,&savedReadBuffer);
glReadBuffer(GL_BACK_LEFT);
ostate->vtkglReadBuffer(GL_BACK_LEFT);
// To workaround pixel ownership test,
// get value from current read buffer at pixel (x,y) instead of just
......@@ -177,11 +177,11 @@ vtkIdType vtkOpenGLContextBufferId::GetPickedItem(int x, int y)
if(savedReadBuffer!=GL_BACK_LEFT)
{
glReadBuffer(static_cast<GLenum>(savedReadBuffer));
ostate->vtkglReadBuffer(static_cast<GLenum>(savedReadBuffer));
}
if(savedDrawBuffer!=GL_BACK_LEFT)
{
glDrawBuffer(static_cast<GLenum>(savedDrawBuffer));
ostate->vtkglDrawBuffer(static_cast<GLenum>(savedDrawBuffer));
}
int value=(static_cast<int>(rgb[0])<<16)|(static_cast<int>(rgb[1])<<8)
......
......@@ -424,7 +424,7 @@ void vtkOpenGLContextDevice2D::BufferIdModeBegin(
this->ProjectionMatrix->SetMatrix(*matrix);
glDrawBuffer(GL_BACK_LEFT);
ostate->vtkglDrawBuffer(GL_BACK_LEFT);
ostate->vtkglClearColor(0.0,0.0,0.0,0.0); // id=0 means no hit, just background
ostate->vtkglClear(GL_COLOR_BUFFER_BIT);
ostate->vtkglDisable(GL_STENCIL_TEST);
......
......@@ -67,26 +67,26 @@ void vtkExternalOpenGLCamera::Render(vtkRenderer *ren)
{
if (ren->GetRenderWindow()->GetDoubleBuffer())
{
glDrawBuffer(static_cast<GLenum>(win->GetBackLeftBuffer()));
glReadBuffer(static_cast<GLenum>(win->GetBackLeftBuffer()));
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetBackLeftBuffer()));
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetBackLeftBuffer()));
}
else
{
glDrawBuffer(static_cast<GLenum>(win->GetFrontLeftBuffer()));
glReadBuffer(static_cast<GLenum>(win->GetFrontLeftBuffer()));
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetFrontLeftBuffer()));
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetFrontLeftBuffer()));
}
}
else
{
if (ren->GetRenderWindow()->GetDoubleBuffer())
{
glDrawBuffer(static_cast<GLenum>(win->GetBackRightBuffer()));
glReadBuffer(static_cast<GLenum>(win->GetBackRightBuffer()));
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetBackRightBuffer()));
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetBackRightBuffer()));
}
else
{
glDrawBuffer(static_cast<GLenum>(win->GetFrontRightBuffer()));
glReadBuffer(static_cast<GLenum>(win->GetFrontRightBuffer()));
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetFrontRightBuffer()));
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetFrontRightBuffer()));
}
}
break;
......@@ -104,21 +104,21 @@ void vtkExternalOpenGLCamera::Render(vtkRenderer *ren)
{
if (ren->GetRenderWindow()->GetDoubleBuffer())
{
glDrawBuffer(static_cast<GLenum>(win->GetBackBuffer()));
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetBackBuffer()));
// 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.
glReadBuffer(static_cast<GLenum>(win->GetBackBuffer()));
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetBackBuffer()));
}
else
{
glDrawBuffer(static_cast<GLenum>(win->GetFrontBuffer()));
ostate->vtkglDrawBuffer(static_cast<GLenum>(win->GetFrontBuffer()));
// 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.
glReadBuffer(static_cast<GLenum>(win->GetFrontBuffer()));
ostate->vtkglReadBuffer(static_cast<GLenum>(win->GetFrontBuffer()));
}
}
......
......@@ -301,7 +301,7 @@ void vtkCompositeSurfaceLICMapper::Render(
vtkNew<vtkOpenGLFramebufferObject> fbo;
fbo->SetContext(vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow()));
fbo->SaveCurrentBindingsAndBuffers();
ostate->PushFramebufferBindings();
// allocate rendering resources, initialize or update
// textures and shaders.
......@@ -326,5 +326,5 @@ void vtkCompositeSurfaceLICMapper::Render(
// ----------------------------------------------- depth test and copy to screen
this->LICInterface->CopyToScreen();
fbo->RestorePreviousBindingsAndBuffers();
ostate->PopFramebufferBindings();
}
......@@ -439,6 +439,7 @@ int vtkImageDataLIC2D::RequestData(
vtkTextureObject *magVectorTex = vectorTex;
if (this->Magnification > 1)
{
vtkOpenGLState *ostate = this->Context->GetState();
magVectorTex = vtkTextureObject::New();
magVectorTex->SetContext(this->Context);
magVectorTex->Create2D(magVectorSize[0], magVectorSize[1], 4, VTK_FLOAT, false);
......@@ -446,8 +447,8 @@ int vtkImageDataLIC2D::RequestData(
vtkOpenGLFramebufferObject *drawFbo = vtkOpenGLFramebufferObject::New();
drawFbo->SetContext(this->Context);
drawFbo->SaveCurrentBindings();
drawFbo->Bind(GL_FRAMEBUFFER);
ostate->PushFramebufferBindings();
drawFbo->Bind();
drawFbo->AddColorAttachment(0U, magVectorTex);
drawFbo->ActivateDrawBuffer(0U);
//drawFbo->AddColorAttachment(vtkgl::FRAMEBUFFER_EXT, 0U, vectorTex);
......@@ -494,7 +495,7 @@ int vtkImageDataLIC2D::RequestData(
vectorTex->Delete();
shaderHelper.ReleaseGraphicsResources(this->Context);
drawFbo->UnBind(GL_FRAMEBUFFER);
ostate->PopFramebufferBindings();
drawFbo->Delete();
}
......
......@@ -433,7 +433,7 @@ public:
// Description:
// Setup read/write from/to the active lic/seed buffer texture pair
// for LIC pass.
void AttachLICBuffers(vtkOpenGLFramebufferObject *vtkNotUsed(fbo))
void AttachLICBuffers(vtkOpenGLFramebufferObject *fbo)
{
// activate read textures
vtkTextureObject **readTex = this->Textures[this->ReadIndex];
......@@ -459,17 +459,13 @@ public:
0);
vtkOpenGLStaticCheckErrorMacro("failed at glFramebuffereadTexture2D");
GLenum atts[2] = {
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1
};
glDrawBuffers(2, atts);
fbo->ActivateDrawBuffers(2);
vtkOpenGLStaticCheckErrorMacro("failed at glDrawBuffers");
}
// Description:
// Remove input/output buffers used for computing the LIC.
void DettachLICBuffers(vtkOpenGLFramebufferObject *vtkNotUsed(fbo))
void DettachLICBuffers(vtkOpenGLFramebufferObject *fbo)
{
vtkOpenGLStaticCheckErrorMacro("failed at glDrawBuffers");
glFramebufferTexture2D(
......@@ -487,8 +483,7 @@ public:
0U,
0);
GLenum atts[1] = {GL_NONE};
glDrawBuffers(1, atts);
fbo->DeactivateDrawBuffers();
vtkOpenGLStaticCheckErrorMacro("failed at glDrawBuffers");
vtkTextureObject **readTex = this->Textures[this->ReadIndex];
......@@ -498,7 +493,7 @@ public:
// Description:
// Attach read/write buffers for transform pass.
void AttachImageVectorBuffer(vtkOpenGLFramebufferObject *vtkNotUsed(fbo))
void AttachImageVectorBuffer(vtkOpenGLFramebufferObject *fbo)
{
this->VectorTexture->Activate();
......@@ -510,14 +505,13 @@ public:
0);
vtkOpenGLStaticCheckErrorMacro("failed at glFramebufferTexture2D");
GLenum atts[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, atts);
fbo->ActivateDrawBuffers(1);
vtkOpenGLStaticCheckErrorMacro("failed at glDrawBuffers");
}
// Description:
// Attach read/write buffers for transform pass.
void DettachImageVectorBuffer(vtkOpenGLFramebufferObject *vtkNotUsed(fbo))
void DettachImageVectorBuffer(vtkOpenGLFramebufferObject *fbo)
{
this->VectorTexture->Deactivate();
......@@ -528,14 +522,13 @@ public:
0U,
0);
GLenum atts[1] = {GL_NONE};
glDrawBuffers(1, atts);
fbo->DeactivateDrawBuffers();
vtkOpenGLStaticCheckErrorMacro("failed at glDrawBuffers");
}
// Description:
// Attach read/write buffers for EE pass.
void AttachEEBuffer(vtkOpenGLFramebufferObject *vtkNotUsed(fbo))
void AttachEEBuffer(vtkOpenGLFramebufferObject *fbo)
{
vtkTextureObject **readTex = this->Textures[this->ReadIndex];
readTex[0]->Activate();
......@@ -548,8 +541,7 @@ public:
0);
vtkOpenGLStaticCheckErrorMacro("failed at glFramebufferTexture2D");
GLenum atts[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, atts);
fbo->ActivateDrawBuffers(1);
vtkOpenGLStaticCheckErrorMacro("failed at glDrawBuffers");
DEBUG3CheckFrameBufferStatusMacro(GL_DRAW_FRAMEBUFFER);
......@@ -557,7 +549,7 @@ public:
// Description:
// Attach read/write buffers for EE pass.
void DettachEEBuffer(vtkOpenGLFramebufferObject *vtkNotUsed(fbo))
void DettachEEBuffer(vtkOpenGLFramebufferObject *fbo)
{
vtkTextureObject **readTex = this->Textures[this->ReadIndex];
readTex[0]->Deactivate();
......@@ -569,15 +561,14 @@ public:
0U,
0);
GLenum atts[1] = {GL_NONE};
glDrawBuffers(1, atts);
fbo->DeactivateDrawBuffers();
vtkOpenGLStaticCheckErrorMacro("failed at glDrawBuffers");
}
// Description:
// Deactivates and removes all read/write buffers that were in
// use during the run, restoring a pristine FBO/texture unit state.
void DettachBuffers(vtkOpenGLFramebufferObject *vtkNotUsed(fbo))
void DettachBuffers(vtkOpenGLFramebufferObject *fbo)
{
glFramebufferTexture2D(
GL_DRAW_FRAMEBUFFER,
......@@ -595,8 +586,7 @@ public:
0);
vtkOpenGLStaticCheckErrorMacro("failed at glFramebufferTexture2D");
GLenum none = GL_NONE;
glDrawBuffers(1, &none);
fbo->DeactivateDrawBuffers();
vtkOpenGLStaticCheckErrorMacro("failed at glDrawBuffers");
// deactivate all textures?
......@@ -1505,8 +1495,8 @@ vtkTextureObject *vtkLineIntegralConvolution2D::Execute(
noiseBoundsPt1[1] = ((float)noiseTexSize[1]+1.0f)/((float)inputTexSize[1]);
// bind our fbo
this->FBO->SaveCurrentBindings();
this->FBO->Bind(GL_FRAMEBUFFER);
ostate->PushFramebufferBindings();
this->FBO->Bind();
this->FBO->InitializeViewport(computeTexSize[0], computeTexSize[1]);
// initialize the buffer manager. Textures are assigned
......@@ -2080,7 +2070,7 @@ vtkTextureObject *vtkLineIntegralConvolution2D::Execute(
}
bufs.DettachBuffers(this->FBO);
this->FBO->UnBind(GL_FRAMEBUFFER);
ostate->PopFramebufferBindings();
vtkTextureObject *outputTex = bufs.GetLastLICBuffer();
outputTex->Register(nullptr);
......
......@@ -28,6 +28,7 @@
#include "vtkTextureObject.h"
#include "vtkObjectFactory.h"
#include "vtkOpenGLRenderWindow.h"
#include "vtkOpenGLState.h"
#include "vtkPointData.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkOpenGLError.h"
......@@ -509,6 +510,8 @@ int vtkStructuredGridLIC2D::RequestData(
vtkDebugMacro( << "Vector field in image space (target) textureId = "
<< vector2->GetHandle() << endl );
vtkOpenGLState *ostate = renWin->GetState();
ostate->PushFramebufferBindings();
vtkOpenGLFramebufferObject *fbo = vtkOpenGLFramebufferObject::New();
fbo->SetContext(renWin);
fbo->Bind();
......@@ -522,6 +525,7 @@ int vtkStructuredGridLIC2D::RequestData(
if ( !fbo->Start( magWidth, magHeight ) )
{
ostate->PopFramebufferBindings();
fbo->Delete();
vector2->Delete();
pointBus->Delete();
......@@ -599,6 +603,7 @@ int vtkStructuredGridLIC2D::RequestData(
delete this->LICProgram;
this->LICProgram = nullptr;
ostate->PopFramebufferBindings();
fbo->Delete();
vector2->Delete();
internal->Delete();
......@@ -646,6 +651,7 @@ int vtkStructuredGridLIC2D::RequestData(
delete this->LICProgram;
this->LICProgram = nullptr;
ostate->PopFramebufferBindings();
fbo->Delete();
vector2->Delete();
internal->Delete();
......@@ -752,6 +758,8 @@ int vtkStructuredGridLIC2D::RequestData(
++tz;
}
ostate->PopFramebufferBindings();
internal->Delete();
noiseBus->Delete();
vectorFieldBus->Delete();
......
......@@ -184,17 +184,12 @@ void vtkSurfaceLICInterface::PrepareForGeometry()
vtkOpenGLState *ostate = this->Internals->Context->GetState();
// save the active fbo and its draw buffer
this->PrevDrawBuf = 0;
glGetIntegerv(GL_DRAW_BUFFER, &this->PrevDrawBuf);
this->PrevFbo = 0;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &this->PrevFbo);
ostate->PushFramebufferBindings();
// ------------------------------------------- render geometry, project vectors onto screen, etc
// setup our fbo
vtkOpenGLFramebufferObject *fbo = this->Internals->FBO;
fbo->SaveCurrentBindings();
fbo->Bind(GL_FRAMEBUFFER);
fbo->Bind();
fbo->AddDepthAttachment(this->Internals->DepthImage);
fbo->AddColorAttachment(0U, this->Internals->GeometryImage);
fbo->AddColorAttachment(1U, this->Internals->VectorImage);
......@@ -220,7 +215,6 @@ void vtkSurfaceLICInterface::CompletedGeometry()
fbo->RemoveColorAttachment(1U);
fbo->RemoveColorAttachment(2U);
fbo->DeactivateDrawBuffers();
fbo->UnBind(GL_FRAMEBUFFER);
#if vtkSurfaceLICInterfaceDEBUG >= 2
vtkPainterCommunicator *comm = this->GetCommunicator();
......@@ -505,12 +499,12 @@ void vtkSurfaceLICInterface::CombineColorsAndLIC()
this->Internals->Viewsize[1]);
vtkOpenGLFramebufferObject *fbo = this->Internals->FBO;
fbo->SaveCurrentBindings();
fbo->Bind(GL_FRAMEBUFFER);
ostate->PushFramebufferBindings();
fbo->Bind();
fbo->InitializeViewport(this->Internals->Viewsize[0], this->Internals->Viewsize[1]);
fbo->AddColorAttachment(0U, this->Internals->RGBColorImage);
fbo->AddColorAttachment(1U, this->Internals->HSLColorImage);
fbo->ActivateDrawBuffers(2U);
fbo->AddColorAttachment(0, this->Internals->RGBColorImage);
fbo->AddColorAttachment(1, this->Internals->HSLColorImage);
fbo->ActivateDrawBuffers(2);
vtkCheckFrameBufferStatusMacro(GL_FRAMEBUFFER);
// clear the parts of the screen which we will modify
......@@ -656,7 +650,7 @@ void vtkSurfaceLICInterface::CombineColorsAndLIC()
fbo->DeactivateDrawBuffers();
}
fbo->UnBind(GL_FRAMEBUFFER);
ostate->PopFramebufferBindings();
#if vtkSurfaceLICInterfaceDEBUG >= 2
vtkTextureIO::Write(
......@@ -675,9 +669,8 @@ void vtkSurfaceLICInterface::CopyToScreen()
this->Internals->Viewsize[0],
this->Internals->Viewsize[1]);
glBindFramebuffer(GL_FRAMEBUFFER, this->PrevFbo);
glDrawBuffer(this->PrevDrawBuf);
ostate->PopFramebufferBindings();
ostate->vtkglDisable(GL_BLEND);
ostate->vtkglDisable(GL_SCISSOR_TEST);
......
......@@ -587,10 +587,6 @@ protected:
vtkSurfaceLICHelper* Internals;
// save the active fbo and its draw buffer
int PrevDrawBuf;
int PrevFbo;
private:
vtkSurfaceLICInterface(const vtkSurfaceLICInterface&) = delete;
void operator=(const vtkSurfaceLICInterface&) = delete;
......
......@@ -1117,7 +1117,6 @@ void vtkDualDepthPeelingPass::Prepare()
this->VolumetricRenderCount = 0;
// Save the current FBO bindings to restore them later.
this->Framebuffer->SaveCurrentBindingsAndBuffers(GL_DRAW_FRAMEBUFFER);
this->Framebuffer->Bind(GL_DRAW_FRAMEBUFFER);
// The source front buffer must be initialized, since it simply uses additive
......
......@@ -20,6 +20,7 @@
#include "vtkOpenGLError.h"
#include "vtkOpenGLRenderWindow.h"
#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLState.h"
#include "vtkRendererCollection.h"
vtkStandardNewMacro(vtkGenericOpenGLRenderWindow);
......@@ -111,6 +112,7 @@ void vtkGenericOpenGLRenderWindow::Finalize()
void vtkGenericOpenGLRenderWindow::Frame()
{
this->InvokeEvent(vtkCommand::WindowFrameEvent, nullptr);
this->GetState()->ResetFramebufferBindings();
}
void vtkGenericOpenGLRenderWindow::MakeCurrent()
......@@ -278,9 +280,40 @@ int vtkGenericOpenGLRenderWindow::ReadPixels(
{
if (this->ReadyForRendering)
{
this->GetState()->ResetFramebufferBindings();
return this->Superclass::ReadPixels(rect, front, glFormat, glType, data, right);
}
vtkWarningMacro("`ReadPixels` called before window is ready for rendering; ignoring.");
return VTK_ERROR;
}
int vtkGenericOpenGLRenderWindow::SetRGBACharPixelData(int x1, int y1, int x2,
int y2, unsigned char *data,
int front, int blend, int right)
{
if (this->ReadyForRendering)
{
this->GetState()->ResetFramebufferBindings();
return this->Superclass::SetRGBACharPixelData(
x1, y1, x2, y2, data, front, blend, right);
}
vtkWarningMacro("`SetRGBACharPixelData` called before window is ready for rendering; ignoring.");
return VTK_ERROR;
}
int vtkGenericOpenGLRenderWindow::SetRGBACharPixelData(int x1, int y1, int x2,
int y2, vtkUnsignedCharArray *data,
int front, int blend, int right)
{
if (this->ReadyForRendering)
{
this->GetState()->ResetFramebufferBindings();
return this->Superclass::SetRGBACharPixelData(
x1, y1, x2, y2, data, front, blend, right);
}
vtkWarningMacro("`SetRGBACharPixelData` called before window is ready for rendering; ignoring.");
return VTK_ERROR;
}
......@@ -181,6 +181,13 @@ protected:
int ReadPixels(
const vtkRecti& rect, int front, int glFormat, int glType, void* data, int right) override;
int SetRGBACharPixelData(int x1, int y1, int x2,
int y2, unsigned char *data,
int front, int blend, int right) override;
int SetRGBACharPixelData(int x,int y,int x2,int y2,
vtkUnsignedCharArray *data, int front,
int blend=0,int right=0) override;
int DirectStatus;
int SupportsOpenGLStatus;
bool CurrentStatus;
......
......@@ -218,40 +218,10 @@ public:
/**
* Store/Restore the current framebuffer bindings and buffers.
*/
void SaveCurrentBindings();
void SaveCurrentBindings(unsigned int mode);
void SaveCurrentBindingsAndBuffers() {
this->SaveCurrentBuffers();
this->SaveCurrentBindings();
}
void SaveCurrentBindingsAndBuffers(unsigned int mode) {
this->SaveCurrentBuffers(mode);
this->SaveCurrentBindings(mode);
}
void RestorePreviousBindings();
void RestorePreviousBindings(unsigned int mode);
void RestorePreviousBindingsAndBuffers() {
this->RestorePreviousBindings();
this->RestorePreviousBuffers();
}
void RestorePreviousBindingsAndBuffers(unsigned int mode) {
this->RestorePreviousBindings(mode);
this->RestorePreviousBuffers(mode);
}
//@}
//@{
/**
* Store the current draw and read buffers. When restored
* only the buffers matching mode are modified.
* GetDrawMode() -> glDrawBuffer
* GetReadMode() -> glReadBuffer
* GetBothMode() -> both
*/
void SaveCurrentBuffers();
void SaveCurrentBuffers(unsigned int mode);
void RestorePreviousBuffers();
void RestorePreviousBuffers(unsigned int mode);
void SaveCurrentBindingsAndBuffers();
void SaveCurrentBindingsAndBuffers(unsigned int mode);
void RestorePreviousBindingsAndBuffers();
void RestorePreviousBindingsAndBuffers(unsigned int mode);
//@}
//@{
......@@ -287,6 +257,9 @@ public:
void DeactivateReadBuffer();
//@}
vtkGetMacro(ActiveReadBuffer, unsigned int);
unsigned int GetActiveDrawBuffer(unsigned int id);
/**
* Renders a quad at the given location with pixel coordinates. This method
* is provided as a convenience, since we often render quads in a FBO.
......@@ -561,17 +534,14 @@ protected:
unsigned int FBOIndex;
unsigned int PreviousDrawFBO;
unsigned int PreviousReadFBO;
bool DrawBindingSaved;
bool ReadBindingSaved;
unsigned int PreviousDrawBuffer;
unsigned int PreviousReadBuffer;
bool DrawBufferSaved;
bool ReadBufferSaved;
int LastSize[2];
std::vector<unsigned int> ActiveBuffers;
unsigned int ActiveReadBuffer;
vtkFOInfo *DepthBuffer;
std::map<unsigned int, vtkFOInfo *> ColorBuffers;
......
......@@ -103,13 +103,16 @@ void vtkOpenGLHardwareSelector::PostCapturePass(int pass)
//----------------------------------------------------------------------------
void vtkOpenGLHardwareSelector::BeginSelection()
{
// render normally to set the zbuffer
if (this->FieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS)
{
vtkOpenGLRenderWindow *rwin =
static_cast<vtkOpenGLRenderWindow *>(this->Renderer->GetRenderWindow());
vtkOpenGLState *ostate = rwin->GetState();
ostate->ResetFramebufferBindings();
// render normally to set the zbuffer
if (this->FieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS)
{
// Disable multisample, and blending before writing the zbuffer
#ifdef GL_MULTISAMPLE
vtkOpenGLState::ScopedglEnableDisable msaver(ostate, GL_MULTISAMPLE);
......
......@@ -81,44 +81,64 @@ public:
FrameBufferHelper(EType type, vtkOpenGLRenderWindow* ren,
int front, int right)
: Type(type)
, LastFrameBuffer(0)
, LastColorBuffer(0)
{
// If offscreen buffers are in use, then use them, otherwise look at if the
// default frame-buffer id is provided (which happens when using external
// OpenGL context).
const unsigned int fb = (ren->GetUseOffScreenBuffers() && ren->GetOffScreenFramebuffer())
? ren->GetOffScreenFramebuffer()->GetFBOIndex() : (ren->GetDefaultFrameBufferId()
? ren->GetDefaultFrameBufferId() : 0);
const GLint buf = front ?
(right ? ren->GetFrontRightBuffer() : ren->GetFrontLeftBuffer()) :
(right ? ren->GetBackRightBuffer() : ren->GetBackLeftBuffer());
switch (type)
this->State = ren->GetState();
// If offscreen buffers are in use, then use them, otherwise look at if the
// default frame-buffer id is provided (which happens when using external
// OpenGL context).
if (ren->GetUseOffScreenBuffers() && ren->GetOffScreenFramebuffer())
{
case READ:
switch (type)
{
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, reinterpret_cast<GLint*>(&this->LastFrameBuffer));
#ifdef GL_READ_BUFFER