Commit b75bc715 authored by Ken Martin's avatar Ken Martin

Update VTK to always use a framebuffer for rendering

Modify VTK so that the render process always uses a
framebuffer. The basic approach is that render() calls

- Start (pushes the current bindings + binds fb)
- DoStereoRender
  - StereoUpdate()
  - StereoMidpoint() (blits for crystal eyes)
  - StereoComplete()
- End (pops the bindings)
- CopyResultingFrame
  - stereo pixel processing
  - Frame() (blits the resulting frame)

The depth buffer will be 32 bit fixed unless a
stencil buffer is requested. Then it will be
24 depth + 8 stencil. If multisamples is requested
VTK will try to create a framebuffer with multisamples.

Only one color buffer is created. For stereo rendering
the StereoMidpoint must be used to read or blit the left
eye prior to starting rendering of the right eye.

If you want color or depth values from an external
codebase to be used in the rendering process you must
write them into the framebuffer prior to calling Render()
in VTK. See vtkExternalOpenGLRenderWindow for an example
of this.

Probably still some optimization that will happen in a
further topic once this settles as there are some old
methods that no longer really are needed.
parent 77896059
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;
......
......@@ -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)
......@@ -562,6 +575,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];
......@@ -1438,6 +1452,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 +1509,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:
......
......@@ -425,6 +425,8 @@ public:
*/
void Resize(int width, int height);
int GetMultiSamples();
protected:
/**
* Attach a specific buffer
......
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
{
......
......@@ -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();
vtkOpenGLState::ScopedglViewport vsaver(this->Context->GetState());
this->Context->GetState()->vtkglViewport(0, 0, width, height);
vtkOpenGLState::ScopedglScissor ssaver(this->Context->GetState());
this->Context->GetState()->vtkglScissor(0, 0, width, height);
// Now blit to resolve the MSAA and get an anti-aliased rendering in
// resolvedFBO.
// Note: extents are (x-min, x-max, y-min, y-max).
const int srcExtents[4] = { srcXmin, srcXmin + width, srcYmin, srcYmin + height };
const int destExtents[4] = { 0, width, 0, height };
vtkOpenGLFramebufferObject::Blit(
srcExtents, destExtents, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
// Now make the resolvedFBO the read buffer and read from it.
this->Context->GetState()->PushReadFramebufferBinding();
resolvedFBO->Bind(GL_READ_FRAMEBUFFER);
resolvedFBO->ActivateReadBuffer(0);
this->Activate();
glCopyTexImage2D(this->Target, 0, this->InternalFormat, 0, 0, width, height, 0);
// restore bindings and release the resolvedFBO.
this->Context->GetState()->PopFramebufferBindings();
}
else
{
this->Activate();
glCopyTexImage2D(this->Target, 0, this->InternalFormat, srcXmin, srcYmin, width, height, 0);
}
glCopyTexImage2D(this->Target, 0, this->InternalFormat, srcXmin, srcYmin, width, height, 0);
vtkOpenGLCheckErrorMacro("failed at glCopyTexImage2D " << this->InternalFormat);
}
......
......@@ -354,6 +354,7 @@ void vtkWin32OpenGLRenderWindow::Frame(void)
{
this->MakeCurrent();
this->Superclass::Frame();
if (!this->AbortRender && this->DoubleBuffer && this->SwapBuffers)
{
// If this check is not enforced, we crash in offscreen rendering
......@@ -550,8 +551,7 @@ void vtkWin32OpenGLRenderWindow::SetupPixelFormatPaletteAndContext(
return;
}
// First we try to use the newer wglChoosePixelFormatARB which enables
// features like multisamples.
// First we try to use the newer wglChoosePixelFormatARB
PIXELFORMATDESCRIPTOR pfd;
int pixelFormat = 0;
if (wglChoosePixelFormatARB)
......@@ -575,18 +575,6 @@ void vtkWin32OpenGLRenderWindow::SetupPixelFormatPaletteAndContext(
stereoAttributeIndex = n + 1;
n += 2;
}
unsigned int multiSampleAttributeIndex = 0;
unsigned int multiSampleBuffersIndex = 0;
if (this->MultiSamples > 1 && wglewIsSupported("WGL_ARB_multisample"))
{
attrib[n] = WGL_SAMPLE_BUFFERS_ARB;
attrib[n + 1] = 1;
attrib[n + 2] = WGL_SAMPLES_ARB;
attrib[n + 3] = this->MultiSamples;
multiSampleBuffersIndex = n + 1;
multiSampleAttributeIndex = n + 3;
n += 4;
}
if (this->UseSRGBColorSpace && WGLEW_EXT_framebuffer_sRGB)
{
attrib[n++] = WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT;
......@@ -601,32 +589,7 @@ void vtkWin32OpenGLRenderWindow::SetupPixelFormatPaletteAndContext(
unsigned int numFormats;
if (!wglChoosePixelFormatARB(hDC, attrib, 0, 1, &pixelFormat, &numFormats) || numFormats == 0)
{
// if we are trying for stereo and multisamples
// then drop stereo first if we cannot get a context
if (stereoAttributeIndex && multiSampleAttributeIndex)
{
attrib[stereoAttributeIndex] = FALSE;
wglChoosePixelFormatARB(hDC, attrib, 0, 1, &pixelFormat, &numFormats);
}
// Next try dropping multisamples if requested
if (multiSampleAttributeIndex && numFormats == 0)
{
while (numFormats == 0 && attrib[multiSampleAttributeIndex] > 0)
{
attrib[multiSampleAttributeIndex] /= 2;
if (attrib[multiSampleAttributeIndex] < 2)
{
// try disabling multisampling altogether
attrib[multiSampleAttributeIndex] = 0;
if (multiSampleBuffersIndex)
{
attrib[multiSampleBuffersIndex] = 0;
}
}
wglChoosePixelFormatARB(hDC, attrib, 0, 1, &pixelFormat, &numFormats);
}
}
// finally try dropping stereo when requested without multisamples
// try dropping stereo when requested
if (stereoAttributeIndex && numFormats == 0)
{
attrib[stereoAttributeIndex] = FALSE;
......
......@@ -95,7 +95,7 @@ vtkStandardNewMacro(vtkXOpenGLRenderWindow);
#define MAX_LIGHTS 8
GLXFBConfig vtkXOpenGLRenderWindowTryForFBConfig(Display* DisplayId, int drawable_type,
vtkTypeBool doublebuff, vtkTypeBool stereo, int multisamples, vtkTypeBool stencil, bool srgb)
vtkTypeBool doublebuff, vtkTypeBool stereo, vtkTypeBool stencil, bool srgb)
{
int index;
static int attributes[50];
......@@ -132,15 +132,6 @@ GLXFBConfig vtkXOpenGLRenderWindowTryForFBConfig(Display* DisplayId, int drawabl
attributes[index++] = GLX_STEREO;
attributes[index++] = True;
}
if (multisamples)
{
#ifdef GLX_SAMPLE_BUFFERS_SGIS
attributes[index++] = GLX_SAMPLE_BUFFERS_SGIS;
attributes[index++] = 1;
attributes[index++] = GLX_SAMPLES_SGIS;
attributes[index++] = multisamples;
#endif
}
if (srgb)
{
......@@ -155,7 +146,6 @@ GLXFBConfig vtkXOpenGLRenderWindowTryForFBConfig(Display* DisplayId, int drawabl
// << " drawable_type : " << drawable_type << endl
// << " doublebuff : " << doublebuff << endl
// << " stereo : " << stereo << endl
// << " multisamples : " << multisamples << endl
// << " alphaBitPlanes : " << alphaBitPlanes << endl
// << " stencil : " << stencil << endl;
int tmp;
...