找回密码
 注册
搜索
查看: 4485|回复: 0

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>! U' c& i% d4 `5 {( D
#include <stdlib.h>
% c7 H/ t8 w9 a+ Y4 F8 f#include <string.h>7 J5 c6 J4 C, l* r* C& A
#include <windows.h>: P6 w5 T! A5 @6 ~& z& }" e; i
#include <GL/gl.h>
9 x3 f* y3 P+ A$ G
9 m) e$ h+ E! H9 y; c6 C$ lclass tgaImageFile( u/ B5 P* f2 g" q
{
: @# V" L% @# Q: A. R" }6 a6 kpublic:
6 p( i$ t8 L- q' k. S+ p, Q2 Y- T9 b; o2 Y( k9 C, V: b
tgaImageFile(void) :   ?1 C* Z, D$ F+ r! G/ q
m_texFormat(-1),6 l; y* `- N# r
m_nImageWidth(0),% ^: ]2 O+ F/ L7 {& F
m_nImageHeight(0),4 K/ S8 @+ `) z/ f  {: K* Y. y. t- D& u
m_nImageBits(0),$ o- M3 t4 V4 @: \5 }
m_nImageData(NULL) {}. d8 w  \/ L+ _5 E/ ^0 A) {

! j" i9 A- J' P3 v  B/ ^* I' X~tgaImageFile(void);5 K5 \6 I* {6 e$ M

% a* M$ s. D5 W3 T, Nenum TGALoadError$ ?8 ]; O# c' O" E
{
6 K: p% ]1 Y$ x% c9 ^TGA_NO_ERROR = 1, // No error
+ P" D1 m; q, ]2 ^. |) y* g" A3 VTGA_FILE_NOT_FOUND, // File was not found ! h' ?' W/ d- x
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed7 ]* r- v- l, \( |
TGA_BAD_DIMENSION, // Dimension is not a power of 2 : \2 S/ c& [, h- {( ~% J0 l, T
TGA_BAD_BITS, // Image bits is not 8, 24 or 32 ; _) v3 j% U' |0 a7 c* H$ Z6 `8 K
TGA_BAD_DATA // Image data could not be loaded
( Y( _, A- `4 p  };
, A9 M7 D. [" j4 W
* Q, e6 k- @/ n' a; F# V+ otgaImageFile::TGALoadError load( char *name );+ n, Z7 Y: p% {* r
7 R. [0 y8 h- z" z4 X) t
GLenum m_texFormat;8 V* M0 x4 }6 t; _  M
int m_nImageWidth;5 Y# C! A" X, R; b+ P' F& C
int m_nImageHeight;- j! ~& ~  i4 n" b, T& i
int m_nImageBits;: T; ^5 g5 o; J6 a4 `$ ~
unsigned char * m_nImageData;7 [: n# {: h/ p( t$ K; s0 J: ]! J

0 ?# D( ^  e0 ^7 d; vprivate:
. U7 I- v; ]) A7 c1 t  l; @0 T5 `0 r  s
bool checkSize(int x);) M: G$ s/ }9 r, `% ~  B
int returnError(FILE *s, int error);3 M6 }! a) h1 X3 z$ \$ ~6 a6 w( }
unsigned char *getRGBA(FILE *s, int size);6 k, c7 B) n9 ]& Q; ~+ v0 U
unsigned char *getRGB(FILE *s, int size);
  e  ]. x! r3 d% w; Xunsigned char *getGray(FILE *s, int size);. h5 k+ I5 a( r
};
4 f( W: [) v. O0 X' O2 H, e
1 }( P- x+ {) b* ?+ ntgaImageFile::~tgaImageFile( void ); D1 c9 a$ A+ A" Q; I+ g. e' r% T
{! Y* l( J1 _8 V
if( m_nImageData != NULL )
% Q, p3 N5 U( M, E+ k; H) ]: L{8 a* t! s- u) z& b9 C6 c% W
free( m_nImageData );
; Y7 W0 Y( q" p6 w; f. Q, ?m_nImageData = NULL;5 }8 E; N5 a! m7 {+ T
}) t! N1 a6 H% M! E' R0 W
}+ A: W; h5 _0 t3 D6 V. v' q5 U

