|
|
#include <stdio.h>
( r" s7 C ^# y2 s: v Q#include <stdlib.h>
+ f v& \' }) C2 {#include <string.h>
, [9 y! y1 d- K9 K5 l, X4 B#include <windows.h>
& d& y1 ^$ j) A. V) Q: n' ~#include <GL/gl.h>3 P& e& X! ^* T3 k/ g+ ~8 m+ r
& {6 T! m' X) h2 e1 R# t' `class tgaImageFile, J$ t' b) Z1 f1 [$ u; j- C
{' e4 ]. a6 a" X: Z6 ^1 d
public:
6 ?) x* P5 ]8 N' y
+ y/ v9 f& n9 s& ?- {& R) OtgaImageFile(void) : ! F6 @) t# ^! ` D" N& U
m_texFormat(-1),' A/ r; K% t& }7 q
m_nImageWidth(0),; i6 u- ?* W, J( L6 \
m_nImageHeight(0),8 _( R3 x5 ~) I4 x0 I8 h5 h
m_nImageBits(0), |4 Q* X+ [1 R) h
m_nImageData(NULL) {}3 e" T% c1 M2 K
o, _0 O: [! n9 I6 |: v3 M
~tgaImageFile(void);
0 r8 ~# y% g" F* _! b
_: d7 x* K1 oenum TGALoadError& E) z8 i% g( L$ k; Z* \
{/ {2 G# u$ X' K* [& X+ Q: s
TGA_NO_ERROR = 1, // No error
; Q Y# X2 ~0 ?- KTGA_FILE_NOT_FOUND, // File was not found 9 l5 _ J M0 Y& [
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed( d+ H* h( I" W
TGA_BAD_DIMENSION, // Dimension is not a power of 2 ) a* S) ] O5 @& V$ o; Z# e
TGA_BAD_BITS, // Image bits is not 8, 24 or 32
6 c2 u& L% q6 C' }0 _3 NTGA_BAD_DATA // Image data could not be loaded
4 x0 p; D8 H( B8 R };, m- f. l( A; p- v& a
, |: [7 d, v( t9 G% [
tgaImageFile::TGALoadError load( char *name );
7 O! p! o- Y* F, c
: A; A' e8 O/ |$ U* f$ K6 [GLenum m_texFormat;( m8 E6 L, v& k9 `# o
int m_nImageWidth;' p2 {" T+ Y" G& S, [/ q
int m_nImageHeight;
9 ?; S$ a2 N; E3 J. {int m_nImageBits;
8 V3 n2 }* w6 _0 C( ~" Qunsigned char * m_nImageData;% p: F; K a6 `. ^# g0 }* l0 D N" r; b
, U' y( r; ~9 [3 E5 O2 gprivate:
/ J- n( p% K. r0 ?, g2 y3 T8 L/ a) ^- H
bool checkSize(int x);: d) t8 s7 [1 L1 L
int returnError(FILE *s, int error);
; ~& X7 P4 I) t& I4 m1 A: a1 z7 lunsigned char *getRGBA(FILE *s, int size);) _+ W; r; c3 X
unsigned char *getRGB(FILE *s, int size);& P& G6 w ]6 {6 [* ~
unsigned char *getGray(FILE *s, int size);7 ^& d0 h; T+ `2 m0 C% L' j
};
( E; h% m) Z0 R3 P. i6 {, A$ \/ P$ B0 t
tgaImageFile::~tgaImageFile( void )/ A9 t8 h$ s) a) Q4 M0 n# o; J Y
{
# l$ b, g. @5 U7 }+ u6 D9 mif( m_nImageData != NULL )
% L$ a- h2 W0 k7 g3 l4 Y3 l{- ?# W3 Q# z8 o _- I* T0 A# L
free( m_nImageData );% d5 u. R0 `2 g! i2 U0 c
m_nImageData = NULL;, v! M. Y% o$ {& S
} O& m4 L Z* z9 ]
}
) F) Z' c1 u# D* P
' q6 Q- _. ]0 O5 t% Z0 d. K$ |bool tgaImageFile::checkSize( int x )
3 @% ^% F( W& O3 Z: A1 M{
3 m" k6 g5 W$ X! J// Make sure its a power of 2.
) w5 f1 r$ ^5 k' S# j3 z: Dif( x == 2 || x == 4 || ) d# b4 J& P, o9 w w1 U
x == 8 || x == 16 || - J( r+ H k' @' ]
x == 32 || x == 64 ||
5 Q9 z2 x G$ g0 F2 M3 ox == 128 || x == 256 || & f, K6 r" `, y: F
x == 512 )5 d; R- e P3 f: R' v: u9 W# y
return true;0 u$ @, i3 b3 s
) G% T E; l4 E: @8 creturn false;$ o, ] v; ?5 M0 ~9 j7 e
}# y9 \5 p$ z V
9 n7 b3 u u* F- I+ E0 G( j
int tgaImageFile::returnError( FILE *s, int error )
8 e, P \" |# ~7 z{
. u) f/ z ?3 P: V+ Y y// Called when there is an error loading the .tga texture file.
5 e/ I) q% R: z3 |fclose( s );/ D2 O7 {0 y. n, D H
return error;1 [% H+ I P1 }1 c7 ?# W }8 S c0 |
}
( Q. Y9 y% p' y% Q9 S
8 F0 F% A$ H& i7 _unsigned char *tgaImageFile::getRGBA( FILE *s, int size )# d! m3 v1 |7 }/ X8 e: B' Q
{- d3 C5 w) s# S" s
// Read in RGBA data for a 32bit image. ; x- |) k/ @& m' U' `; p
unsigned char *rgba;
0 A$ {1 W$ w6 I* Vunsigned char temp;; @% O. Z6 I) X: k; A' u
int bread;
3 V v" z" L6 K7 j- ~int i;+ g' U" ]6 S- e2 Q1 ?
! E) p8 r# D: d8 K9 ~rgba = (unsigned char *)malloc( size * 4 );* O0 Y; \0 D: h7 d7 p$ b5 @
8 t4 I5 g! i# r8 K% A% F' S1 nif( rgba == NULL )* E2 a; K1 n6 L6 S. p
return 0;" k4 y& A8 ?/ E" h
@, `5 K4 g) H5 P: C
bread = fread( rgba, sizeof (unsigned char), size * 4, s );
! l( D/ q) a2 V# t& Q' d- ^# p
) `+ l/ a4 S! {1 ?1 l6 j7 I! P// TGA is stored in BGRA, make it RGBA
1 U) o1 ?8 ^$ e" O* x' hif( bread != size * 4 )* Y/ _ Z/ [" P# W% L) v
{
9 }/ f9 C3 f# E. i; tfree( rgba );
) h# O. H" v# _$ T& L* u2 X) ?% ~return 0;
2 L1 o$ l H/ k}* c8 j2 @0 L, j5 ?$ q
/ k; h/ ? N7 p' s! g* Nfor( i = 0; i < size * 4; i += 4 )
0 r% w! h0 ~$ W8 N) k* Q0 ~& i{5 c# X! o1 k( R7 H5 ]! Y- O" I
temp = rgba[i];
/ o! r( {; ?8 J. X8 P# h0 K2 Grgba[i] = rgba[i + 2];9 \8 p) `- w" q
rgba[i + 2] = temp;
" K8 l& s, q( s3 |}% K' r% D+ [% u* O9 z
8 m4 S" `7 N% f9 P; t1 P- b9 N
m_texFormat = GL_RGBA;& }/ o" c; j" p
return rgba;
- Y j) Q2 ]4 }4 r}+ c# I! @( x# G! E
; o" }( [: _: t8 l& a- g' h) k# zunsigned char *tgaImageFile::getRGB( FILE *s, int size )) [/ u9 H& v+ }, ]
{7 \/ S% F; U4 e H/ `: r& m. E" z/ s
// Read in RGB data for a 24bit image. 0 S% R3 l( l6 N( z- z
unsigned char *rgb;
5 x$ p% W" H) J' vunsigned char temp;5 A9 T* K% F( T, \! ]* P
int bread;- k( }( D& ~& t
int i;
1 J) I; j% @1 N* y0 B e
: i0 g7 P+ Q7 f/ U* A: \rgb = (unsigned char*)malloc( size * 3 );
& o* { |$ g5 t! \6 x
& `5 A8 _3 |' Z" M6 L/ O/ qif( rgb == NULL )6 ^, N+ f0 o- W
return 0;
J& [7 S! U3 }. G4 e6 Q
9 }* r4 v# G8 q( Bbread = fread( rgb, sizeof (unsigned char), size * 3, s );' U( @" x! o% g* }% ^9 Z. m
2 l o& q& {" p. i7 `" @6 vif(bread != size * 3)2 ?4 C: a$ j1 k) K2 e$ i; O
{) J; w5 K9 P% W
free( rgb );
0 ?5 m, C) G: J ]return 0;- @2 i1 ~% N% H) q$ L
}0 \/ ?+ V% Y2 N5 Q
1 E/ B( b- L$ m9 V1 d! d+ x L// TGA is stored in BGR, make it RGB $ w8 T( V" V) `) |7 d
for( i = 0; i < size * 3; i += 3 )% G3 e/ b* h$ p7 i/ h# ~, N
{. [5 X5 t S/ C/ [2 Y) l1 P
temp = rgb[i];6 u, g) Y4 D! G. V. q/ F/ m
rgb[i] = rgb[i + 2];9 G9 i5 e9 B) {9 i4 D
rgb[i + 2] = temp;9 M1 {& W" J9 a x+ F l
}) R) f9 r+ G8 ~
5 r% X I+ T6 N9 y8 \% h" f8 y* |
m_texFormat = GL_RGB;& W* N+ C! K7 z4 N$ ]+ }% L# C6 Q
) l# G q8 J& w& }, I
return rgb;8 y* |! R- t1 r
}. o& B$ w+ p2 m' A. ^/ P1 Z6 E
' s: Q9 s4 M5 |$ J5 v
unsigned char *tgaImageFile::getGray( FILE *s, int size )1 D8 E6 Z% H8 a$ ?
{' H" |+ {3 \7 R- H# s3 M
// Gets the grayscale image data. Used as an alpha channel.
. Y8 F8 J1 S& F; M8 Aunsigned char *grayData; Q9 O5 I! c8 ~0 z3 K) k, q
int bread;
- J& S& e2 x) o. J3 E6 J+ T, W1 m: b
! l7 ?( Z# M- U$ D! K% zgrayData = (unsigned char*)malloc( size );
& E2 P0 e) K5 v& s# }+ {* h5 Y' |; N- q0 S
if( grayData == NULL )' n& P' t, {! t5 w) f3 e! W; j
return 0;
" }9 v% m( o/ D8 W% J1 d2 _' ^+ T* ?+ `1 o2 o3 F: W, N
bread = fread( grayData, sizeof (unsigned char), size, s );, E3 E$ G% J( v2 f5 Q
1 C; H5 _5 l6 \: j5 ~% H+ |if( bread != size )1 F" Y( \% }. Q& p
{ _6 I1 H* Q& M9 c" \* t
free( grayData );! f* C9 f& H0 F0 u, c
return 0;3 _; y1 W7 Z& B' e0 L3 j: _1 ^
}3 s6 X/ p$ c+ a" `. j2 x
9 O3 w; I9 E! H
m_texFormat = GL_ALPHA;. [0 e, ]4 p9 i
) s S/ \, i4 A& {" a) ~8 Y
return grayData;
$ s, O; k% J% `& c}
' b7 b* e2 U& l+ S% T+ X& F& `* z$ s
8 h' w9 e. w& v4 ZtgaImageFile::TGALoadError tgaImageFile::load( char *name )& d1 Y2 ?( j/ P5 _
{! I6 E, A7 S5 [8 Y+ n( H
// Loads up a targa file. Supported types are 8, 24 and 32
- D0 M/ q1 j4 P" m5 A; k: ~// uncompressed images. t. P1 W b/ M& @' x( h
unsigned char type[4];
1 k6 n# { E5 x1 Eunsigned char info[7];
/ m( K; B4 M$ B0 w) ~FILE *s = NULL;6 T W5 @; c) j6 Z- m: `
int size = 0;
5 ^% {: I: ^ s8 ~7 H V
2 _ _7 G5 M& P; V) v; F4 D5 ]if( !(s = fopen( name, "rb" )) )4 {5 e) [ B# K, B! Z# ^
return TGA_FILE_NOT_FOUND;, h! [6 s4 Y3 g+ O
1 \& F! T+ E6 G
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
. u9 S* ^/ Q) u0 sfseek( s, 12, SEEK_SET); // Seek past the header and useless info) P/ u4 @; k; _% _
fread( &info, sizeof (char), 6, s );
8 ~0 E4 u1 B! D9 y; q
, ~& @: o3 W& `7 bif( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
/ J. @- t; g( L, C [1 }% EreturnError( s, TGA_BAD_IMAGE_TYPE );) Z% d. C" A: }
4 v( w- W( S8 N% l8 e: x
m_nImageWidth = info[0] + info[1] * 256; : D- d, u2 X, I2 P
m_nImageHeight = info[2] + info[3] * 256;
" I ]$ @0 @/ Nm_nImageBits = info[4]; & h/ T5 p! F# Q: _
( @7 z3 s4 @ i: F; s
size = m_nImageWidth * m_nImageHeight;8 E/ j" i- l1 ^) W/ q( u. z9 o
" L& v" D( i/ {- a( P
// Make sure dimension is a power of 2 # x! F5 P5 U# a
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))
4 a7 v8 c) ~" r: U. X' \returnError( s, TGA_BAD_DIMENSION);: s# B4 h! ?' a; J! |# g
, J' e" ?: L) O* W+ S2 |! B// Make sure we are loading a supported type ) N9 r. ?6 `7 n" S8 b4 X" O" W
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 ): A& ]* R, i0 N. Z. @" T
returnError( s, TGA_BAD_BITS );( |) r: K# t8 f6 P
+ R- q2 i: v: Fif( m_nImageBits == 32 )2 g8 X& g6 a# J( K3 ^% W$ c
m_nImageData = getRGBA( s, size );
# r7 k. `/ v- D( oelse if( m_nImageBits == 24 )% a% Q. Y, v B0 \7 D- v# j
m_nImageData = getRGB( s, size );
3 C* M9 P. H! w# X; I' belse if( m_nImageBits == 8 )
. }. u* u ]6 y) S, p& Rm_nImageData = getGray( s, size );
- E6 F8 ]* B! a& @, D. N0 X. K8 R
# c8 `% h# {+ ?" n' c* O// No image data
2 m I& ^# \3 K9 A3 a; _7 e2 c% u. s" pif( m_nImageData == NULL )% \2 h2 B0 g0 N5 C
returnError( s, TGA_BAD_DATA );
P7 S' X! K2 V! w$ m6 `/ w6 \: P5 c: i8 U- u( ?
fclose( s );
p( T) L# ?3 b$ k5 _+ K3 `6 T# N$ U5 E+ b; f# p9 x
return TGA_NO_ERROR;
7 `1 a9 U2 L, p}
+ u. k5 d9 ~! C: c- A$ ^6 ]
& c" V9 I# I1 ? K: s
. A9 S% X! |2 T: d$ p, j2 L; F. w调用举例: `$ p* w) s M( \" t& B
//
/ l9 k8 }3 M- C4 T- j// For the billboard poly, load a texture of a steel sphere. We'll use a
) {/ ?# y# r; f+ w// .tga file for this image so we can use an alpha channel.% U0 s& H; b: {0 G9 \
//
) [: [' _0 P3 u+ o' r, T) \: w) _
# n5 y& T2 u3 n" s+ }tgaImageFile tgaImage;
; l$ V3 l& q3 o% \tgaImage.load( "steel_sphere.tga" );$ k7 ]' E( k: D" ~( X% L4 @& N
& N# b9 d1 G+ r& JglGenTextures( 1, &g_sphereTextureID );& A7 Y! k9 O! e% _# P, j
- L( N3 c: ]3 b; c JglBindTexture( GL_TEXTURE_2D, g_sphereTextureID );; T3 O5 n/ H |
1 M% B2 Y/ o. }# S
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
, Z8 z, J2 a3 R/ X3 o4 ?glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
3 q: Y& q# g3 u# V& B; u
. d0 q# S0 Q" G+ BglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
5 h& Y) [, W1 ?& X. a$ a/ ]tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, 8 |8 `% d$ [- d: S3 W/ T" {
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
) |3 s/ y) c2 {& C- I% HtgaImage.m_nImageData );[/i][/i][/i][/i] |
|