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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>
( r" s7 C  ^# y2 s: v  Q#include <stdlib.h>
+ f  v& \' }) C2 {#include <string.h>
, [9 y! y1 d- K9 K5 l, X4 B#include <windows.h>
& d& y1 ^$ j) A. V) Q: n' ~#include <GL/gl.h>3 P& e& X! ^* T3 k/ g+ ~8 m+ r

& {6 T! m' X) h2 e1 R# t' `class tgaImageFile, J$ t' b) Z1 f1 [$ u; j- C
{' e4 ]. a6 a" X: Z6 ^1 d
public:
6 ?) x* P5 ]8 N' y
+ y/ v9 f& n9 s& ?- {& R) OtgaImageFile(void) : ! F6 @) t# ^! `  D" N& U
m_texFormat(-1),' A/ r; K% t& }7 q
m_nImageWidth(0),; i6 u- ?* W, J( L6 \
m_nImageHeight(0),8 _( R3 x5 ~) I4 x0 I8 h5 h
m_nImageBits(0),  |4 Q* X+ [1 R) h
m_nImageData(NULL) {}3 e" T% c1 M2 K
  o, _0 O: [! n9 I6 |: v3 M
~tgaImageFile(void);
0 r8 ~# y% g" F* _! b
  _: d7 x* K1 oenum TGALoadError& E) z8 i% g( L$ k; Z* \
{/ {2 G# u$ X' K* [& X+ Q: s
TGA_NO_ERROR = 1, // No error
; Q  Y# X2 ~0 ?- KTGA_FILE_NOT_FOUND, // File was not found 9 l5 _  J  M0 Y& [
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed( d+ H* h( I" W
TGA_BAD_DIMENSION, // Dimension is not a power of 2 ) a* S) ]  O5 @& V$ o; Z# e
TGA_BAD_BITS, // Image bits is not 8, 24 or 32
6 c2 u& L% q6 C' }0 _3 NTGA_BAD_DATA // Image data could not be loaded
4 x0 p; D8 H( B8 R  };, m- f. l( A; p- v& a
, |: [7 d, v( t9 G% [
tgaImageFile::TGALoadError load( char *name );
7 O! p! o- Y* F, c
: A; A' e8 O/ |$ U* f$ K6 [GLenum m_texFormat;( m8 E6 L, v& k9 `# o
int m_nImageWidth;' p2 {" T+ Y" G& S, [/ q
int m_nImageHeight;
9 ?; S$ a2 N; E3 J. {int m_nImageBits;
8 V3 n2 }* w6 _0 C( ~" Qunsigned char * m_nImageData;% p: F; K  a6 `. ^# g0 }* l0 D  N" r; b

, U' y( r; ~9 [3 E5 O2 gprivate:
/ J- n( p% K. r0 ?, g2 y3 T8 L/ a) ^- H
bool checkSize(int x);: d) t8 s7 [1 L1 L
int returnError(FILE *s, int error);
; ~& X7 P4 I) t& I4 m1 A: a1 z7 lunsigned char *getRGBA(FILE *s, int size);) _+ W; r; c3 X
unsigned char *getRGB(FILE *s, int size);& P& G6 w  ]6 {6 [* ~
unsigned char *getGray(FILE *s, int size);7 ^& d0 h; T+ `2 m0 C% L' j
};
( E; h% m) Z0 R3 P. i6 {, A$ \/ P$ B0 t
tgaImageFile::~tgaImageFile( void )/ A9 t8 h$ s) a) Q4 M0 n# o; J  Y
{
# l$ b, g. @5 U7 }+ u6 D9 mif( m_nImageData != NULL )
% L$ a- h2 W0 k7 g3 l4 Y3 l{- ?# W3 Q# z8 o  _- I* T0 A# L
free( m_nImageData );% d5 u. R0 `2 g! i2 U0 c
m_nImageData = NULL;, v! M. Y% o$ {& S
}  O& m4 L  Z* z9 ]
}
) F) Z' c1 u# D* P
' q6 Q- _. ]0 O5 t% Z0 d. K$ |bool tgaImageFile::checkSize( int x )
3 @% ^% F( W& O3 Z: A1 M{
3 m" k6 g5 W$ X! J// Make sure its a power of 2.
) w5 f1 r$ ^5 k' S# j3 z: Dif( x == 2   || x == 4 || ) d# b4 J& P, o9 w  w1 U
x == 8   || x == 16 || - J( r+ H  k' @' ]
x == 32 || x == 64 ||
5 Q9 z2 x  G$ g0 F2 M3 ox == 128 || x == 256 || & f, K6 r" `, y: F
x == 512 )5 d; R- e  P3 f: R' v: u9 W# y
return true;0 u$ @, i3 b3 s

) G% T  E; l4 E: @8 creturn false;$ o, ]  v; ?5 M0 ~9 j7 e
}# y9 \5 p$ z  V
9 n7 b3 u  u* F- I+ E0 G( j
int tgaImageFile::returnError( FILE *s, int error )
8 e, P  \" |# ~7 z{
. u) f/ z  ?3 P: V+ Y  y// Called when there is an error loading the .tga texture file.
5 e/ I) q% R: z3 |fclose( s );/ D2 O7 {0 y. n, D  H
return error;1 [% H+ I  P1 }1 c7 ?# W  }8 S  c0 |
}
( Q. Y9 y% p' y% Q9 S
8 F0 F% A$ H& i7 _unsigned char *tgaImageFile::getRGBA( FILE *s, int size )# d! m3 v1 |7 }/ X8 e: B' Q
{- d3 C5 w) s# S" s
// Read in RGBA data for a 32bit image. ; x- |) k/ @& m' U' `; p
unsigned char *rgba;
0 A$ {1 W$ w6 I* Vunsigned char temp;; @% O. Z6 I) X: k; A' u
int bread;
3 V  v" z" L6 K7 j- ~int i;+ g' U" ]6 S- e2 Q1 ?

! E) p8 r# D: d8 K9 ~rgba = (unsigned char *)malloc( size * 4 );* O0 Y; \0 D: h7 d7 p$ b5 @

8 t4 I5 g! i# r8 K% A% F' S1 nif( rgba == NULL )* E2 a; K1 n6 L6 S. p
return 0;" k4 y& A8 ?/ E" h
  @, `5 K4 g) H5 P: C
bread = fread( rgba, sizeof (unsigned char), size * 4, s );
! l( D/ q) a2 V# t& Q' d- ^# p
) `+ l/ a4 S! {1 ?1 l6 j7 I! P// TGA is stored in BGRA, make it RGBA
1 U) o1 ?8 ^$ e" O* x' hif( bread != size * 4 )* Y/ _  Z/ [" P# W% L) v
{
9 }/ f9 C3 f# E. i; tfree( rgba );
) h# O. H" v# _$ T& L* u2 X) ?% ~return 0;
2 L1 o$ l  H/ k}* c8 j2 @0 L, j5 ?$ q

/ k; h/ ?  N7 p' s! g* Nfor( i = 0; i < size * 4; i += 4 )
0 r% w! h0 ~$ W8 N) k* Q0 ~& i{5 c# X! o1 k( R7 H5 ]! Y- O" I
temp = rgba[i];
/ o! r( {; ?8 J. X8 P# h0 K2 Grgba[i] = rgba[i + 2];9 \8 p) `- w" q
rgba[i + 2] = temp;
" K8 l& s, q( s3 |}% K' r% D+ [% u* O9 z
8 m4 S" `7 N% f9 P; t1 P- b9 N
m_texFormat = GL_RGBA;& }/ o" c; j" p
return rgba;
- Y  j) Q2 ]4 }4 r}+ c# I! @( x# G! E

