Equalizer  1.6.1
pixelViewport.h
1 
2 /* Copyright (c) 2006-2013, Stefan Eilemann <eile@equalizergraphics.com>
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License version 2.1 as published
6  * by the Free Software Foundation.
7  *
8  * This library is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11  * details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this library; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16  */
17 
18 #ifndef EQFABRIC_PIXELVIEWPORT_H
19 #define EQFABRIC_PIXELVIEWPORT_H
20 
21 #include <eq/fabric/viewport.h> // used in inline method
22 #include <eq/fabric/pixel.h> // used in inline method
23 #include <eq/fabric/zoom.h> // used in inline method
24 
25 #include <lunchbox/debug.h>
26 
27 #include <limits>
28 
29 namespace eq
30 {
31 namespace fabric
32 {
35  {
36  public:
40  PixelViewport() : x(0), y(0), w(-1), h(-1) {}
41 
43  explicit PixelViewport( const int32_t x_, const int32_t y_,
44  const int32_t w_, const int32_t h_ )
45  : x(x_), y(y_), w(w_), h(h_) {}
46 
48  explicit PixelViewport( const int32_t pvp[4] )
49  : x( pvp[0] ), y( pvp[1] ), w( pvp[2] ), h( pvp[3] ) {}
51 
55  void invalidate() { x = 0; y = 0; w = -1; h = -1; }
56 
62  bool isValid() const { return (w>=0 && h>=0); }
63 
69  bool hasArea() const { return (w>0 && h>0); }
70 
72  uint32_t getArea() const { return w * h; }
73 
78  bool isInside( const int32_t pX, const int32_t pY ) const
79  {
80  if( pX < x || pY < y || pX > (x+w) || pY > (y+h) )
81  return false;
82  return true;
83  }
85 
89  void apply( const Viewport& rhs )
90  {
91  // honor position over size to avoid rounding artifacts
92  const int32_t xEnd = x + static_cast<int32_t>((rhs.x+rhs.w)*w);
93  const int32_t yEnd = y + static_cast<int32_t>((rhs.y+rhs.h)*h);
94 
95  x += static_cast<int32_t>( w * rhs.x );
96  y += static_cast<int32_t>( h * rhs.y );
97  w = xEnd - x;
98  h = yEnd - y;
99  }
100 
102  void apply( const Pixel& pixel )
103  {
104  if( pixel.w > 1 )
105  {
106  int32_t newWidth = w / pixel.w;
107  // This would be the correct thing to do, but it would
108  // require frustum adaptations in CUV::_computeFrustum:
109  //if( w - ( newWidth * pixel.w ) > pixel.x )
110  if( w - ( newWidth * pixel.w ) != 0 )
111  ++newWidth;
112 
113  w = newWidth;
114  }
115  if( pixel.h > 1 )
116  {
117  int32_t newHeight = h / pixel.h;
118  // This would be the correct thing to do, but it would
119  // require frustum adaptations in CUV::_computeFrustum:
120  // if( w - ( newWidth * pixel.h ) > pixel.y )
121  if( h - ( newHeight * pixel.h ) != 0 )
122  ++newHeight;
123 
124  h = newHeight;
125  }
126  }
127 
129  void apply( const Zoom& zoom )
130  {
131  if( zoom == Zoom::NONE )
132  return;
133 
134  x = static_cast< int32_t >( x * zoom.x() + .5f );
135  y = static_cast< int32_t >( y * zoom.y() + .5f );
136  w = static_cast< int32_t >( w * zoom.x() + .5f );
137  h = static_cast< int32_t >( h * zoom.y() + .5f );
138  }
139 
145  const Zoom getZoom( const PixelViewport& rhs ) const
146  {
147  if( *this == rhs )
148  return Zoom::NONE;
149 
150  if( !rhs.hasArea( ))
151  return Zoom( std::numeric_limits< float >::max(),
152  std::numeric_limits< float >::max( ));
153 
154  return Zoom( w / static_cast<float>( rhs.w ),
155  h / static_cast<float>( rhs.h ));
156  }
157 
159  int32_t getXEnd() const { return x+w; }
160 
162  int32_t getYEnd() const { return y+h; }
163 
165  void convertToPlugin( uint64_t dims[4] ) const
166  {
167  dims[ 0 ] = x;
168  dims[ 1 ] = w;
169  dims[ 2 ] = y;
170  dims[ 3 ] = h;
171  }
172 
174  void convertFromPlugin( const uint64_t dims[4] )
175  {
176  x = int32_t( dims[ 0 ]);
177  w = int32_t( dims[ 1 ]);
178  y = int32_t( dims[ 2 ]);
179  h = int32_t( dims[ 3 ]);
180  }
181 
183  const PixelViewport operator + ( const Vector2i& offset ) const
184  {
185  return PixelViewport( x+offset.x(), y+offset.y(), w, h );
186  }
187 
192  Viewport operator / ( const PixelViewport& rhs ) const
193  {
194  if( *this == rhs )
195  return Viewport::FULL;
196 
197  if( !rhs.hasArea( ))
198  return Viewport( static_cast<float>( x ),
199  static_cast<float>( y ), 0.f, 0.f );
200 
201  return Viewport( ( x - rhs.x )/ static_cast<float>( rhs.w ),
202  ( y - rhs.y )/ static_cast<float>( rhs.h ),
203  ( w )/ static_cast<float>( rhs.w ),
204  ( h )/ static_cast<float>( rhs.h ));
205  }
206 
208  const PixelViewport& operator -= ( const Vector2i& offset )
209  {
210  x -= offset.x();
211  y -= offset.y();
212  return *this;
213  }
214 
220  void unapply( const Pixel& pixel )
221  {
222  w *= pixel.w;
223  h *= pixel.h;
224  x += pixel.x;
225  y += pixel.y;
226  }
227 
232  bool operator == ( const PixelViewport& rhs ) const
233  {
234  return ( x==rhs.x && y==rhs.y && w==rhs.w && h==rhs.h );
235  }
236 
241  bool operator != ( const PixelViewport& rhs ) const
242  {
243  return ( x!=rhs.x || y!=rhs.y || w!=rhs.w || h!=rhs.h );
244  }
245 
250  void merge( const PixelViewport& rhs )
251  {
252  if( *this == rhs || !rhs.hasArea() )
253  return;
254 
255  if( !hasArea() )
256  {
257  *this = rhs;
258  return;
259  }
260 
261  const int32_t sEx = x + w;
262  const int32_t sEy = y + h;
263  const int32_t dEx = rhs.x + rhs.w;
264  const int32_t dEy = rhs.y + rhs.h;
265 
266  x = LB_MIN( x, rhs.x );
267  y = LB_MIN( y, rhs.y );
268  w = LB_MAX( sEx, dEx ) - x;
269  h = LB_MAX( sEy, dEy ) - y;
270  }
271 
273  void intersect( const PixelViewport& rhs )
274  {
275  if( *this == rhs )
276  return;
277 
278  if( !rhs.isValid() || !isValid() )
279  {
280  invalidate();
281  return;
282  }
283 
284  if( !rhs.hasArea() || !hasArea() )
285  {
286  x = 0;
287  y = 0;
288  w = 0;
289  h = 0;
290  return;
291  }
292 
293  const int32_t sEx = x + w;
294  const int32_t sEy = y + h;
295  const int32_t dEx = rhs.x + rhs.w;
296  const int32_t dEy = rhs.y + rhs.h;
297 
298  x = LB_MAX( x, rhs.x );
299  y = LB_MAX( y, rhs.y );
300  w = LB_MIN( sEx, dEx ) - x;
301  h = LB_MIN( sEy, dEy ) - y;
302  }
303 
305 
306  int32_t x;
307  int32_t y;
308  int32_t w;
309  int32_t h;
310  };
311 
312  inline std::ostream& operator << ( std::ostream& os,
313  const PixelViewport& pvp )
314  {
315  os << "[ " << pvp.x << " " << pvp.y << " " << pvp.w << " " << pvp.h
316  <<" ]";
317  return os;
318  }
319 }
320 }
321 
322 namespace lunchbox
323 {
324 template<> inline void byteswap( eq::fabric::PixelViewport& value )
325 {
326  byteswap( value.x );
327  byteswap( value.y );
328  byteswap( value.w );
329  byteswap( value.h );
330 }
331 }
332 #endif // EQFABRIC_PIXELVIEWPORT_H
int32_t getYEnd() const
void apply(const Zoom &zoom)
Apply a zoom to this pixel viewport.
const Zoom getZoom(const PixelViewport &rhs) const
static const Viewport FULL
A full viewport.
Definition: viewport.h:186
float h
The height.
Definition: viewport.h:184
bool isInside(const int32_t pX, const int32_t pY) const
Definition: pixelViewport.h:78
bool operator==(const PixelViewport &rhs) const
Holds a pixel decomposition specification with methods for manipulation.
Definition: pixel.h:39
PixelViewport()
Construct a new, invalid pixel viewport.
Definition: pixelViewport.h:40
void apply(const Pixel &pixel)
Apply a pixel decomposition to this pixel viewport.
const PixelViewport operator+(const Vector2i &offset) const
void convertToPlugin(uint64_t dims[4]) const
Convert into a lunchbox::Plugin usable format.
uint32_t getArea() const
Definition: pixelViewport.h:72
float w
The width.
Definition: viewport.h:183
Holds a 2D pixel viewport with methods for manipulation.
Definition: pixelViewport.h:34
PixelViewport(const int32_t pvp[4])
Construct a new pixel viewport with default values.
Definition: pixelViewport.h:48
bool operator!=(const PixelViewport &rhs) const
void apply(const Viewport &rhs)
Apply a fractional viewport to this pixel viewport.
Definition: pixelViewport.h:89
void merge(const PixelViewport &rhs)
Create a pixel viewport that includes both viewports (union).
PixelViewport(const int32_t x_, const int32_t y_, const int32_t w_, const int32_t h_)
Construct a new pixel viewport with default values.
Definition: pixelViewport.h:43
void unapply(const Pixel &pixel)
Perform the inverse operation of applying a pixel decomposition to this pixel viewport.
float x
The X coordinate.
Definition: viewport.h:181
static const Zoom NONE
The zoom NONE (1,1) value.
Definition: zoom.h:68
A zoom specification with methods for manipulation.
Definition: zoom.h:34
void convertFromPlugin(const uint64_t dims[4])
Convert from a lunchbox::Plugin format.
const PixelViewport & operator-=(const Vector2i &offset)
A fractional viewport with methods for manipulation.
Definition: viewport.h:36
void invalidate()
Invalidate the pixel viewport.
Definition: pixelViewport.h:55
int32_t getXEnd() const
void intersect(const PixelViewport &rhs)
Create the intersection of the two pixel viewports.
float y
The Y coordinate.
Definition: viewport.h:182
vmml::vector< 2, int > Vector2i
A two-component integer vector.
Definition: vmmlib.h:40