Commit e015655e authored by Ken Martin's avatar Ken Martin
Browse files

better picking support some cleanup

Change-Id: I199eb7fb5128884763067568a6a5aec398fb414f
parent 86fd8434
......@@ -511,10 +511,6 @@ int vtkHardwareSelector::Render(vtkRenderer* renderer, vtkProp** propArray,
return 0;
}
// I have no idea what this comment means. Preserving from the original code.
//todo: save off and swap in other renderer/renderwindow settings that
//could affect colors
int propsRenderered = 0;
// loop through props and give them a chance to
// render themselves as opaque geometry
......
......@@ -158,16 +158,16 @@ public:
// Description:
// Called by any vtkMapper or vtkProp subclass to render a composite-index.
// Currently indices >= 0xffffff are not supported.
void RenderCompositeIndex(unsigned int index);
virtual void RenderCompositeIndex(unsigned int index);
// Description:
// Called by any vtkMapper or vtkProp subclass to render an attribute's id.
void RenderAttributeId(vtkIdType attribid);
virtual void RenderAttributeId(vtkIdType attribid);
// Description:
// Called by any vtkMapper or subclass to render process id. This has any
// effect when this->UseProcessIdFromData is true.
void RenderProcessId(unsigned int processid);
virtual void RenderProcessId(unsigned int processid);
// Description:
// Called by vtkRenderer to render the selection pass.
......@@ -186,6 +186,11 @@ public:
vtkSetMacro(ProcessID, int);
vtkGetMacro(ProcessID, int);
// Description:
// Get/Set the color to be used by the prop when drawing
vtkGetVector3Macro(PropColorValue,float);
vtkSetVector3Macro(PropColorValue,float);
// Description:
// Get the current pass number.
vtkGetMacro(CurrentPass, int);
......@@ -230,6 +235,14 @@ public:
MAX_KNOWN_PASS = ID_HIGH16,
MIN_KNOWN_PASS = PROCESS_PASS
};
static void Convert(int id, float tcoord[3])
{
tcoord[0] = static_cast<float>((id & 0xff)/255.0);
tcoord[1] = static_cast<float>(((id & 0xff00) >> 8)/255.0);
tcoord[2] = static_cast<float>(((id & 0xff0000) >> 16)/255.0);
}
protected:
vtkHardwareSelector();
~vtkHardwareSelector();
......@@ -239,13 +252,6 @@ protected:
virtual void BeginRenderProp(vtkRenderWindow *) = 0;
virtual void EndRenderProp(vtkRenderWindow *) = 0;
static void Convert(int id, float tcoord[3])
{
tcoord[0] = static_cast<float>((id & 0xff)/255.0);
tcoord[1] = static_cast<float>(((id & 0xff00) >> 8)/255.0);
tcoord[2] = static_cast<float>(((id & 0xff0000) >> 16)/255.0);
}
int Convert(unsigned long offset, unsigned char* pb)
{
if (!pb)
......@@ -336,11 +342,13 @@ protected:
int ProcessID;
int CurrentPass;
int InPropRender;
int PropID;
float PropColorValue[3];
private:
vtkHardwareSelector(const vtkHardwareSelector&); // Not implemented.
void operator=(const vtkHardwareSelector&); // Not implemented.
int PropID;
class vtkInternals;
vtkInternals* Internals;
//ETX
......
......@@ -14,7 +14,7 @@
=========================================================================*/
// .NAME vtkScenePicker - Picks an entire viewport at one shot.
// .SECTION Description
// The Scene picker, unline conventional pickers picks an entire viewport at
// The Scene picker, unlike conventional pickers picks an entire viewport at
// one shot and caches the result, which can be retrieved later.
// The utility of the class arises during <b>Actor Selection</b>. Let's
// say you have a couple of polygonal objects in your scene and you wish to
......
......@@ -230,6 +230,8 @@ public:
double GetPickX2() const {return this->PickX2;}
double GetPickY2() const {return this->PickY2;}
vtkGetMacro(IsPicking, int);
vtkGetMacro(CurrentPickId, unsigned int);
void SetCurrentPickId(unsigned int a) {this->CurrentPickId = a;};
vtkGetObjectMacro(PickResultProps, vtkPropCollection);
// Description:
......
......@@ -83,7 +83,7 @@ public:
vtkSelection *res = sel->Select();
#if 0
#if 1
cerr << "x0 " << x0 << " y0 " << y0 << "\t";
cerr << "x1 " << x1 << " y1 " << y1 << endl;
res->Print(cout);
......
......@@ -24,6 +24,7 @@ set(Module_SRCS
vtkOpenGL2Camera.cxx
vtkOpenGL2ImageSliceMapper.cxx
vtkOpenGL2Glyph3DMapper.cxx
vtkOpenGL2HardwareSelector.cxx
vtkOpenGL2Light.cxx
vtkOpenGL2PolyDataMapper2D.cxx
vtkOpenGL2Property.cxx
......@@ -104,6 +105,7 @@ if(VTK_REPLACE_OPENGL_OVERRIDES)
set(opengl_overrides
Actor
Camera
HardwareSelector
ImageSliceMapper
Glyph3DMapper
Light
......
......@@ -24,6 +24,9 @@ uniform vec3 diffuseColorUniform; // intensity weighted color
//VTK::Color::Dec
// picking support
//VTK::Picking::Dec
void main()
{
//VTK::Color::Impl
......@@ -31,4 +34,11 @@ void main()
gl_FragColor = vec4(ambientColor + diffuseColor, opacity);
//VTK::TCoord::Impl
if (gl_FragColor.a <= 0)
{
discard;
}
//VTK::Picking::Impl
}
......@@ -40,6 +40,9 @@ varying vec4 vertexVC;
// Texture coordinates
//VTK::TCoord::Dec
// picking support
//VTK::Picking::Dec
void main()
{
//VTK::Color::Impl
......@@ -57,6 +60,13 @@ void main()
gl_FragColor = vec4(ambientColor + diffuse + specular, opacity);
//VTK::TCoord::Impl
if (gl_FragColor.a <= 0)
{
discard;
}
//VTK::Picking::Impl
}
......
......@@ -49,6 +49,9 @@ varying vec4 vertexVC;
// Texture coordinates
//VTK::TCoord::Dec
// picking support
//VTK::Picking::Dec
void main()
{
//VTK::Color::Impl
......@@ -81,6 +84,13 @@ void main()
gl_FragColor = vec4(ambientColor + diffuse + specular, opacity);
//VTK::TCoord::Impl
if (gl_FragColor.a <= 0)
{
discard;
}
//VTK::Picking::Impl
}
......
......@@ -56,6 +56,9 @@ varying vec4 vertexWC;
// Texture coordinates
//VTK::TCoord::Dec
// picking support
//VTK::Picking::Dec
void main()
{
//VTK::Color::Impl
......@@ -122,6 +125,13 @@ void main()
gl_FragColor = vec4(ambientColor + diffuse + specular, opacity);
//VTK::TCoord::Impl
if (gl_FragColor.a <= 0)
{
discard;
}
//VTK::Picking::Impl
}
......
......@@ -64,6 +64,9 @@ public:
std::vector<unsigned char> Colors;
std::vector<vtkMatrix4x4 * > Matrices;
vtkTimeStamp BuildTime;
bool LastSelectingState;
vtkOpenGL2Glyph3DMapperEntry() { this->LastSelectingState = false; };
};
class vtkOpenGL2Glyph3DMapper::vtkOpenGL2Glyph3DMapperArray
......@@ -83,6 +86,7 @@ vtkOpenGL2Glyph3DMapper::vtkOpenGL2Glyph3DMapper()
{
this->GlyphValues = new vtkOpenGL2Glyph3DMapper::vtkOpenGL2Glyph3DMapperArray();
this->Mapper = vtkVBOPolyDataMapper::New();
this->Mapper->SetPopulateSelectionSettings(0);
this->LastWindow = 0;
}
......@@ -141,9 +145,9 @@ void vtkOpenGL2Glyph3DMapper::Render(vtkRenderer *ren, vtkActor *actor)
this->SetupColorMapper();
vtkHardwareSelector* selector = NULL;// ren->GetSelector();
bool selecting_points = false; /* selector && (selector->GetFieldAssociation() ==
vtkDataObject::FIELD_ASSOCIATION_POINTS); */
vtkHardwareSelector* selector = ren->GetSelector();
bool selecting_points = selector && (selector->GetFieldAssociation() ==
vtkDataObject::FIELD_ASSOCIATION_POINTS);
if (selector)
{
......@@ -287,7 +291,8 @@ void vtkOpenGL2Glyph3DMapper::Render(
}
}
if (building || entry->BuildTime < dataset->GetMTime())
if (building || entry->BuildTime < dataset->GetMTime() ||
entry->LastSelectingState != selecting_points)
{
entry->Colors.resize(numPts*4);
entry->Matrices.resize(numPts);
......@@ -437,11 +442,14 @@ void vtkOpenGL2Glyph3DMapper::Render(
}
else
{
selectionId = static_cast<vtkIdType>(
selectionId = static_cast<vtkIdType>(
*selectionArray->GetTuple(inPtId));
}
}
selector->RenderAttributeId(selectionId);
entry->Colors[inPtId*4] = selectionId & 0xff;
entry->Colors[inPtId*4+1] = (selectionId & 0xff00) >> 8;
entry->Colors[inPtId*4+2] = (selectionId & 0xff0000) >> 16;
entry->Colors[inPtId*4+3] = 255;
}
else if (colors)
{
......@@ -475,6 +483,7 @@ void vtkOpenGL2Glyph3DMapper::Render(
entry->Matrices[inPtId]->DeepCopy(trans->GetMatrix());
}
trans->Delete();
entry->LastSelectingState = selecting_points;
entry->BuildTime.Modified();
}
......@@ -499,6 +508,11 @@ void vtkOpenGL2Glyph3DMapper::Render(
rgba[1] = entry->Colors[inPtId*4+1];
rgba[2] = entry->Colors[inPtId*4+2];
rgba[3] = entry->Colors[inPtId*4+3];
if (selecting_points)
{
selector->RenderAttributeId(rgba[0] + (rgba[1] << 8) + (rgba[2] << 16));
}
if (!primed)
{
if (fastPath)
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkOpenGL2HardwareSelector.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 "vtkOpenGL2HardwareSelector.h"
#include "vtkObjectFactory.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkOpenGL2RenderWindow.h"
#include "vtkOpenGLExtensionManager.h"
#include "vtkgl.h"
#include "vtkOpenGLError.h"
#define ID_OFFSET 1
// Description:
// Internal state and helper methods.
class vtkOpenGL2HardwareSelector::vtkInternals
{
public:
vtkOpenGL2RenderWindow *Context;
bool MultisampleSupport;
bool OriginalMultisample;
bool OriginalBlending;
vtkInternals() :
Context(NULL),
MultisampleSupport(false),
OriginalMultisample(false),
OriginalBlending(false)
{}
// Description:
// Set the rendering context and load the required
// extensions.
void SetContext(vtkRenderWindow *context)
{
if (this->Context != context)
{
this->MultisampleSupport = false;
this->Context = vtkOpenGL2RenderWindow::SafeDownCast(context);
if (this->Context)
{
vtkOpenGLExtensionManager *manager
= this->Context->GetExtensionManager();
// don't need any of the functions so don't bother
// to load the extension, but do make sure enums are
// defined.
this->MultisampleSupport
= manager->ExtensionSupported("GL_ARB_multisample")==1;
// todo the above line currently does not work so we hard code it to true
this->MultisampleSupport = true;
}
}
}
// Description:
// Check if lighting is enabled.
bool QueryLighting()
{
if (glIsEnabled(GL_LIGHTING))
{
return true;
}
else
{
return false;
}
}
// Description:
// Enable/disable multisampling.
void EnableMultisampling(bool mode)
{
if (this->MultisampleSupport)
{
if (mode)
{
glEnable(vtkgl::MULTISAMPLE);
}
else
{
glDisable(vtkgl::MULTISAMPLE);
}
}
}
// Description:
// Check if multisample is enabled.
bool QueryMultisampling()
{
if (this->MultisampleSupport && glIsEnabled(vtkgl::MULTISAMPLE))
{
return true;
}
else
{
return false;
}
}
// Description:
// Enable/Disable blending
void EnableBlending(bool mode)
{
if (mode)
{
glEnable(GL_BLEND);
}
else
{
glDisable(GL_BLEND);
}
}
// Description:
// Check if blending is enabled.
bool QueryBlending()
{
if (glIsEnabled(GL_BLEND))
{
return true;
}
else
{
return false;
}
}
};
//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkOpenGL2HardwareSelector);
//----------------------------------------------------------------------------
vtkOpenGL2HardwareSelector::vtkOpenGL2HardwareSelector()
{
#ifdef vtkOpenGL2HardwareSelectorDEBUG
cerr << "=====vtkOpenGL2HardwareSelector::vtkOpenGL2HardwareSelector" << endl;
#endif
this->Internals = new vtkInternals;
}
//----------------------------------------------------------------------------
vtkOpenGL2HardwareSelector::~vtkOpenGL2HardwareSelector()
{
#ifdef vtkOpenGL2HardwareSelectorDEBUG
cerr << "=====vtkOpenGL2HardwareSelector::~vtkOpenGL2HardwareSelector" << endl;
#endif
delete this->Internals;
}
//----------------------------------------------------------------------------
void vtkOpenGL2HardwareSelector::BeginRenderProp(vtkRenderWindow *context)
{
#ifdef vtkOpenGL2HardwareSelectorDEBUG
cerr << "=====vtkOpenGL2HardwareSelector::BeginRenderProp" << endl;
#endif
this->Internals->SetContext(context);
// Disable multisample, lighting, and blending.
this->Internals->OriginalMultisample = this->Internals->QueryMultisampling();
this->Internals->EnableMultisampling(false);
this->Internals->OriginalBlending = this->Internals->QueryBlending();
this->Internals->EnableBlending(false);
}
//----------------------------------------------------------------------------
void vtkOpenGL2HardwareSelector::EndRenderProp(vtkRenderWindow *)
{
#ifdef vtkOpenGL2HardwareSelectorDEBUG
cerr << "=====vtkOpenGL2HardwareSelector::EndRenderProp" << endl;
#endif
// Restore multisample, lighting, and blending.
this->Internals->EnableMultisampling(this->Internals->OriginalMultisample);
this->Internals->EnableBlending(this->Internals->OriginalBlending);
}
//----------------------------------------------------------------------------
void vtkOpenGL2HardwareSelector::BeginRenderProp()
{
this->InPropRender++;
if (this->InPropRender != 1)
{
return;
}
// device specific prep
vtkRenderWindow *renWin = this->Renderer->GetRenderWindow();
this->BeginRenderProp(renWin);
//cout << "In BeginRenderProp" << endl;
//glFinish();
if (this->CurrentPass == ACTOR_PASS)
{
int propid = this->PropID;
if (propid >= 0xfffffe)
{
vtkErrorMacro("Too many props. Currently only " << 0xfffffe
<< " props are supported.");
return;
}
float color[3];
// Since 0 is reserved for nothing selected, we offset propid by 1.
propid = propid + 1;
vtkHardwareSelector::Convert(propid, color);
this->SetPropColorValue(color);
}
else if (this->CurrentPass == PROCESS_PASS)
{
float color[3];
// Since 0 is reserved for nothing selected, we offset propid by 1.
vtkHardwareSelector::Convert(this->ProcessID + 1, color);
this->SetPropColorValue(color);
}
}
//----------------------------------------------------------------------------
void vtkOpenGL2HardwareSelector::RenderCompositeIndex(unsigned int index)
{
if (index > 0xffffff)
{
vtkErrorMacro("Indices > 0xffffff are not supported.");
return;
}
index += ID_OFFSET;
if (this->CurrentPass == COMPOSITE_INDEX_PASS)
{
float color[3];
vtkHardwareSelector::Convert(static_cast<int>(0xffffff & index), color);
this->SetPropColorValue(color);
}
}
//----------------------------------------------------------------------------
// TODO: make inline
void vtkOpenGL2HardwareSelector::RenderAttributeId(vtkIdType attribid)
{
if (attribid < 0)
{
vtkErrorMacro("Invalid id: " << attribid);
return;
}
this->MaxAttributeId = (attribid > this->MaxAttributeId)? attribid :
this->MaxAttributeId;
if (this->CurrentPass < ID_LOW24 || this->CurrentPass > ID_HIGH16)
{
return;
}
// 0 is reserved.
attribid += ID_OFFSET;
for (int cc=0; cc < 3; cc++)
{
int words24 = (0xffffff & attribid);
attribid = attribid >> 24;
if ((this->CurrentPass - ID_LOW24) == cc)
{
float color[3];
vtkHardwareSelector::Convert(words24, color);
this->SetPropColorValue(color);
break;
}
}
}
//----------------------------------------------------------------------------
void vtkOpenGL2HardwareSelector::RenderProcessId(unsigned int processid)
{
if (this->CurrentPass == PROCESS_PASS && this->UseProcessIdFromData)
{
if (processid >= 0xffffff)
{
vtkErrorMacro("Invalid id: " << processid);
return;
}
float color[3];
vtkHardwareSelector::Convert(
static_cast<int>(processid + 1), color);
this->SetPropColorValue(color);
}