2 Copyright (C) 2003 Rice1964
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "TextureManager.h"
23 //////////////////////////////////////////
24 // Constructors / Deconstructors
26 // Probably shouldn't need more than 4096 * 4096
28 CTexture::CTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage) :
31 m_dwCreatedTextureWidth(dwWidth),
32 m_dwCreatedTextureHeight(dwHeight),
39 m_bIsEnhancedTexture(false),
42 m_dwTextureFmt(TEXTURE_FMT_A8R8G8B8)
44 // fix me, do something here
48 CTexture::~CTexture(void)
52 TextureFmt CTexture::GetSurfaceFormat(void)
54 if (m_pTexture == NULL)
55 return TEXTURE_FMT_UNKNOWN;
57 return m_dwTextureFmt;
60 uint32 CTexture::GetPixelSize()
62 if( m_dwTextureFmt == TEXTURE_FMT_A8R8G8B8 )
69 // There are reasons to create this function. D3D and OGL will only create surface of width and height
70 // as 2's pow, for example, N64's 20x14 image, D3D and OGL will create a 32x16 surface.
71 // When we using such a surface as D3D texture, and the U and V address is for the D3D and OGL surface
72 // width and height. It is still OK if the U and V addr value is less than the real image within
73 // the D3D surface. But we will have problems if the U and V addr value is larger than it, or even
75 // In such a case, we need to scale the image to the D3D surface dimension, to ease the U/V addr
77 void CTexture::ScaleImageToSurface(bool scaleS, bool scaleT)
79 uint8 g_ucTempBuffer[1024*1024*4];
81 if( scaleS==false && scaleT==false) return;
83 // If the image is not scaled, call this function to scale the real image to
84 // the D3D given dimension
86 uint32 width = scaleS ? m_dwWidth : m_dwCreatedTextureWidth;
87 uint32 height = scaleT ? m_dwHeight : m_dwCreatedTextureHeight;
94 if (!StartUpdate(&di))
99 int pixSize = GetPixelSize();
101 // Copy across from the temp buffer to the surface
106 memcpy((uint8*)g_ucTempBuffer, (uint8*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*4);
111 for (yDst = 0; yDst < m_dwCreatedTextureHeight; yDst++)
113 // ySrc ranges from 0..m_dwHeight
114 // I'd rather do this but sometimes very narrow (i.e. 1 pixel)
115 // surfaces are created which results in /0...
116 //ySrc = (yDst * (m_dwHeight-1)) / (d3dTextureHeight-1);
117 ySrc = (uint32)((yDst * height) / m_dwCreatedTextureHeight+0.49f);
119 pSrc = (uint32*)((uint8*)g_ucTempBuffer + (ySrc * m_dwCreatedTextureWidth * 4));
120 pDst = (uint32*)((uint8*)di.lpSurface + (yDst * di.lPitch));
122 for (xDst = 0; xDst < m_dwCreatedTextureWidth; xDst++)
124 xSrc = (uint32)((xDst * width) / m_dwCreatedTextureWidth+0.49f);
125 pDst[xDst] = pSrc[xSrc];
133 memcpy((uint8*)g_ucTempBuffer, (uint8*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*2);
138 for (yDst = 0; yDst < m_dwCreatedTextureHeight; yDst++)
140 // ySrc ranges from 0..m_dwHeight
141 ySrc = (yDst * height) / m_dwCreatedTextureHeight;
143 pSrc = (uint16*)((uint8*)g_ucTempBuffer + (ySrc * m_dwCreatedTextureWidth * 2));
144 pDst = (uint16*)((uint8*)di.lpSurface + (yDst * di.lPitch));
146 for (xDst = 0; xDst < m_dwCreatedTextureWidth; xDst++)
148 xSrc = (xDst * width) / m_dwCreatedTextureWidth;
149 pDst[xDst] = pSrc[xSrc];
159 if( scaleS ) m_bScaledS = true;
160 if( scaleT ) m_bScaledT = true;
163 void CTexture::ClampImageToSurfaceS()
165 if( !m_bClampedS && m_dwWidth < m_dwCreatedTextureWidth )
168 if( StartUpdate(&di) )
170 if( m_dwTextureFmt == TEXTURE_FMT_A8R8G8B8 )
172 for( uint32 y = 0; y<m_dwHeight; y++ )
174 uint32* line = (uint32*)((uint8*)di.lpSurface+di.lPitch*y);
175 uint32 val = line[m_dwWidth-1];
176 for( uint32 x=m_dwWidth; x<m_dwCreatedTextureWidth; x++ )
184 for( uint32 y = 0; y<m_dwHeight; y++ )
186 uint16* line = (uint16*)((uint8*)di.lpSurface+di.lPitch*y);
187 uint16 val = line[m_dwWidth-1];
188 for( uint32 x=m_dwWidth; x<m_dwCreatedTextureWidth; x++ )
200 void CTexture::ClampImageToSurfaceT()
202 if( !m_bClampedT && m_dwHeight < m_dwCreatedTextureHeight )
205 if( StartUpdate(&di) )
207 if( m_dwTextureFmt == TEXTURE_FMT_A8R8G8B8 )
209 uint32* linesrc = (uint32*)((uint8*)di.lpSurface+di.lPitch*(m_dwHeight-1));
210 for( uint32 y = m_dwHeight; y<m_dwCreatedTextureHeight; y++ )
212 uint32* linedst = (uint32*)((uint8*)di.lpSurface+di.lPitch*y);
213 for( uint32 x=0; x<m_dwCreatedTextureWidth; x++ )
215 linedst[x] = linesrc[x];
221 uint16* linesrc = (uint16*)((uint8*)di.lpSurface+di.lPitch*(m_dwHeight-1));
222 for( uint32 y = m_dwHeight; y<m_dwCreatedTextureHeight; y++ )
224 uint16* linedst = (uint16*)((uint8*)di.lpSurface+di.lPitch*y);
225 for( uint32 x=0; x<m_dwCreatedTextureWidth; x++ )
227 linedst[x] = linesrc[x];
237 void CTexture::RestoreAlphaChannel(void)
241 if ( StartUpdate(&di) )
243 uint32 *pSrc = (uint32 *)di.lpSurface;
244 int lPitch = di.lPitch;
246 for (uint32 y = 0; y < m_dwHeight; y++)
248 uint32 * dwSrc = (uint32 *)((uint8 *)pSrc + y*lPitch);
249 for (uint32 x = 0; x < m_dwWidth; x++)
251 uint32 dw = dwSrc[x];
252 uint32 dwRed = (uint8)((dw & 0x00FF0000)>>16);
253 uint32 dwGreen = (uint8)((dw & 0x0000FF00)>>8 );
254 uint32 dwBlue = (uint8)((dw & 0x000000FF) );
255 uint32 dwAlpha = (dwRed+dwGreen+dwBlue)/3;
260 uint32 dw = dwSrc[x];
261 if( (dw&0x00FFFFFF) > 0 )
272 //TRACE0("Cannot lock texture");