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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>$ L, X/ q! D' I* y8 `& d
#include <stdlib.h>
4 @! b1 ?1 W1 P' O+ m#include <string.h>
6 o  ]! u$ V  \5 f#include <windows.h>
, l' X% l+ D4 Q% g7 N. D6 D. x#include <GL/gl.h>% I& O" y2 Z1 w5 @
. k- E2 t: L9 _( ?$ v
class tgaImageFile
) h# O4 n) y* C5 i6 y{; g& t0 O* H( V, c% Y3 G* Y% D' t
public:0 g% W% g$ S' _. j4 T/ ~- O! k$ Q$ K
: C& Y1 g% I: G
tgaImageFile(void) :
4 Z: Y, ^" u8 \# R+ V  E1 Z: \+ Zm_texFormat(-1),1 b; ~/ E" l. X
m_nImageWidth(0),
, s* `' J/ n/ _3 ~: ]5 t5 Z# fm_nImageHeight(0),
) m) z. R  M: jm_nImageBits(0),
. [7 z8 e3 j3 D) Qm_nImageData(NULL) {}
" n3 U$ h. K/ W( y8 q; H. M4 B; n; K% k' Z8 Z+ z
~tgaImageFile(void);: j3 x! W5 c# q9 ?9 ?: W7 V
! b2 {1 ]% O9 q! @' d/ ]
enum TGALoadError9 |$ m2 [- m. K* N
{
' ~" l3 u, {) L5 i3 dTGA_NO_ERROR = 1, // No error
! c( R7 y! z' j* Z' Z' FTGA_FILE_NOT_FOUND, // File was not found 6 {- K7 L0 F/ Z+ h
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
: K! j/ y6 L( A7 C1 Q  OTGA_BAD_DIMENSION, // Dimension is not a power of 2 7 K/ j1 I: {) |9 Q
TGA_BAD_BITS, // Image bits is not 8, 24 or 32
. n. w% u, `/ L& Q  Q% \& nTGA_BAD_DATA // Image data could not be loaded
  E  b8 C6 l# }% J/ S$ g3 ]9 `$ W  };