6 _0 k3 S* q$ e! |bool tgaImageFile::checkSize( int x )
& _9 w, K- f; U, w{0 m& z* y+ Q( Q% t" \$ L
// Make sure its a power of 2." Q; D2 o) H% T# F, A/ \6 r0 n( G) T
if( x == 2   || x == 4 ||
. J2 ~  f1 H3 q# U/ o# ~x == 8   || x == 16 ||
6 Q5 v6 O+ v: I2 w; wx == 32 || x == 64 ||4 C6 B1 ^% p2 a6 f
x == 128 || x == 256 ||
* c  d4 X0 Z( n+ j0 D( S9 n" b# nx == 512 )/ X9 y8 U0 q) k& w
return true;
( u: t* }; T$ O* |: q, T* j0 u* G) D' _* ]" x* A
return false;
& [' k: O4 w* t' u* P" g}# I: {$ c2 `5 n0 I, A
# O$ x$ B+ R! P- T, |
int tgaImageFile::returnError( FILE *s, int error ): W2 v) j, [0 K0 Z7 p* d
{
* A6 r& ]2 y( l5 E! c// Called when there is an error loading the .tga texture file.
1 c6 Q; O% E5 X7 n0 t) _) afclose( s );7 \  i% C' I  u( H2 j0 M) v
return error;* O/ @. B7 F6 T( p; n% D
}% o( c* q: L5 Q6 W- {3 B1 L3 N/ x

# t. Y& G: O; Lunsigned char *tgaImageFile::getRGBA( FILE *s, int size )1 H3 j# q5 X: Z
{! r. E' H) |1 s" h. a' b! q
// Read in RGBA data for a 32bit image.
$ r  V3 C% V; d6 J/ ~4 j0 n$ z- xunsigned char *rgba;5 D1 R7 N+ G) g4 Z1 p1 O. s9 F
unsigned char temp;( {9 j. j6 }7 Y6 ?
int bread;
0 i0 {9 I5 I6 v9 Y2 S! n. V. g- kint i;8 ~9 c$ A( z4 i6 w
, D2 m, ~/ j9 @) L$ y
rgba = (unsigned char *)malloc( size * 4 );
0 q; P/ _" w: x, u0 I0 H/ w0 y
' E3 b; `; E% J1 A6 H; i$ oif( rgba == NULL )
- {5 r  [  x9 n8 B- a4 Z5 {; Vreturn 0;
1 d  u) v- p4 h8 I
; `4 O+ G3 d( J& {bread = fread( rgba, sizeof (unsigned char), size * 4, s ); & i& k8 M, _# j% M2 O* {5 n' b, `* w
$ B& ?: x5 c2 J6 U
// TGA is stored in BGRA, make it RGBA
7 w# x" L8 g# ~8 N! ?7 n7 _if( bread != size * 4 ): q9 y* p9 ^- c; ^
{
3 D5 u# O7 ]" s( x' xfree( rgba );: [7 S: g7 _7 t- I# M0 Y7 Z$ S
return 0;
$ Z0 j) ^3 C" |9 x9 y}
4 ^  [& Q  ~( `1 E  U
3 E; i" b( }& ]1 ]for( i = 0; i < size * 4; i += 4 )
! s& {5 X7 c- T# J{0 q+ k  H8 M' o. A5 J2 g
temp = rgba[i];, A2 V) h# m# X: p
rgba[i] = rgba[i + 2];& S. l9 a5 m4 y# i
rgba[i + 2] = temp;
$ o% Y$ @7 q* b8 p, e0 B, t}
0 l9 U6 k: X8 V" C8 C' Y
+ c: s1 V/ ~" T- w7 S% Um_texFormat = GL_RGBA;
/ H; M# q' h! y+ w9 w+ Creturn rgba;
' Q" }/ g7 ~6 M% c/ w. F}
' \+ R0 J6 D+ [
/ M" I) b* V5 i7 x& Xunsigned char *tgaImageFile::getRGB( FILE *s, int size )
1 t, N- P8 _) W6 B1 K/ ~{) F  R. o- c' ^# {: w; V: k
// Read in RGB data for a 24bit image.
' X' m9 Z& N  w# R! I* n: d  g& gunsigned char *rgb;* H& [6 `" U- D$ ~2 a( d
unsigned char temp;
# J7 U# p5 `# n! Y4 @- h0 n- B- aint bread;0 {* ]! d# m: X
int i;& A: Y+ b. |/ k7 {" l0 Y* S0 m& d

) `+ d$ e  R4 t0 P, h6 ^rgb = (unsigned char*)malloc( size * 3 );
# A! k  n2 _0 |/ C! P& Q) \" y/ v$ l/ m: c+ W7 c
if( rgb == NULL )' c, w: ~4 m/ R# e* x: f- V
return 0;
' o! O3 v4 i/ m( _" k+ p0 {' w) h$ N7 _/ T5 c. H0 I, m: w& k- q; t, n
bread = fread( rgb, sizeof (unsigned char), size * 3, s );4 o0 U$ z" t( w' w. P

2 b8 Q; g) }  D0 ?4 i" j/ [if(bread != size * 3)# l: X7 P. y) r! O% e4 o. x& E3 i
{8 Q) W% P3 a  j
free( rgb );
4 @/ i& W4 p7 n0 {return 0;/ Q5 j4 `2 k0 g2 B- j
}
* O6 {+ |; B% M7 n8 w! O! `/ }, Y/ Q& K3 G& r
// TGA is stored in BGR, make it RGB 3 o0 r' d% ?9 i, ^4 W. h
for( i = 0; i < size * 3; i += 3 )
: C) j6 i5 ~& B; E( V6 ^{8 v) m: c2 B0 ?9 H% ~0 {
temp = rgb[i];
, x3 S% \. ]6 T; S; t+ v& Prgb[i] = rgb[i + 2];
1 ^% d& g+ W/ [0 Xrgb[i + 2] = temp;
! d- h6 N0 c/ w! }8 }}
% z. X) `: S* t: p2 r: Z2 Q- V
m_texFormat = GL_RGB;
8 l, a& I$ Y4 `1 K) }3 Q# U8 Y% ^7 l; [' ~' O
return rgb;: K# D! e8 K: X! a8 T6 |
}  r4 z- @# d! P  q& H# [3 ]
* v# O( f" x! i9 b
unsigned char *tgaImageFile::getGray( FILE *s, int size )
1 \3 D% X! ?0 ^) r# H3 i9 d/ `' `$ G{
1 J) r) I9 D# Y# r// Gets the grayscale image data. Used as an alpha channel.7 B" }# n/ U% D8 I8 p7 L# U
unsigned char *grayData;* B6 X) b- [5 E- |$ ^" T) R2 s- y
int bread;# ^$ d: o: X2 Q5 R! b

# x: Q, C6 U$ ?. CgrayData = (unsigned char*)malloc( size );/ [3 s! a2 O! Y. I& Q

5 _% @; P5 c5 G& ~$ _+ gif( grayData == NULL )
9 T9 C8 l3 Y( H8 Freturn 0;
3 C; H% a; _/ H! @; `- Z: ~9 b# O3 j( P. U* |
bread = fread( grayData, sizeof (unsigned char), size, s );
' ?9 A. {  O  ?* |  s: X3 p" K7 e. A! l' ?
if( bread != size )
4 m6 ~9 z7 s* g. m; f{$ ?, A& {( N0 M1 p) C8 O
free( grayData );
0 R9 ?8 K' l' C. P) _9 G5 |return 0;. V4 z8 Z9 @: Y# L
}
7 K; E; W: P$ ^* V' g* p& [
' Z; D& b' U! O1 i* tm_texFormat = GL_ALPHA;5 m3 A2 i4 \7 l; d1 E/ b
" r% ~) c$ O0 ~
return grayData;7 y  j5 {  X; T6 ]
}
1 |5 t$ q  S8 ~1 `1 G  i* n( ]
: s: g  M) r3 H2 Q1 b. e4 @# I+ ^tgaImageFile::TGALoadError tgaImageFile::load( char *name )# F4 a; W4 f) Y2 A5 K5 P
{
+ R/ p+ h" q1 O( ^( O* k% p// Loads up a targa file. Supported types are 8, 24 and 32 + c& T/ t3 J; R. J
// uncompressed images.# y( T, ]  ?( k" ~/ \
unsigned char type[4];4 g0 ?) ]$ g4 Q! N) |
unsigned char info[7];
" J; p1 Y. l" I# b9 v- }FILE *s = NULL;( Z" w6 s! ?( P3 u, T  i
int size = 0;
' Q! ^2 m7 ^7 t1 {( i# A- T3 ?0 ?
! B8 t$ f# [7 w$ eif( !(s = fopen( name, "rb" )) )
/ k0 T" ?+ u1 Q( h+ greturn TGA_FILE_NOT_FOUND;# M; E. c0 J+ d* C; H8 G' o

4 [) E6 J- Y4 W( Afread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
. L# I  U8 ~/ Q$ Dfseek( s, 12, SEEK_SET);       // Seek past the header and useless info
5 Q1 f( i9 r9 {* {  p  gfread( &info, sizeof (char), 6, s );  o; @% X8 D! |: x+ D1 E9 L
; Y7 z6 @9 g8 N4 l
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
- r( P% M0 T& _, z; }returnError( s, TGA_BAD_IMAGE_TYPE );
6 P/ q& K3 c/ L0 E' a
. h  [: ]7 g8 c1 [" Hm_nImageWidth = info[0] + info[1] * 256; 5 w  }! f% X& _+ f! p: g0 O& s
m_nImageHeight = info[2] + info[3] * 256;& I" q" I% V7 Z4 l  L' F7 e" g! j
m_nImageBits = info[4];
& U- h( X" b: b" U$ X, K9 c# l, I' z; i
size = m_nImageWidth * m_nImageHeight;6 e1 y5 a. V. T; L/ U7 y2 o' w

$ i2 l7 A  E& E7 [$ H: A// Make sure dimension is a power of 2 # Z/ _1 h+ V1 U
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))
/ H  q5 q* m' Q6 LreturnError( s, TGA_BAD_DIMENSION);
) _, F% U" Q+ U7 R
" i' Z2 H. F4 R// Make sure we are loading a supported type / a" F3 S. k. C/ w+ ^
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
8 i) h! f. C3 x% |0 B/ CreturnError( s, TGA_BAD_BITS );' D( i& S2 E% s' r

% T' I- X3 U$ @if( m_nImageBits == 32 )4 i6 t8 o/ ]0 {% a" N
m_nImageData = getRGBA( s, size );' v/ p8 S, D. g4 T8 f
else if( m_nImageBits == 24 )( {) {' T: A, u) ~$ I6 \* }0 s
m_nImageData = getRGB( s, size );  
3 u& |, B/ j( r3 Y8 t0 |+ R, Ielse if( m_nImageBits == 8 )
/ e& X) Y; \; n& P" Im_nImageData = getGray( s, size );& ^! E& R9 @  J4 `

" Q2 L' M* t4 w; g: j% H// No image data ( j5 Y. p( N0 x/ u* u; H3 ^
if( m_nImageData == NULL )
/ G( R0 @- ^5 O( N1 K. ^4 CreturnError( s, TGA_BAD_DATA );( e, L- y1 ]$ {* y4 V7 Q8 H

5 A  k3 {+ b" g- A, ~$ E1 Dfclose( s );
# j! w! A& y  R" {6 `( Y" ]- U; P* \2 z. Z; t" |" A& \
return TGA_NO_ERROR;
" B: u1 S; ^4 ]7 r1 A}: `6 k5 c1 v$ q: }( D! t3 L+ r
0 q! F( Z+ S2 L9 H1 C/ L

% u7 M9 Z' Q* m. `. O3 D调用举例:
# e' S# G: U, v) i+ Y//. B4 A6 m0 r& m* `/ }
// For the billboard poly, load a texture of a steel sphere. We'll use a . l, i* ]7 c, r. ~( O) p/ m5 K  \+ X
// .tga file for this image so we can use an alpha channel.. C! M" s: _# E& D0 \
//  L7 N2 ]2 T! I
5 j3 N+ {6 ]+ S5 Q+ \$ `
tgaImageFile tgaImage;
9 V, H5 ^# F) S( w$ n" Z2 Z1 `0 ]: RtgaImage.load( "steel_sphere.tga" );
/ z" r- ^( K% h) ^5 b, q* E2 q3 l
! q; U3 J: `: _* {$ E2 W5 aglGenTextures( 1, &g_sphereTextureID );. `- u& F# E4 O0 R0 _+ a! Y9 D
3 y5 S' J: r. U
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
! e# I5 e6 K6 e( N& F) w; V, a; m- t& b+ B' S+ z
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );% ]  j. G' G- m. h+ ~0 y! H
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );7 R, V6 b7 G# j  N# H* p& ^

& l' Y; h1 q8 Z# F+ iglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, # T( n$ Y3 h% q
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, * w3 N, ?# e' Y
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
$ Y1 l3 O" Q& vtgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2026-5-2 08:56 , Processed in 0.019693 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表