Skip to content

Commit d36ae7d

Browse files
authored
Merge pull request #1404 from ericmehl/OpenGLWorldDepth
IECoreGL::Selector : Camera-space depth sampling
2 parents 373dfa2 + 6872587 commit d36ae7d

File tree

6 files changed

+84
-13
lines changed

6 files changed

+84
-13
lines changed

Changes

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
10.5.x.x (relative to 10.5.5.0)
22
========
33

4+
API
5+
------------
6+
7+
- `IECoreGL::Selector`: Added constructor overload that accepts a boolean indicating a more precise, camera-space depth sample will be used to sample depth instead of OpenGL's depth buffer.
8+
- `IECoreGL::ColorTexture`: Added new constructor that accepts an argument specifying the internal storage format to use.
9+
410

511

612
10.5.5.0 (relative to 10.5.4.2)

include/IECoreGL/ColorTexture.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,11 @@ class IECOREGL_API ColorTexture : public Texture
5151

5252
IE_CORE_DECLARERUNTIMETYPEDEXTENSION( IECoreGL::ColorTexture, ColorTextureTypeId, Texture );
5353

54-
/// Constructs an empty texture of the specified dimensions.
54+
/// \todo Remove this constructor when client code has transitioned to the one
55+
/// specifying the internal storage format.
5556
ColorTexture( unsigned int width, unsigned int height );
57+
/// Constructs an empty texture of the specified dimensions and internal storage format.
58+
ColorTexture( unsigned int width, unsigned int height, const GLint internalFormat );
5659
/// Constructs a new ColorTexture. All channels must be of the same type, and must
5760
/// be some form of numeric VectorData.
5861
ColorTexture( unsigned int width, unsigned int height, const IECore::Data *r,

include/IECoreGL/Selector.h

+7
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ class IECOREGL_API Selector : boost::noncopyable
9999
/// responsibility to keep the hits vector alive for the lifetime
100100
/// of the Selector.
101101
Selector( const Imath::Box2f &region, Mode mode, std::vector<HitRecord> &hits );
102+
/// Same as above, and if `useCameraDepth` is `true`, the depth
103+
/// values in `hits` will be taken from the camera-space Z coordinate
104+
/// instead of the less precise OpenGL depth buffer.
105+
106+
/// \todo Remove when client code has migrated and use the more
107+
/// precise alternative exclusively.
108+
Selector( const Imath::Box2f &region, Mode mode, std::vector<HitRecord> &hits, bool useCameraDepth );
102109
/// Completes the selection operation, filling in the vector
103110
/// of hits that was passed to the constructor.
104111
virtual ~Selector();

src/IECoreGL/ColorTexture.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ using namespace boost;
4848

4949
IE_CORE_DEFINERUNTIMETYPED( ColorTexture );
5050

51-
ColorTexture::ColorTexture( unsigned int width, unsigned int height )
51+
ColorTexture::ColorTexture( unsigned int width, unsigned int height ) :
52+
ColorTexture( width, height, GL_RGBA )
53+
{
54+
}
55+
56+
ColorTexture::ColorTexture( unsigned int width, unsigned int height, const GLint internalFormat )
5257
{
5358
glGenTextures( 1, &m_texture );
5459
ScopedBinding binding( *this );
@@ -58,7 +63,7 @@ ColorTexture::ColorTexture( unsigned int width, unsigned int height )
5863
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
5964
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
6065

61-
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
66+
glTexImage2D( GL_TEXTURE_2D, 0, internalFormat, width, height, 0, GL_RGBA,
6267
GL_FLOAT, nullptr );
6368
}
6469

src/IECoreGL/Selector.cpp

+59-10
Original file line numberDiff line numberDiff line change
@@ -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+
6472
class Selector::Implementation : public IECore::RefCounted
6573
{
6674

6775
public :
6876

69-
Implementation( Selector *parent, const Imath::Box2f &region, 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 &region, 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

484528
Selector::Selector( const Imath::Box2f &region, 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 &region, Mode mode, std::vector<HitRecord> &hits, bool useCameraDepth )
534+
: m_implementation( new Implementation( this, region, mode, hits, useCameraDepth ) )
486535
{
487536
}
488537

src/IECoreGL/bindings/ColorTextureBinding.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ void bindColorTexture()
5050
{
5151
IECorePython::RunTimeTypedClass<ColorTexture>()
5252
.def( init<unsigned int, unsigned int>() )
53+
.def( init<unsigned int, unsigned int, const GLint>() )
5354
.def( init<unsigned int, unsigned int, const IECore::Data *, const IECore::Data *, const IECore::Data *, const IECore::Data *>() )
5455
.def( init<const IECoreImage::ImagePrimitive *>() )
5556
;

0 commit comments

Comments
 (0)