Equalizer  1.4.1
pixelViewport.h
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
Generated on Mon Nov 26 2012 14:41:49 for Equalizer 1.4.1 by  doxygen 1.7.6.1