|
|
#include <stdio.h>
# W9 e0 @0 E! q4 } g#include <stdlib.h>/ Y d7 C6 j+ N' R9 r
#include <string.h>% X$ m: G% _* L+ F; s! k1 b
#include <windows.h>+ u3 j) g" m+ x8 ^& \9 B' e5 s8 s3 l
#include <GL/gl.h>
! g9 h3 m+ P: n9 ?9 u
/ p+ N: P! o8 I" v* J r+ s" x5 oclass tgaImageFile
" u0 [! r! X! ?7 x{2 Y7 J' ~1 G1 h2 \1 \9 S$ T' ~5 Z
public:+ H5 \0 @ ?* O
5 n0 I9 F! {- @! H/ I% ^. t' E
tgaImageFile(void) : 7 Z7 m. A% k2 r7 p+ |. u
m_texFormat(-1),
% ]- O5 G5 t. bm_nImageWidth(0),
" N. }& }" D/ em_nImageHeight(0),
# _; m( _* a% s/ }m_nImageBits(0),8 v Z. W* n. C5 ~! y/ q n7 s
m_nImageData(NULL) {}; J1 |1 O. Q' o! x4 }- C
3 x* L# B1 b, F2 z k- K~tgaImageFile(void);
9 m1 a5 x/ w, |9 e8 e$ G; m" [2 X+ g& G" h* b5 f6 ]
enum TGALoadError
# e$ k, u* ]: t$ w/ Y; p( {{8 o+ O3 Z! O- M5 H1 o( R6 q+ g: W( C
TGA_NO_ERROR = 1, // No error0 g2 l, k7 x2 ~
TGA_FILE_NOT_FOUND, // File was not found
* V# c# D7 R9 L2 {' t( hTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
6 j( x9 u6 v- ]' w) ^! ITGA_BAD_DIMENSION, // Dimension is not a power of 2
/ P! U* v6 H s2 i$ Y6 pTGA_BAD_BITS, // Image bits is not 8, 24 or 32 y7 d1 z6 Q4 d* `, P; Y% M+ Y0 @
TGA_BAD_DATA // Image data could not be loaded
2 D2 |. S2 G6 [ };
6 f" m4 Q0 P: v9 K
; F+ k" c) j% htgaImageFile::TGALoadError load( char *name );
" ?7 @! _" I& s- p5 a1 d9 O* b. O. q! y4 h, g& z5 G
GLenum m_texFormat;0 m9 a+ M2 g& n5 q. |
int m_nImageWidth;
% L6 E8 S# w( Y0 Xint m_nImageHeight;
8 G( d ~3 \- Bint m_nImageBits;! B. d( l9 `; }' g0 K- B F5 m* ?
unsigned char * m_nImageData;
- B% n2 k! q% I7 H+ U! G5 k/ Y: C( F- z6 T! u+ [+ w; F+ `. x6 M' K
private:( M; L* z3 ^2 a$ P
2 I0 ~/ K& E1 l9 [0 m& r! \. obool checkSize(int x);: @3 C7 h/ d' W% ~- V. D+ f
int returnError(FILE *s, int error);4 I! F. z( V, l( A
unsigned char *getRGBA(FILE *s, int size);
. e: B1 F4 _. x/ R7 n% Kunsigned char *getRGB(FILE *s, int size);
9 Z/ K* D1 w0 R g) T. j; k1 ]unsigned char *getGray(FILE *s, int size);8 @2 I1 R6 y" G, [3 f+ [/ h1 ^* ?+ `
};, k' |* }; h8 m0 A
! b. B& J- ]) j6 z7 C0 dtgaImageFile::~tgaImageFile( void )
! J$ u8 u. X# a. [( }6 J* v{' P3 L1 B: V! V; y
if( m_nImageData != NULL )( k8 Z! H9 j3 z* h
{
) l3 p9 C* v7 H' w* h. ]free( m_nImageData );
# C9 G4 X6 h2 Am_nImageData = NULL;1 v3 \/ z. M( r2 F* Q0 h4 C% E& ~7 B
}
6 E- A( `" V w0 c}" i" V: r" [/ P
0 i/ g6 W, e5 l6 i# g: Jbool tgaImageFile::checkSize( int x )
/ J) G- |% a2 }( R{, Z5 l3 M" K, M( E, r
// Make sure its a power of 2.' j/ l2 l/ Y4 g7 Y! U3 i9 t
if( x == 2 || x == 4 || % H0 Z1 S" x' a6 U% E# {: }3 O
x == 8 || x == 16 ||
9 y, t" ~' N7 `x == 32 || x == 64 ||! h( B: r5 D+ L2 q: `) `
x == 128 || x == 256 || / r* h1 v! ?" U- ~2 s: m8 S1 t
x == 512 )/ L3 F6 `1 k0 d/ i& |1 X2 T/ S% _
return true;2 g0 T' u# W' X/ m k2 u) D* b
" ?( ^! j& R& I* @* n9 f- y
return false;
! Z# B5 c; Y. n} h4 A+ j) b) h+ n8 m
4 E1 `# j9 _7 m4 @8 E
int tgaImageFile::returnError( FILE *s, int error )5 t/ j" Q1 f/ x7 @! R% D( s
{3 S, q; i7 m4 _. c7 M3 b
// Called when there is an error loading the .tga texture file.: z) c8 U; v- C! }7 |' v+ P
fclose( s );
% k4 H+ b4 ]* l% V8 freturn error;
% e* Z4 i5 @6 H0 J/ v& t* V7 S}7 Y; K# w! o; X) i
: N0 d5 q9 `1 \0 z% D4 e A
unsigned char *tgaImageFile::getRGBA( FILE *s, int size )
5 t D/ }4 @. N! ^- d0 d6 m) R. E{
4 U1 v; F+ T6 x( j; L// Read in RGBA data for a 32bit image.
& X0 z0 m# ^" d; y' junsigned char *rgba;$ L- @1 C% [, A4 m3 g% m% r
unsigned char temp;1 B; H/ Z! T( g, A
int bread;: s) a9 }- s% t0 `- }
int i;1 N4 u F- z5 _) Z7 B3 n
' m2 [+ m- ~6 u; z- y
rgba = (unsigned char *)malloc( size * 4 );
& P' U! k9 d2 ~+ D+ W6 A% ?7 U
2 v$ S# b0 g' S- T! L7 uif( rgba == NULL )
; [: }% D. {$ E) q0 @return 0;- v: A8 p4 y5 d9 V1 {2 T
+ ?& y% y/ s8 c$ X: C" {7 l: mbread = fread( rgba, sizeof (unsigned char), size * 4, s );
( q9 t) u6 y3 L7 Q* w( E6 {
( b; g; I' B2 O' p' f6 |5 x// TGA is stored in BGRA, make it RGBA * Y E) B: e, B4 L9 f. r, g
if( bread != size * 4 )
4 H" ^* T+ V1 }: O* g{
) j3 b: j# G- a( J8 Ufree( rgba );" h8 R5 [& }! ]0 I \7 v
return 0;. m6 H% J8 M8 ~' P( D3 L
}# D+ ?" y$ l+ p+ A2 {% X4 i* s) ]
5 K0 q" R$ |0 P, u- }, [! x, sfor( i = 0; i < size * 4; i += 4 )
1 j! y+ H$ G, O5 y4 o6 h* A{3 ^- r4 _- g& ]% ?/ q
temp = rgba[i];* B% d; a4 [* `2 h/ S8 l
rgba[i] = rgba[i + 2];8 M, j3 V+ S8 C$ b% a
rgba[i + 2] = temp;; `3 @& Z7 c9 N( c2 o% K/ d: @% Q
}
1 D; m& S" B1 L. l" n* U, i7 u Y, l) h4 x* r
m_texFormat = GL_RGBA;
4 u2 D! Q! C8 L8 U7 A- d7 B6 ureturn rgba;
. `. v6 _2 z2 T, L8 s, j}
& e1 }0 u9 M6 b# b( ]+ c" Q) k7 o! \
unsigned char *tgaImageFile::getRGB( FILE *s, int size )
8 o# o# w9 M$ L{0 B/ J T% {( @" }( o
// Read in RGB data for a 24bit image. 1 m* n9 I4 b N: G# t) [ a% h
unsigned char *rgb;! ^, L1 I( I8 F5 s' p( ?5 y
unsigned char temp;$ c/ g- N- E$ ?
int bread;
/ D* s1 h# y. _) {; Iint i;# ]: J$ r$ ~. j. ^" x6 G
, u$ d# U- N- Z( Grgb = (unsigned char*)malloc( size * 3 );- U* i ^ m/ T3 x, U1 v
1 h3 Z' G) d6 K; j7 z+ \" A
if( rgb == NULL )
$ e/ T$ @/ F5 x/ }, V$ R& Lreturn 0;3 E3 `! g" Y c9 j/ k
@# t6 o! ] l- E! X7 s% B! m
bread = fread( rgb, sizeof (unsigned char), size * 3, s );
, B& f" a/ Y9 n- A Q1 O6 i/ F) n( \7 B' r% [9 q8 g U
if(bread != size * 3)2 R& L" f) v; W4 o
{2 ^( U9 X ]+ I' ]: m0 A" A% g' Y4 f
free( rgb );
! G4 N5 d5 n9 J: F) n8 O- Qreturn 0;
$ c+ ]9 G" n$ M# L0 J# R& [' X}
r( m$ V$ j2 p& W0 c% x# g6 k3 Q2 k
// TGA is stored in BGR, make it RGB
& A3 e( L' V, E' {8 h0 z4 p6 X) Tfor( i = 0; i < size * 3; i += 3 )
9 [/ N' U# e& W6 X/ ~$ O2 S- I{
" Q/ `0 L: X& Y+ t" k$ N4 ~. `temp = rgb[i];# A) t. t- d8 Q2 v# c$ a; Z
rgb[i] = rgb[i + 2];
6 A" W) Y. Z7 l6 I2 {rgb[i + 2] = temp;( B2 a9 P+ Z1 p( d, t* d1 v
}9 L) P% [: ]7 B$ A% a2 }1 m
$ ~+ c) j, Q& b' y" D! ?m_texFormat = GL_RGB;
- H- g7 _4 h# }: u. \8 {) `( J& B5 V) T+ B% q8 K
return rgb;8 Q1 \0 f0 a+ Q2 S1 Y0 A0 y
}% m4 L8 q6 P) d: g' Y, W# p& p
8 g: Z2 t, ~7 |: ^& cunsigned char *tgaImageFile::getGray( FILE *s, int size )
' x- H! U a: }9 c{
( O) [4 V+ C& l7 Y" l) o( o// Gets the grayscale image data. Used as an alpha channel.5 A' l5 H6 j3 o
unsigned char *grayData;" M. l3 G1 u) I, d% C0 i' J
int bread;& \; |3 z$ H7 g$ C
. Q5 O) W3 k2 m- w( _3 P& ?
grayData = (unsigned char*)malloc( size );
2 z! H2 F( Z1 X L, Q, c* ~) n: c: b$ B
if( grayData == NULL )
, m* }" I A) k# D$ M) ereturn 0;
/ v n& e' h; t( S6 j9 j3 p6 z: I
5 @/ n+ c. ~/ r2 L& ~/ W+ f' ubread = fread( grayData, sizeof (unsigned char), size, s );5 R% L( v3 p; o0 w3 A4 x- P. R" Z- k1 G6 e
9 g' H }; O1 r# x X/ Y8 [if( bread != size )) C, y# H, F3 P
{; l5 W- {5 E4 l3 m( h- _
free( grayData );6 k# K b) j; F# W+ Y4 c$ P1 A
return 0;: R9 y0 @4 o2 E9 \ j1 p! R
}, x, B$ s: a8 S. B5 S4 @9 E% D7 ]
, i, d+ _* P R: @' ]0 @2 r* R
m_texFormat = GL_ALPHA;& R. O- P a3 w7 _- B2 [
$ S) {4 p# n; ~' C: sreturn grayData;1 ^2 t, H5 ]" ]/ M3 v6 b
}
, ~( x5 c0 Z. W9 y) w% Q8 u& F& A0 G6 Z3 f
tgaImageFile::TGALoadError tgaImageFile::load( char *name )
" v g) l- l3 e- M+ M/ c# T1 V9 B{6 k/ H' X1 ^* D# Q l# I$ e- o
// Loads up a targa file. Supported types are 8, 24 and 32 0 K) k% P8 O: y: C% i/ a
// uncompressed images.8 [8 Q3 _. d* Z, d3 O
unsigned char type[4];
0 ]2 t! X1 _$ B. D: r8 ?unsigned char info[7];
- o3 A' l6 ]& Z |+ s2 N4 sFILE *s = NULL;" [) L* E) ~4 E: M5 }
int size = 0;$ G7 m6 {* K1 m1 T7 C) n
0 C' x: p! S) v9 v# v' d- j
if( !(s = fopen( name, "rb" )) )
: l& s! N- c9 b8 ?0 i. |; ^% Nreturn TGA_FILE_NOT_FOUND;
# {$ Y$ ~$ u8 z, _* v8 C5 R( x- E' |; U- B
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
2 l/ g# y- a4 R! y* v1 S) X% Ofseek( s, 12, SEEK_SET); // Seek past the header and useless info6 c) F" ` i$ A
fread( &info, sizeof (char), 6, s );
+ q) U& U3 n0 w* k9 n$ I+ V# i0 l1 l B/ ?6 H
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )$ p3 V8 w, R" C2 q% w# D2 S) S
returnError( s, TGA_BAD_IMAGE_TYPE );
8 Y( I& a: S% {# ~( M4 K, M d
) Y+ Z! _: {4 D" P* i, M: vm_nImageWidth = info[0] + info[1] * 256;
' Y: h. D) b: {m_nImageHeight = info[2] + info[3] * 256;4 E# h/ h7 l( `* u* J ?
m_nImageBits = info[4];
" p( p3 n8 y/ T$ h# T5 S
" N* Z- ^0 ]/ x5 d0 Esize = m_nImageWidth * m_nImageHeight;
; [5 v4 g$ }1 y* l& T
u6 f5 N1 r; _9 v. C1 L// Make sure dimension is a power of 2
* M3 l5 \" w& H. ?if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))2 s7 y# F) `' L' g! |$ k9 O5 H
returnError( s, TGA_BAD_DIMENSION);
8 a+ B8 Z0 L2 ]8 x. `7 U B% S7 P: I/ U+ Y0 Z& L7 R
// Make sure we are loading a supported type
, ]% h& J/ L0 f( i: Oif( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )2 q4 }8 C# I# e0 ?# n2 R) G% Y# {
returnError( s, TGA_BAD_BITS );
/ {* j+ w5 K' j" y. d$ \, K' h4 X3 k7 e0 r% d2 x1 q8 o
if( m_nImageBits == 32 )
$ l( [* \; g! [; Y3 N. p. ~2 bm_nImageData = getRGBA( s, size );) s3 V& I9 N) r9 `
else if( m_nImageBits == 24 )
9 D2 f: X2 ~; Q7 Lm_nImageData = getRGB( s, size ); " Z) U6 I' N- G" w/ t
else if( m_nImageBits == 8 )
8 g. k& X0 l/ v# W+ Um_nImageData = getGray( s, size );8 [# \3 P/ _; ]7 E
2 ~0 ^6 `5 V( a2 I+ }// No image data
6 j: `2 n3 m- H1 X9 Z) _if( m_nImageData == NULL )
! Y6 E/ L9 @6 B8 W1 ^returnError( s, TGA_BAD_DATA ); Y9 l0 }- E+ h; u3 F# `6 s% i
$ O6 B. h! |0 o! Ufclose( s );" R& ~3 y4 i5 w/ \
% `2 P4 C, y% \" b, Q( sreturn TGA_NO_ERROR;
# y6 X+ }# H7 M" S T}% }+ R+ x% Z+ r
5 H2 @9 O& v3 A+ G) D- x$ v6 A1 E" N
调用举例:
, L1 \; l6 M. s7 l" N' b//+ A5 ^" f. f$ U
// For the billboard poly, load a texture of a steel sphere. We'll use a
( c5 O( q: K( p7 J// .tga file for this image so we can use an alpha channel.& u: W) o* ~& z5 P& P7 U% i$ Q6 ]
//
9 v, p: T1 L6 w+ v) ?5 ^% Q* p; {! E* Q: c( e) Y
tgaImageFile tgaImage;6 Q. d# ?! N- ]/ ^
tgaImage.load( "steel_sphere.tga" );1 `) t% H/ C; O8 u, O+ N; z
% {+ O# O# o% P7 a8 A
glGenTextures( 1, &g_sphereTextureID );3 e9 q* }6 B2 j9 d' p* A- z
9 H6 a/ o* Y. `0 L9 P o9 EglBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
- O. J: z3 H- R: `) n! r7 K( B. k& G% j
, q: {- {9 v$ hglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );; O' n. c6 x4 w0 S1 t
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );1 U* p2 Y. j* N
0 N! X1 \% A9 g/ O, w: k8 T
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, 4 [ f6 k/ j8 d: N# T# f3 C. ^
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, ( J# P+ j, R3 x; b" _2 L2 J h
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, 6 k) U! Z7 w' p6 \$ B
tgaImage.m_nImageData );[/i][/i][/i][/i] |
|