Equalizer 1.0
|
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 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_) {} 00047 00051 void invalidate() { x = 0; y = 0; w = -1; h = -1; } 00052 00058 bool isValid() const { return (w>=0 && h>=0); } 00059 00065 bool hasArea() const { return (w>0 && h>0); } 00066 00068 uint32_t getArea() const { return w * h; } 00069 00074 bool isInside( const int32_t pX, const int32_t pY ) const 00075 { 00076 if( pX < x || pY < y || pX > (x+w) || pY > (y+h) ) 00077 return false; 00078 return true; 00079 } 00081 00085 void apply( const Viewport& rhs ) 00086 { 00087 // honor position over size to avoid rounding artifacts 00088 const int32_t xEnd = x + static_cast<int32_t>((rhs.x+rhs.w)*w); 00089 const int32_t yEnd = y + static_cast<int32_t>((rhs.y+rhs.h)*h); 00090 00091 x += static_cast<int32_t>( w * rhs.x ); 00092 y += static_cast<int32_t>( h * rhs.y ); 00093 w = xEnd - x; 00094 h = yEnd - y; 00095 } 00096 00098 void apply( const Pixel& pixel ) 00099 { 00100 if( pixel.w > 1 ) 00101 { 00102 int32_t newWidth = w / pixel.w; 00103 // This would be the correct thing to do, but it would 00104 // require frustum adaptations in CUV::_computeFrustum: 00105 //if( w - ( newWidth * pixel.w ) > pixel.x ) 00106 if( w - ( newWidth * pixel.w ) != 0 ) 00107 ++newWidth; 00108 00109 w = newWidth; 00110 } 00111 if( pixel.h > 1 ) 00112 { 00113 int32_t newHeight = h / pixel.h; 00114 // This would be the correct thing to do, but it would 00115 // require frustum adaptations in CUV::_computeFrustum: 00116 // if( w - ( newWidth * pixel.h ) > pixel.y ) 00117 if( h - ( newHeight * pixel.h ) != 0 ) 00118 ++newHeight; 00119 00120 h = newHeight; 00121 } 00122 } 00123 00125 void apply( const Zoom& zoom ) 00126 { 00127 if( zoom == Zoom::NONE ) 00128 return; 00129 00130 w = static_cast< int32_t >( w * zoom.x() + .5f ); 00131 h = static_cast< int32_t >( h * zoom.y() + .5f ); 00132 } 00133 00139 const Viewport getSubVP( const PixelViewport& rhs ) const 00140 { 00141 if( *this == rhs ) 00142 return Viewport::FULL; 00143 00144 if( !rhs.hasArea( )) 00145 return Viewport( static_cast<float>( x ), 00146 static_cast<float>( y ), 0.f, 0.f ); 00147 00148 return Viewport( ( x - rhs.x )/ static_cast<float>( rhs.w ), 00149 ( y - rhs.y )/ static_cast<float>( rhs.h ), 00150 ( w )/ static_cast<float>( rhs.w ), 00151 ( h )/ static_cast<float>( rhs.h )); 00152 } 00153 00159 const Zoom getZoom( const PixelViewport& rhs ) const 00160 { 00161 if( *this == rhs ) 00162 return Zoom::NONE; 00163 00164 if( !rhs.hasArea( )) 00165 return Zoom( std::numeric_limits< float >::max(), 00166 std::numeric_limits< float >::max( )); 00167 00168 return Zoom( w / static_cast<float>( rhs.w ), 00169 h / static_cast<float>( rhs.h )); 00170 } 00171 00173 int32_t getXEnd() const { return x+w; } 00174 00176 int32_t getYEnd() const { return y+h; } 00177 00179 const PixelViewport operator + ( const Vector2i& offset ) const 00180 { 00181 return PixelViewport( x+offset.x(), y+offset.y(), w, h ); 00182 } 00183 00189 void unapply( const Pixel& pixel ) 00190 { 00191 w *= pixel.w; 00192 h *= pixel.h; 00193 x += pixel.x; 00194 y += pixel.y; 00195 } 00196 00201 bool operator == ( const PixelViewport& rhs ) const 00202 { 00203 return ( x==rhs.x && y==rhs.y && w==rhs.w && h==rhs.h ); 00204 } 00205 00210 bool operator != ( const PixelViewport& rhs ) const 00211 { 00212 return ( x!=rhs.x || y!=rhs.y || w!=rhs.w || h!=rhs.h ); 00213 } 00214 00219 void merge( const PixelViewport& rhs ) 00220 { 00221 if( *this == rhs || !rhs.hasArea() ) 00222 return; 00223 00224 if( !hasArea() ) 00225 { 00226 *this = rhs; 00227 return; 00228 } 00229 00230 const int32_t sEx = x + w; 00231 const int32_t sEy = y + h; 00232 const int32_t dEx = rhs.x + rhs.w; 00233 const int32_t dEy = rhs.y + rhs.h; 00234 00235 x = EQ_MIN( x, rhs.x ); 00236 y = EQ_MIN( y, rhs.y ); 00237 w = EQ_MAX( sEx, dEx ) - x; 00238 h = EQ_MAX( sEy, dEy ) - y; 00239 } 00240 00242 void intersect( const PixelViewport& rhs ) 00243 { 00244 if( *this == rhs ) 00245 return; 00246 00247 if( !rhs.isValid() || !isValid() ) 00248 { 00249 invalidate(); 00250 return; 00251 } 00252 00253 if( !rhs.hasArea() || !hasArea() ) 00254 { 00255 x = 0; 00256 y = 0; 00257 w = 0; 00258 h = 0; 00259 return; 00260 } 00261 00262 const int32_t sEx = x + w; 00263 const int32_t sEy = y + h; 00264 const int32_t dEx = rhs.x + rhs.w; 00265 const int32_t dEy = rhs.y + rhs.h; 00266 00267 x = EQ_MAX( x, rhs.x ); 00268 y = EQ_MAX( y, rhs.y ); 00269 w = EQ_MIN( sEx, dEx ) - x; 00270 h = EQ_MIN( sEy, dEy ) - y; 00271 } 00272 00274 00275 int32_t x; 00276 int32_t y; 00277 int32_t w; 00278 int32_t h; 00279 }; 00280 00281 inline std::ostream& operator << ( std::ostream& os, 00282 const PixelViewport& pvp ) 00283 { 00284 os << "[ " << pvp.x << " " << pvp.y << " " << pvp.w << " " << pvp.h 00285 <<" ]"; 00286 return os; 00287 } 00288 } 00289 } 00290 00291 #endif // EQFABRIC_PIXELVIEWPORT_H