Equalizer  1.2.1
pixelViewport.h
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
Generated on Fri Jun 8 2012 15:44:32 for Equalizer 1.2.1 by  doxygen 1.8.0