|
|
#include <stdio.h>7 c+ D0 B! Z/ U5 @+ l5 H6 B2 s
#include <stdlib.h>
% V. @8 H' y# m#include <string.h>& Q0 U$ f0 {! M0 q+ g3 ]" C% w
#include <windows.h>4 k) J' r2 A8 n( m
#include <GL/gl.h>- u) b- k- L5 r4 S- q% i7 @4 E" z
- G6 Y& P8 Y3 B6 ~
class tgaImageFile
) L6 Z% A6 s* A) e{
/ J/ r R9 d, S8 [4 N8 S3 ]public:- R! P2 i& `& i. g1 f/ h# J& E$ O
6 R& M- D9 ^( t2 htgaImageFile(void) : F( d4 S) I; N- q, h; n' R
m_texFormat(-1),
! c ?& \2 s" L& }m_nImageWidth(0),
* l( ^7 X% G$ i+ A, ]* |m_nImageHeight(0),
# {; f3 w' G# ]. T# ~( }m_nImageBits(0),% ^4 Q7 _% N. a* { r5 _
m_nImageData(NULL) {}
% b+ v' @1 d; n5 ^2 Y9 s ^5 H1 ]
~tgaImageFile(void);
/ n- _$ N9 {) X8 q1 _- H( W
6 c5 k+ _5 a$ S0 S# P; Menum TGALoadError0 t6 |. h: F( S3 ^; c4 d
{, C. ~: k0 S I, @* C# e X! q1 Z' n
TGA_NO_ERROR = 1, // No error" i; Z) c2 b; P: t( S
TGA_FILE_NOT_FOUND, // File was not found
8 A- g6 M- Y9 R! l& E* r; CTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
+ R: A) s+ u2 q6 `6 T, H3 u( `- j) KTGA_BAD_DIMENSION, // Dimension is not a power of 2
3 R4 ?, q( t) k6 c5 GTGA_BAD_BITS, // Image bits is not 8, 24 or 32 " G) B9 f. v( \, t y
TGA_BAD_DATA // Image data could not be loaded $ N# G/ r. s2 L' n# y; R
};
% g5 @" |' w+ v% v( E
' W; f6 \; ^. x3 x: O7 ] R0 _5 DtgaImageFile::TGALoadError load( char *name );/ L; Y: d+ p$ o2 e
: g5 T" X. \& a& A/ xGLenum m_texFormat;5 K# B1 |4 b, s ^4 \- ?3 o
int m_nImageWidth;
6 k, F+ k9 C' W$ dint m_nImageHeight;
; P$ b7 {. H8 L. |2 v8 ` i0 ~. eint m_nImageBits;* G$ Q% X" a; a0 {' {) H
unsigned char * m_nImageData;
' |# b! X. w0 m7 G! p
3 U& r! T: C9 f, N. {private:
/ v$ l) {% p$ M3 a- X
5 ~4 w7 a1 `' ]7 z4 c2 B" n0 Lbool checkSize(int x);
+ p6 m- U, X2 rint returnError(FILE *s, int error); t4 W5 j+ b0 G) _
unsigned char *getRGBA(FILE *s, int size);
2 w; m% `) R# e. nunsigned char *getRGB(FILE *s, int size);7 [2 J5 _0 ]+ s3 e4 r
unsigned char *getGray(FILE *s, int size);7 H, O: ?) M" I* ^/ P) ?
};
$ L1 N0 d9 \8 b$ J4 V+ ?# v) E- Y# j9 ~
tgaImageFile::~tgaImageFile( void )) i, z- \7 P* @9 n- Q' U
{/ w' o5 _' i- O. n% m) }- }
if( m_nImageData != NULL )5 t' ?, J# N( V$ I( H! J P
{
! e/ N# T8 V6 kfree( m_nImageData );
4 s; @2 ^9 Z3 G& t. ^m_nImageData = NULL;7 z3 ?- e. w0 H) t/ G
}2 w' r+ z& z2 \5 q4 \
}# e" k( b J _' l/ c+ }) h
6 f: g( h! _6 e9 I R' vbool tgaImageFile::checkSize( int x )
/ Z/ P$ N" Y- i/ M" J; T. Z{* b5 }& F X" M9 L; h* R
// Make sure its a power of 2." _0 o6 H& w8 |+ l- ~" [0 E; A) J
if( x == 2 || x == 4 || ' K& J1 {3 e- }: w" g& g5 I
x == 8 || x == 16 ||
- i) M6 J s3 }4 X: Wx == 32 || x == 64 ||# p) b- s2 Y9 X8 A& J# W
x == 128 || x == 256 || - U# O5 W$ ~9 J# d+ m+ T
x == 512 )
2 A9 c3 y2 b8 Xreturn true;& O1 S: r, O( A) `- ~$ h6 K% i
2 m0 |6 |& N: t0 c- Greturn false;
5 ?- f4 q& ~' j4 d}
0 E" N+ I' {2 T. J4 g) g6 U, W4 ]
9 N8 a! \, ~! Z! J% U0 H Cint tgaImageFile::returnError( FILE *s, int error )
$ n$ M" l0 r' P6 Q. t. l6 r; G{
7 f. r5 t' N; u/ H" Z7 v0 G* K// Called when there is an error loading the .tga texture file.- ~; @0 |# u9 j! B
fclose( s );) U; a/ k% U$ B
return error;1 @, T9 F W1 Z0 B7 ]
}
) s/ F& C. k6 Q+ }( S7 `3 O5 F2 F, u4 l; h
unsigned char *tgaImageFile::getRGBA( FILE *s, int size )
! i# \# D- ?' Z{
/ M7 F) H9 |8 F2 P) W// Read in RGBA data for a 32bit image. @5 B' R- A z# V
unsigned char *rgba;* M0 e; F, X( P% b1 n% F
unsigned char temp;. @1 |9 Z5 Q, L A$ g
int bread;3 s+ z8 u; A* s3 J) s# o# ]
int i;, z1 w; Y- k9 |! ?
2 l: X+ [" \$ ^% L" D' Z0 d
rgba = (unsigned char *)malloc( size * 4 );1 {7 d. h% k2 N. D/ j5 f
1 {. Q) I, e' q- I# g: \7 R
if( rgba == NULL )
' g( p2 T4 c3 e+ zreturn 0;
# y" X2 @1 U' h' z. _& i, g& B& t1 o( I/ k1 m0 t
bread = fread( rgba, sizeof (unsigned char), size * 4, s );
- w; I; R" p3 F8 c3 Q1 }
" @$ m6 A" n3 D. H8 P2 F// TGA is stored in BGRA, make it RGBA ; H( q2 A; i/ Q1 x1 ~- c
if( bread != size * 4 )
7 D# l: e" B+ T; C- ^{& o- P, v; E( N! ?) P6 `5 M x
free( rgba );
$ D* n$ U2 C# n: I# j u2 }return 0;& g( ?& W3 K' b Z6 A6 X5 b; ?
}) o/ A- |$ a# s2 O1 Y" J* G
3 G7 E. v1 N0 j' K, r* X
for( i = 0; i < size * 4; i += 4 )$ r* ~3 j9 U9 w5 Z0 ?
{. a* Q% h/ o B, ?- j I
temp = rgba[i];8 h L3 B9 T; N
rgba[i] = rgba[i + 2];- `# d+ q; b/ z0 y' u9 |! m
rgba[i + 2] = temp;
2 j+ ?& x/ K% U7 u}" c0 ~$ e5 S& x
9 u( ]/ L7 A; Dm_texFormat = GL_RGBA;
! `* u' l- _2 Wreturn rgba;
; }7 \: @' C8 N4 M! B3 B* d}
9 F( g" L* t0 j V( F, y# |- k: j
unsigned char *tgaImageFile::getRGB( FILE *s, int size )) M6 r8 \7 o1 f! U2 t
{' L! X* {/ [! ~5 b3 h+ E
// Read in RGB data for a 24bit image.
" z$ E, f" Y3 [( I! A* ]unsigned char *rgb;
& j* M' w, I! j+ w; R0 xunsigned char temp;
, e& {3 ` O9 b+ B& K: [) gint bread;1 m0 m1 A5 R1 K
int i;
1 a$ K3 U. i& Q0 [4 m+ z% D
' V/ _3 H* I+ u; ?; ^rgb = (unsigned char*)malloc( size * 3 );- R5 N% q9 v3 _0 r: m2 D* L" i
r6 `* o8 \& r( w
if( rgb == NULL )# t. [+ B5 O8 D1 P. U
return 0;) {% ~- ?& g' H* ~; P! Z
, l$ d3 @- R# C4 Q3 Q0 Z8 ?3 u$ Ubread = fread( rgb, sizeof (unsigned char), size * 3, s );
& S2 e% E6 U3 d* z$ Q+ w" C3 ~. p
# Q, R; `. Z) {& [if(bread != size * 3)
) u, ]8 B) p/ p% T4 O( r{: n* J M: q4 k: e3 @, e( ^2 k+ F. t
free( rgb );/ z+ U. I/ A9 e# S
return 0;
+ { s* M6 ]" \# y; l! H}
8 s; Z* x0 U& r6 d1 N% i2 H! o# @1 Z* r2 F) v
// TGA is stored in BGR, make it RGB + e; M4 M- h4 R
for( i = 0; i < size * 3; i += 3 )' v" I9 B# v( M L
{
3 c ?8 L0 P4 }- |- ], [1 Qtemp = rgb[i];
; b, G( X' u9 ?# M [6 T" t6 Grgb[i] = rgb[i + 2];
# [( }! s) o( r4 Argb[i + 2] = temp;
/ E4 o4 p8 f4 p9 {$ s}7 h. V- V$ U1 E& D1 r4 a9 H; m6 S0 Y
) K, y. ]; y3 j; X9 r+ k
m_texFormat = GL_RGB;
$ P* B% ^7 |' ]/ d+ j$ X$ `
. O* j! B6 S: _; e, U( creturn rgb;
. h/ A( a* q2 \' r- I}
# u9 O: ^- [4 T, e6 T$ P4 l
2 e! d% K! M. E* R# l1 h1 {3 }unsigned char *tgaImageFile::getGray( FILE *s, int size )
" l/ b r! i ~2 N7 M{* P+ ?4 \; u& q, E9 j+ \+ G
// Gets the grayscale image data. Used as an alpha channel.! G5 W$ @0 s* @7 ~7 k$ D0 z
unsigned char *grayData;7 `* W1 [# j' S/ S6 J$ Z
int bread;+ b- o, ~1 G, h) o% Z# |- K' R
5 p6 G' z' @4 t3 h6 T' ^grayData = (unsigned char*)malloc( size );4 p) R$ d7 T$ W/ h
7 a) L3 J- s9 t# ?# O2 r1 o( tif( grayData == NULL )
1 N1 V& l# W% Q+ p. S' {/ preturn 0;
% f% [! y; [( I1 x% V
; X* X( y6 N9 k4 ~, ~* Abread = fread( grayData, sizeof (unsigned char), size, s );2 G8 n- O9 E0 f' F. S9 J0 W
3 H5 p( `- r! G. I- Q* D2 oif( bread != size )/ F- P, d" Q( N* N% U7 P$ I- q, ^7 Y
{
$ X/ X: C- P6 _# J# ]' Lfree( grayData );2 H0 C2 v/ G" m1 A( Q2 W
return 0;: U8 t v3 `; ^/ |) l# d1 o2 E6 }$ d
}
1 H( z' s0 a4 [, ]# q0 D/ ~0 T, C
! Y0 S! M6 }( I& e$ @, Xm_texFormat = GL_ALPHA;- ]- k7 a+ h$ Z/ H; z* J
! |# ~! O1 N( L' p9 w3 g% areturn grayData;5 f; p1 }7 u$ ^
}% `% t6 V! D, M, b/ b
: F+ @( f+ O7 H+ A% `3 wtgaImageFile::TGALoadError tgaImageFile::load( char *name )
) Y+ U( `7 `* [- n0 d& U{
6 h# M# N. U0 a, `; g8 O; o// Loads up a targa file. Supported types are 8, 24 and 32
" w g. Z7 V; S4 S+ |7 Z// uncompressed images.
* f/ b5 B7 O6 r \unsigned char type[4];
5 [* k. ?5 S+ D' Z1 B6 n4 `unsigned char info[7];
! b0 Y: K% k5 aFILE *s = NULL;
# I2 Q0 p+ v9 N0 A7 g: Iint size = 0;1 Q G, \' T; K g; _7 g$ @9 L+ y
% U5 `) T7 k- `7 f8 b# r
if( !(s = fopen( name, "rb" )) )
: E. c+ k1 \( E% e% _return TGA_FILE_NOT_FOUND;
- A; S2 e1 w7 O
) z( A) {. U0 ~6 h# H* jfread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
8 U0 R B2 m8 {7 O6 y: w8 c9 U# l2 y5 x- Cfseek( s, 12, SEEK_SET); // Seek past the header and useless info
6 i7 y1 U9 ~9 d, D8 _7 H2 Yfread( &info, sizeof (char), 6, s );+ c/ A8 B. Z' f7 M5 Z& U' ]# ]
3 D! y0 X$ S0 S+ d Sif( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
4 N; W" b+ c6 ]& x0 }6 AreturnError( s, TGA_BAD_IMAGE_TYPE );
0 x4 z3 Q% k- s* [) q6 y
% g' t( g9 e: Q! B! T& x/ C Rm_nImageWidth = info[0] + info[1] * 256;
7 m0 G4 S! r- L4 pm_nImageHeight = info[2] + info[3] * 256;
: Z( @% W: g8 m2 u# X8 wm_nImageBits = info[4]; . t( `1 A) M8 ]- U: Z) e! ^7 I" y
' H% ^8 C) N/ [0 N6 u g" i, tsize = m_nImageWidth * m_nImageHeight;7 Z6 P4 [+ G# ^/ w1 [, q' U
4 \7 I( `& [6 Z# b2 _/ D
// Make sure dimension is a power of 2 ) o! o$ [3 w) M8 B X- e/ g
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))) E- n: t, X- w; W
returnError( s, TGA_BAD_DIMENSION);: B2 G$ Z1 h. s/ i$ B
8 }# w" U+ J3 c) b, {
// Make sure we are loading a supported type
( j1 B' \" V, H% W) bif( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
: U* z+ A/ y& Q! j* E4 QreturnError( s, TGA_BAD_BITS );3 R- E% L. k, y" A5 ~, B. D
. S+ C0 _. ?8 ^8 C3 _if( m_nImageBits == 32 )* b3 s. w$ V) O( t0 C3 I. p; A- n0 S
m_nImageData = getRGBA( s, size );: L. s% J' F7 ?/ F- q2 N
else if( m_nImageBits == 24 )3 F1 }) F! O! B* ?2 ?
m_nImageData = getRGB( s, size );
6 j& l% D' V( l5 {else if( m_nImageBits == 8 )
, c+ r- r4 _1 h im_nImageData = getGray( s, size );; F8 G! J3 K2 B; `. {
8 |3 C* N1 R0 t% o// No image data
# t; U7 z) G! A2 c& [7 g+ Q' b% Fif( m_nImageData == NULL )
6 j% z% W# B% G$ ]/ `& zreturnError( s, TGA_BAD_DATA );
4 g/ G ?* a! s. S$ k2 I* v
- _+ N- q5 A- A P8 A1 ufclose( s );8 a. t0 h& D' Y. T1 L) A) G7 d
3 v- Z, G& _+ C4 v* `; l
return TGA_NO_ERROR;; ^2 E0 o1 G5 S0 L
}
3 C6 J1 c% d7 Q8 [6 Q5 Q7 |1 r' ~
8 T, ~" b* k# N- f/ x
9 h' o5 P# E9 J& ?- P f( n调用举例:
$ k' u6 G) c: v- O' I4 d4 P//+ u* d5 `+ m7 { w/ X2 C# ~9 @3 N
// For the billboard poly, load a texture of a steel sphere. We'll use a
' F, F }1 Z( c, Y6 ]// .tga file for this image so we can use an alpha channel.7 s' w3 Z0 k, q
//
! M# K" D- m2 n( M# J6 L- O+ s
) V: E4 ]" c9 n5 i3 ktgaImageFile tgaImage;
/ _& L3 q" w' Z S. EtgaImage.load( "steel_sphere.tga" );
1 y' R3 O) ~. l+ r8 f$ B1 p
7 C7 ^3 y! F$ b9 Z7 XglGenTextures( 1, &g_sphereTextureID );0 h9 `. g6 y4 M4 d
% t: ?# o5 n8 b6 J
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );- e7 E8 L8 L$ Y' y1 R0 _# j: W
' W" r M5 _7 k' j* d
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );" j# |2 L) w$ c* n3 A
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
) F) U( y# Y1 Y3 e) b
, b; G5 q' F/ v" S ]" RglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, 8 n) z, Y( O0 s5 C; l
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, # s; V' a* R& a6 u- r8 U4 Z
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
9 s2 P1 n1 W! c4 c) q& r3 VtgaImage.m_nImageData );[/i][/i][/i][/i] |
|