|
|
#include <stdio.h>$ F$ {& G' L" a* M
#include <stdlib.h>* j# X7 s3 \/ a& A; z
#include <string.h>% j, V1 I1 a; D. }7 K3 G2 _
#include <windows.h>' ~* k1 B/ W6 F8 {4 E
#include <GL/gl.h>
/ T- |: ~* T" ?$ E0 ]( O+ Q& ?2 {; f" o7 x3 T) Q$ S& C0 z
class tgaImageFile
- b1 }: ]" P1 j0 A' N{
( H4 {& x! r2 fpublic:
4 u ?1 e. ]1 k
A4 _5 M% y& U) W- r* K; QtgaImageFile(void) : * y6 ^, Q8 ^1 G+ b3 f% _# _
m_texFormat(-1),7 L; u9 g# ?+ H; U) K( b
m_nImageWidth(0),
w4 {6 N/ s, Fm_nImageHeight(0),
; G$ X8 [) _- S% V2 Q, @ Km_nImageBits(0),
9 P+ o3 W7 D1 S2 B' wm_nImageData(NULL) {}
- A! S- e/ t1 T0 s! B+ q
, I( o+ [" p: L~tgaImageFile(void);6 |2 a: \% x7 Q# K- `9 Q
% H6 b% E: X7 e' f; h
enum TGALoadError! I. P3 ^9 A3 G% x, y
{
- e! a3 s% Q9 x3 VTGA_NO_ERROR = 1, // No error# P* C" T1 v4 B& h4 ~" R
TGA_FILE_NOT_FOUND, // File was not found
2 S/ h4 G9 F. L1 b$ K6 \2 vTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
: z _3 K; \0 D/ D8 ^3 S+ ?2 oTGA_BAD_DIMENSION, // Dimension is not a power of 2 7 B% ?' B W6 n& n0 e* d
TGA_BAD_BITS, // Image bits is not 8, 24 or 32
+ M& Z' w! j& x, M$ U- HTGA_BAD_DATA // Image data could not be loaded
- U+ L! O5 R8 x9 }4 B& L };8 L" t' A$ R2 `6 L
2 w& }' }' A% J! x0 |+ V8 ^tgaImageFile::TGALoadError load( char *name );. h( u/ V* l+ x) o
3 Z3 B# d: d" v: R1 C
GLenum m_texFormat;- W& u+ y$ y c9 @7 h$ A
int m_nImageWidth;
6 |+ N" i6 I* }3 _" Qint m_nImageHeight;
% P5 k+ n% Y, ^; W T$ o$ ?int m_nImageBits;
& U; ~* J- [/ Y, @5 \- W& g4 w! @$ Zunsigned char * m_nImageData;
% @/ \, _) s* X3 E2 g0 P! L [6 r' u! y( U
private:
1 q8 {5 j" b4 A) a* N P3 _+ r& b! N2 Q) P: p4 g G1 _$ J! ]
bool checkSize(int x);
% m* y0 n% {- D' Kint returnError(FILE *s, int error);
0 i5 z+ C4 L0 L" g" C1 n4 Cunsigned char *getRGBA(FILE *s, int size);
. M- W3 J ~7 w0 K4 uunsigned char *getRGB(FILE *s, int size);
5 {# _# X- e, o7 _) C# P) y" q6 Punsigned char *getGray(FILE *s, int size);
. J& x: ~* F5 ^# Z# w# U4 J};
! M9 z, J# S$ S- r' J2 A$ L: D3 O) C4 V6 U7 [
tgaImageFile::~tgaImageFile( void ): y5 A) @" b" _9 g& r5 e3 H, G
{
2 D, d7 G. @" Z3 G( F; tif( m_nImageData != NULL )
! y# p2 F. N, t{
$ m0 ^4 ?$ |) j7 n/ X. Wfree( m_nImageData );5 j9 L' H( n3 ?
m_nImageData = NULL;1 I a, }" V& M) r2 ~
}+ _$ L# l: J- U8 G
}
: I( @ _" |% o9 T) w& H& U, [4 i0 H# K" V V: E3 V
bool tgaImageFile::checkSize( int x )2 {+ Y. X0 [# D
{
4 ^. O, \' G* m+ t$ t& R/ v// Make sure its a power of 2.
- f) ^4 J8 _& o+ [if( x == 2 || x == 4 || 2 I7 V7 X% ~, t9 f! D
x == 8 || x == 16 ||
. J$ u* p7 L- C P0 W: {x == 32 || x == 64 ||
" o2 [4 \ o8 q8 g! |* q1 O% M! ex == 128 || x == 256 ||
1 d) [! u) T$ o5 G5 J( Bx == 512 )
5 F$ S% d+ O8 \% [( greturn true;% z, Z3 g1 g: k6 s) p: C/ D K
9 i/ `& Z( R+ T# a+ o+ T- B$ a
return false;
; `4 E' N+ Y: Y5 Z}9 y/ l, }) |8 P9 w/ I' B* G+ I. k
. V: N' q- B2 q5 U& q: H/ b
int tgaImageFile::returnError( FILE *s, int error )
% n& R5 h. k$ [' ]% D" P# l{
0 S2 R$ r) y, t6 \// Called when there is an error loading the .tga texture file.* X8 W% D- p4 J+ O" U! C6 V/ @
fclose( s );# i' n2 r# v# K! |" `
return error;
; h/ ?8 {* I9 ^$ |( ]0 U0 v}
$ I2 Y/ ?# a# ?, j/ l
) \; S7 A6 E4 S( M1 ^' tunsigned char *tgaImageFile::getRGBA( FILE *s, int size )$ V U) \& q9 _2 J! Y9 Z. |, F a
{. K' N$ D+ h+ _ Z6 _* Y' i
// Read in RGBA data for a 32bit image. ' e0 z1 B) D- h4 [1 E
unsigned char *rgba;$ |2 E) v' R& E$ ^4 B
unsigned char temp;7 ` d7 C$ {; V$ H Z
int bread;' D( `! W% o3 X& {+ P! [# x
int i;# J Z# o4 t0 f
8 l" t& ?9 {7 _" H
rgba = (unsigned char *)malloc( size * 4 );
5 L8 d) v" B) W( ]/ _6 j2 O2 r- R, e, B2 F, [0 V
if( rgba == NULL )
* J, n3 J5 E" v& u/ breturn 0;. o( I9 U0 G4 Q8 U4 S* _ m6 r P/ M
4 n9 f# B2 P) ]1 N' L+ h& T# X
bread = fread( rgba, sizeof (unsigned char), size * 4, s ); / Q D0 P) D3 w f
! a* I/ Z: l2 Q. {& M// TGA is stored in BGRA, make it RGBA 8 Z' V: x! p2 ^0 T' V% T! Q) g) n7 H" r
if( bread != size * 4 )$ i* H! {/ L5 L7 X1 ]
{$ w( m, m; p6 j4 z. M4 d
free( rgba );
, Z: Q1 F" B1 v9 o; ereturn 0;; [ g$ u- v0 k
}: |! w5 T( h) Y) O o: J
" f% @' P, s& |
for( i = 0; i < size * 4; i += 4 )
9 h6 @- Q9 e Z* F9 @0 K! f{; T' F& q8 W9 ?0 G
temp = rgba[i];9 q: |1 p- S% n
rgba[i] = rgba[i + 2];; \/ V3 |- Z+ h% Z# z4 F
rgba[i + 2] = temp;1 b% g3 _; t0 W1 P _0 M
}
. z2 o, L! C' l& ]5 f1 { P% G, Q: J1 x$ }4 A; K9 E- O
m_texFormat = GL_RGBA;
/ [, F& L1 R. ]8 Vreturn rgba;
1 K- e; i5 Y- K}- j3 d% ~* B% j" z6 O3 ~8 t. V
9 O3 c7 w; }8 d
unsigned char *tgaImageFile::getRGB( FILE *s, int size )
0 P3 N3 j; V/ P# H( K{
" N: X% [5 q# j// Read in RGB data for a 24bit image.
- \# Y7 n7 ~4 i' i% y% i- Iunsigned char *rgb;1 C4 c$ u3 I+ c. o
unsigned char temp;
3 f( p; }: L# q, F+ ~int bread;2 @9 Y6 L1 X$ ]5 u( n7 Q9 P9 q4 H
int i;+ H+ Y4 s+ K" ~0 v5 v: h( p! a
- j4 \# a* [" t: Argb = (unsigned char*)malloc( size * 3 );$ C# e& h# o6 }
6 x9 R4 M4 V1 G# l& Y+ _+ K
if( rgb == NULL )
+ ^/ g( J8 d- Q9 \return 0;2 C4 u# e1 X% x$ h. U4 n4 Y& U9 F
6 v6 Q& ?$ f' ubread = fread( rgb, sizeof (unsigned char), size * 3, s );
: S5 `8 W# w9 \) ~$ E7 K, K s
8 `* R) H% J1 C/ i( x( n+ Yif(bread != size * 3)
- |% r; Q7 c- d% @{" j V) k' t- W1 p% Q) x
free( rgb );
) O2 j% {' A% u9 S" f- c; O6 |return 0;! l3 h ?4 r) b9 C) a
}
/ x. U3 p( s: _
* o; y6 E e7 H; I// TGA is stored in BGR, make it RGB
# u& t) c& z7 Z: M$ t8 p3 qfor( i = 0; i < size * 3; i += 3 )
( l0 R) K$ B5 g# c! ^# d* L{7 V. }& O# O6 k X3 C/ M
temp = rgb[i];
% A2 k- e% K1 Z3 @' O' ^' Hrgb[i] = rgb[i + 2];
2 u' V+ J7 n8 f6 L& i. Z; crgb[i + 2] = temp;
4 ?2 a) w8 b ~}
. x1 x& m- H, J5 e& N% y2 b* L, b0 x1 P( `1 {
m_texFormat = GL_RGB;8 c; ]1 y4 R3 ^; J5 a
4 b. B; j \5 Q' {. a8 o6 @0 H5 w2 Dreturn rgb;+ i9 w" Y0 M3 f( }5 t
}
4 z9 o* p) ? q+ k2 M# N8 O9 N- u, R6 C! X5 X
unsigned char *tgaImageFile::getGray( FILE *s, int size )8 G& f" c$ y6 Q7 M0 l
{
7 {6 q; x+ _/ ?. G$ t4 B) G& ^/ ^// Gets the grayscale image data. Used as an alpha channel.4 x: C/ Y! O3 u
unsigned char *grayData;
' j, X z% G, v5 \5 D( ?1 \int bread;
( M5 D+ u5 {' j8 X h& Q% j' x7 w/ |: m1 e+ b3 b ?# `
grayData = (unsigned char*)malloc( size );7 l& L$ \" S+ ?, u2 P1 Q
& F' Q+ C. i- b1 T( U% o6 cif( grayData == NULL )
0 j3 V2 a. Y- wreturn 0;
0 [% w6 O+ n6 ?7 p% |2 H2 ]. z h2 M3 ~# w! m, o
bread = fread( grayData, sizeof (unsigned char), size, s );
' I( A/ _. d' |* V1 s- h
7 z1 ]/ L7 m( M8 ~9 hif( bread != size ). }# h! W9 Q( x, l: r2 m' F2 t ?
{. v, c- g- e- G" W
free( grayData );
# F6 _4 O/ u% x2 ereturn 0;! s0 @4 `- a2 h" e% k8 T
}
- L) {5 |3 y) D% K; v
1 M# E' \( T4 V" g* ]. {m_texFormat = GL_ALPHA;
& ?; g, z! T/ o* Z; x+ }" v8 ~: Z+ \! c. ^8 q
return grayData;* j5 j; x" b- v. ] t2 a. O* c% y
}
% r2 _2 ?& N! d$ P
; ^4 |2 ^ V2 q1 M1 A" PtgaImageFile::TGALoadError tgaImageFile::load( char *name ) A1 U- ]/ D, l9 j# d
{$ V! a# m T' I$ P/ {6 X( E
// Loads up a targa file. Supported types are 8, 24 and 32
, _$ Y' `% I+ m( ^: o% i X// uncompressed images.
% a+ {, k6 m2 G8 O* E2 ~6 Lunsigned char type[4];
5 O; U& X, j% g8 V; o" ?- dunsigned char info[7];0 D& J ~& `) }1 B
FILE *s = NULL;$ ~2 ^ u+ {; z- L
int size = 0;
+ @- B/ y9 c( g8 |2 \' @. P3 e; ^1 `. t+ a L8 D/ ]
if( !(s = fopen( name, "rb" )) )
$ h" g2 o5 |) `return TGA_FILE_NOT_FOUND;6 Z: Y2 H: J( r7 Y& L
6 a- A6 k0 G. o% _# ]# efread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored7 }& V, B5 O6 i
fseek( s, 12, SEEK_SET); // Seek past the header and useless info3 s* y4 U% N( Q, ?& p
fread( &info, sizeof (char), 6, s );: Y+ h' F. B- }3 ]7 |4 J
1 k+ X+ v+ R" c; S. H% Zif( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
0 h1 y9 ?3 c1 i2 j3 q: g9 areturnError( s, TGA_BAD_IMAGE_TYPE );
& F+ _5 B3 o% ]3 l; }
2 X" |; ^$ K i+ km_nImageWidth = info[0] + info[1] * 256; 3 K( N( H2 |. j8 v* @
m_nImageHeight = info[2] + info[3] * 256;
* p" K* a% g" i" w" tm_nImageBits = info[4];
" H) p. {& X; }
d) j+ Q! R1 I$ w4 f- N7 ~6 lsize = m_nImageWidth * m_nImageHeight;; `! E x% D1 }
- E. y- T: L/ o% `! @( B& ?// Make sure dimension is a power of 2 ( \: S j* r* D/ l' d: F
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))9 v- Z& t1 x9 I2 k2 V
returnError( s, TGA_BAD_DIMENSION);
+ n! h$ ]' |+ b4 z- M
' ]8 M0 q5 o6 O* w6 N8 r8 a8 y' m4 v// Make sure we are loading a supported type
2 m U" K% k* b) F1 Eif( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
, [, `6 ?; {7 q0 f/ mreturnError( s, TGA_BAD_BITS );
; v# b8 y8 I: p' s% D7 P! K& Q1 l# }4 B- l& F2 O3 k ^
if( m_nImageBits == 32 )7 n) F) `/ h; }6 _) L& b+ S! v; p
m_nImageData = getRGBA( s, size );
5 `, a* R, \- F* q8 j0 U6 T' velse if( m_nImageBits == 24 )
1 k. g G& _( t4 S; z* n+ I X6 H7 dm_nImageData = getRGB( s, size ); 5 e* W" ?3 V4 y- ^8 `
else if( m_nImageBits == 8 )7 S3 l8 x" R7 z6 H$ u
m_nImageData = getGray( s, size );
; q8 a8 F6 w" k. Y7 c$ u' b( C/ v8 w; U% n* S5 T. j
// No image data # H3 z) X0 g/ k
if( m_nImageData == NULL )
6 F% E, U4 `% ~returnError( s, TGA_BAD_DATA );
( U J. G- {8 @# Q
- p) ?6 [5 k- d; T$ c& i+ ]fclose( s );' C- z4 h4 W; K& ?3 s
( {3 o! Q, f* H; G1 kreturn TGA_NO_ERROR;
; B- N) g+ u3 \" g) l2 `# P+ U: R& g}) b/ u: @0 t( P0 i0 A
* P4 V! }0 j5 p9 y$ p
J/ s( o4 c7 q# v2 g调用举例:
% Z) B' ?, H" Q! t% e+ L/ Q+ J3 f) O//- { v% p5 F, P) C
// For the billboard poly, load a texture of a steel sphere. We'll use a " f& }8 u# f6 A1 X, I
// .tga file for this image so we can use an alpha channel.+ n- r. Z& x! z& j: n2 M
// P5 F+ _, B/ E9 H
0 D1 } [+ C$ B2 q" d. A& h3 T
tgaImageFile tgaImage;# h/ ]+ c: A4 _2 e+ d' C
tgaImage.load( "steel_sphere.tga" );
2 O A4 `& i& J# S$ x9 W3 I- s8 ?- {+ H
glGenTextures( 1, &g_sphereTextureID ); p r" P! Q. u, c8 e+ B1 G3 _) K) s% v
9 S: e6 p9 T# l& B
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
) j5 \8 \5 J) C6 M, N* [8 v+ W- E" h. t- S( v7 [( B
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );. j9 T$ W- W* `/ ~. S
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
4 C4 A4 F+ g& l: A* h( F: ^4 e) L" d0 s
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, / y1 {% J1 S! {" ^. L( P; n
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, " T5 ?- R7 u! \5 D! A
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, # S) G' z$ g1 n( m! l( ]( c) k: b
tgaImage.m_nImageData );[/i][/i][/i][/i] |
|