Equalizer 1.0

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         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
Generated on Sun May 8 2011 19:11:07 for Equalizer 1.0 by  doxygen 1.7.3