Equalizer
1.4.1
|
00001 00002 /* Copyright (c) 2006-2012, Stefan Eilemann <eile@equalizergraphics.com> 00003 * 00004 * This library is free software; you can redistribute it and/or modify it under 00005 * the terms of the GNU Lesser General Public License version 2.1 as published 00006 * by the Free Software Foundation. 00007 * 00008 * This library is distributed in the hope that it will be useful, but WITHOUT 00009 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00010 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00011 * details. 00012 * 00013 * You should have received a copy of the GNU Lesser General Public License 00014 * along with this library; if not, write to the Free Software Foundation, Inc., 00015 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00016 */ 00017 00018 #ifndef EQFABRIC_PIXELVIEWPORT_H 00019 #define EQFABRIC_PIXELVIEWPORT_H 00020 00021 #include <eq/fabric/viewport.h> // used in inline method 00022 #include <eq/fabric/pixel.h> // used in inline method 00023 #include <eq/fabric/zoom.h> // used in inline method 00024 00025 #include <lunchbox/debug.h> 00026 00027 #include <limits> 00028 00029 namespace eq 00030 { 00031 namespace fabric 00032 { 00034 class PixelViewport 00035 { 00036 public: 00040 PixelViewport() : x(0), y(0), w(-1), h(-1) {} 00041 00043 explicit PixelViewport( const int32_t x_, const int32_t y_, 00044 const int32_t w_, const int32_t h_ ) 00045 : x(x_), y(y_), w(w_), h(h_) {} 00046 00048 explicit PixelViewport( const int32_t pvp[4] ) 00049 : x( pvp[0] ), y( pvp[1] ), w( pvp[2] ), h( pvp[3] ) {} 00051 00055 void invalidate() { x = 0; y = 0; w = -1; h = -1; } 00056 00062 bool isValid() const { return (w>=0 && h>=0); } 00063 00069 bool hasArea() const { return (w>0 && h>0); } 00070 00072 uint32_t getArea() const { return w * h; } 00073 00078 bool isInside( const int32_t pX, const int32_t pY ) const 00079 { 00080 if( pX < x || pY < y || pX > (x+w) || pY > (y+h) ) 00081 return false; 00082 return true; 00083 } 00085 00089 void apply( const Viewport& rhs ) 00090 { 00091 // honor position over size to avoid rounding artifacts 00092 const int32_t xEnd = x + static_cast<int32_t>((rhs.x+rhs.w)*w); 00093 const int32_t yEnd = y + static_cast<int32_t>((rhs.y+rhs.h)*h); 00094 00095 x += static_cast<int32_t>( w * rhs.x ); 00096 y += static_cast<int32_t>( h * rhs.y ); 00097 w = xEnd - x; 00098 h = yEnd - y; 00099 } 00100 00102 void apply( const Pixel& pixel ) 00103 { 00104 if( pixel.w > 1 ) 00105 { 00106 int32_t newWidth = w / pixel.w; 00107 // This would be the correct thing to do, but it would 00108 // require frustum adaptations in CUV::_computeFrustum: 00109 //if( w - ( newWidth * pixel.w ) > pixel.x ) 00110 if( w - ( newWidth * pixel.w ) != 0 ) 00111 ++newWidth; 00112 00113 w = newWidth; 00114 } 00115 if( pixel.h > 1 ) 00116 { 00117 int32_t newHeight = h / pixel.h; 00118 // This would be the correct thing to do, but it would 00119 // require frustum adaptations in CUV::_computeFrustum: 00120 // if( w - ( newWidth * pixel.h ) > pixel.y ) 00121 if( h - ( newHeight * pixel.h ) != 0 ) 00122 ++newHeight; 00123 00124 h = newHeight; 00125 } 00126 } 00127 00129 void apply( const Zoom& zoom ) 00130 { 00131 if( zoom == Zoom::NONE ) 00132 return; 00133 00134 w = static_cast< int32_t >( w * zoom.x() + .5f ); 00135 h = static_cast< int32_t >( h * zoom.y() + .5f ); 00136 } 00137 00143 const Zoom getZoom( const PixelViewport& rhs ) const 00144 { 00145 if( *this == rhs ) 00146 return Zoom::NONE; 00147 00148 if( !rhs.hasArea( )) 00149 return Zoom( std::numeric_limits< float >::max(), 00150 std::numeric_limits< float >::max( )); 00151 00152 return Zoom( w / static_cast<float>( rhs.w ), 00153 h / static_cast<float>( rhs.h )); 00154 } 00155 00157 int32_t getXEnd() const { return x+w; } 00158 00160 int32_t getYEnd() const { return y+h; } 00161 00163 const PixelViewport operator + ( const Vector2i& offset ) const 00164 { 00165 return PixelViewport( x+offset.x(), y+offset.y(), w, h ); 00166 } 00167 00172 Viewport operator / ( const PixelViewport& rhs ) const 00173 { 00174 if( *this == rhs ) 00175 return Viewport::FULL; 00176 00177 if( !rhs.hasArea( )) 00178 return Viewport( static_cast<float>( x ), 00179 static_cast<float>( y ), 0.f, 0.f ); 00180 00181 return Viewport( ( x - rhs.x )/ static_cast<float>( rhs.w ), 00182 ( y - rhs.y )/ static_cast<float>( rhs.h ), 00183 ( w )/ static_cast<float>( rhs.w ), 00184 ( h )/ static_cast<float>( rhs.h )); 00185 } 00186 00188 const PixelViewport& operator -= ( const Vector2i& offset ) 00189 { 00190 x -= offset.x(); 00191 y -= offset.y(); 00192 return *this; 00193 } 00194 00200 void unapply( const Pixel& pixel ) 00201 { 00202 w *= pixel.w; 00203 h *= pixel.h; 00204 x += pixel.x; 00205 y += pixel.y; 00206 } 00207 00212 bool operator == ( const PixelViewport& rhs ) const 00213 { 00214 return ( x==rhs.x && y==rhs.y && w==rhs.w && h==rhs.h ); 00215 } 00216 00221 bool operator != ( const PixelViewport& rhs ) const 00222 { 00223 return ( x!=rhs.x || y!=rhs.y || w!=rhs.w || h!=rhs.h ); 00224 } 00225 00230 void merge( const PixelViewport& rhs ) 00231 { 00232 if( *this == rhs || !rhs.hasArea() ) 00233 return; 00234 00235 if( !hasArea() ) 00236 { 00237 *this = rhs; 00238 return; 00239 } 00240 00241 const int32_t sEx = x + w; 00242 const int32_t sEy = y + h; 00243 const int32_t dEx = rhs.x + rhs.w; 00244 const int32_t dEy = rhs.y + rhs.h; 00245 00246 x = LB_MIN( x, rhs.x ); 00247 y = LB_MIN( y, rhs.y ); 00248 w = LB_MAX( sEx, dEx ) - x; 00249 h = LB_MAX( sEy, dEy ) - y; 00250 } 00251 00253 void intersect( const PixelViewport& rhs ) 00254 { 00255 if( *this == rhs ) 00256 return; 00257 00258 if( !rhs.isValid() || !isValid() ) 00259 { 00260 invalidate(); 00261 return; 00262 } 00263 00264 if( !rhs.hasArea() || !hasArea() ) 00265 { 00266 x = 0; 00267 y = 0; 00268 w = 0; 00269 h = 0; 00270 return; 00271 } 00272 00273 const int32_t sEx = x + w; 00274 const int32_t sEy = y + h; 00275 const int32_t dEx = rhs.x + rhs.w; 00276 const int32_t dEy = rhs.y + rhs.h; 00277 00278 x = LB_MAX( x, rhs.x ); 00279 y = LB_MAX( y, rhs.y ); 00280 w = LB_MIN( sEx, dEx ) - x; 00281 h = LB_MIN( sEy, dEy ) - y; 00282 } 00283 00285 00286 int32_t x; 00287 int32_t y; 00288 int32_t w; 00289 int32_t h; 00290 }; 00291 00292 inline std::ostream& operator << ( std::ostream& os, 00293 const PixelViewport& pvp ) 00294 { 00295 os << "[ " << pvp.x << " " << pvp.y << " " << pvp.w << " " << pvp.h 00296 <<" ]"; 00297 return os; 00298 } 00299 } 00300 } 00301 00302 #endif // EQFABRIC_PIXELVIEWPORT_H