d07c171f |
1 | /* |
2 | Copyright (C) 2003 Rice1964 |
3 | |
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. |
8 | |
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. |
13 | |
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. |
17 | |
18 | */ |
19 | |
20 | #include "TextureManager.h" |
21 | |
22 | |
23 | ////////////////////////////////////////// |
24 | // Constructors / Deconstructors |
25 | |
26 | // Probably shouldn't need more than 4096 * 4096 |
27 | |
28 | CTexture::CTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage) : |
29 | m_dwWidth(dwWidth), |
30 | m_dwHeight(dwHeight), |
31 | m_dwCreatedTextureWidth(dwWidth), |
32 | m_dwCreatedTextureHeight(dwHeight), |
33 | m_fXScale(1.0f), |
34 | m_fYScale(1.0f), |
35 | m_bScaledS(false), |
36 | m_bScaledT(false), |
37 | m_bClampedS(false), |
38 | m_bClampedT(false), |
39 | m_bIsEnhancedTexture(false), |
40 | m_Usage(usage), |
41 | m_pTexture(NULL), |
42 | m_dwTextureFmt(TEXTURE_FMT_A8R8G8B8) |
43 | { |
44 | // fix me, do something here |
45 | } |
46 | |
47 | |
48 | CTexture::~CTexture(void) |
49 | { |
50 | } |
51 | |
52 | TextureFmt CTexture::GetSurfaceFormat(void) |
53 | { |
54 | if (m_pTexture == NULL) |
55 | return TEXTURE_FMT_UNKNOWN; |
56 | else |
57 | return m_dwTextureFmt; |
58 | } |
59 | |
60 | uint32 CTexture::GetPixelSize() |
61 | { |
62 | if( m_dwTextureFmt == TEXTURE_FMT_A8R8G8B8 ) |
63 | return 4; |
64 | else |
65 | return 2; |
66 | } |
67 | |
68 | |
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 |
74 | // large then 1.0. |
75 | // In such a case, we need to scale the image to the D3D surface dimension, to ease the U/V addr |
76 | // limition |
77 | void CTexture::ScaleImageToSurface(bool scaleS, bool scaleT) |
78 | { |
79 | uint8 g_ucTempBuffer[1024*1024*4]; |
80 | |
81 | if( scaleS==false && scaleT==false) return; |
82 | |
83 | // If the image is not scaled, call this function to scale the real image to |
84 | // the D3D given dimension |
85 | |
86 | uint32 width = scaleS ? m_dwWidth : m_dwCreatedTextureWidth; |
87 | uint32 height = scaleT ? m_dwHeight : m_dwCreatedTextureHeight; |
88 | |
89 | uint32 xDst, yDst; |
90 | uint32 xSrc, ySrc; |
91 | |
92 | DrawInfo di; |
93 | |
94 | if (!StartUpdate(&di)) |
95 | { |
96 | return; |
97 | } |
98 | |
99 | int pixSize = GetPixelSize(); |
100 | |
101 | // Copy across from the temp buffer to the surface |
102 | switch (pixSize) |
103 | { |
104 | case 4: |
105 | { |
106 | memcpy((uint8*)g_ucTempBuffer, (uint8*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*4); |
107 | |
108 | uint32 * pDst; |
109 | uint32 * pSrc; |
110 | |
111 | for (yDst = 0; yDst < m_dwCreatedTextureHeight; yDst++) |
112 | { |
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); |
118 | |
119 | pSrc = (uint32*)((uint8*)g_ucTempBuffer + (ySrc * m_dwCreatedTextureWidth * 4)); |
120 | pDst = (uint32*)((uint8*)di.lpSurface + (yDst * di.lPitch)); |
121 | |
122 | for (xDst = 0; xDst < m_dwCreatedTextureWidth; xDst++) |
123 | { |
124 | xSrc = (uint32)((xDst * width) / m_dwCreatedTextureWidth+0.49f); |
125 | pDst[xDst] = pSrc[xSrc]; |
126 | } |
127 | } |
128 | } |
129 | |
130 | break; |
131 | case 2: |
132 | { |
133 | memcpy((uint8*)g_ucTempBuffer, (uint8*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*2); |
134 | |
135 | uint16 * pDst; |
136 | uint16 * pSrc; |
137 | |
138 | for (yDst = 0; yDst < m_dwCreatedTextureHeight; yDst++) |
139 | { |
140 | // ySrc ranges from 0..m_dwHeight |
141 | ySrc = (yDst * height) / m_dwCreatedTextureHeight; |
142 | |
143 | pSrc = (uint16*)((uint8*)g_ucTempBuffer + (ySrc * m_dwCreatedTextureWidth * 2)); |
144 | pDst = (uint16*)((uint8*)di.lpSurface + (yDst * di.lPitch)); |
145 | |
146 | for (xDst = 0; xDst < m_dwCreatedTextureWidth; xDst++) |
147 | { |
148 | xSrc = (xDst * width) / m_dwCreatedTextureWidth; |
149 | pDst[xDst] = pSrc[xSrc]; |
150 | } |
151 | } |
152 | } |
153 | break; |
154 | |
155 | } |
156 | |
157 | EndUpdate(&di); |
158 | |
159 | if( scaleS ) m_bScaledS = true; |
160 | if( scaleT ) m_bScaledT = true; |
161 | } |
162 | |
163 | void CTexture::ClampImageToSurfaceS() |
164 | { |
165 | if( !m_bClampedS && m_dwWidth < m_dwCreatedTextureWidth ) |
166 | { |
167 | DrawInfo di; |
168 | if( StartUpdate(&di) ) |
169 | { |
170 | if( m_dwTextureFmt == TEXTURE_FMT_A8R8G8B8 ) |
171 | { |
172 | for( uint32 y = 0; y<m_dwHeight; y++ ) |
173 | { |
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++ ) |
177 | { |
178 | line[x] = val; |
179 | } |
180 | } |
181 | } |
182 | else |
183 | { |
184 | for( uint32 y = 0; y<m_dwHeight; y++ ) |
185 | { |
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++ ) |
189 | { |
190 | line[x] = val; |
191 | } |
192 | } |
193 | } |
194 | EndUpdate(&di); |
195 | } |
196 | } |
197 | m_bClampedS = true; |
198 | } |
199 | |
200 | void CTexture::ClampImageToSurfaceT() |
201 | { |
202 | if( !m_bClampedT && m_dwHeight < m_dwCreatedTextureHeight ) |
203 | { |
204 | DrawInfo di; |
205 | if( StartUpdate(&di) ) |
206 | { |
207 | if( m_dwTextureFmt == TEXTURE_FMT_A8R8G8B8 ) |
208 | { |
209 | uint32* linesrc = (uint32*)((uint8*)di.lpSurface+di.lPitch*(m_dwHeight-1)); |
210 | for( uint32 y = m_dwHeight; y<m_dwCreatedTextureHeight; y++ ) |
211 | { |
212 | uint32* linedst = (uint32*)((uint8*)di.lpSurface+di.lPitch*y); |
213 | for( uint32 x=0; x<m_dwCreatedTextureWidth; x++ ) |
214 | { |
215 | linedst[x] = linesrc[x]; |
216 | } |
217 | } |
218 | } |
219 | else |
220 | { |
221 | uint16* linesrc = (uint16*)((uint8*)di.lpSurface+di.lPitch*(m_dwHeight-1)); |
222 | for( uint32 y = m_dwHeight; y<m_dwCreatedTextureHeight; y++ ) |
223 | { |
224 | uint16* linedst = (uint16*)((uint8*)di.lpSurface+di.lPitch*y); |
225 | for( uint32 x=0; x<m_dwCreatedTextureWidth; x++ ) |
226 | { |
227 | linedst[x] = linesrc[x]; |
228 | } |
229 | } |
230 | } |
231 | EndUpdate(&di); |
232 | } |
233 | } |
234 | m_bClampedT = true; |
235 | } |
236 | |
237 | void CTexture::RestoreAlphaChannel(void) |
238 | { |
239 | DrawInfo di; |
240 | |
241 | if ( StartUpdate(&di) ) |
242 | { |
243 | uint32 *pSrc = (uint32 *)di.lpSurface; |
244 | int lPitch = di.lPitch; |
245 | |
246 | for (uint32 y = 0; y < m_dwHeight; y++) |
247 | { |
248 | uint32 * dwSrc = (uint32 *)((uint8 *)pSrc + y*lPitch); |
249 | for (uint32 x = 0; x < m_dwWidth; x++) |
250 | { |
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; |
256 | dw &= 0x00FFFFFF; |
257 | dw |= (dwAlpha<<24); |
258 | |
259 | /* |
260 | uint32 dw = dwSrc[x]; |
261 | if( (dw&0x00FFFFFF) > 0 ) |
262 | dw |= 0xFF000000; |
263 | else |
264 | dw &= 0x00FFFFFF; |
265 | */ |
266 | } |
267 | } |
268 | EndUpdate(&di); |
269 | } |
270 | else |
271 | { |
272 | //TRACE0("Cannot lock texture"); |
273 | } |
274 | } |
275 | |