; o" }( [: _: t8 l& a- g' h) k# zunsigned char *tgaImageFile::getRGB( FILE *s, int size )) [/ u9 H& v+ }, ]
{7 \/ S% F; U4 e  H/ `: r& m. E" z/ s
// Read in RGB data for a 24bit image. 0 S% R3 l( l6 N( z- z
unsigned char *rgb;
5 x$ p% W" H) J' vunsigned char temp;5 A9 T* K% F( T, \! ]* P
int bread;- k( }( D& ~& t
int i;
1 J) I; j% @1 N* y0 B  e
: i0 g7 P+ Q7 f/ U* A: \rgb = (unsigned char*)malloc( size * 3 );
& o* {  |$ g5 t! \6 x
& `5 A8 _3 |' Z" M6 L/ O/ qif( rgb == NULL )6 ^, N+ f0 o- W
return 0;
  J& [7 S! U3 }. G4 e6 Q
9 }* r4 v# G8 q( Bbread = fread( rgb, sizeof (unsigned char), size * 3, s );' U( @" x! o% g* }% ^9 Z. m

2 l  o& q& {" p. i7 `" @6 vif(bread != size * 3)2 ?4 C: a$ j1 k) K2 e$ i; O
{) J; w5 K9 P% W
free( rgb );
0 ?5 m, C) G: J  ]return 0;- @2 i1 ~% N% H) q$ L
}0 \/ ?+ V% Y2 N5 Q

