Equalizer
1.2.1
|
00001 00002 /* Copyright (c) 2006-2011, 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 <co/base/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 Viewport getSubVP( const PixelViewport& rhs ) const 00144 { 00145 if( *this == rhs ) 00146 return Viewport::FULL; 00147 00148 if( !rhs.hasArea( )) 00149 return Viewport( static_cast<float>( x ), 00150 static_cast<float>( y ), 0.f, 0.f ); 00151 00152 return Viewport( ( x - rhs.x )/ static_cast<float>( rhs.w ), 00153 ( y - rhs.y )/ static_cast<float>( rhs.h ), 00154 ( w )/ static_cast<float>( rhs.w ), 00155 ( h )/ static_cast<float>( rhs.h )); 00156 } 00157 00163 const Zoom getZoom( const PixelViewport& rhs ) const 00164 { 00165 if( *this == rhs ) 00166 return Zoom::NONE; 00167 00168 if( !rhs.hasArea( )) 00169 return Zoom( std::numeric_limits< float >::max(), 00170 std::numeric_limits< float >::max( )); 00171 00172 return Zoom( w / static_cast<float>( rhs.w ), 00173 h / static_cast<float>( rhs.h )); 00174 } 00175 00177 int32_t getXEnd() const { return x+w; } 00178 00180 int32_t getYEnd() const { return y+h; } 00181 00183 const PixelViewport operator + ( const Vector2i& offset ) const 00184 { 00185 return PixelViewport( x+offset.x(), y+offset.y(), w, h ); 00186 } 00187 00193 void unapply( const Pixel& pixel ) 00194 { 00195 w *= pixel.w; 00196 h *= pixel.h; 00197 x += pixel.x; 00198 y += pixel.y; 00199 } 00200 00205 bool operator == ( const PixelViewport& rhs ) const 00206 { 00207 return ( x==rhs.x && y==rhs.y && w==rhs.w && h==rhs.h ); 00208 } 00209 00214 bool operator != ( const PixelViewport& rhs ) const 00215 { 00216 return ( x!=rhs.x || y!=rhs.y || w!=rhs.w || h!=rhs.h ); 00217 } 00218 00223 void merge( const PixelViewport& rhs ) 00224 { 00225 if( *this == rhs || !rhs.hasArea() ) 00226 return; 00227 00228 if( !hasArea() ) 00229 { 00230 *this = rhs; 00231 return; 00232 } 00233 00234 const int32_t sEx = x + w; 00235 const int32_t sEy = y + h; 00236 const int32_t dEx = rhs.x + rhs.w; 00237 const int32_t dEy = rhs.y + rhs.h; 00238 00239 x = EQ_MIN( x, rhs.x ); 00240 y = EQ_MIN( y, rhs.y ); 00241 w = EQ_MAX( sEx, dEx ) - x; 00242 h = EQ_MAX( sEy, dEy ) - y; 00243 } 00244 00246 void intersect( const PixelViewport& rhs ) 00247 { 00248 if( *this == rhs ) 00249 return; 00250 00251 if( !rhs.isValid() || !isValid() ) 00252 { 00253 invalidate(); 00254 return; 00255 } 00256 00257 if( !rhs.hasArea() || !hasArea() ) 00258 { 00259 x = 0; 00260 y = 0; 00261 w = 0; 00262 h = 0; 00263 return; 00264 } 00265 00266 const int32_t sEx = x + w; 00267 const int32_t sEy = y + h; 00268 const int32_t dEx = rhs.x + rhs.w; 00269 const int32_t dEy = rhs.y + rhs.h; 00270 00271 x = EQ_MAX( x, rhs.x ); 00272 y = EQ_MAX( y, rhs.y ); 00273 w = EQ_MIN( sEx, dEx ) - x; 00274 h = EQ_MIN( sEy, dEy ) - y; 00275 } 00276 00278 00279 int32_t x; 00280 int32_t y; 00281 int32_t w; 00282 int32_t h; 00283 }; 00284 00285 inline std::ostream& operator << ( std::ostream& os, 00286 const PixelViewport& pvp ) 00287 { 00288 os << "[ " << pvp.x << " " << pvp.y << " " << pvp.w << " " << pvp.h 00289 <<" ]"; 00290 return os; 00291 } 00292 } 00293 } 00294 00295 #endif // EQFABRIC_PIXELVIEWPORT_H