Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
ww3dformat.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WW3D *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/ww3dformat.cpp $*
26 * *
27 * Original Author:: Hector Yee *
28 * *
29 * Author : Kenny Mitchell *
30 * *
31 * $Modtime:: 06/27/02 1:27p $*
32 * *
33 * $Revision:: 14 $*
34 * *
35 * 06/27/02 KM Z Format support *
36 *---------------------------------------------------------------------------------------------*
37 * Functions: *
38 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
39
40#include "ww3dformat.h"
41#include "vector4.h"
42#include "wwdebug.h"
43#include "targa.h"
44#include "dx8wrapper.h"
45#include "dx8caps.h"
46#include <d3d8.h>
47
48 /*
49 WW3D_FORMAT_UNKNOWN=0,
50 WW3D_FORMAT_R8G8B8,
51 WW3D_FORMAT_A8R8G8B8,
52 WW3D_FORMAT_X8R8G8B8,
53 WW3D_FORMAT_R5G6B5,
54 WW3D_FORMAT_X1R5G5B5,
55 WW3D_FORMAT_A1R5G5B5,
56 WW3D_FORMAT_A4R4G4B4,
57 WW3D_FORMAT_R3G3B2,
58 WW3D_FORMAT_A8,
59 WW3D_FORMAT_A8R3G3B2,
60 WW3D_FORMAT_X4R4G4B4,
61 WW3D_FORMAT_A8P8,
62 WW3D_FORMAT_P8,
63 WW3D_FORMAT_L8,
64 WW3D_FORMAT_A8L8,
65 WW3D_FORMAT_A4L4,
66 WW3D_FORMAT_COUNT // Used only to determine number of surface formats
67*/
68
70{
71 switch (format) {
72 default:
73 case WW3D_FORMAT_UNKNOWN: name="Unknown"; break;
74 case WW3D_FORMAT_R8G8B8: name="R8G8B8"; break;
75 case WW3D_FORMAT_A8R8G8B8: name="A8R8G8B8"; break;
76 case WW3D_FORMAT_X8R8G8B8: name="X8R8G8B8"; break;
77 case WW3D_FORMAT_R5G6B5: name="R5G6B5"; break;
78 case WW3D_FORMAT_X1R5G5B5: name="X1R5G5B5"; break;
79 case WW3D_FORMAT_A1R5G5B5: name="A1R5G5B5"; break;
80 case WW3D_FORMAT_A4R4G4B4: name="A4R4G4B4"; break;
81 case WW3D_FORMAT_R3G3B2: name="R3G3B2"; break;
82 case WW3D_FORMAT_A8: name="A8"; break;
83 case WW3D_FORMAT_A8R3G3B2: name="A8R3G3B2"; break;
84 case WW3D_FORMAT_X4R4G4B4: name="X4R4G4B4"; break;
85 case WW3D_FORMAT_A8P8: name="A8P8"; break;
86 case WW3D_FORMAT_P8: name="P8"; break;
87 case WW3D_FORMAT_L8: name="L8"; break;
88 case WW3D_FORMAT_A8L8: name="A8L8"; break;
89 case WW3D_FORMAT_A4L4: name="A4L4"; break;
90 case WW3D_FORMAT_U8V8: name="U8V8"; break; // Bumpmap
91 case WW3D_FORMAT_L6V5U5: name="L6V5U5"; break; // Bumpmap
92 case WW3D_FORMAT_X8L8V8U8: name="X8L8V8U8"; break; // Bumpmap
93 case WW3D_FORMAT_DXT1: name="DXT1"; break;
94 case WW3D_FORMAT_DXT2: name="DXT2"; break;
95 case WW3D_FORMAT_DXT3: name="DXT3"; break;
96 case WW3D_FORMAT_DXT4: name="DXT4"; break;
97 case WW3D_FORMAT_DXT5: name="DXT5"; break;
98 }
99}
100
101//**********************************************************************************************
103
106{
107 switch (format)
108 {
109 default:
110 case WW3D_FORMAT_UNKNOWN : name="Unknown"; break;
111 case WW3D_ZFORMAT_D16_LOCKABLE: name="D16Lockable"; break; // 16-bit z-buffer bit depth. This is an application-lockable surface format.
112 case WW3D_ZFORMAT_D32 : name="D32"; break; // 32-bit z-buffer bit depth.
113 case WW3D_ZFORMAT_D15S1 : name="D15S1"; break; // 16-bit z-buffer bit depth where 15 bits are reserved for the depth channel and 1 bit is reserved for the stencil channel.
114 case WW3D_ZFORMAT_D24S8 : name="D24S8"; break; // 32-bit z-buffer bit depth using 24 bits for the depth channel and 8 bits for the stencil channel.
115 case WW3D_ZFORMAT_D16 : name="D16"; break; // 16-bit z-buffer bit depth.
116 case WW3D_ZFORMAT_D24X8 : name="D24X8"; break; // 32-bit z-buffer bit depth using 24 bits for the depth channel.
117 case WW3D_ZFORMAT_D24X4S4 : name="D24X4S4"; break; // 32-bit z-buffer bit depth using 24 bits for the depth channel and 4 bits for the stencil channel.
118#ifdef _XBOX
119 case WW3D_ZFORMAT_LIN_D24S8 : name="D24S8LIN"; break;
120 case WW3D_ZFORMAT_LIN_F24S8 : name="F24S8LIN"; break;
121 case WW3D_ZFORMAT_LIN_D16 : name="D16LIN"; break;
122 case WW3D_ZFORMAT_LIN_F16 : name="F16LIN"; break;
123#endif
124 }
125}
126
127// extract the luminance from the RGB using the CIE 709 standard
128unsigned char RGB_to_CIEY(Vector4 color)
129{
130 float lum=0.2126f*color.X + 0.7152f*color.Y + 0.0722f*color.Z;
131 return (unsigned char) (255.0f*lum);
132}
133
134void Vector4_to_Color(unsigned int *outc,const Vector4 &inc,const WW3DFormat format)
135{
136 // convert to ARGB 32-bit
137 unsigned int color=DX8Wrapper::Convert_Color(inc);
138 unsigned char *argb=(unsigned char*) &color;
139 unsigned char r,g,b,a,lum;
140
141 switch (format)
142 {
143 case WW3D_FORMAT_R8G8B8:
146 *outc=color;
147 break;
149 r=argb[1] >> 3;
150 g=argb[2] >> 2;
151 b=argb[3] >> 3;
152 *outc=(r << 11) | (g<<5) | b;
153 break;
156 a=argb[0] >> 7;
157 r=argb[1] >> 3;
158 g=argb[2] >> 3;
159 b=argb[3] >> 3;
160 *outc=(a<<15) | (r<<10) | (g<<5) | b;
161 break;
162
165 a=argb[0] >> 4;
166 r=argb[1] >> 4;
167 g=argb[2] >> 4;
168 b=argb[3] >> 4;
169 *outc=(a<<12) | (r<<8) | (g<<4) | b;
170 break;
173 a=argb[0];
174 r=argb[1] >> 5;
175 g=argb[2] >> 5;
176 b=argb[3] >> 6;
177 *outc=(a<<8) | (r<<5) | (g<<2) | b;
178 break;
179 case WW3D_FORMAT_A8:
180 *outc=argb[0];
181 break;
182 case WW3D_FORMAT_L8:
183 lum=RGB_to_CIEY(inc);
184 *outc=lum;
185 break;
186 case WW3D_FORMAT_A8L8:
187 a=argb[0];
188 lum=RGB_to_CIEY(inc);
189 *outc=(a<<8) | lum;
190 break;
191 case WW3D_FORMAT_A4L4:
192 a=argb[0] >> 4;
193 lum=RGB_to_CIEY(inc);
194 lum=lum>>4;
195 *outc=(a<<4) | lum;
196 break;
197 default:
198 WWASSERT(0);
199 }
200}
201
202void Color_to_Vector4(Vector4* outc,const unsigned int inc,const WW3DFormat format)
203{
204 WWASSERT(outc);
205
206 unsigned char *argb=(unsigned char*) &inc;
207 unsigned char a,r,g,b;
208 a=r=g=b=0;
209
210 switch (format)
211 {
215 a=argb[0];
216 r=argb[1];
217 g=argb[2];
218 b=argb[3];
219 break;
221 r=argb[1]<<3;
222 g=argb[2]<<2;
223 b=argb[3]<<3;
224 break;
227 a=argb[0]<<7;
228 r=argb[1]<<3;
229 g=argb[2]<<3;
230 b=argb[3]<<3;
231 break;
233 a=argb[0]<<4;
234 r=argb[1]<<4;
235 g=argb[2]<<4;
236 b=argb[3]<<4;
237 break;
238 case WW3D_FORMAT_R3G3B2:
239 r=argb[1]<<5;
240 g=argb[2]<<5;
241 b=argb[3]<<6;
242 break;
243 case WW3D_FORMAT_A8:
244 a=argb[0];
245 break;
247 a=argb[0];
248 r=argb[1]<<5;
249 g=argb[2]<<5;
250 b=argb[3]<<6;
251 break;
253 r=argb[1]<<4;
254 g=argb[2]<<4;
255 b=argb[3]<<4;
256 break;
257 default:
258 WWASSERT(0);
259 }
260 outc->X=r/255.0f;
261 outc->Y=g/255.0f;
262 outc->Z=b/255.0f;
263 outc->W=a/255.0f;
264}
265
266// ----------------------------------------------------------------------------
267//
268// Utility function for determining WW3D format from TGA file header.
269//
270// ----------------------------------------------------------------------------
271
272void Get_WW3D_Format(WW3DFormat& dest_format,WW3DFormat& src_format,unsigned& src_bpp,const Targa& targa)
273{
274 Get_WW3D_Format(src_format,src_bpp,targa);
275 dest_format=src_format;
276 if ((dest_format==WW3D_FORMAT_P8) || (dest_format==WW3D_FORMAT_L8)) {
277 dest_format=WW3D_FORMAT_X8R8G8B8;
278 }
279 dest_format=Get_Valid_Texture_Format(dest_format,false); // No compressed destination format if reading from targa...
280
281}
282
283void Get_WW3D_Format(WW3DFormat& src_format,unsigned& src_bpp,const Targa& targa)
284{
285 // Guess the format from the TGA Header bits:
286 src_format = WW3D_FORMAT_UNKNOWN;
287 src_bpp=0;
288 switch (targa.Header.PixelDepth) {
289 case 32: src_format = WW3D_FORMAT_A8R8G8B8; src_bpp=4; break;
290 case 24: src_format = WW3D_FORMAT_R8G8B8; src_bpp=3; break;
291 case 16: src_format = WW3D_FORMAT_A1R5G5B5; src_bpp=2; break;
292 case 8:
293 src_bpp=1;
294 if (targa.Header.ColorMapType == 1) src_format = WW3D_FORMAT_P8;
295 else if (targa.Header.ImageType == TGA_MONO) src_format = WW3D_FORMAT_L8;
296 else src_format = WW3D_FORMAT_A8;
297 break;
298 default:
299 WWDEBUG_SAY(("TextureClass: Targa has unsupported bitdepth(%i)\n",targa.Header.PixelDepth));
300// WWASSERT(0);
301 break;
302 }
303}
304
305// ----------------------------------------------------------------------------
306//
307// Utility function for determining valid WW3D format
308//
309// ----------------------------------------------------------------------------
310
311WW3DFormat Get_Valid_Texture_Format(WW3DFormat format, bool is_compression_allowed)
312{
313 int w,h,bits;
314 bool windowed;
315
316 if (!DX8Wrapper::Get_Current_Caps()->Support_DXTC() ||
317 !is_compression_allowed) {
318 switch (format) {
319 case WW3D_FORMAT_DXT1: format=WW3D_FORMAT_R8G8B8; break;
320 case WW3D_FORMAT_DXT2:
321 case WW3D_FORMAT_DXT3:
322 case WW3D_FORMAT_DXT4:
323 case WW3D_FORMAT_DXT5: format=WW3D_FORMAT_A8R8G8B8; break;
324 default: break;
325 }
326 }
327 else {
328 switch (format) {
329 case WW3D_FORMAT_DXT1:
330 // NVidia hack - switch to DXT2 is there is no DXT1 support (which is disabled on NVidia cards)
331 if (!DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(WW3D_FORMAT_DXT1) &&
332 DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(WW3D_FORMAT_DXT2)) {
333 format=WW3D_FORMAT_DXT2;
334 }
335 break;
336 case WW3D_FORMAT_DXT2:
337 case WW3D_FORMAT_DXT3:
338 case WW3D_FORMAT_DXT4:
339 case WW3D_FORMAT_DXT5:
340 if (!DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(format)) format=WW3D_FORMAT_A8R8G8B8;
341 break;
342 }
343 }
344
345 if (format==WW3D_FORMAT_R8G8B8) {
347 }
348
349 WW3D::Get_Device_Resolution(w,h,bits,windowed);
350 if (WW3D::Get_Texture_Bitdepth()==16) bits=16;
351
352 // if the device bitdepth is 16, don't allow 32 bit textures
353 if (bits<=16) {
354 switch (format) {
361 case WW3D_FORMAT_L8:
362 case WW3D_FORMAT_A8:
363 case WW3D_FORMAT_P8:
364 default:
365 // Basically, anything goes here (just make sure the most common 32 bit formats are converted to 16 bit
366 break;
367 }
368
369 }
370
371 // Fallback if the hardware doesn't support the texture format
372 if (!DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(format)) {
374 if (!DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(format)) {
376 if (!DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(format)) {
377 // If still no luck, try non-alpha formats
378
380 if (!DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(format)) {
381 format=WW3D_FORMAT_R5G6B5;
382 if (!DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(format)) {
383 WWASSERT_PRINT(0,("No valid texture format found"));
384 }
385 }
386 }
387 }
388 }
389
390 return format;
391}
392
394{
395 switch (format) {
398 case WW3D_FORMAT_A8R8G8B8: return 4;
399 case WW3D_FORMAT_R8G8B8: return 3;
402 case WW3D_FORMAT_U8V8:
404 case WW3D_FORMAT_R5G6B5: return 2;
406 case WW3D_FORMAT_L8:
407 case WW3D_FORMAT_A8:
408 case WW3D_FORMAT_P8: return 1;
409
410 default: WWASSERT(0); break;
411 }
412 return 0;
413}
414
416{
417 switch (zformat)
418 {
419 case WW3D_ZFORMAT_D16_LOCKABLE: return 16; break;
420 case WW3D_ZFORMAT_D32 : return 32; break;
421 case WW3D_ZFORMAT_D15S1 : return 15; break;
422 case WW3D_ZFORMAT_D24S8 : return 24; break;
423 case WW3D_ZFORMAT_D16 : return 16; break;
424 case WW3D_ZFORMAT_D24X8 : return 24; break;
425 case WW3D_ZFORMAT_D24X4S4 : return 24; break;
426#ifdef _XBOX
427 case WW3D_ZFORMAT_LIN_D24S8 : return 24; break;
428 case WW3D_ZFORMAT_LIN_F24S8 : return 24; break;
429 case WW3D_ZFORMAT_LIN_D16 : return 16; break;
430 case WW3D_ZFORMAT_LIN_F16 : return 16; break;
431#endif
432 };
433 return 0;
434};
435
437{
438 switch (zformat)
439 {
440 case WW3D_ZFORMAT_D16_LOCKABLE: return 0; break;
441 case WW3D_ZFORMAT_D32 : return 0; break;
442 case WW3D_ZFORMAT_D15S1 : return 1; break;
443 case WW3D_ZFORMAT_D24S8 : return 8; break;
444 case WW3D_ZFORMAT_D16 : return 0; break;
445 case WW3D_ZFORMAT_D24X8 : return 0; break;
446 case WW3D_ZFORMAT_D24X4S4 : return 4; break;
447#ifdef _XBOX
448 case WW3D_ZFORMAT_LIN_D24S8 : return 8; break;
449 case WW3D_ZFORMAT_LIN_F24S8 : return 8; break;
450 case WW3D_ZFORMAT_LIN_D16 : return 0; break;
451 case WW3D_ZFORMAT_LIN_F16 : return 0; break;
452#endif
453 };
454 return 0;
455};
#define WWASSERT
#define TGA_MONO
Definition TARGA.H:88
static const DX8Caps * Get_Current_Caps()
Definition dx8wrapper.h:536
static Vector4 Convert_Color(unsigned color)
Definition dx8wrapper.h:958
Definition TARGA.H:260
TGAHeader Header
Definition TARGA.H:287
float Y
Definition vector4.h:67
float Z
Definition vector4.h:68
float X
Definition vector4.h:66
float W
Definition vector4.h:69
static int Get_Texture_Bitdepth()
Definition ww3d.cpp:1979
static void Get_Device_Resolution(int &set_w, int &set_h, int &get_bits, bool &get_windowed)
Definition ww3d.cpp:670
unsigned Get_Num_Depth_Bits(WW3DZFormat zformat)
void Vector4_to_Color(unsigned int *outc, const Vector4 &inc, const WW3DFormat format)
void Color_to_Vector4(Vector4 *outc, const unsigned int inc, const WW3DFormat format)
unsigned char RGB_to_CIEY(Vector4 color)
unsigned Get_Bytes_Per_Pixel(WW3DFormat format)
unsigned Get_Num_Stencil_Bits(WW3DZFormat zformat)
WW3DFormat Get_Valid_Texture_Format(WW3DFormat format, bool is_compression_allowed)
void Get_WW3D_ZFormat_Name(WW3DZFormat format, StringClass &name)
Get W3D depth stencil format string name.
void Get_WW3D_Format(WW3DFormat &dest_format, WW3DFormat &src_format, unsigned &src_bpp, const Targa &targa)
void Get_WW3D_Format_Name(WW3DFormat format, StringClass &name)
WW3DFormat
Definition ww3dformat.h:75
@ WW3D_FORMAT_R5G6B5
Definition ww3dformat.h:80
@ WW3D_FORMAT_X8L8V8U8
Definition ww3dformat.h:95
@ WW3D_FORMAT_DXT3
Definition ww3dformat.h:98
@ WW3D_FORMAT_R3G3B2
Definition ww3dformat.h:84
@ WW3D_FORMAT_L8
Definition ww3dformat.h:90
@ WW3D_FORMAT_DXT2
Definition ww3dformat.h:97
@ WW3D_FORMAT_X4R4G4B4
Definition ww3dformat.h:87
@ WW3D_FORMAT_A4L4
Definition ww3dformat.h:92
@ WW3D_FORMAT_P8
Definition ww3dformat.h:89
@ WW3D_FORMAT_X8R8G8B8
Definition ww3dformat.h:79
@ WW3D_FORMAT_A8
Definition ww3dformat.h:85
@ WW3D_FORMAT_DXT5
Definition ww3dformat.h:100
@ WW3D_FORMAT_UNKNOWN
Definition ww3dformat.h:76
@ WW3D_FORMAT_L6V5U5
Definition ww3dformat.h:94
@ WW3D_FORMAT_DXT4
Definition ww3dformat.h:99
@ WW3D_FORMAT_A8R3G3B2
Definition ww3dformat.h:86
@ WW3D_FORMAT_A8P8
Definition ww3dformat.h:88
@ WW3D_FORMAT_R8G8B8
Definition ww3dformat.h:77
@ WW3D_FORMAT_DXT1
Definition ww3dformat.h:96
@ WW3D_FORMAT_A4R4G4B4
Definition ww3dformat.h:83
@ WW3D_FORMAT_A8R8G8B8
Definition ww3dformat.h:78
@ WW3D_FORMAT_A1R5G5B5
Definition ww3dformat.h:82
@ WW3D_FORMAT_X1R5G5B5
Definition ww3dformat.h:81
@ WW3D_FORMAT_U8V8
Definition ww3dformat.h:93
@ WW3D_FORMAT_A8L8
Definition ww3dformat.h:91
WW3DZFormat
Definition ww3dformat.h:106
@ WW3D_ZFORMAT_D16_LOCKABLE
Definition ww3dformat.h:108
@ WW3D_ZFORMAT_D24X4S4
Definition ww3dformat.h:114
@ WW3D_ZFORMAT_D32
Definition ww3dformat.h:109
@ WW3D_ZFORMAT_D24X8
Definition ww3dformat.h:113
@ WW3D_ZFORMAT_D24S8
Definition ww3dformat.h:111
@ WW3D_ZFORMAT_D16
Definition ww3dformat.h:112
@ WW3D_ZFORMAT_D15S1
Definition ww3dformat.h:110
#define WWASSERT_PRINT(expr, string)
Definition wwdebug.h:135
#define WWDEBUG_SAY(x)
Definition wwdebug.h:114