1 E/ B( b- L$ m9 V1 d! d+ x  L// TGA is stored in BGR, make it RGB $ w8 T( V" V) `) |7 d
for( i = 0; i < size * 3; i += 3 )% G3 e/ b* h$ p7 i/ h# ~, N
{. [5 X5 t  S/ C/ [2 Y) l1 P
temp = rgb[i];6 u, g) Y4 D! G. V. q/ F/ m
rgb[i] = rgb[i + 2];9 G9 i5 e9 B) {9 i4 D
rgb[i + 2] = temp;9 M1 {& W" J9 a  x+ F  l
}) R) f9 r+ G8 ~
5 r% X  I+ T6 N9 y8 \% h" f8 y* |
m_texFormat = GL_RGB;& W* N+ C! K7 z4 N$ ]+ }% L# C6 Q
) l# G  q8 J& w& }, I
return rgb;8 y* |! R- t1 r
}. o& B$ w+ p2 m' A. ^/ P1 Z6 E
' s: Q9 s4 M5 |$ J5 v
unsigned char *tgaImageFile::getGray( FILE *s, int size )1 D8 E6 Z% H8 a$ ?
{' H" |+ {3 \7 R- H# s3 M
// Gets the grayscale image data. Used as an alpha channel.
. Y8 F8 J1 S& F; M8 Aunsigned char *grayData;  Q9 O5 I! c8 ~0 z3 K) k, q
int bread;
- J& S& e2 x) o. J3 E6 J+ T, W1 m: b
! l7 ?( Z# M- U$ D! K% zgrayData = (unsigned char*)malloc( size );
& E2 P0 e) K5 v& s# }+ {* h5 Y' |; N- q0 S
if( grayData == NULL )' n& P' t, {! t5 w) f3 e! W; j
return 0;
" }9 v% m( o/ D8 W% J1 d2 _' ^+ T* ?+ `1 o2 o3 F: W, N
bread = fread( grayData, sizeof (unsigned char), size, s );, E3 E$ G% J( v2 f5 Q

1 C; H5 _5 l6 \: j5 ~% H+ |if( bread != size )1 F" Y( \% }. Q& p
{  _6 I1 H* Q& M9 c" \* t
free( grayData );! f* C9 f& H0 F0 u, c
return 0;3 _; y1 W7 Z& B' e0 L3 j: _1 ^
}3 s6 X/ p$ c+ a" `. j2 x
9 O3 w; I9 E! H
m_texFormat = GL_ALPHA;. [0 e, ]4 p9 i
) s  S/ \, i4 A& {" a) ~8 Y
return grayData;
$ s, O; k% J% `& c}
' b7 b* e2 U& l+ S% T+ X& F& `* z$ s
8 h' w9 e. w& v4 ZtgaImageFile::TGALoadError tgaImageFile::load( char *name )& d1 Y2 ?( j/ P5 _
{! I6 E, A7 S5 [8 Y+ n( H
// Loads up a targa file. Supported types are 8, 24 and 32
- D0 M/ q1 j4 P" m5 A; k: ~// uncompressed images.  t. P1 W  b/ M& @' x( h
unsigned char type[4];
1 k6 n# {  E5 x1 Eunsigned char info[7];
/ m( K; B4 M$ B0 w) ~FILE *s = NULL;6 T  W5 @; c) j6 Z- m: `
int size = 0;
5 ^% {: I: ^  s8 ~7 H  V
2 _  _7 G5 M& P; V) v; F4 D5 ]if( !(s = fopen( name, "rb" )) )4 {5 e) [  B# K, B! Z# ^
return TGA_FILE_NOT_FOUND;, h! [6 s4 Y3 g+ O
1 \& F! T+ E6 G
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
. u9 S* ^/ Q) u0 sfseek( s, 12, SEEK_SET);       // Seek past the header and useless info) P/ u4 @; k; _% _
fread( &info, sizeof (char), 6, s );
8 ~0 E4 u1 B! D9 y; q
, ~& @: o3 W& `7 bif( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
/ J. @- t; g( L, C  [1 }% EreturnError( s, TGA_BAD_IMAGE_TYPE );) Z% d. C" A: }
4 v( w- W( S8 N% l8 e: x
m_nImageWidth = info[0] + info[1] * 256; : D- d, u2 X, I2 P
m_nImageHeight = info[2] + info[3] * 256;
" I  ]$ @0 @/ Nm_nImageBits = info[4]; & h/ T5 p! F# Q: _
( @7 z3 s4 @  i: F; s
size = m_nImageWidth * m_nImageHeight;8 E/ j" i- l1 ^) W/ q( u. z9 o
" L& v" D( i/ {- a( P
// Make sure dimension is a power of 2 # x! F5 P5 U# a
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))
4 a7 v8 c) ~" r: U. X' \returnError( s, TGA_BAD_DIMENSION);: s# B4 h! ?' a; J! |# g

, J' e" ?: L) O* W+ S2 |! B// Make sure we are loading a supported type ) N9 r. ?6 `7 n" S8 b4 X" O" W
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 ): A& ]* R, i0 N. Z. @" T
returnError( s, TGA_BAD_BITS );( |) r: K# t8 f6 P

+ R- q2 i: v: Fif( m_nImageBits == 32 )2 g8 X& g6 a# J( K3 ^% W$ c
m_nImageData = getRGBA( s, size );
# r7 k. `/ v- D( oelse if( m_nImageBits == 24 )% a% Q. Y, v  B0 \7 D- v# j
m_nImageData = getRGB( s, size );  
3 C* M9 P. H! w# X; I' belse if( m_nImageBits == 8 )
. }. u* u  ]6 y) S, p& Rm_nImageData = getGray( s, size );
- E6 F8 ]* B! a& @, D. N0 X. K8 R
# c8 `% h# {+ ?" n' c* O// No image data
2 m  I& ^# \3 K9 A3 a; _7 e2 c% u. s" pif( m_nImageData == NULL )% \2 h2 B0 g0 N5 C
returnError( s, TGA_BAD_DATA );
  P7 S' X! K2 V! w$ m6 `/ w6 \: P5 c: i8 U- u( ?
fclose( s );
  p( T) L# ?3 b$ k5 _+ K3 `6 T# N$ U5 E+ b; f# p9 x
return TGA_NO_ERROR;
7 `1 a9 U2 L, p}
+ u. k5 d9 ~! C: c- A$ ^6 ]
& c" V9 I# I1 ?  K: s
. A9 S% X! |2 T: d$ p, j2 L; F. w调用举例:  `$ p* w) s  M( \" t& B
//
/ l9 k8 }3 M- C4 T- j// For the billboard poly, load a texture of a steel sphere. We'll use a
) {/ ?# y# r; f+ w// .tga file for this image so we can use an alpha channel.% U0 s& H; b: {0 G9 \
//
) [: [' _0 P3 u+ o' r, T) \: w) _
# n5 y& T2 u3 n" s+ }tgaImageFile tgaImage;
; l$ V3 l& q3 o% \tgaImage.load( "steel_sphere.tga" );$ k7 ]' E( k: D" ~( X% L4 @& N

& N# b9 d1 G+ r& JglGenTextures( 1, &g_sphereTextureID );& A7 Y! k9 O! e% _# P, j

- L( N3 c: ]3 b; c  JglBindTexture( GL_TEXTURE_2D, g_sphereTextureID );; T3 O5 n/ H  |
1 M% B2 Y/ o. }# S
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
, Z8 z, J2 a3 R/ X3 o4 ?glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
3 q: Y& q# g3 u# V& B; u
. d0 q# S0 Q" G+ BglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
5 h& Y) [, W1 ?& X. a$ a/ ]tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, 8 |8 `% d$ [- d: S3 W/ T" {
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
) |3 s/ y) c2 {& C- I% HtgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 11:47 , Processed in 0.018893 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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