|
|
#include <stdio.h>" @7 `+ b6 |% D4 k
#include <stdlib.h>% t4 ]# ~4 m+ i+ z
#include <string.h>; [! h; [0 R! g" Q
#include <windows.h>. b! H- a& h# \- l+ ~2 i% M b# L
#include <GL/gl.h>4 F8 t9 S+ g& V
- H ?& C! _9 p- Y& m& qclass tgaImageFile
/ K# W3 K0 N6 ~{
# j/ I, \" h5 @public:, y% e# w8 g# V
" I+ ~- u3 E( G9 e
tgaImageFile(void) :
" b1 q- N7 S9 b( H- {m_texFormat(-1),
; Q5 j1 D. ^' x) Nm_nImageWidth(0),
: T' {2 p% p' {+ F7 B( Gm_nImageHeight(0),
0 U9 [7 x; T& K0 R4 ]m_nImageBits(0),
( ?% A9 h. K: X& M) o+ _m_nImageData(NULL) {}: R9 V/ E Y1 ^
3 O1 N8 S4 d" q0 ?~tgaImageFile(void);' \% ^! [1 }# f* I
& X) a- }3 [! m% m. j
enum TGALoadError7 k7 t2 z' M4 I& A
{
6 l0 ~; I6 V! e& B4 V1 \2 ATGA_NO_ERROR = 1, // No error: k' c! a' S& f4 b
TGA_FILE_NOT_FOUND, // File was not found
# W1 {0 {0 w% V6 Y) g0 wTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
b: s( Y! i+ O- W) Z( y$ a; b g$ {TGA_BAD_DIMENSION, // Dimension is not a power of 2
2 z r7 A+ y7 r3 i; e0 WTGA_BAD_BITS, // Image bits is not 8, 24 or 32 ! a, g0 ]2 V+ O' L5 Z6 ^3 R% s
TGA_BAD_DATA // Image data could not be loaded
1 ]+ b X8 Y, r };$ y. X( e0 J. E- [: _( s, l
8 y+ ?/ N( m. f# b; c
tgaImageFile::TGALoadError load( char *name );; A: m; j6 b+ |! p% ?" P8 H
6 w) Q# g U: f I L8 N# K1 w
GLenum m_texFormat;
+ h1 t! g" s3 j) B9 A/ s# u5 S Q Mint m_nImageWidth;, R# m/ Q4 d" I5 `6 V# u
int m_nImageHeight;0 [9 i, z z+ p7 s
int m_nImageBits;; c) C9 S1 l( U5 J c+ H% D
unsigned char * m_nImageData;
% O0 m4 E' _ z( N9 a
?* m* d c- P9 Eprivate:2 } d7 i# h, D" q- U/ A; f, Y4 {4 n
+ {3 x: ^1 t, P0 f- L+ D p9 B7 f
bool checkSize(int x);
# J7 f! i7 ?9 ?; A8 r3 G/ Vint returnError(FILE *s, int error);
8 p& H8 j1 ^5 J! ounsigned char *getRGBA(FILE *s, int size);) M; t+ C5 v: _6 P; f
unsigned char *getRGB(FILE *s, int size);
2 S3 f- u7 H8 Yunsigned char *getGray(FILE *s, int size);
8 Q" D4 h- ^' i+ B};
- _( f+ u0 P5 X) y6 a5 S" c. _" a# F7 r5 l
tgaImageFile::~tgaImageFile( void ): L" I2 l( p' S4 N f3 ^7 P* P
{
5 `: n" `9 Y1 Q# n* l+ |if( m_nImageData != NULL )$ F. A7 K' V8 \4 A6 t
{
! W# T( @' b/ Y, t+ @free( m_nImageData );, R g4 G! W9 b1 h+ [+ R7 G$ W
m_nImageData = NULL;' Q2 y9 u m; t$ @2 L K
}
+ q# P5 [+ D, q) u/ K0 n}
- h( R7 t) a5 w: D# Z* V6 b' H2 s ~1 A' o R
bool tgaImageFile::checkSize( int x )
. Z, j' ]# f: n' |- t{% G0 v1 X3 d. F3 p5 r/ n8 w
// Make sure its a power of 2.* {/ J0 P9 G9 Y- e1 d: Y/ [, f
if( x == 2 || x == 4 ||
, Y, U$ L. `4 J8 s. vx == 8 || x == 16 ||
" x& f* V8 v9 z* Jx == 32 || x == 64 ||% m* @0 l! U7 f2 n! d* W2 x# j
x == 128 || x == 256 ||
) y% v( N3 v' Tx == 512 )% E3 a7 i7 U1 J c4 p5 {# C# J! K
return true;
6 @' H" i3 t( u/ b
" f5 |' O! b$ `% {7 J8 @# y5 freturn false; M3 `% A" H0 R
}
/ t* P& Q% H( X4 X, [2 E
+ r ~$ f1 G2 U5 n4 yint tgaImageFile::returnError( FILE *s, int error )% A* N( _2 ?; u8 H( j
{4 g+ W- a! G1 ^0 Q
// Called when there is an error loading the .tga texture file.
' U9 k0 P& D b8 L8 ?" @ rfclose( s );
9 z1 N1 c* O* Hreturn error;
+ J1 U. E! l5 `- @4 j5 @2 G7 m3 ~}$ i4 c+ M# k3 I" m$ y3 X9 h! @1 k
" n( Q) k a; Junsigned char *tgaImageFile::getRGBA( FILE *s, int size )
# ~7 h$ q$ J5 p9 H& A{
) d$ Y3 [ T: d1 @// Read in RGBA data for a 32bit image. ! t! ?$ w, _+ H" l b9 O/ A
unsigned char *rgba;
/ [1 e5 `( C/ o% t4 C5 F5 F; l" Yunsigned char temp;
$ l8 v" m' m/ ^int bread;" W* c: S3 @6 U* n1 k
int i;
, s& @5 |: H4 i5 w( h% I* P6 y0 I" c3 k3 y
rgba = (unsigned char *)malloc( size * 4 );
9 W4 S( v8 i& q; u* G
; H9 e: N r6 j9 A: X& O7 mif( rgba == NULL )3 s7 Y4 @" V2 G( k5 U" @! d* j; Z9 i
return 0;3 V( K: i2 I, ~
6 R! R8 j- B- T/ |* l8 g
bread = fread( rgba, sizeof (unsigned char), size * 4, s ); ; r- c$ R2 [6 E% ]3 N, I
% ^5 `3 N8 e1 K+ o! J! u+ U
// TGA is stored in BGRA, make it RGBA
* {0 C, i0 X- ^3 t- m2 ^2 J8 nif( bread != size * 4 )* E% e0 E0 R2 k6 @+ l
{
7 V4 R* j. g% N! a# O5 g! H* Jfree( rgba );% g0 a) M4 K- L) D9 t2 D8 g7 R
return 0;
2 U: @; I1 o6 U}. I4 ~9 N5 H" V% N# A( y) H5 X) e
$ Y, D1 b% G% X1 @) G! W4 R
for( i = 0; i < size * 4; i += 4 )0 n, E2 b% G: s4 ]
{/ B \9 T5 V8 l. a: P* I
temp = rgba[i];# [# _: G# w) X2 C8 \
rgba[i] = rgba[i + 2];' m, v Q8 ^7 A& r' W
rgba[i + 2] = temp;
% K( S' h3 t9 w& S7 S G}( H8 i6 y2 I; A" l% @* f
- Y6 x: c" r+ p' R F# f, Gm_texFormat = GL_RGBA; v4 V4 T# j8 s# J# j1 [5 ?
return rgba;0 b3 J6 l/ J; @ l& J( J, s# T; J
}. j4 K- }, u3 Y* l" w! N) G
& p5 J2 A7 S) X0 w/ |, munsigned char *tgaImageFile::getRGB( FILE *s, int size )
$ x' t L- {' m# ~' X3 b; k6 y{
) N5 u2 _; S, D& T: b// Read in RGB data for a 24bit image.
; h$ b) O" q2 ^* x+ qunsigned char *rgb;
! k' A7 s% I* x/ Junsigned char temp;
6 ~* @+ c5 B5 }6 F0 k7 E: Fint bread;5 |& k/ ]9 c, _& K. Z( N
int i;
& u; i; \- g( j6 P
! P& c4 K3 D5 p$ [: p: P. w3 U2 ^. C3 Hrgb = (unsigned char*)malloc( size * 3 );
! D3 E! y( f# U; f
* g; M5 ]) Q6 o- B, Xif( rgb == NULL )
/ f4 j8 z- ]- T0 B, B ireturn 0;
$ t3 E# u6 v4 ?8 }9 h5 p* Q F* \% D4 }
bread = fread( rgb, sizeof (unsigned char), size * 3, s );
Z# N% n5 F7 w* W+ k% n' U, R2 v9 l6 x
if(bread != size * 3)
; u; L1 W0 ^9 C: t" o. A9 X% p{$ y- e7 p5 z9 I& f( c0 ?' f
free( rgb );
" K2 q7 J+ y3 r, x. `return 0;; b6 e+ a# U) a
}; D2 `3 x5 e7 U3 r0 H; B
+ y' } A; G1 M9 X4 ]// TGA is stored in BGR, make it RGB
3 Z& e& _% N) T! V" c; }for( i = 0; i < size * 3; i += 3 )
' ~3 c4 z4 x7 [) {' }3 v2 G/ |+ p{
4 p/ e/ d2 G% i1 itemp = rgb[i];
- J1 r" F- r7 G0 j: ~6 o! Hrgb[i] = rgb[i + 2];* ^" p; V' Y, Z( L: ~
rgb[i + 2] = temp;( J& |; P8 N4 o9 ^& _! w# I F1 T! H
}) T# I, G- }1 ?( l3 r% S# q
4 z3 d# A% e& ]' X1 x$ b2 ?m_texFormat = GL_RGB;
5 M" ?7 o! q2 y5 |$ g! l7 z3 Y. Q' L9 o, @& D8 b: g9 Y A
return rgb;
. t2 y n0 }# L( c! x0 J; e" @}
& T" p) ^/ p+ [/ B* `/ f/ r% \0 q% H5 v5 w( T; f# s, R, F
unsigned char *tgaImageFile::getGray( FILE *s, int size )
" a7 P6 t2 X5 `! A, w. w, w) @7 H{; F; H4 C: h D- _( G5 v+ V
// Gets the grayscale image data. Used as an alpha channel.
! d& o6 U* b0 @# {; n6 H+ Iunsigned char *grayData;
: R# M3 }; L8 h1 c& mint bread;
8 z4 X5 C0 s5 L# a& T
! @& {& B6 @0 O" SgrayData = (unsigned char*)malloc( size );, h, Z- d v5 R/ K9 [) {
# A. Z" _1 ^- R# U0 Aif( grayData == NULL )
4 i6 y! g, i+ A( _* X$ areturn 0;8 \/ C% ^4 m- p1 e v$ |$ [
7 { w3 x' @4 D, s- ?bread = fread( grayData, sizeof (unsigned char), size, s );, Z8 E: M7 f! X2 |$ X
' x# q2 F/ m0 A0 a* d7 `
if( bread != size )
/ D' m4 Y2 E3 r{
5 a# r; S; H' yfree( grayData );5 h1 Y. G/ P" m0 {; x$ ^
return 0;
. [: j# `3 f( x, c7 s3 g- q7 M, r}$ v( X( D" |. i4 C! w
9 b( Z/ s/ w% q1 u& y
m_texFormat = GL_ALPHA;) X" ]9 x, F6 L
7 g/ x7 f6 J5 J! o8 |return grayData;! \, `3 |! |! ^5 u" F
}
5 V0 m$ `; W' A! T% k. a6 ?4 V
% v8 I+ Y1 ^+ N5 o5 etgaImageFile::TGALoadError tgaImageFile::load( char *name )/ W! k0 o6 n; L( E( h. d8 m
{
7 ^/ D. ^- I: q3 U( C. F// Loads up a targa file. Supported types are 8, 24 and 32 4 ]0 J& d, }% y2 l6 }
// uncompressed images.
# t2 b) }! `8 _$ d9 l0 sunsigned char type[4];
/ k$ I0 h0 ?8 q6 S7 cunsigned char info[7];7 U ~+ f0 f: d R! r* D7 Q* ^
FILE *s = NULL;
" B( ]* s3 D4 vint size = 0;% m7 J9 p/ L ^& S
$ ]# S y- d F2 Y
if( !(s = fopen( name, "rb" )) )( V$ |6 b5 u3 E. c; j; m
return TGA_FILE_NOT_FOUND;; O2 o( e$ _5 |& c, \8 r5 s
/ x9 R X+ q- C/ k* x) ^8 T3 Ufread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
7 T F% i! Y' P; y% t- qfseek( s, 12, SEEK_SET); // Seek past the header and useless info2 D" S* M& ~2 p8 P2 E6 _; J. K+ d E
fread( &info, sizeof (char), 6, s );
( ?5 ]' z% J" W+ ]3 ~
$ F4 b2 }6 Z# U6 ?) B& w, zif( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
/ Z4 u" w( F- K" G0 rreturnError( s, TGA_BAD_IMAGE_TYPE );$ |% E4 k5 C+ A' B. |6 \5 Q
* ~. A+ R9 z+ d( X9 mm_nImageWidth = info[0] + info[1] * 256; - j7 L# }. ~) }' S& ]
m_nImageHeight = info[2] + info[3] * 256;
- `& o- I `' D! R+ v* q1 O+ Pm_nImageBits = info[4]; ( b5 v5 u2 h- `1 L
1 X% n' M. e) L+ _# x
size = m_nImageWidth * m_nImageHeight;% W* W" K; ?$ k
' w; Q" k2 Z3 i \( p! P4 ?
// Make sure dimension is a power of 2 6 y) M6 t" W2 W J
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))
5 |; @# Y, L/ ^" t( o, ireturnError( s, TGA_BAD_DIMENSION);2 A- U" y" m) a0 B
$ a2 Y7 e7 [& Y! l" f1 a// Make sure we are loading a supported type 9 _2 I M" n2 C2 m% x7 j' C, n& n
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
* h# ~; l$ l" J3 ]. ?returnError( s, TGA_BAD_BITS );1 P$ o& v4 p* i; T. d4 [0 t
) q4 Q4 y; R3 P) s# c' wif( m_nImageBits == 32 ): P( N: b, V/ X
m_nImageData = getRGBA( s, size );
) R$ y: Y$ r1 V7 N. }3 s, Z& V; pelse if( m_nImageBits == 24 )
% G% q' N3 y! D+ F1 Sm_nImageData = getRGB( s, size ); ' g, s" t5 D5 [5 i
else if( m_nImageBits == 8 )) X$ y8 @% Z% a3 F
m_nImageData = getGray( s, size );$ ?2 E- a1 Y% Z3 z: ]# Z- M0 m
6 S- l* R, X: G2 S6 p
// No image data
2 Q- L: O5 O& R" ^7 C2 b7 e( Y2 m% Y7 Jif( m_nImageData == NULL )
. T2 K$ _% {: areturnError( s, TGA_BAD_DATA );1 h: X/ `( `5 G8 n
, v4 v) I/ M1 U. A
fclose( s );- f" J V& F- l, w& T
5 A! _6 C' o# t( |
return TGA_NO_ERROR;
, c) W; v+ D' m. n- s* d, S' \4 {} _& F6 K6 U1 f' m: x" f/ T, \
a' ?, i6 D; L) e
' q& _$ N3 C+ U5 D! g* b调用举例:8 j; F9 g" l% f! [9 U3 k; d
//
& _5 y8 j/ m& o6 t// For the billboard poly, load a texture of a steel sphere. We'll use a . s. z* `' m0 v' v0 R& E7 |: Y
// .tga file for this image so we can use an alpha channel.2 Y6 j. f) J; O9 B) T/ u; K
//: z0 v: Z% ^8 _1 b+ I+ |( O
# N) ~7 D* y1 N5 }
tgaImageFile tgaImage;: }& k. P5 Z6 f
tgaImage.load( "steel_sphere.tga" );
% I4 `' U: A N/ }8 X& {, F1 ]
9 b; D3 {% u+ F u& M, d1 VglGenTextures( 1, &g_sphereTextureID );
" [1 d( u( Y" ]; _* P) v y. c1 b: O$ p. M# f$ r. K; }: K d" G
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );/ U2 o! ~. M! D9 c' _: R
# D, }2 j3 J3 C$ {; [* Y7 N% sglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );) J& }5 s$ u9 G* d2 p
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
$ w0 H# @4 ~& S0 Y5 h: x) c* n
' @: D6 k, W$ Z% M4 M1 N! FglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
( Y D& B& @. r5 [2 V) t+ TtgaImage.m_nImageWidth, tgaImage.m_nImageHeight,
; a$ D7 o) m/ H# w9 l/ q0 n1 T0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
& ?- Y: t1 E( e: JtgaImage.m_nImageData );[/i][/i][/i][/i] |
|