Commit 09685dfa authored by Cédric Traizet's avatar Cédric Traizet

Merge branch '1930-shader-bug-rel' into 'release-7.0'

Ice OpenGL refactoring (release)

See merge request !612
parents 94d1fc58 365f21cb
Pipeline #2878 passed with stages
in 97 minutes and 6 seconds
......@@ -38,8 +38,8 @@ git shortlog -es HEAD | cut -f 2- \
curl -s ${GITLAB_PROJECT_URL}/raw/master/CI/contributors/known-contributors.txt \
| sort -u > ${KNOWN_CONTRIBUTORS}
diff ${KNOWN_CONTRIBUTORS} ${GIT_CONTRIBUTORS} > ${UNKNOWN_CONTRIBUTORS}
if [ "$?" -ne "0" ] ; then
diff ${KNOWN_CONTRIBUTORS} ${GIT_CONTRIBUTORS} | grep '^>' > ${UNKNOWN_CONTRIBUTORS}
if [ -s "${UNKNOWN_CONTRIBUTORS}" ] ; then
echo ""
echo "WARNING: ***************************************************************"
echo "WARNING: Unknown contributors found:"
......
......@@ -24,13 +24,14 @@
#include <itkObject.h>
#include "otbViewSettings.h"
#include "otbShader.h"
#include "OTBIceExport.h"
#include <string>
namespace otb
{
class OTBIce_EXPORT GlActor
class OTBIce_EXPORT GlActor
: public itk::Object
{
public:
......@@ -42,7 +43,7 @@ public:
itkSetObjectMacro(Settings,ViewSettings);
itkGetObjectMacro(Settings,ViewSettings);
itkGetConstObjectMacro(Settings,ViewSettings);
itkSetMacro(Visible,bool);
itkGetMacro(Visible,bool);
itkBooleanMacro(Visible);
......@@ -58,6 +59,9 @@ public:
itkGetMacro( Overlay, bool );
itkBooleanMacro( Overlay );
itkGetObjectMacro( Shader, Shader );
itkSetObjectMacro( Shader, Shader );
// Retrieve the full extent of the actor
virtual void GetExtent(double & ulx, double & uly, double & lrx, double & lry) const = 0;
......@@ -70,15 +74,20 @@ public:
// Gl rendering of current state
virtual void Render() = 0;
/** create the shader (no shader created by default) */
virtual void CreateShader();
protected:
GlActor();
~GlActor() override;
Shader::Pointer m_Shader;
private:
// prevent implementation
GlActor(const Self&);
void operator=(const Self&);
GlActor( const Self & ) = delete;
void operator=( const Self & ) = delete;
ViewSettings::Pointer m_Settings;
......
/*
* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otb_GlBufferObject_h
#define otb_GlBufferObject_h
#include "OTBIceExport.h"
#include "otbGlHandle.h"
#include "otbGlTypeTraits.h"
namespace otb { namespace gl {
/** OpenGL element-type of buffer-object.
*/
enum class element : GLenum
{
vertex = GL_ARRAY_BUFFER,
index = GL_ELEMENT_ARRAY_BUFFER,
};
/**
*/
template< element E >
struct BufferObjectPolicy
{
static
void
Generate( Id_t & id )
{
glGenBuffers( 1, &id );
}
static
void
Bind( Id_t id )
{
glBindBuffer( static_cast< GLenum >( E ), id );
}
static
void
Release( Id_t & id )
{
glDeleteBuffers( 1, &id );
}
};
/**
* @class OpenGL object.
*/
template< element E >
struct BufferObject
{
/** Buffer identifier type. */
using Id_t = otb::gl::Id_t;
/** @return element type. */
static constexpr
element
Element() noexcept
{
return E;
}
/** Default constructor. */
BufferObject() = default;
/** Construct and fill. */
template< typename T >
BufferObject( std::initializer_list< T > data,
std::size_t components = 1 ) :
m_Id(),
m_Count( data.size() ),
m_Size( sizeof( T ) ),
m_Components( components ),
m_GlType( TypeTraits< T >::value() )
{
assert( data.size() );
assert( components );
glBufferData(
static_cast< GLenum >( E ),
data.size() * sizeof( T ),
data.begin(),
GL_STATIC_DRAW
);
CheckError();
}
~BufferObject() = default;
BufferObject( BufferObject && ) = default;
BufferObject & operator = ( BufferObject && ) = default;
/** Cast operator. */
operator Id_t() const noexcept
{
return m_Id;
}
void
Bind( bool isEnabled = true ) const
{
m_Id.Bind( isEnabled );
}
GLenum
GlType() const noexcept
{
return m_GlType;
}
std::size_t
Size() const noexcept
{
return m_Size;
}
std::size_t
Stride( std::size_t components ) const noexcept
{
assert( m_Size>0 );
assert( m_Components>0 );
assert( components<=m_Components );
return m_Size * ( m_Components - components );
}
private:
Handle< BufferObjectPolicy< E > > m_Id;
std::size_t m_Count = 0;
std::size_t m_Size = 0;
std::size_t m_Components = 0;
GLenum m_GlType = GL_ZERO;
};
using VertexBufferObject = BufferObject< element::vertex >;
using IndexBufferObject = BufferObject< element::index >;
} // end namespace gl.
} // end namespace otb.
#endif // otb_GlBufferObject_h
/*
* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otb_GlError_h
#define otb_GlError_h
#include "OTBIceExport.h"
#ifdef _WIN32
# include <windows.h>
#endif
#include <GL/glew.h>
#include <cassert>
#include <iostream>
#include <stdexcept>
namespace otb { namespace gl {
/**
* @class OpenGL-specific exception.
*/
struct OTBIce_EXPORT Error : public std::runtime_error
{
/** Construct an OpenGL exception related to the OpenGL error code.
*/
Error( GLenum code );
}; // End class GlError
enum class error : int
{
clear = 0,
trace,
assertion,
exception,
};
template< error E = error::exception >
GLenum
CheckError()
{
GLenum glError = glGetError();
if( E>=error::trace )
if( glError!=GL_NO_ERROR )
std::cerr
<< "OPenGL error #" << glError << ": '" << gluErrorString( glError ) << "'"
<< std::endl;
if( E>=error::assertion )
assert( glError==GL_NO_ERROR );
// When assert is removed (NDEBUG) and Throw is false, this function
// body is emtpy and the C++ compiler should optimize the call by
// removing it.
//
// N.B.: equivalent of a scoped (and breakpoint-friendly) macro.
// Condition is splitted because first is determined at compile time
// and may be removed (see above) and second is determined at
// runtime.
if( E>=error::exception )
if( glError!=GL_NO_ERROR )
throw Error( glError );
return glError;
}
} // End of namespace gl.
} // End namespace otb.
#endif // otb_GlError_h
/*
* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otb_GlHandle_h
#define otb_GlHandle_h
#include "OTBIceExport.h"
#ifdef _WIN32
# include <windows.h>
#endif
#include <GL/glew.h>
#include "otbGlError.h"
#include <cassert>
#include <utility>
namespace otb { namespace gl {
using Id_t = GLuint;
/**
* @class OpenGL handle.
*/
template< typename Policy >
class OTBIce_EXPORT Handle
{
using Policy_t = Policy;
public:
/** OpenGL handle identifier type */
using Id_t = otb::gl::Id_t;
/** Default constructor */
Handle()
{
Policy::Generate( m_Id );
assert( m_Id );
CheckError();
Policy::Bind( m_Id );
CheckError();
}
/** Destructor */
~Handle()
{
Release();
}
/** Copy constructor (disabled). */
Handle( Handle const & ) = delete;
/** Assignement operator (disabled). */
Handle & operator = ( Handle const & ) = delete;
/** Move constructor. */
Handle( Handle && rhs ) noexcept :
m_Id( std::exchange( rhs.m_Id, 0 ) ) {}
/** Move assignment operator. */
Handle &
operator = ( Handle && rhs )
{
Release();
m_Id = std::exchange( rhs.m_Id, GL_ZERO );
return *this;
}
/** Cast operator. */
operator Id_t() const noexcept
{
return m_Id;
}
/** OpenGL handle binding */
void
Bind( bool isEnabled = true ) const
{
assert( m_Id );
Policy::Bind( isEnabled ? m_Id : GL_ZERO );
CheckError();
}
protected:
/** OpenGL handle identifier (handler) */
Id_t m_Id = GL_ZERO;
private:
void
Release()
{
CheckError< error::clear >();
Policy::Release( m_Id );
m_Id = GL_ZERO;
CheckError();
}
};
} // end namespace gl.
} // end namespace otb.
#endif // otb_GlHandle_h
......@@ -26,7 +26,6 @@
#include "itkCenteredRigid2DTransform.h"
#include "otbFragmentShader.h"
#include "otbGenericRSTransform.h"
#include "otbGeoInterface.h"
#include "otbGlActor.h"
......@@ -35,13 +34,20 @@
#include "otbMultiChannelExtractROI.h"
#include "otbVectorRescaleIntensityImageFilter.h"
#include "otbVectorImage.h"
#include <string>
namespace otb
{
class OTBIce_EXPORT GlImageActor
namespace gl
{
struct Mesh;
}
class OTBIce_EXPORT GlImageActor
: public GlActor, public GeoInterface
{
public:
......@@ -63,7 +69,7 @@ public:
typedef VectorImageType::SpacingType SpacingType;
typedef VectorImageType::PointType PointType;
typedef VectorRescaleIntensityImageFilter<VectorImageType,UCharVectorImageType> RescaleFilterType;
struct ResolutionAlgorithm
{
enum type
......@@ -76,7 +82,7 @@ public:
///performances, better quality)
MAX__};
};
// Initialize with a new image
void Initialize(const std::string & filename);
......@@ -125,11 +131,7 @@ public:
itkSetMacro(TileSize,unsigned int);
itkGetMacro(TileSize,unsigned int);
itkBooleanMacro(SoftwareRendering );
itkSetMacro(SoftwareRendering, bool );
itkGetMacro(SoftwareRendering, bool );
void CreateShader();
void CreateShader() override;
void SetResolutionAlgorithm(ResolutionAlgorithm::type alg)
{
......@@ -144,7 +146,7 @@ public:
virtual void SetRedIdx(const unsigned int idx)
{
if ( this->m_RedIdx != idx )
{
{
this->m_RedIdx = std::min(this->GetNumberOfComponents(),idx);
this->Modified();
}
......@@ -153,25 +155,25 @@ public:
virtual void SetGreenIdx(const unsigned int idx)
{
if ( this->m_GreenIdx != idx )
{
{
this->m_GreenIdx = std::min(this->GetNumberOfComponents(),idx);
this->Modified();
}
}
}
virtual void SetBlueIdx(const unsigned int idx)
{
if ( this->m_BlueIdx != idx )
{
{
this->m_BlueIdx = std::min(this->GetNumberOfComponents(),idx);
this->Modified();
this->Modified();
}
}
PointType ViewportToImageTransform(const PointType & in, bool physical = true) const;
PointType ImageToViewportTransform(const PointType & in, bool physical = true) const;
bool GetPixelFromViewport( const PointType & in, PixelType & pixel ) const;
bool GetPixelFromViewport( const PointType & view,
......@@ -181,9 +183,6 @@ public:
bool GetPixel( const PointType & physical, PixelType & pixel, IndexType & index ) const;
itkGetObjectMacro(Shader,FragmentShader);
itkSetObjectMacro(Shader,FragmentShader);
itkGetObjectMacro( ImageSettings, ImageSettings );
//
......@@ -203,7 +202,7 @@ public:
protected:
GlImageActor();
~GlImageActor() override;
typedef ImageFileReader<VectorImageType> ReaderType;
......@@ -216,33 +215,23 @@ protected:
class Tile
{
public:
Tile()
: m_Loaded(false),
m_TextureId(0),
m_ImageRegion(),
m_TileSize(0),
m_Image(),
m_UL(),
m_UR(),
m_LL(),
m_LR(),
m_Resolution(1),
m_RedIdx(1),
m_GreenIdx(2),
m_BlueIdx(3),
m_RescaleFilter(nullptr)
{
m_UL.Fill(0);
m_UR.Fill(0);
m_LL.Fill(0);
m_LR.Fill(0);
}
Tile();
~Tile();
void Link( ReaderType::OutputImageType * );
ReaderType::OutputImageType::Pointer const &
Image() const noexcept
{ return m_Image; }
void Acquire() noexcept;
void Release();
bool m_Loaded;
unsigned int m_TextureId;
RegionType m_ImageRegion;
unsigned int m_TileSize;
VectorImageType::Pointer m_Image;
PointType m_UL;
PointType m_UR;
PointType m_LL;
......@@ -252,10 +241,14 @@ protected:
unsigned int m_GreenIdx;
unsigned int m_BlueIdx;
RescaleFilterType::Pointer m_RescaleFilter;
private:
VectorImageType::Pointer m_Image;
};
typedef std::vector<Tile> TileVectorType;
typedef std::list< Tile > TileVectorType;
private:
// prevent implementation
GlImageActor(const Self&);
......@@ -263,7 +256,7 @@ private:
// Load tile to GPU
void LoadTile(Tile& tile);
// Unload tile from GPU
void UnloadTile(Tile& tile);
......@@ -283,11 +276,11 @@ private:
void ViewportExtentToImageRegion(const double& ulx, const double & uly, const double & lrx, const double & lry, RegionType & region) const;
void UpdateResolution();
unsigned int m_TileSize;
std::string m_FileName;
ReaderType::Pointer m_FileReader;
TileVectorType m_LoadedTiles;
......@@ -308,7 +301,6 @@ private:
unsigned int m_NumberOfComponents;
ImageSettings::Pointer m_ImageSettings;
FragmentShader::Pointer m_Shader;
RSTransformType::Pointer m_ViewportToImageTransform;
RSTransformType::Pointer m_ImageToViewportTransform;
......@@ -318,7 +310,8 @@ private:
ResolutionAlgorithm::type m_ResolutionAlgorithm;
bool m_SoftwareRendering;
/** OpenGL quad. */
std::unique_ptr< gl::Mesh > m_Mesh;
}; // End class GlImageActor
......
/*
* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otb_GlMesh_h
#define otb_GlMesh_h