2 R, f0 m- E, S# F* B; Q
0 o9 E9 \  O5 z1 r, StgaImageFile::TGALoadError load( char *name );
) j7 Z: `8 Q# l# A' N) F' H" y6 q' Z* C0 M2 J# J! h4 D
GLenum m_texFormat;
/ Z# N: `8 y5 C4 @int m_nImageWidth;& c7 B  b( r# k' Y
int m_nImageHeight;
' _3 ~) s; m( z( W0 ~, Yint m_nImageBits;6 D( P2 K/ R) V' P; d' n6 F5 \5 S# @
unsigned char * m_nImageData;8 k( S9 Y4 }2 `9 ~! n
: U' o, g* T" l  ~+ |. r* ?$ o* l; h
private:
: A; G1 c9 q9 R! K
3 X6 ]  w2 r7 v. b* qbool checkSize(int x);6 s1 D+ n8 D+ ^3 U8 q6 F
int returnError(FILE *s, int error);0 a9 u7 Q! Q! ?5 X4 B3 x$ G( l- b
unsigned char *getRGBA(FILE *s, int size);" F% ]( ?0 u1 N. M) P) m+ u- ?/ D
unsigned char *getRGB(FILE *s, int size);
6 @- l0 N7 Y; I, j. n* gunsigned char *getGray(FILE *s, int size);; Q6 P2 {3 [, e% F% W$ T
};+ D. N1 f1 e8 Y! l4 [8 [
% y8 h  O. j+ ]1 J. ~! c/ p/ u, Z
tgaImageFile::~tgaImageFile( void )
) i: E; b4 c( d+ Y9 w/ h; B. H0 {{+ c4 G, g  `/ J( h5 M$ X7 Y
if( m_nImageData != NULL )# y  x* ^& J  n5 i
{$ [5 v' R6 z- [& E& R5 w
free( m_nImageData );
+ C: W) _0 l- Y+ g) Ym_nImageData = NULL;4 W, v) e8 h2 Z. l
}4 j, l% ~/ t/ i
}5 B7 q5 z6 c1 U
( ^$ Z5 N3 t: n( t0 L
bool tgaImageFile::checkSize( int x )
, G4 z5 w2 B3 t{4 d6 O0 G1 S" j. Y
// Make sure its a power of 2.# m( ]: p! X# X( D, ~+ d
if( x == 2   || x == 4 || : p5 T+ ]  S, @  q- v2 O
x == 8   || x == 16 || ' D' b6 A4 D& r/ k2 g$ X& `
x == 32 || x == 64 ||
" z0 D- W7 ]. p$ Rx == 128 || x == 256 ||
  m3 y8 }- R. Y  ]. K( ix == 512 )
2 u6 M/ p( \. P* D! h& wreturn true;" A0 a7 m& P) \# s6 v
. \5 L9 x* W4 U! J3 y- h/ h1 a
return false;
& _$ B) ^, T0 R" p}
4 n% B& S. f6 k, O! E, q: \) I" G1 M
int tgaImageFile::returnError( FILE *s, int error )/ G/ p6 k+ w, c& t" K; X% b% w+ U' o
{
1 _$ X7 P  i2 p! i) ^// Called when there is an error loading the .tga texture file.) C; X! G1 B0 G8 G) d8 Y
fclose( s );/ o# A, A3 h4 C# A7 ~8 |+ f
return error;
3 D# V5 M* u! w/ c3 n; E' r}
/ [- B4 h0 H& n& U+ X
$ x; L5 ~+ w4 Q' Z2 r" B& [unsigned char *tgaImageFile::getRGBA( FILE *s, int size )6 S% n. _" E; n, A7 e
{
$ }* P" f" M8 X% b  k  B// Read in RGBA data for a 32bit image. 1 o) Y& }* Y+ Q# a
unsigned char *rgba;
1 \6 K% l/ v- ?unsigned char temp;
. w6 H) w' h8 Q! M+ J- ~0 `int bread;
7 t0 o8 _/ t8 D) E, J9 ^int i;( g* V' I7 @* u4 E5 G7 T& ~, C, j; L
/ i, U7 P4 S9 a6 W5 ]2 t$ X
rgba = (unsigned char *)malloc( size * 4 );
; M0 z, N/ c$ H4 F+ p& {) H9 J: G: g$ F/ B* v
if( rgba == NULL )5 b- K% \4 C) I$ Z9 G
return 0;8 ~7 @& B  S8 t' \3 `7 M5 }

0 w6 m: A1 R' b" D7 u  cbread = fread( rgba, sizeof (unsigned char), size * 4, s ); . d  R& a3 J( t$ p0 b* g, V6 e
( N. b6 U  J$ ]1 r+ V, ~& [
// TGA is stored in BGRA, make it RGBA 2 e, O' n$ i  E. k' o
if( bread != size * 4 )9 ^5 |8 e+ Y( T
{$ V: D; ?: v2 @1 L/ v! i& j
free( rgba );
& z3 ?2 _" k* R- Wreturn 0;
# f8 K0 M6 N+ i2 j9 R) z* _}
5 ~) v* f' H/ w! ]) o) W0 G. G' V
3 a+ `- t$ y& g3 R. w( vfor( i = 0; i < size * 4; i += 4 )
) G' G. q2 x3 I3 F{
' j; x; n/ G5 `2 gtemp = rgba[i];4 Y0 _  ?3 I2 t2 Y
rgba[i] = rgba[i + 2];* a! H7 j9 `2 d6 h( x% f
rgba[i + 2] = temp;0 d/ Z% P! O5 u/ i1 h) `
}
3 ~% p9 v/ i( k2 P
7 d, a& e1 K; e* d. cm_texFormat = GL_RGBA;
+ ?! C5 W$ W4 F: Wreturn rgba;. W* J* E8 f! q9 H- ^% D% I0 @
}3 P) w' i! M3 I
& I, U) K8 n( P" a+ {
unsigned char *tgaImageFile::getRGB( FILE *s, int size )
9 S9 w2 Q1 t3 p! t{$ I. g8 p, O, L& g
// Read in RGB data for a 24bit image. 5 v, x, {, c9 ?4 v& g1 U8 K7 `
unsigned char *rgb;
& ]; |- J- Z, p: }! e2 ^unsigned char temp;! A8 v/ s7 d1 A3 \5 f8 F
int bread;6 L  L7 A* ~% d& U! }1 y3 z
int i;. Q  s/ |& [' C  E; ~" l

# L# m+ T6 f7 P1 I6 Y- Lrgb = (unsigned char*)malloc( size * 3 );, T/ z0 T. F* J8 Z

4 \$ B% `: Y' x# E8 `( B8 `if( rgb == NULL )/ H# h) q3 f% _" a  f8 V4 c: ?
return 0;
# x. q0 T% K2 Q2 ?( ~8 _# A# m5 u; G+ e, s
bread = fread( rgb, sizeof (unsigned char), size * 3, s );/ V/ R  y( O/ i1 D; Z
2 M1 g2 L. _5 s; ]/ M& @3 c; @% Y
if(bread != size * 3)
( R/ h+ b; v$ ^; J$ K6 Y{$ L! h' J0 H, Z/ Q. y
free( rgb );
* t- d" V0 S9 R+ Ereturn 0;% V2 ^. Y) ]! i! o5 u, |8 O
}
, N5 q/ x/ |9 w5 W
" ~3 \5 }4 w' k' k4 r2 S9 R; e// TGA is stored in BGR, make it RGB 5 Y$ \; e* q' K# l6 z2 U
for( i = 0; i < size * 3; i += 3 )
, D9 }& D7 z9 v; A{
8 x1 [! `8 ]! Ptemp = rgb[i];
9 l( y7 s& I% q: argb[i] = rgb[i + 2];" D. X) ~4 v5 K/ B- o, G( z8 U0 h: y% E
rgb[i + 2] = temp;
: B. c  o7 j# v. v' ?& n/ J9 K}
' a4 |- Y$ Z! l; E* O' Q$ b, {) {3 ~
) Z4 [* {0 A( L8 r+ i! um_texFormat = GL_RGB;/ A4 e& x3 W4 n; E! w9 D

# K* B0 x% i1 W% breturn rgb;
; P7 H8 p6 W9 [}) }( Z2 [, N" G" ~" H
% K; K, _" Y  e" @0 Z0 R5 W
unsigned char *tgaImageFile::getGray( FILE *s, int size )# E8 h7 ~  \. L
{5 s1 [. z. d+ E# k# [
// Gets the grayscale image data. Used as an alpha channel." E/ A' e. v/ J
unsigned char *grayData;
8 }" p5 h3 p( G9 m9 ^int bread;; f3 c, a+ S3 E# B

2 G! \& [  o1 c7 i3 R9 S! GgrayData = (unsigned char*)malloc( size );
% b7 X" J% ?9 }
4 D$ V" C8 R' Bif( grayData == NULL )
! e$ p, F  }0 A1 u, q/ r& Greturn 0;
& m* p+ X3 s/ @& ?/ V
% R0 ?  h/ t& |7 t. Ybread = fread( grayData, sizeof (unsigned char), size, s );6 e, ~  z; Y/ b) _1 B

- t1 R9 `, u6 `* yif( bread != size )
. Z5 m4 y" `, m1 p, X) A$ l{8 ]$ w1 i" p; R; M8 E
free( grayData );* z+ I* i3 h% V- N7 r, P5 p
return 0;) o: V: u1 u$ R1 }- d' y. F
}
1 U, c; R6 a% q/ a
! A7 o. I+ i4 A2 N5 \, R3 @m_texFormat = GL_ALPHA;
' S4 A: u/ |/ x, f9 M) S3 {4 ~2 i. ~* V& ]# _2 X
return grayData;+ ~, u( F3 ]' ?! V. \
}
# R7 ^) a8 h3 N; K" ]0 R/ S0 X& a
/ F7 P( F2 Y3 V. ?. U5 HtgaImageFile::TGALoadError tgaImageFile::load( char *name )
5 P. h! a- J) j+ C" ?# @6 k0 Y{
8 @3 T  Z+ y" i  l// Loads up a targa file. Supported types are 8, 24 and 32
1 ^% Y; P; E5 D// uncompressed images.
- V/ U' h2 z3 E9 r/ H% dunsigned char type[4];
% P1 `; Z) ~+ v8 t4 T2 G) K/ iunsigned char info[7];
! G: v$ g; e" S, H. ?3 {FILE *s = NULL;: a$ o3 \8 D* x! n1 W
int size = 0;
# f: @; n2 j% T# h, N8 W4 @3 \* A2 ~0 r; E& X
if( !(s = fopen( name, "rb" )) )) Y1 V9 \: v/ v  E
return TGA_FILE_NOT_FOUND;
: `6 j; P, Z/ `1 R1 y- b2 h& p+ P, W
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored/ H; C4 |- b! O  @' J0 n
fseek( s, 12, SEEK_SET);       // Seek past the header and useless info
0 b- D- d$ D# f( m+ ifread( &info, sizeof (char), 6, s );! [4 B; M! c+ {- R! J* J

4 b8 O: W: F; p& x9 o+ cif( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
' z5 H. r' l) g4 }' S' SreturnError( s, TGA_BAD_IMAGE_TYPE );. R6 Y& C2 b+ W- b$ Y" N! ^

* A" _3 J' P4 d, t; X' p- x! V$ _m_nImageWidth = info[0] + info[1] * 256;
6 q; W& L& w8 `5 G8 ~: ^m_nImageHeight = info[2] + info[3] * 256;
6 @! Y* A( H, d2 ~m_nImageBits = info[4];
, c- C% Q6 M9 N; S* E" l1 K6 R! d: f* L& J* ~  o
size = m_nImageWidth * m_nImageHeight;
! O: N+ |1 C4 ]! C3 c: W, @0 I9 C4 F! \3 R4 G
// Make sure dimension is a power of 2 1 z+ p" t) D" @
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))
( J' o/ M1 m4 L9 @. G" ereturnError( s, TGA_BAD_DIMENSION);" v: i8 C2 T$ y3 Q2 f, u  U

; k5 r6 z5 J  J6 ?( A9 P: J9 j7 k// Make sure we are loading a supported type
3 Q+ B, f3 d* v, ]4 Aif( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )( G' i+ c5 e2 o2 x% ]+ _/ ~
returnError( s, TGA_BAD_BITS );
- ]* _6 B6 l9 B. S3 e: W
, M- N& N: w9 W! v4 Nif( m_nImageBits == 32 ): I: }  }4 |: L% i
m_nImageData = getRGBA( s, size );
5 e( k( f! @. x  A8 v& Qelse if( m_nImageBits == 24 )0 R# A6 B% n7 i9 c1 x6 h# }
m_nImageData = getRGB( s, size );  4 B; n. t9 ~% W9 |5 B
else if( m_nImageBits == 8 )3 c& f$ f: W4 H
m_nImageData = getGray( s, size );
, |  m) [4 i$ m2 P9 _# D# I( e7 e- u% h+ N
// No image data 2 ]8 P% e1 E( G6 U" ]
if( m_nImageData == NULL )
# p6 w( t; d- KreturnError( s, TGA_BAD_DATA );
9 R, |. A) T/ ~* ?3 k7 Z
+ \- X; y3 v1 o; Xfclose( s );
/ f! [% c+ ?4 |; ~& @1 W/ @. w7 i9 p" Z  A0 H
return TGA_NO_ERROR;
+ p2 N0 ^( H) y( E; |}  b( U# B1 _) ^3 T3 z
; M/ u4 }3 @$ I) e7 a" k
2 {: w: {* x7 }! q( I
调用举例:
4 G! F$ f2 L# J6 C: [; |//) Q! H* [5 ]6 L/ Y
// For the billboard poly, load a texture of a steel sphere. We'll use a
- V: ~/ v" q+ P- D2 r6 s/ S// .tga file for this image so we can use an alpha channel." h0 l% e7 G  O6 I( a, t
//" C3 O  O* ]# I; ~7 `
  A6 f- U) O: z5 P
tgaImageFile tgaImage;
% d: r; X# v9 M5 |' z0 q& wtgaImage.load( "steel_sphere.tga" );
5 j& P) E6 A4 l9 O/ }. B4 g; u* D1 k# n
glGenTextures( 1, &g_sphereTextureID );
- D$ f7 y. H. H: `6 d! B8 c
( G* I3 t5 Y( B# K2 }! m- @glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );7 d$ p3 O+ q* U. M. W* U

1 z  B3 \- X5 V; AglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );0 `: z8 ]3 f( \
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
3 p4 j  `& K5 ^: `) k2 J* I1 V1 W' A0 X( C: K
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
1 W5 u& M6 d$ ~* ]+ |tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, + M9 H! S3 \8 Z
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, + ~$ D+ n; E6 C. {. {5 ]* M- H
tgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-20 02:32 , Processed in 0.038190 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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