Commit f133d013 authored by Alvaro Sanchez's avatar Alvaro Sanchez

Fixed broken tests and updated documentation.

Moved member variables of vtkValuePass and ValuePassHelper into internals. Added
a secondary baseline image for the case when the required extensions are not
supported and vtkValuePass falls back to INVERTIBLE_LUT.
parent 582ada60
Pipeline #26784 passed with stage
......@@ -150,7 +150,7 @@ void RenderComponentImages(std::vector<vtkSmartPointer<vtkImageData> >& colorImO
/// Get the resulting values
vtkFloatArray* result = valuePass->GetFloatImageDataArray(renderer);
std::vector<int> ext = valuePass->GetFloatImageExtents();
int* ext = valuePass->GetFloatImageExtents();
// Map the resulting float image to a color table
vtkUnsignedCharArray* colored = lut->MapScalars(result, VTK_COLOR_MODE_DEFAULT,
......@@ -158,9 +158,10 @@ void RenderComponentImages(std::vector<vtkSmartPointer<vtkImageData> >& colorImO
// Create an image dataset to render in a quad.
vtkSmartPointer<vtkImageData> colorIm = vtkSmartPointer<vtkImageData>::New();
colorIm->SetExtent(&(ext.front()));
colorIm->SetExtent(ext);
colorIm->GetPointData()->SetScalars(colored);
colorImOut.push_back(colorIm);
colored->Delete();
}
};
......@@ -241,7 +242,9 @@ int TestValuePassFloatingPoint(int argc, char *argv[])
glRenderer->SetPass(cameraPass);
window->Render();
if (RenderingMode == vtkValuePass::FLOATING_POINT)
// Check whether the RenderingMode change (this could happen due to a lack of
// extension/context support
if (valuePass->GetRenderingMode() == vtkValuePass::FLOATING_POINT)
{
// Render point data images
std::vector<vtkSmartPointer<vtkImageData> > colorImagesPoint;
......
......@@ -132,6 +132,7 @@ set_source_files_properties(
vtkOpenGLGL2PSHelper
vtkOpenGLGlyph3DHelper
vtkOpenGLHelper
vtkValuePassHelper
PROPERTIES WRAP_EXCLUDE_PYTHON 1)
set_source_files_properties(
......
......@@ -1576,7 +1576,7 @@ bool vtkOpenGLPolyDataMapper::GetNeedToRebuildShaders(
cellBO.ShaderSourceTime < this->SelectionStateChanged ||
cellBO.ShaderSourceTime < renderPassMTime ||
cellBO.ShaderSourceTime < this->LightComplexityChanged[&cellBO] ||
this->ValuePassHelper->RequiresShaderRebuild(actor))
this->ValuePassHelper->RequiresShaderRebuild())
{
return true;
}
......
......@@ -58,12 +58,25 @@ public:
bool ScalarRangeSet;
bool ReloadData;
// Description:
// Array holder for FLOATING_POINT mode. The result pixels are downloaded
// into this array.
vtkSmartPointer<vtkFloatArray> Values;
// Description:
// FLOATING_POINT mode resources. FBO, attachments and other control variables.
vtkFrameBufferObject2* ValueFrameBO;
vtkRenderbuffer* ValueRenderBO;
vtkRenderbuffer* DepthRenderBO;
bool ValuePassResourcesAllocated;
int FloatImageExt[6];
vtkInternals()
: Values(NULL)
, ValueFrameBO(NULL)
, ValueRenderBO(NULL)
, DepthRenderBO(NULL)
, ValuePassResourcesAllocated(false)
{
this->Values = vtkSmartPointer<vtkFloatArray>::New();
this->Values->SetNumberOfComponents(1); /* GL_RED */
......@@ -77,16 +90,31 @@ public:
this->ScalarRange[1] = -1.0;
this->ScalarRangeSet = false;
this->ReloadData = true;
this->FloatImageExt[0] = 0; this->FloatImageExt[1] = 0;
this->FloatImageExt[2] = 0; this->FloatImageExt[3] = 0;
this->FloatImageExt[4] = 0; this->FloatImageExt[5] = 0;
}
~vtkInternals()
{
if (this->ValueFrameBO)
{
this->ValueFrameBO->Delete();
}
if (this->ValueRenderBO)
{
this->ValueRenderBO->Delete();
}
if (this->DepthRenderBO)
{
this->DepthRenderBO->Delete();
}
}
};
// ----------------------------------------------------------------------------
vtkValuePass::vtkValuePass()
: ValueFrameBO(NULL)
, ValueRenderBO(NULL)
, DepthRenderBO(NULL)
, ValuePassResourcesAllocated(false)
, RenderingMode(INVERTIBLE_LUT)
: RenderingMode(INVERTIBLE_LUT)
{
this->Internals = new vtkInternals();
}
......@@ -271,8 +299,8 @@ void vtkValuePass::BeginPass(vtkRenderer* ren)
if (this->InitializeFloatingPointMode(ren))
{
this->ValueFrameBO->SaveCurrentBindings();
this->ValueFrameBO->Bind(GL_DRAW_FRAMEBUFFER);
this->Internals->ValueFrameBO->SaveCurrentBindings();
this->Internals->ValueFrameBO->Bind(GL_DRAW_FRAMEBUFFER);
}
break;
......@@ -296,7 +324,7 @@ void vtkValuePass::EndPass()
{
case vtkValuePass::FLOATING_POINT:
// Unbind the float FBO and glReadPixels to host side.
this->ValueFrameBO->UnBind(GL_DRAW_FRAMEBUFFER);
this->Internals->ValueFrameBO->UnBind(GL_DRAW_FRAMEBUFFER);
break;
case vtkValuePass::INVERTIBLE_LUT:
......@@ -309,13 +337,13 @@ void vtkValuePass::EndPass()
//------------------------------------------------------------------------------
bool vtkValuePass::HasWindowSizeChanged(vtkRenderer* ren)
{
if (!this->ValueFrameBO)
if (!this->Internals->ValueFrameBO)
{
return true;
}
int* size = ren->GetSize();
int* fboSize = this->ValueFrameBO->GetLastSize(false);
int* fboSize = this->Internals->ValueFrameBO->GetLastSize(false);
return (fboSize[0] != size[0] || fboSize[1] != size[1]);
}
......@@ -323,7 +351,7 @@ bool vtkValuePass::HasWindowSizeChanged(vtkRenderer* ren)
//------------------------------------------------------------------------------
bool vtkValuePass::InitializeFloatingPointMode(vtkRenderer* ren)
{
if (this->ValuePassResourcesAllocated)
if (this->Internals->ValuePassResourcesAllocated)
{
return true;
}
......@@ -338,38 +366,38 @@ bool vtkValuePass::InitializeFloatingPointMode(vtkRenderer* ren)
int* size = ren->GetSize();
// Allocate FBO's Color attachment target
this->ValueRenderBO = vtkRenderbuffer::New();
this->ValueRenderBO->SetContext(renWin);
this->Internals->ValueRenderBO = vtkRenderbuffer::New();
this->Internals->ValueRenderBO->SetContext(renWin);
// CreateColorAttachment formats the attachment RGBA32F by
// default, this is what vtkValuePass expects.
this->ValueRenderBO->CreateColorAttachment(size[0], size[1]);
this->Internals->ValueRenderBO->CreateColorAttachment(size[0], size[1]);
// Allocate FBO's depth attachment target
this->DepthRenderBO = vtkRenderbuffer::New();
this->DepthRenderBO->SetContext(renWin);
this->DepthRenderBO->CreateDepthAttachment(size[0], size[1]);
this->Internals->DepthRenderBO = vtkRenderbuffer::New();
this->Internals->DepthRenderBO->SetContext(renWin);
this->Internals->DepthRenderBO->CreateDepthAttachment(size[0], size[1]);
// Initialize the FBO into which the float value pass is rendered.
this->ValueFrameBO = vtkFrameBufferObject2::New();
this->ValueFrameBO->SetContext(renWin);
this->ValueFrameBO->SaveCurrentBindings();
this->ValueFrameBO->Bind(GL_FRAMEBUFFER);
this->ValueFrameBO->InitializeViewport(size[0], size[1]);
this->ValueFrameBO->GetLastSize(true); /*force a cached size update*/
this->Internals->ValueFrameBO = vtkFrameBufferObject2::New();
this->Internals->ValueFrameBO->SetContext(renWin);
this->Internals->ValueFrameBO->SaveCurrentBindings();
this->Internals->ValueFrameBO->Bind(GL_FRAMEBUFFER);
this->Internals->ValueFrameBO->InitializeViewport(size[0], size[1]);
this->Internals->ValueFrameBO->GetLastSize(true); /*force a cached size update*/
/* GL_COLOR_ATTACHMENT0 */
this->ValueFrameBO->AddColorAttachment(GL_FRAMEBUFFER, 0, this->ValueRenderBO);
this->ValueFrameBO->AddDepthAttachment(GL_FRAMEBUFFER, this->DepthRenderBO);
this->Internals->ValueFrameBO->AddColorAttachment(GL_FRAMEBUFFER, 0, this->Internals->ValueRenderBO);
this->Internals->ValueFrameBO->AddDepthAttachment(GL_FRAMEBUFFER, this->Internals->DepthRenderBO);
// Verify FBO
if(!this->ValueFrameBO->CheckFrameBufferStatus(GL_FRAMEBUFFER))
if(!this->Internals->ValueFrameBO->CheckFrameBufferStatus(GL_FRAMEBUFFER))
{
vtkErrorMacro("Failed to attach FBO.");
this->ReleaseFloatingPointMode(ren);
return false;
}
this->ValueFrameBO->UnBind(GL_FRAMEBUFFER);
this->ValuePassResourcesAllocated = true;
this->Internals->ValueFrameBO->UnBind(GL_FRAMEBUFFER);
this->Internals->ValuePassResourcesAllocated = true;
return true;
}
......@@ -377,7 +405,7 @@ bool vtkValuePass::InitializeFloatingPointMode(vtkRenderer* ren)
//-----------------------------------------------------------------------------
void vtkValuePass::ReleaseFloatingPointMode(vtkRenderer* ren)
{
if (!this->ValuePassResourcesAllocated)
if (!this->Internals->ValuePassResourcesAllocated)
{
return;
}
......@@ -386,16 +414,16 @@ void vtkValuePass::ReleaseFloatingPointMode(vtkRenderer* ren)
renWin->MakeCurrent();
// Cleanup FBO (grahpics resources cleaned internally)
this->ValueFrameBO->Delete();
this->ValueFrameBO = NULL;
this->Internals->ValueFrameBO->Delete();
this->Internals->ValueFrameBO = NULL;
this->ValueRenderBO->Delete();
this->ValueRenderBO = NULL;
this->Internals->ValueRenderBO->Delete();
this->Internals->ValueRenderBO = NULL;
this->DepthRenderBO->Delete();
this->DepthRenderBO = NULL;
this->Internals->DepthRenderBO->Delete();
this->Internals->DepthRenderBO = NULL;
this->ValuePassResourcesAllocated = false;
this->Internals->ValuePassResourcesAllocated = false;
}
//-----------------------------------------------------------------------------
......@@ -425,7 +453,7 @@ bool vtkValuePass::IsFloatFBOSupported(vtkRenderWindow *renWin)
<< " supported.");
}
return contextSupport || extSupport;
return contextSupport && extSupport;
#else
return true;
#endif
......@@ -438,7 +466,7 @@ vtkFloatArray* vtkValuePass::GetFloatImageDataArray(vtkRenderer* ren)
renWin->MakeCurrent();
//Allocate output array.
int* size = this->ValueFrameBO->GetLastSize(false);
int* size = this->Internals->ValueFrameBO->GetLastSize(false);
this->Internals->Values->SetNumberOfTuples(size[0] * size[1]);
// RGB channels are equivalent in the FBO (they all contain the rendered
......@@ -454,8 +482,8 @@ void vtkValuePass::GetFloatImageData(int const format, int const width,
int const height, void* data)
{
// Prepare and bind value texture and FBO.
this->ValueFrameBO->SaveCurrentBindings();
this->ValueFrameBO->Bind(GL_READ_FRAMEBUFFER);
this->Internals->ValueFrameBO->SaveCurrentBindings();
this->Internals->ValueFrameBO->Bind(GL_READ_FRAMEBUFFER);
GLint originalReadBuff;
glGetIntegerv(GL_READ_BUFFER, &originalReadBuff);
......@@ -469,21 +497,19 @@ void vtkValuePass::GetFloatImageData(int const format, int const width,
data);
glReadBuffer(originalReadBuff);
this->ValueFrameBO->UnBind(GL_READ_FRAMEBUFFER);
this->Internals->ValueFrameBO->UnBind(GL_READ_FRAMEBUFFER);
vtkOpenGLCheckErrorMacro("Failed to read pixels from OpenGL buffer!");
}
//-------------------------------------------------------------------------------
std::vector<int> vtkValuePass::GetFloatImageExtents()
int* vtkValuePass::GetFloatImageExtents()
{
int* size = this->ValueFrameBO->GetLastSize(false);
int* size = this->Internals->ValueFrameBO->GetLastSize(false);
std::vector<int> ext;
ext.reserve(6);
ext.push_back(0); ext.push_back(size[0] - 1);
ext.push_back(0); ext.push_back(size[1] - 1);
ext.push_back(0); ext.push_back(0);
this->Internals->FloatImageExt[0] = 0; this->Internals->FloatImageExt[1] = size[0] - 1;
this->Internals->FloatImageExt[2] = 0; this->Internals->FloatImageExt[3] = size[1] - 1;
this->Internals->FloatImageExt[4] = 0; this->Internals->FloatImageExt[5] = 0;
return ext;
return this->Internals->FloatImageExt;
}
......@@ -12,18 +12,30 @@
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkValuePass - TO DO
// .NAME vtkValuePass
//
// .SECTION Description
// TO DO
// Renders geometry using the values of a field array as fragment colors. The
// output can be used for deferred color mapping. It supports using arrays of
// either point or cell data. The target array can be selected by setting an
// array name/id and a component number. Only opaque geometry is supported.
//
// There are two rendering modes available:
//
// * INVERTIBLE_LUT Encodes array values as RGB data and renders the result to
// the default framebuffer.
//
// * FLOATING_POINT Renders actual array values as floating point data to an
// internal RGBA32F framebuffer. This class binds and unbinds the framebuffer
// on each render pass.
//
// .SECTION See Also
// vtkRenderPass vtkDefaultPass
// vtkRenderPass vtkDefaultPass vtkValuePassHelper vtkMapper
#ifndef vtkValuePass_h
#define vtkValuePass_h
#include <vector>
#include "vtkRenderingOpenGL2Module.h" // For export macro
#include "vtkDefaultPass.h"
......@@ -32,8 +44,6 @@ class vtkInformationIntegerKey;
class vtkInformationStringKey;
class vtkRenderer;
class vtkRenderWindow;
class vtkFrameBufferObject2;
class vtkRenderbuffer;
class vtkFloatArray;
class VTKRENDERINGOPENGL2_EXPORT vtkValuePass : public vtkDefaultPass
......@@ -72,22 +82,23 @@ public:
// \pre s_exists: s!=0
virtual void Render(const vtkRenderState *s);
/// @{
/// @description Interface to get the result of a render pass in
/// FLOATING_POINT mode.
/// @brief Returns a single component array containing the rendered values.
/// The returned array is owned by vtkValuePass so it is intended to be deep copied.
// Description:
// Interface to get the rendered image in FLOATING_POINT mode. Returns a
// single component array containing the rendered values. The returned array
// is owned by vtkValuePass so it is intended to be deep copied.
vtkFloatArray* GetFloatImageDataArray(vtkRenderer* ren);
/// @brief Image extents of the value array.
std::vector<int> GetFloatImageExtents();
/// @brief Low level API, a format for the internal glReadPixels call can be
/// specified. 'data' is expected to be allocated and cleaned-up by the caller.
// Description:
// Interface to get the rendered image in FLOATING_POINT mode. Low level API,
// a format for the internal glReadPixels call can be specified. 'data' is expected
// to be allocated and cleaned-up by the caller.
void GetFloatImageData(int const format, int const width, int const height,
void* data);
/// @}
// Description:
// Interface to get the rendered image in FLOATING_POINT mode. Image extents of
// the value array.
int* GetFloatImageExtents();
protected:
// Description:
......@@ -112,25 +123,17 @@ public:
// Unbinds internal FBO when FLOATING_POINT mode is enabled.
void EndPass();
/// \brief Member methods managing graphics resources required during FLOATING_POINT
/// mode.
// Description:
// Methods managing graphics resources required during FLOATING_POINT mode.
bool IsFloatFBOSupported(vtkRenderWindow* renWin);
bool HasWindowSizeChanged(vtkRenderer* ren);
bool InitializeFloatingPointMode(vtkRenderer* ren);
void ReleaseFloatingPointMode(vtkRenderer* ren);
///////////////////////////////////////////////////////////////////////////////
/// \brief FLOATING_POINT mode resources. FBO, attachments and other
/// control variables.
vtkFrameBufferObject2* ValueFrameBO;
vtkRenderbuffer* ValueRenderBO;
vtkRenderbuffer* DepthRenderBO;
bool ValuePassResourcesAllocated;
int RenderingMode;
class vtkInternals;
vtkInternals *Internals;
int RenderingMode;
private:
vtkValuePass(const vtkValuePass&) VTK_DELETE_FUNCTION;
......
This diff is collapsed.
#include <vector>
/*=========================================================================
Program: Visualization Toolkit
Module: vtkValuePassHelper.h
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.
=========================================================================*/
// .NAME vtkValuePassHelper
//
// .SECTION Description
// Implementation of both rendering modes of vtkValuePass for the
// vtkOpenGLPolyDataMapper. The mapper is intended to call various methods
// of this helper in order to setup the appropriate rendering state.
//
// * INVERTIBLE_LUT It uses a texture as a color LUT to map the values to RGB
// data. Texture size constraints limit its precision (currently 12-bit). Most
// of the implementation of this mode is in vtkMapper (InvertibleLookupTable)
// where the color LUT is generated.
//
// * FLOATING_POINT Resources are allocated on demand. When rendering point data
// values are uploaded to the GPU as vertex attributes. When rendering cell data
// values are uploaded as a texture buffer. Custom vertex and fragment shaders are
// defined in order to adjust its behavior for either type of data.
//
// .SECTION See Also
// vtkValuePass vtkOpenGLPolyDataMapper vtkMapper
#ifndef vtkValuePassHelper_h
#define vtkValuePassHelper_h
#include "vtkRenderingOpenGL2Module.h" // For export macro
#include "vtkObject.h"
#include "vtkRenderingOpenGL2Module.h"
class vtkActor;
class vtkDataArray;
class vtkDataSet;
class vtkFloatArray;
class vtkMapper;
class vtkOpenGLBufferObject;
class vtkOpenGLHelper;
class vtkRenderer;
class vtkTextureObject;
class vtkWindow;
class vtkValuePass;
class VTKRENDERINGOPENGL2_EXPORT vtkValuePassHelper : public vtkObject
{
......@@ -23,6 +53,8 @@ class VTKRENDERINGOPENGL2_EXPORT vtkValuePassHelper : public vtkObject
public:
static vtkValuePassHelper* New();
vtkTypeMacro(vtkValuePassHelper, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent);
protected:
......@@ -31,33 +63,45 @@ protected:
vtkGetMacro(RenderingMode, int);
// Description:
// Configure the internal state depending on the settings defined by the
// vtkValuePass (RenderingMode, RENDER_VALUES, SCALAR_MODE, etc.).
void UpdateConfiguration(vtkRenderer* ren, vtkActor* act, vtkMapper* mapper);
// Description:
// Upload new data if necessary, bind textures, etc.
void RenderPieceStart(vtkActor* actor, vtkDataSet* input);
// Description:
// Add necessary shader definitions.
void UpdateShaders(std::string & VSSource, std::string & FSSource,
std::string & required);
// Description:
// Bind shader variables.
void BindAttributes(vtkOpenGLHelper& cellBO);
void BindUniforms(vtkOpenGLHelper& cellBO);
void ReleaseGraphicsResources(vtkWindow* win);
// Description:
// Unbind textures, etc.
void RenderPieceFinish();
bool RequiresShaderRebuild(vtkActor* actor);
// Description:
// Query whether a shader rebuild will be required.
bool RequiresShaderRebuild();
void ReleaseGraphicsResources(vtkWindow* win);
private:
void AllocateGraphicsResources(vtkRenderer* ren);
vtkValuePassHelper(const vtkValuePassHelper &); // Not implemented.
void operator=(const vtkValuePassHelper &); // Not implemented.
vtkValuePassHelper(const vtkValuePassHelper &) VTK_DELETE_FUNCTION;
void operator=(const vtkValuePassHelper &) VTK_DELETE_FUNCTION;
////////////////////////////////////////////////////////////////////////////////
vtkOpenGLBufferObject* ValueBuffer;
vtkDataArray* ValuePassArray;
std::vector<float> Buffer;
int CurrentDataArrayMode;
int LastDataArrayMode;
class vtkInternals;
vtkInternals* Impl;
int RenderingMode;
bool ResourcesAllocated;
vtkTextureObject* CellFloatTexture;
vtkOpenGLBufferObject* CellFloatBuffer;
};
#endif // vtkValuePassHelper_h
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment