|
|
#include <stdio.h>
; |# C5 ~+ _; f& j" S#include <stdlib.h>
r) K" d) H% r#include <string.h>4 t/ f; y8 v* o
#include <windows.h>
2 ?1 L* h3 U$ a' _( @' A5 ^1 W#include <GL/gl.h>
4 I( P Z+ e0 h+ k
% F/ L/ b3 H, V r" [class tgaImageFile
; s1 [$ x! G. S! `: _3 R- m2 W{; G8 H4 P# M1 ?3 D! C1 e, Q
public:' I. ]& C5 e" q9 F' G! y; Q8 K
]. }: Z8 O+ a0 J
tgaImageFile(void) :
/ S- ~1 C% U1 y! E# lm_texFormat(-1), C/ x+ U2 H# @: m5 V) y5 x
m_nImageWidth(0),8 V4 C6 a9 Z \" L4 q
m_nImageHeight(0),7 Z& v) p1 H+ S& X l
m_nImageBits(0),5 C) @* M3 {& x! c1 D. @
m_nImageData(NULL) {}* Y3 j4 b, N8 e3 o- v M4 m* m
* K: q0 q2 c( n5 }8 K8 ^~tgaImageFile(void);
; ]. _% A- H! h- e6 {4 P1 ^: @
0 ~7 x& a8 S& ?9 Eenum TGALoadError
- c0 i/ G. c& w& ?( z{% E$ z# W, V: k1 {( u0 t) n" R% ?
TGA_NO_ERROR = 1, // No error
/ z2 O8 F& I$ H. K1 C* HTGA_FILE_NOT_FOUND, // File was not found 9 M$ t3 u, s8 c" ]% d }
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
0 F/ ^1 l2 B4 B) ~" O. f; LTGA_BAD_DIMENSION, // Dimension is not a power of 2
) u6 x4 w" y9 @: \! } f1 }0 }TGA_BAD_BITS, // Image bits is not 8, 24 or 32
5 V' h# P1 m) O1 S2 p# B3 p$ }TGA_BAD_DATA // Image data could not be loaded
6 ?) u. O8 H* ?) i5 H5 c7 \ };' W$ J9 t. K6 a. L0 `$ Q$ A- i
8 g" U2 K( O1 H' v( f6 ]* {: itgaImageFile::TGALoadError load( char *name );7 j x& f! w- \0 y+ V
6 L- _ X* p& h$ S5 XGLenum m_texFormat;
7 X1 i1 q. o' b3 T' N; W- g' ~int m_nImageWidth;
7 {% A% }" a; h0 ?' ?1 A7 Uint m_nImageHeight;
' }4 I, Q4 k2 r% T9 O* X6 f( W; xint m_nImageBits;
# r- D4 t( ]- j. w2 O! Sunsigned char * m_nImageData; @; s6 E9 a1 E& Q4 M
8 }# `* f O7 s0 z
private:
# P/ a5 [1 j: u& r( f& E0 V/ q+ Y" G6 y
bool checkSize(int x);
5 \( e" \1 A$ U+ b! iint returnError(FILE *s, int error);: n6 f% C/ M9 G0 q; Q0 e+ J6 C- |
unsigned char *getRGBA(FILE *s, int size);
. l1 n9 ?& X1 R p0 t9 Z! [6 gunsigned char *getRGB(FILE *s, int size);( P/ \( n. E9 X9 F9 g
unsigned char *getGray(FILE *s, int size);( _& ], y1 {2 b) n
};
; w5 v9 B5 s8 I |& q
6 C" M4 t# Z/ \5 Z% ctgaImageFile::~tgaImageFile( void ), G: p7 u. i# Q1 ~; M
{( y: S2 D2 R; V: U5 M% P0 b5 d( m9 t
if( m_nImageData != NULL )) G; ^1 ^# j3 Z+ x" H
{$ T# {( K! b: I: [
free( m_nImageData );
3 D6 I5 } a* F4 f% y- M/ Tm_nImageData = NULL;
d2 Z0 i7 ^& V0 E O# A; V}
2 S6 P* K9 l/ k3 X, i2 T* K/ K, X}3 s! Z- L3 \$ p# ]9 E1 o, t
( l8 r+ A: m5 Q) W. k% v/ P- Vbool tgaImageFile::checkSize( int x )4 W, i x# M8 t4 W
{% o( o" _% g+ q& q+ l+ Q5 q& j. F
// Make sure its a power of 2.- f' p! V; i n, E/ d8 x* v
if( x == 2 || x == 4 ||
% X* F0 S6 v1 N) Gx == 8 || x == 16 || 8 P+ _4 j7 {3 n( J% U
x == 32 || x == 64 ||
% l) x. Q+ ^& n$ \& }$ T3 Y% k* ^x == 128 || x == 256 ||
1 x+ Z1 Z7 V" O7 c, B: p6 P$ Y9 rx == 512 )) a2 l4 D7 A5 |' Y
return true;5 o w6 P) A- s$ l5 }& m' Q) w
" v7 V0 g C! r, p- P# Treturn false;
2 Q3 I$ e8 Z% M: V}* p2 O, J* X) j" ?
0 T B( t! Q% \ D0 W g
int tgaImageFile::returnError( FILE *s, int error )
, c0 W; W6 d; c" v0 G( I{
9 p/ e1 h3 P3 j* _// Called when there is an error loading the .tga texture file.# G1 l* `; I% ?; R o2 c
fclose( s );, T. J# L* X7 J3 o) [: q6 _
return error;
( L6 n9 M5 [( I' ]; C; O}
5 }4 K( C4 M/ |# ?
' \, F" ~: q* z- }+ g# k% W& ^unsigned char *tgaImageFile::getRGBA( FILE *s, int size )9 H2 i) S% W8 v2 p1 u9 c0 z
{
, y; R& o4 G/ l// Read in RGBA data for a 32bit image. " ` m/ M3 ], B: X
unsigned char *rgba;
' V1 \& ~( V) N7 k6 O) @unsigned char temp;: Y3 M$ X e! k( q9 {3 j8 I S
int bread;
+ s6 G& i& i3 M bint i;1 O& U- ?# A' A. q) e# Z
. U: I8 k; c& n8 o
rgba = (unsigned char *)malloc( size * 4 );
( D H1 K4 ^; [ o9 y
5 w8 K4 m$ Q7 m, g' w' yif( rgba == NULL )
: y- V$ C$ p3 f5 _$ F/ \return 0;. m% i7 ?) {. T% H( o
- @, p3 ~+ c5 S$ P8 p
bread = fread( rgba, sizeof (unsigned char), size * 4, s ); # S, L- ^# }# K# x4 T: B1 R6 t
% L8 q0 n, q; `- o: N: L. ^// TGA is stored in BGRA, make it RGBA
) n7 O" {* O+ _' k; T! E; L4 Wif( bread != size * 4 )( M4 Q2 s7 H, E
{
0 c! x! p5 P* p1 Afree( rgba );5 a' ?0 d [ @% s, Z Q2 M7 s
return 0;
4 l8 A, F2 r* C* n8 G+ P, J}% F( d9 L4 f& ]+ S) ~' u3 ]& v! Y. H
2 `- D* R1 z3 Q- `; a! C3 r
for( i = 0; i < size * 4; i += 4 )- o2 J, A# s1 i5 |. M6 a8 [8 W. ?) ]% F
{& U$ r) C2 f' `6 j+ R
temp = rgba[i];
( U$ ^; T- T! L+ {; X/ K; Q# ^rgba[i] = rgba[i + 2];. x9 s% j L4 x& v* w- R
rgba[i + 2] = temp;
/ j0 S3 r3 @6 U9 a: G}0 w3 O4 ]" _" |. [# r) d1 r
' {: n: I F. @; b# L$ x- K2 Hm_texFormat = GL_RGBA;
& X0 @6 o4 x/ i8 }, w, M' \return rgba;0 k/ |1 r& O3 a _5 h
} h% k+ V6 Z _
/ ?/ t$ A1 J+ c5 t% ^7 `( funsigned char *tgaImageFile::getRGB( FILE *s, int size )( Z( H9 x6 ~; P; h5 m4 P& \$ g6 b
{
/ G% b3 S! ^4 n4 k; `6 [// Read in RGB data for a 24bit image.
2 w: r7 T: r8 eunsigned char *rgb;& Q. K, M3 Y8 b9 L) D$ O
unsigned char temp;
5 s5 L+ |% c x7 n( J& ?0 {int bread;- S* r9 |. N& E# b1 M, z
int i;7 \7 _3 h7 {4 t% g6 B% `
% p3 G7 l- w2 S7 n3 H
rgb = (unsigned char*)malloc( size * 3 );4 P/ o* O. o, Y+ E
( b ~# d1 y, E' p2 ~* J% Fif( rgb == NULL )
4 E* A5 d; D, P2 freturn 0;5 F, D7 U" h, {5 e
; {9 f6 _: G' Y6 Ebread = fread( rgb, sizeof (unsigned char), size * 3, s );
' z) ~) U6 t: B2 }0 A1 J
: K5 p L) ?; q4 }9 E0 qif(bread != size * 3)# Z, H0 `4 r# z) ^- l
{$ q5 C" f: w* g2 E% W( w7 C; L) ~
free( rgb );
4 k2 F7 C( ?0 n8 c0 B$ H3 S. V: l$ Ureturn 0;3 i: e- T2 q7 f6 B7 w( D; ^1 Z# E
}, G8 L' D) m0 w8 P8 b( R5 G
# d8 b! q" ?7 |2 H3 `# n// TGA is stored in BGR, make it RGB
( _& w, P1 [4 K- Z7 _for( i = 0; i < size * 3; i += 3 )- y$ Y) X7 @5 n# Q# H$ P
{% C3 @ T6 c% D2 A" U5 V
temp = rgb[i];
3 f" D6 H: |( V4 q3 O2 w1 E% N, d% lrgb[i] = rgb[i + 2];
1 e9 a0 @- b- @rgb[i + 2] = temp;
; X1 ?3 c% A- W& m- _) y( \; k}
* y+ V+ \8 s8 f. x/ a, f. z) O& s: D3 b
m_texFormat = GL_RGB;
! _" x- I6 L3 [% y7 ]! X0 ?: S- m9 b4 H6 D+ P" D+ j1 G% L4 E
return rgb;
+ _9 a1 h+ y1 ^, n: |}0 T Z! l- _2 w$ ^" r7 V) r1 ]% |) _2 f
9 b; ^' W" C4 q' aunsigned char *tgaImageFile::getGray( FILE *s, int size )# \9 p) v( g- _7 ?; D6 X5 o, T$ A
{* k% @2 j) @: e( ~; _
// Gets the grayscale image data. Used as an alpha channel.
, a' s. S, d, U+ x% Y, D2 ~unsigned char *grayData;" N) o7 A) n/ B- J
int bread;
( q$ e5 ^) l* p3 |6 \
& [( C4 i" _; d% zgrayData = (unsigned char*)malloc( size );, w2 p6 v2 y" s5 u9 p/ A' `
8 Z; K. K8 @0 [3 fif( grayData == NULL )
_+ D, v ]& }* G( w% }' Treturn 0;) U4 j" `$ n. ]5 q
" j, ^: ?; D: x# }6 R7 R# ]' lbread = fread( grayData, sizeof (unsigned char), size, s );: B9 ^; W$ w4 S5 I0 m; O' V
6 A7 f7 J3 R& V5 {: s9 @ zif( bread != size )9 ^0 E! @/ h, C2 \8 O: S. _
{( s# r% E! v) I; } M/ i
free( grayData );
0 r3 Q [- j3 H# T4 Areturn 0;
/ r' f# S3 r4 }( P! ?3 K( B; E}
; |2 U2 Q. S( U1 @4 w
' X) E: a% H* v5 V+ \1 im_texFormat = GL_ALPHA;* Z3 ~! a2 h! F! l" Q, B) m0 q
8 h& d$ w6 e% c- N: ^8 v0 R
return grayData;! D+ |3 i7 ^7 a$ ^* d1 K2 }0 d$ V
}. y7 n( C/ z7 }2 s0 O+ t: q
9 \5 f- F0 d) i: E9 m3 |+ A
tgaImageFile::TGALoadError tgaImageFile::load( char *name )
7 j" X+ o8 o, s T{6 S3 } M5 a1 d
// Loads up a targa file. Supported types are 8, 24 and 32
, t) V4 ~5 J- E" k5 p// uncompressed images.2 u# [& o) U" z1 F
unsigned char type[4];
% R7 F8 m3 `) D; C0 F: Yunsigned char info[7];
" x, }* r9 y7 q/ Y* O) oFILE *s = NULL;8 U; z0 m$ r2 ` @7 T
int size = 0;
5 o2 G9 t" y2 p# x& F( R6 W0 f; T* c; X5 P
if( !(s = fopen( name, "rb" )) )' ^5 n1 e2 f0 b
return TGA_FILE_NOT_FOUND;
" M' W. O' Y" {& J: M2 ?/ ~7 v0 |7 w
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
0 [: ] S2 \" E; u* O# wfseek( s, 12, SEEK_SET); // Seek past the header and useless info' _2 g! ]2 ^5 b: d7 t" Z% E
fread( &info, sizeof (char), 6, s );
/ q* m( k5 {7 m8 ?0 I- x1 Y% m5 V; Q
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )! k0 }; ~4 B3 ?1 V/ P$ Y, [
returnError( s, TGA_BAD_IMAGE_TYPE );
2 n0 f# S ]3 k2 T: k) {7 A0 a0 i$ n4 m" V) B
m_nImageWidth = info[0] + info[1] * 256;
8 T9 o. K; p9 M/ qm_nImageHeight = info[2] + info[3] * 256; d: y1 E8 H/ U
m_nImageBits = info[4]; 5 t) o- B' h1 n! i- E/ Q+ \- Y2 T
3 v. Y# P" J* g3 V+ o
size = m_nImageWidth * m_nImageHeight;& f" L+ l5 u0 m; J- ]5 `
8 C) }2 f* s; Q3 y) i: d
// Make sure dimension is a power of 2
! w9 F! N$ t7 [! ?# j4 r' Zif( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))
! ? l$ C9 ^9 V5 Z+ g% WreturnError( s, TGA_BAD_DIMENSION);
3 ^ Z* ?$ F4 g/ z* f5 S
; \5 t# j" h. q// Make sure we are loading a supported type " `8 c9 X6 D% K2 |
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
) o) W, g& {& v# OreturnError( s, TGA_BAD_BITS );/ @. S+ b+ R# k, c( M
6 T' U! P5 s6 [$ Tif( m_nImageBits == 32 )
, i+ s1 }2 w4 Am_nImageData = getRGBA( s, size );" n7 C% X m3 X/ N# _
else if( m_nImageBits == 24 )
8 u- z; D/ ?4 [; p( N; }: t9 ]m_nImageData = getRGB( s, size ); - u0 n: h; R& h; _2 M
else if( m_nImageBits == 8 )/ b: X3 M, N, t7 x) Q, K
m_nImageData = getGray( s, size );& n6 Q: c7 ^, ?
5 C3 ?! N9 ?' w8 _ Y: b// No image data
2 W, T* w$ Q- Sif( m_nImageData == NULL )
6 |8 C, ? A% ]" N0 E" M/ P% k lreturnError( s, TGA_BAD_DATA );
. b# x% {' Z c5 o2 w5 t! _0 k$ a- _; y2 x9 i
fclose( s );
- p( K) h' c. k) ^4 t& I7 e. W
6 X1 v. S2 H' t/ {2 y4 _( Wreturn TGA_NO_ERROR;
% L8 K. F* q* o5 [3 O% ]}
# I+ M; g( U- z: Z z( A1 k% H$ D3 U. M- K7 z
# ]% p Z' o3 v( X% s) u4 W
调用举例:
/ v2 J' h$ a( h9 J. @//
9 Y) I7 h8 M# X: U K6 p# `) F+ f// For the billboard poly, load a texture of a steel sphere. We'll use a 7 K& [- F; ?( ]0 q3 k
// .tga file for this image so we can use an alpha channel.* y4 F, i) W4 c: r0 S# c) M
//
/ y4 ]6 B1 u2 Z+ l; _/ z( ?
8 T+ U6 } F3 v8 @3 mtgaImageFile tgaImage;# j1 c+ J# c6 G0 _1 T2 s
tgaImage.load( "steel_sphere.tga" );
* i3 d/ N9 D% l A& G& t5 G a1 o0 f
glGenTextures( 1, &g_sphereTextureID );) F$ F; d! Q+ \2 \3 G, v# H) v: \
1 T4 D; ?4 j& H: \: R9 _glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );3 S% ~% U, B8 ?
% M- u% g! D% {3 H1 v
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );5 @! ~- V) Q: X: ^/ C1 l* z
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
. E! v0 q6 @ J z$ p- T' f- {0 [/ |. e
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, . C4 V4 b. O2 f, X$ }- [
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, 5 s2 ?( z0 K Y1 d0 u
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
+ b/ z6 ~) j. ?5 [. }, c7 x6 |tgaImage.m_nImageData );[/i][/i][/i][/i] |
|