00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <freecloth/gfx/gfxGLTexture.h>
00020 #include <freecloth/gfx/gfxImage.h>
00021 #include <freecloth/geom/gePoint.h>
00022 #include <freecloth/base/algorithm>
00023 #include <freecloth/base/baMath.h>
00024 #include <freecloth/base/GL_gl.h>
00025 #include <freecloth/base/GL_glu.h>
00026
00027
00028
00029
00030
00031
00032
00033 GfxGLTexture::GfxGLTexture( const ImagePtr& image, Int32 format )
00034 : _format( format )
00035 {
00036 DGFX_ASSERT( ! image.isNull() );
00037 _originalWidth = image->getWidth();
00038 _originalHeight = image->getHeight();
00039 if (
00040 BaMath::isPow2( _originalWidth ) &&
00041 BaMath::isPow2( _originalHeight ) &&
00042 _originalWidth >= 64 && _originalHeight >= 64
00043 ) {
00044 _image = image;
00045 }
00046 else {
00047 _image = makePow2( *image );
00048 }
00049
00050 ::glGenTextures( 1, &_textureId );
00051
00052
00053 ::glBindTexture( GL_TEXTURE_2D, _textureId );
00054 ::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
00055 ::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
00056 ::glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
00057 ::glTexImage2D(
00058 GL_TEXTURE_2D,
00059 0,
00060 _image->getNbComponents(),
00061 _image->getWidth(),
00062 _image->getHeight(),
00063 0,
00064 _format,
00065 GL_UNSIGNED_BYTE,
00066 _image->getRawData()
00067 );
00068 }
00069
00070
00071
00072 GfxGLTexture::~GfxGLTexture()
00073 {
00074 ::glDeleteTextures( 1, &_textureId );
00075 }
00076
00077
00078
00079 void GfxGLTexture::generateMipmaps()
00080 {
00081 ::gluBuild2DMipmaps(
00082 GL_TEXTURE_2D,
00083 _image->getNbComponents(),
00084 _image->getWidth(),
00085 _image->getHeight(),
00086 _format,
00087 GL_UNSIGNED_BYTE,
00088 _image->getRawData()
00089 );
00090 }
00091
00092
00093
00094 UInt32 GfxGLTexture::getTextureId() const
00095 {
00096 return _textureId;
00097 }
00098
00099
00100
00101 void GfxGLTexture::bind() const
00102 {
00103 ::glBindTexture( GL_TEXTURE_2D, _textureId );
00104 }
00105
00106
00107
00108 const GfxImage& GfxGLTexture::getImage() const
00109 {
00110 return *_image;
00111 }
00112
00113
00114
00115 GePoint GfxGLTexture::getCorner() const
00116 {
00117 return GePoint(
00118 static_cast< Float >( _originalWidth ) / _image->getWidth(),
00119 static_cast< Float >( _originalHeight ) / _image->getHeight(),
00120 0
00121 );
00122 }
00123
00124
00125
00126 UInt32 GfxGLTexture::getOriginalWidth() const
00127 {
00128 return _originalWidth;
00129 }
00130
00131
00132
00133 UInt32 GfxGLTexture::getOriginalHeight() const
00134 {
00135 return _originalHeight;
00136 }
00137
00138
00139
00140 Float GfxGLTexture::getOriginalAspectRatio() const
00141 {
00142 return static_cast<Float>( _originalWidth ) / _originalHeight;
00143 }
00144
00145
00146
00147 RCShdPtr<GfxImage> GfxGLTexture::makePow2( const GfxImage& image )
00148 {
00149 RCShdPtr<GfxImage> result( new GfxImage(
00150 std::max( BaMath::roundUpPow2( image.getWidth() ), 64U ),
00151 std::max( BaMath::roundUpPow2( image.getHeight() ), 64U ),
00152 image.getFormat()
00153 ) );
00154 const UInt8* in = image.getRawData();
00155 UInt8* out = result->getRawData();
00156 UInt32 y;
00157 for ( y = 0; y < image.getHeight(); ++y ) {
00158 UInt32 iw = image.getWidth() * image.getNbComponents();
00159 UInt32 x;
00160 for ( x = 0; x < iw; ++x ) {
00161 *out++ = *in++;
00162 }
00163 UInt32 ow = result->getWidth() * result->getNbComponents();
00164 for ( x = iw; x < ow; ++x ) {
00165 *out++ = 0;
00166 }
00167 }
00168 for ( y = image.getHeight(); y < result->getHeight(); ++y ) {
00169 UInt32 ow = result->getWidth() * result->getNbComponents();
00170 for ( UInt32 x = 0; x < ow; ++x ) {
00171 *out++ = 0;
00172 }
00173 }
00174 return result;
00175 }