@@ -61,13 +61,21 @@ using namespace IECoreGL;
6161// Selector::Implementation
6262// ////////////////////////////////////////////////////////////////////////
6363
64+ namespace
65+ {
66+
67+ const int g_idBufferIndex = 0 ;
68+ const int g_cameraDepthBufferIndex = 1 ;
69+
70+ }
71+
6472class Selector ::Implementation : public IECore::RefCounted
6573{
6674
6775 public :
6876
69- Implementation ( Selector *parent, const Imath::Box2f ®ion, Mode mode, std::vector<HitRecord> &hits )
70- : m_mode( mode ), m_hits( hits ), m_baseState( new State( true /* complete */ ) ), m_currentName( 0 ), m_nextGeneratedName( 1 ), m_currentIDShader( nullptr )
77+ Implementation ( Selector *parent, const Imath::Box2f ®ion, Mode mode, std::vector<HitRecord> &hits, bool useCameraDepth )
78+ : m_mode( mode ), m_hits( hits ), m_baseState( new State( true /* complete */ ) ), m_currentName( 0 ), m_nextGeneratedName( 1 ), m_currentIDShader( nullptr ), m_useCameraDepth( useCameraDepth )
7179 {
7280 // we don't want preexisting errors to trigger exceptions
7381 // from error checking code in the begin*() methods, because
@@ -225,12 +233,15 @@ class Selector::Implementation : public IECore::RefCounted
225233 " #version 330\n "
226234 " "
227235 " uniform uint ieCoreGLNameIn;"
236+ " in vec3 geometryP;"
228237 " "
229238 " layout( location=0 ) out uint ieCoreGLNameOut;"
239+ " layout( location=1 ) out vec4 ieCoreGLCameraDepth;"
230240 " "
231241 " void main()"
232242 " {"
233243 " ieCoreGLNameOut = ieCoreGLNameIn;"
244+ " ieCoreGLCameraDepth = vec4( -geometryP.z, -geometryP.z, -geometryP.z, 1 );"
234245 " }" ;
235246
236247 static ShaderPtr s = new Shader ( " " , fragmentSource );
@@ -305,10 +316,16 @@ class Selector::Implementation : public IECore::RefCounted
305316 GLint m_prevViewport[4 ];
306317 GLint m_nameUniformLocation;
307318
319+ bool m_useCameraDepth;
320+
308321 void beginIDRender ()
309322 {
310323 m_frameBuffer = new FrameBuffer ();
311- m_frameBuffer->setColor ( new UIntTexture ( 128 , 128 ) );
324+ m_frameBuffer->setColor ( new UIntTexture ( 128 , 128 ), g_idBufferIndex );
325+ if ( m_useCameraDepth )
326+ {
327+ m_frameBuffer->setColor ( new ColorTexture ( 128 , 128 , GL_RGBA32F ), g_cameraDepthBufferIndex );
328+ }
312329 m_frameBuffer->setDepth ( new DepthTexture ( 128 , 128 ) );
313330 m_frameBuffer->validate ();
314331 m_frameBufferBinding = boost::shared_ptr<FrameBuffer::ScopedBinding>( new FrameBuffer::ScopedBinding ( *m_frameBuffer ) );
@@ -342,13 +359,26 @@ class Selector::Implementation : public IECore::RefCounted
342359 glViewport ( m_prevViewport[0 ], m_prevViewport[1 ], m_prevViewport[2 ], m_prevViewport[3 ] );
343360 m_frameBufferBinding.reset ();
344361
345- IECoreImage::ImagePrimitivePtr idsImage = m_frameBuffer->getColor ()->imagePrimitive ();
362+ IECoreImage::ImagePrimitivePtr idsImage = m_frameBuffer->getColor ( g_idBufferIndex )->imagePrimitive ();
346363 const IECore::UIntVectorData *idsData = static_cast <const IECore::UIntVectorData *>( idsImage->channels [" Y" ].get () );
347364 const std::vector<unsigned int > ids = idsData->readable ();
348365
349- IECoreImage::ImagePrimitivePtr zImage = m_frameBuffer->getDepth ()->imagePrimitive ();
350- const IECore::FloatVectorData *zData = static_cast <const IECore::FloatVectorData *>( zImage->channels [" Z" ].get () );
351- const std::vector<float > z = zData->readable ();
366+ IECoreImage::ImagePrimitivePtr zImage;
367+ std::string channelName;
368+
369+ if ( !m_useCameraDepth )
370+ {
371+ zImage = m_frameBuffer->getDepth ()->imagePrimitive ();
372+ channelName = " Z" ;
373+ }
374+ else
375+ {
376+ zImage = m_frameBuffer->getColor ( g_cameraDepthBufferIndex )->imagePrimitive ();
377+ channelName = " R" ;
378+ }
379+
380+ auto zData = static_cast <const IECore::FloatVectorData *>( zImage->channels [channelName].get () );
381+ const std::vector<float > &z = zData->readable ();
352382
353383 std::map<unsigned int , HitRecord> idRecords;
354384 for ( size_t i = 0 , e = ids.size (); i < e; i++ )
@@ -396,14 +426,28 @@ class Selector::Implementation : public IECore::RefCounted
396426 throw IECore::Exception ( " ID shader does not have an ieCoreGLNameOut output" );
397427 }
398428
429+ GLint depthDataLocation = 0 ;
430+ if ( m_useCameraDepth )
431+ {
432+ depthDataLocation = glGetFragDataLocation ( shader->program (), " ieCoreGLCameraDepth" );
433+ if ( depthDataLocation < 0 )
434+ {
435+ throw IECore::Exception ( " ID shader does not have ieCoreGLCameraDepth output" );
436+ }
437+ }
438+
399439 m_nameUniformLocation = nameParameter->location ;
400440
401441 m_currentIDShader = shader;
402442 glUseProgram ( m_currentIDShader->program () );
403443
404444 std::vector<GLenum> buffers;
405- buffers.resize ( fragDataLocation + 1 , GL_NONE );
406- buffers[buffers.size ()-1 ] = GL_COLOR_ATTACHMENT0;
445+ buffers.resize ( std::max ( fragDataLocation, depthDataLocation ) + 1 , GL_NONE );
446+ buffers[fragDataLocation] = GL_COLOR_ATTACHMENT0;
447+ if ( m_useCameraDepth )
448+ {
449+ buffers[depthDataLocation] = GL_COLOR_ATTACHMENT1;
450+ }
407451 glDrawBuffers ( buffers.size (), &buffers[0 ] );
408452
409453 loadNameIDRender ( m_currentName );
@@ -482,7 +526,12 @@ Selector *Selector::Implementation::g_currentSelector = nullptr;
482526// ////////////////////////////////////////////////////////////////////////
483527
484528Selector::Selector ( const Imath::Box2f ®ion, Mode mode, std::vector<HitRecord> &hits )
485- : m_implementation( new Implementation( this , region, mode, hits ) )
529+ : m_implementation( new Implementation( this , region, mode, hits, false /* useCameraDepth */ ) )
530+ {
531+ }
532+
533+ Selector::Selector ( const Imath::Box2f ®ion, Mode mode, std::vector<HitRecord> &hits, bool useCameraDepth )
534+ : m_implementation( new Implementation( this , region, mode, hits, useCameraDepth ) )
486535{
487536}
488537
0 commit comments