|
|
#include <stdio.h>
6 ?- N" J& Y1 R, G#include <stdlib.h>: b( Y3 \" S! ~+ I
#include <string.h># f+ y( R$ {" M9 p O# u9 e
#include <windows.h>
; } ]- `6 I& X' Z% E- I. @, ?& x7 K#include <GL/gl.h>" W5 y; C j( y! E- }. u9 `
- P- p( V+ c, h; O( v$ W5 rclass tgaImageFile
8 Q8 Z1 K q$ Z8 Y7 K{
' T8 B# w' X% s0 Spublic:
4 x J& E1 w. E) d) M7 @! Y2 \3 `. C* {5 X/ Q7 ^
tgaImageFile(void) : $ w' e% c* h F" X( K
m_texFormat(-1),
) n. d9 |$ I& n0 Gm_nImageWidth(0),
% {& o* c- e6 Q- Q+ V/ f7 a% dm_nImageHeight(0),0 G& d+ o9 d+ `" ]+ [( C
m_nImageBits(0),! o# Z8 [* w k. T( P
m_nImageData(NULL) {}
+ q* P s, [0 U) U |1 s
6 ?5 ]2 Z2 Q+ N3 [! g j1 g+ U9 T~tgaImageFile(void);
4 @' G0 n0 s6 g- u2 y( F
0 W2 @ [' H T* denum TGALoadError6 {3 | W* q$ L* q! W" b& E6 [
{
t9 {4 Z" ~9 @- B' H- TTGA_NO_ERROR = 1, // No error, n3 Q6 c9 M7 v' G- M/ y
TGA_FILE_NOT_FOUND, // File was not found
$ `" g- I* T, a/ R6 t6 YTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
2 Z5 w# o7 g, I" r7 V" C! GTGA_BAD_DIMENSION, // Dimension is not a power of 2 % O2 }4 H, p; ~! c! ~6 x
TGA_BAD_BITS, // Image bits is not 8, 24 or 32
% h1 O L( p4 K" V7 s OTGA_BAD_DATA // Image data could not be loaded . t1 k1 z$ F. e w& |. W# q
};* N8 O4 W) X8 g9 @9 q* l S% G
- S% R0 }* J* }* W& ]
tgaImageFile::TGALoadError load( char *name );( C. M9 p) q* A4 ^
* m0 _" [% l* ]( h, A
GLenum m_texFormat;
+ B! i3 C, q) ?' q( ~7 X* ~int m_nImageWidth;
: `5 a) A7 U1 l! ]int m_nImageHeight;
, h/ [! U1 B7 p- C9 e- A, c% X; sint m_nImageBits;6 ?& F. G, S; U( p+ P+ u
unsigned char * m_nImageData;
$ Q* G9 M$ F; _" k
( M1 \6 D+ E/ Hprivate:* m3 C ]& r! V9 h: g! }
: ]3 F1 @5 S# n3 _8 K/ \) ^5 k8 Bbool checkSize(int x);
! w" @7 r0 ~, J% e8 Y& u% ~int returnError(FILE *s, int error);
! P3 w3 O r3 N* ^' v2 kunsigned char *getRGBA(FILE *s, int size);3 N4 }# J3 r) J! X% _% `
unsigned char *getRGB(FILE *s, int size);
/ V; Y% ]1 V+ I8 m# b6 E) [unsigned char *getGray(FILE *s, int size);
- t! z8 {' R. R6 l+ ]8 u};8 r+ R) `( B$ F1 R
* M" x% r! o5 N! J# ?tgaImageFile::~tgaImageFile( void ) _0 a# ~9 P& v5 _& j. ^ ?* d5 b* P6 `
{6 O4 o2 i' Y- a& V0 v
if( m_nImageData != NULL )
, K, u$ }5 _; v T{' L1 P: o6 m5 A3 O; f7 h9 n9 w6 n
free( m_nImageData );
, o8 {# l$ w; p8 X1 Qm_nImageData = NULL;
5 m( P! H7 V: N( H% {2 i7 c}
* c" X1 Q! h$ j}
# l4 C# z7 F$ `; N
* ~( b, n e2 \6 [* U% \0 d6 Lbool tgaImageFile::checkSize( int x )
& f% l4 S% Y+ h+ b( \{
( I) H/ ]3 {! o0 J6 o, o// Make sure its a power of 2.$ U' Y j) i o6 _& H. u7 d5 Z5 J3 j& e
if( x == 2 || x == 4 || . K- ?* B" {/ s+ d: O
x == 8 || x == 16 ||
4 B) F% ^! y# @x == 32 || x == 64 ||
1 X% R2 [6 |+ h0 nx == 128 || x == 256 ||
5 s3 T" q2 D1 y& C% o7 o3 xx == 512 )3 p: l# @: V9 {! s$ q. V& N) {7 ~
return true;8 b8 E* d$ ~$ x8 ]$ x4 g$ d& H; J: i: m
. v. Y- `5 R2 greturn false;) T( a; C0 T0 f: S
}
/ `1 x$ t Y7 f. F( D, M8 ]5 {/ K8 Z, W6 O2 c; W1 w: o
int tgaImageFile::returnError( FILE *s, int error )
$ i/ I$ _: n u+ C{( G' z; W! H) v! m4 t
// Called when there is an error loading the .tga texture file.6 M9 y3 j: j( }; G
fclose( s );
- z3 p1 H, G& X+ ]9 Z+ `return error;3 G1 I: n: Z* { L: x
}
& k7 }% M9 Z" O- G' \, {+ x3 w) [. N: D! _/ ?
unsigned char *tgaImageFile::getRGBA( FILE *s, int size )) \, e7 g/ }8 V7 m, B( ^
{) N$ r( ^4 h0 f
// Read in RGBA data for a 32bit image. 2 p4 w3 E, R3 a) N: V. y$ t
unsigned char *rgba;7 J# R$ I$ X L( a; k
unsigned char temp;. r ^2 z. W( X( O& l" X
int bread;8 {, D( R, p9 M3 k
int i;
P5 k6 L3 L, r; D9 A
* |- t' U: W/ d8 O. _3 Drgba = (unsigned char *)malloc( size * 4 );
4 {) Y7 _7 X3 d1 O
% t6 W% F. L* M( x E# tif( rgba == NULL )
- O, @( E+ \# m: J8 u% qreturn 0;" t( h* S% x" F
( x0 e) o& W/ h4 X
bread = fread( rgba, sizeof (unsigned char), size * 4, s );
& T. Z5 `( N* @: }8 }/ w
5 J& Q- }: W# i+ A// TGA is stored in BGRA, make it RGBA
9 J0 L: C" _3 f# H1 I% l& T. }if( bread != size * 4 )) ?- @+ Z3 I) i
{
5 s1 P. j+ M' [1 T* Ifree( rgba );
+ M( O# R2 w2 D6 {9 ~* R3 _return 0;) {7 X8 F9 ]" x! I- z7 R
}5 g/ }8 H/ }9 J& W# a/ c$ l' z
" \- I4 b" w8 ^- s6 A% g; Mfor( i = 0; i < size * 4; i += 4 )
; q5 |5 q, F; M( I( U8 C/ j{
) ~: y# C& i0 I% E/ o! Ytemp = rgba[i];
: F/ i; F6 q$ f& {; vrgba[i] = rgba[i + 2];
' o9 }( t) _" S. m% m; Ergba[i + 2] = temp;6 E" N7 X. q1 }6 q0 i, W
}" A9 X6 g6 ?9 z& a1 L' Y9 e
# y' T; @- w+ W( Y" p' c% u; U
m_texFormat = GL_RGBA;& k2 Z! v @( _- o* b* p
return rgba;
- T/ B9 W0 ^' ]: I}
$ e$ c7 H l N- Z6 _! r
% O, V" a( b6 |unsigned char *tgaImageFile::getRGB( FILE *s, int size )% j: q6 n7 q9 C
{
# X3 ?% X4 _& E: F0 t$ c: R7 m// Read in RGB data for a 24bit image. 8 e. S4 Z8 X' }: ]% y# q
unsigned char *rgb;
+ C9 O" h' G: m5 ?9 G1 D: O9 Kunsigned char temp;: g# p) Z1 S/ w# s% Z1 f
int bread; t) c. E$ g8 z) s: @: T/ `
int i;. c3 ~- C* a$ m0 k$ V
" _ e% g! U: B) s3 F7 Wrgb = (unsigned char*)malloc( size * 3 );9 }, ?4 Q9 ~/ e4 B1 y' L# h
; A7 P# M5 X& J! {( j- aif( rgb == NULL )( O( ~4 f2 n; S
return 0;1 J5 W+ g J, q- M% `' z
4 ~' L0 @+ h/ @2 U. K) T. Sbread = fread( rgb, sizeof (unsigned char), size * 3, s );
% A, @7 H- a0 I: \, |" d
( J9 B% x( x" D0 m; R$ C; I3 A4 Dif(bread != size * 3)
: A+ g* }( x3 `{
' [; y; o- e7 O0 C6 |2 q k \free( rgb );
7 J" q8 y4 a3 N7 N" z* W w: Vreturn 0;2 W; f0 |. u8 K5 Q) V# `
}
+ i# X* k2 L& J! D/ g, F% Q @" _) k5 D& F. I! F
// TGA is stored in BGR, make it RGB
: C4 Y9 f" N- K4 v: h; T: Ffor( i = 0; i < size * 3; i += 3 )- b) M0 g- w5 |+ L
{
% a% l9 c8 C$ @% Q' f" Ttemp = rgb[i];4 ?- f3 z) G9 W6 Q }4 N, U6 W
rgb[i] = rgb[i + 2];
2 P/ h+ s" O5 S9 c7 Y) P, Frgb[i + 2] = temp;
# v) v4 y- H' A) R8 x}' C% r* J. p# G* U4 Z; [: V7 P
" p, z1 k& w. z% {& K7 u
m_texFormat = GL_RGB;
; |! k; Z9 W; X0 c
^( b* U4 M% preturn rgb;
" d! ?8 V8 l; c7 c' \}* e9 ~( r- K' T/ Y. ?4 L8 ^6 H% P
: }: x8 l l% ]. R! Y
unsigned char *tgaImageFile::getGray( FILE *s, int size )
. o; j+ b/ T3 w2 }: \{
# ~5 K" a' F2 L- G0 \// Gets the grayscale image data. Used as an alpha channel.6 ^ i! y! H! c- f$ [
unsigned char *grayData;
: e2 c, W4 H9 G& b jint bread;* `0 ]* L: o/ x7 U; S; O0 D( }6 q
, ~" U8 t$ e+ C
grayData = (unsigned char*)malloc( size );& B- v6 w& j+ n
' K" A2 `8 m7 s- L6 v8 K
if( grayData == NULL )9 b) \, z, F' A5 n# w
return 0;' @. G/ q& K' h0 H H( w
; w4 l( r& g K- ^' p5 |bread = fread( grayData, sizeof (unsigned char), size, s );, s, a# s1 j+ X- j! O8 I' N; E
: E% |) ^' l6 r B& v1 \6 O/ H @
if( bread != size )2 w4 X$ t3 N. v
{
3 c+ j" u c1 [5 V; Wfree( grayData );
8 E8 r# I5 K* Q, ~7 L, C& Mreturn 0;
3 V& I, l V' U8 x& Y}
- n1 _" ^: P% Y5 L# N1 Z3 c! q: r$ R+ \* }: _) J" h
m_texFormat = GL_ALPHA;
" [6 Z e7 w( f# |# ~/ V+ T. n1 @1 ^, M. K- I& y H' V2 K
return grayData;( t5 Z3 _' v& z/ y H0 }* z
}
9 C: O% [3 G3 F. A# }4 [' X1 e) g+ ~8 {
tgaImageFile::TGALoadError tgaImageFile::load( char *name )8 ]' m' `- }% Z: E4 ~4 Y
{
2 r: y, x' L: A7 S// Loads up a targa file. Supported types are 8, 24 and 32
7 ^# ~0 b4 B6 ]8 f1 @3 \// uncompressed images.
9 s9 ^" Y: O+ \- nunsigned char type[4];
& a" t- b3 x4 W; u; s8 Lunsigned char info[7];
0 Y2 x8 z; @! r2 oFILE *s = NULL;
7 _8 Q( c" U: e' f& A6 Xint size = 0;
3 p( n5 q' G+ L: z% `
- W* G1 ~& v$ ^ f! t" k2 Dif( !(s = fopen( name, "rb" )) )
` M$ q1 I1 Wreturn TGA_FILE_NOT_FOUND;1 d/ H: |. ]) {+ I* h
9 I) ~: n! Z2 Y
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored/ A& r* l% L: j5 M3 q
fseek( s, 12, SEEK_SET); // Seek past the header and useless info5 R1 ~8 l) d5 A; {8 s4 N0 g5 q
fread( &info, sizeof (char), 6, s );
7 ?! A. Y0 I" u9 H
9 M. L7 B' g* S8 g, y' O$ ]if( type[1] != 0 || (type[2] != 2 && type[2] != 3) ), C) n9 X1 @0 t7 k% v! Z( m
returnError( s, TGA_BAD_IMAGE_TYPE );
3 b, Y) H* E, B5 X6 U" k, w* v j; m6 q3 z
m_nImageWidth = info[0] + info[1] * 256; 7 d) `1 k$ ~6 f( A
m_nImageHeight = info[2] + info[3] * 256;& c/ F, J/ o+ t2 [( U7 D2 |
m_nImageBits = info[4]; z2 }. @3 _- Z4 f7 r# a
6 M; }: Q/ { T" z9 m
size = m_nImageWidth * m_nImageHeight;, f8 I& M4 }- x- e6 ]$ P( h7 V
: O6 S- X& O& ?7 t0 A// Make sure dimension is a power of 2
7 j# {/ b% U6 D( m: d6 [if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))# K1 o4 `3 I% K3 X4 E
returnError( s, TGA_BAD_DIMENSION);6 t5 j* X2 u& y3 ]4 @+ o
3 T- ?5 }, X! h' a// Make sure we are loading a supported type
6 f; }5 h4 O* o6 k) V: uif( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )* Y d+ Z( f% N, i; N( x
returnError( s, TGA_BAD_BITS );" [# j8 p0 j2 h* z" {& i" _; e, O5 C
( G/ b1 k( E& i! U+ f bif( m_nImageBits == 32 )5 f6 V" ?$ ]5 ?& E7 @
m_nImageData = getRGBA( s, size );) G7 {* j5 |6 X, y
else if( m_nImageBits == 24 )
4 ?. b/ h7 y1 K6 p, _' \m_nImageData = getRGB( s, size ); & W5 i; z/ Z' g2 \, F7 n7 S
else if( m_nImageBits == 8 )
4 p. _! j# k; h' j. B, g; F, `2 Nm_nImageData = getGray( s, size );) b0 C% n# \6 G% L
$ s) A* q+ s$ T r1 Z. z8 y5 o* F// No image data , i% s0 w9 P/ V1 T. ~
if( m_nImageData == NULL )
& ~# X( p" G2 u* I, X& ]returnError( s, TGA_BAD_DATA );
' S, Z+ Q! V2 e1 e# ?, E3 p# m x0 R/ n6 k2 _9 r
fclose( s );
, j: ]2 A- D$ [1 T/ I; h3 d6 L, K7 R; p5 Z) n
return TGA_NO_ERROR;0 J( I; Z S; T9 i: @& E
}0 I5 k. ^2 Y9 V# {) I9 N
, J' ^) r4 ~8 a0 T& S- J
) s, w5 e" I. _- M; E5 N调用举例:) |1 I5 B/ C( Z; X, r
//, S* w ^7 C& g3 |7 A X3 E0 R" |
// For the billboard poly, load a texture of a steel sphere. We'll use a & `# f3 H* \7 v% s& E1 n4 D6 e7 A
// .tga file for this image so we can use an alpha channel.- b5 Q2 z7 b, U2 n- Y* D+ W8 J
//, L. ]* m6 u* L {
* I$ Q$ f6 l$ @' g2 G v' t
tgaImageFile tgaImage;
# O, T4 J6 ?* q/ C, O2 XtgaImage.load( "steel_sphere.tga" );' k- }5 i: c2 m& s' V" B j1 o9 J
* m: h+ z2 j2 T8 Q" H7 o: ]glGenTextures( 1, &g_sphereTextureID );
9 z0 K( i w7 @. k% G9 v
! S, m1 t$ Y9 [ EglBindTexture( GL_TEXTURE_2D, g_sphereTextureID );; h, ]# ]& P9 m, i8 G6 V2 q
. f! [0 m C9 Y; F- y2 O
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );$ h! s) ^" P w& j( m& Y( L
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
7 |' R& M0 `& s4 L& m1 _2 v' |- h. \; R+ p' |# T2 Q4 J- C
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, 1 A' ]' w" K- j0 J
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight,
- M y7 Q( H4 I5 D# ^9 q9 S- v/ d0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, 9 w+ O# S7 m$ z; f9 Q8 v3 S s
tgaImage.m_nImageData );[/i][/i][/i][/i] |
|