@@ -61,13 +61,21 @@ using namespace IECoreGL;
61
61
// Selector::Implementation
62
62
// ////////////////////////////////////////////////////////////////////////
63
63
64
+ namespace
65
+ {
66
+
67
+ const int g_idBufferIndex = 0 ;
68
+ const int g_cameraDepthBufferIndex = 1 ;
69
+
70
+ }
71
+
64
72
class Selector ::Implementation : public IECore::RefCounted
65
73
{
66
74
67
75
public :
68
76
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 )
71
79
{
72
80
// we don't want preexisting errors to trigger exceptions
73
81
// from error checking code in the begin*() methods, because
@@ -225,12 +233,15 @@ class Selector::Implementation : public IECore::RefCounted
225
233
" #version 330\n "
226
234
" "
227
235
" uniform uint ieCoreGLNameIn;"
236
+ " in vec3 geometryP;"
228
237
" "
229
238
" layout( location=0 ) out uint ieCoreGLNameOut;"
239
+ " layout( location=1 ) out vec4 ieCoreGLCameraDepth;"
230
240
" "
231
241
" void main()"
232
242
" {"
233
243
" ieCoreGLNameOut = ieCoreGLNameIn;"
244
+ " ieCoreGLCameraDepth = vec4( -geometryP.z, -geometryP.z, -geometryP.z, 1 );"
234
245
" }" ;
235
246
236
247
static ShaderPtr s = new Shader ( " " , fragmentSource );
@@ -305,10 +316,16 @@ class Selector::Implementation : public IECore::RefCounted
305
316
GLint m_prevViewport[4 ];
306
317
GLint m_nameUniformLocation;
307
318
319
+ bool m_useCameraDepth;
320
+
308
321
void beginIDRender ()
309
322
{
310
323
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
+ }
312
329
m_frameBuffer->setDepth ( new DepthTexture ( 128 , 128 ) );
313
330
m_frameBuffer->validate ();
314
331
m_frameBufferBinding = boost::shared_ptr<FrameBuffer::ScopedBinding>( new FrameBuffer::ScopedBinding ( *m_frameBuffer ) );
@@ -342,13 +359,26 @@ class Selector::Implementation : public IECore::RefCounted
342
359
glViewport ( m_prevViewport[0 ], m_prevViewport[1 ], m_prevViewport[2 ], m_prevViewport[3 ] );
343
360
m_frameBufferBinding.reset ();
344
361
345
- IECoreImage::ImagePrimitivePtr idsImage = m_frameBuffer->getColor ()->imagePrimitive ();
362
+ IECoreImage::ImagePrimitivePtr idsImage = m_frameBuffer->getColor ( g_idBufferIndex )->imagePrimitive ();
346
363
const IECore::UIntVectorData *idsData = static_cast <const IECore::UIntVectorData *>( idsImage->channels [" Y" ].get () );
347
364
const std::vector<unsigned int > ids = idsData->readable ();
348
365
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 ();
352
382
353
383
std::map<unsigned int , HitRecord> idRecords;
354
384
for ( size_t i = 0 , e = ids.size (); i < e; i++ )
@@ -396,14 +426,28 @@ class Selector::Implementation : public IECore::RefCounted
396
426
throw IECore::Exception ( " ID shader does not have an ieCoreGLNameOut output" );
397
427
}
398
428
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
+
399
439
m_nameUniformLocation = nameParameter->location ;
400
440
401
441
m_currentIDShader = shader;
402
442
glUseProgram ( m_currentIDShader->program () );
403
443
404
444
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
+ }
407
451
glDrawBuffers ( buffers.size (), &buffers[0 ] );
408
452
409
453
loadNameIDRender ( m_currentName );
@@ -482,7 +526,12 @@ Selector *Selector::Implementation::g_currentSelector = nullptr;
482
526
// ////////////////////////////////////////////////////////////////////////
483
527
484
528
Selector::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 ) )
486
535
{
487
536
}
488
537
0 commit comments