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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>
+ F1 g" x4 J8 h- b* _! R+ ~#include <stdlib.h>
* g$ b+ P( C7 P#include <string.h>
. L% Q% U$ U" P& j; b' n#include <windows.h>
- \% Y. `6 ?5 D" H#include <GL/gl.h>6 o4 W& |6 p6 s
& X4 H- N/ X! I% X  ]7 v
class tgaImageFile0 z+ R7 p. D% d- T0 B- _4 m' _9 U7 U
{
" _. v9 w; k) l" F3 y5 F7 }public:
6 \# o$ j& v! t! l: x4 b& |$ \, ?; r. J/ y# _
tgaImageFile(void) :
' X6 S! S8 z, P7 ^' e" P( p0 _3 H: C1 lm_texFormat(-1),
3 g4 o1 h8 M! F  E6 Im_nImageWidth(0),3 M2 a% z1 J* U) M& P% e
m_nImageHeight(0),
: [& e0 s! a0 @1 a0 u, }m_nImageBits(0),
8 ?/ @0 f. [' w# y% J9 ~+ |m_nImageData(NULL) {}5 E& U4 T& C" }" X6 y# X; e

8 @( T, ~( g9 M: J9 Y. S~tgaImageFile(void);% r3 g6 w" c0 n2 n

8 Z0 ?# d! P0 E) S5 O/ w/ U7 X/ r: Wenum TGALoadError+ B* p4 \' a) a; N) J+ y8 h$ T
{1 ^% z8 I% E+ n- Y- f
TGA_NO_ERROR = 1, // No error& d: f+ n8 M1 j0 T  d" Z# Z
TGA_FILE_NOT_FOUND, // File was not found + I0 ?0 U. E% x0 F8 i- ~
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
2 Q4 M/ t$ }" R, S. L1 y) T* I: X: bTGA_BAD_DIMENSION, // Dimension is not a power of 2 * l( u1 P+ t2 y# U) ?2 A* t4 q( v5 `  C
TGA_BAD_BITS, // Image bits is not 8, 24 or 32 : G% s4 _' D+ Z3 w# ~4 ]1 _
TGA_BAD_DATA // Image data could not be loaded
) {; o. h  j( L* U) Z# U  };
  N' o$ w1 Q3 ]! x4 e3 [0 [3 u1 H# p
tgaImageFile::TGALoadError load( char *name );- o+ T; Y; \$ n3 X2 w
; f5 v1 D* l# v2 U& G& D
GLenum m_texFormat;2 a* A) s; V; S$ I; s0 q9 t0 ?; n
int m_nImageWidth;
% h  h2 _0 v' m3 j3 G3 C4 qint m_nImageHeight;/ ?0 O6 [% b. q' L
int m_nImageBits;
& W8 O' X- [3 l; m0 J- Bunsigned char * m_nImageData;
" m; ]( w0 W, q3 h8 l0 m* V$ P/ V
private:
! J$ w$ v; H9 i9 `4 X. R7 Z3 i; J) g3 ^& l8 u) `5 ]5 I  S
bool checkSize(int x);
, y. t9 y5 x8 n1 g$ X! y: eint returnError(FILE *s, int error);
% s) i5 n  m- O9 e5 c$ P! i  ^unsigned char *getRGBA(FILE *s, int size);- h2 z! t2 p* @# g- A: E
unsigned char *getRGB(FILE *s, int size);" W" ?/ G6 ?2 J8 ~! x+ @, \
unsigned char *getGray(FILE *s, int size);* T* {( A0 [' t' A# `0 S/ o
};/ x+ c& N  A' N/ I
. n# e$ Q" K/ I$ P4 B
tgaImageFile::~tgaImageFile( void )
5 @! ^' W8 C( a' V5 T- Z+ v8 p3 t{
% G% V, S4 R- @0 \& c! Oif( m_nImageData != NULL )
7 V2 O: y1 v& O; n1 W{
$ \$ ?, ~5 U% R4 G8 o. l+ |- n; yfree( m_nImageData );
9 r1 V) A4 l3 j/ p5 Wm_nImageData = NULL;2 G2 r& w; F( c
}
2 t# o8 F1 w' b. z: B}/ ~+ k1 ?  g" y  r6 I+ E
! B" S( }' t, O: x0 h9 `
bool tgaImageFile::checkSize( int x )
, F% L" w: G, m& H' H, R# I6 E{
0 J  z, K! `8 [& y* C' Y) \2 z// Make sure its a power of 2.' A& M  m! u+ g* ], M
if( x == 2   || x == 4 ||
7 |  v( j1 ^) a( ~0 J9 D8 n" g( m, ~x == 8   || x == 16 || # D% {, a6 j( ]# J4 X2 H
x == 32 || x == 64 ||
# E% O$ ]% b0 [1 w6 f2 Z3 U5 Z& Lx == 128 || x == 256 || , W, W  W$ W; l  ^. B& C: s, ^" F
x == 512 )
; ]" q% J, d- r- a4 Freturn true;
; K  h2 v7 w1 ?  e3 j
# G+ g. v5 R: ^# Q" A) Ureturn false;& O) V: B  n1 u4 W& o7 N
}9 \" ~* r3 {5 a

/ P. c9 D5 |/ ]& d7 w0 mint tgaImageFile::returnError( FILE *s, int error )
& c/ _1 Q. x- g. x! \{6 q" m& w! r3 I0 s: d
// Called when there is an error loading the .tga texture file.0 b3 l2 h! S2 D# D
fclose( s );
& [! @% o' H1 f( `! Nreturn error;! u7 g0 d& U: {
}
8 q! S" Q' z$ y# X1 a  F1 t4 ]& m8 x% ]& B7 {$ w9 @- z5 S0 Z2 y
unsigned char *tgaImageFile::getRGBA( FILE *s, int size )
" M% j3 \/ {2 O3 t1 O# v{
  Q9 a- {5 ~2 X5 X& o7 V: ?// Read in RGBA data for a 32bit image.
) r$ g: S8 i9 i- V( iunsigned char *rgba;# ?9 _3 n0 M2 ^# g! o' @. B
unsigned char temp;7 q1 Y& h6 w4 q4 K% {; s
int bread;
, Z$ _) x3 g$ m# I9 ?+ E! M8 U* fint i;
2 |- ?! D) R& J6 l% F. H( D  b' _5 g0 l0 s, ^" d; m6 c) L; p+ s
rgba = (unsigned char *)malloc( size * 4 );9 X- B& |* Y" v! @

3 C& i' E  q% e2 l! tif( rgba == NULL )
" k# ]- w5 s" r5 |return 0;
4 i0 m# {, `5 R; U
, E9 w) `0 N' X. A) f! [9 m: l# Lbread = fread( rgba, sizeof (unsigned char), size * 4, s );
3 H: W" C* A  f4 x9 F( D
" P% D0 c1 {( p' u  V$ T// TGA is stored in BGRA, make it RGBA
; n5 K$ `: k. ]1 K3 Tif( bread != size * 4 )- d/ G  E( h: t) ^
{
  m4 F( f$ X0 J9 w" v6 Ufree( rgba );& ]4 t& s" Y" V) D: p  u
return 0;4 w* |7 D5 [+ d2 Z- C3 U1 v) ?
}
! G7 Y/ c) d3 g: [& @5 o! l% k* P* [$ y9 l& r6 [
for( i = 0; i < size * 4; i += 4 ); r' S/ j/ M/ b+ H9 }% H4 r3 h6 q
{
3 x  _; f. A$ R( Vtemp = rgba[i];
+ [5 c4 B+ ?) Nrgba[i] = rgba[i + 2];) F. U: _* Y" d5 b  Y
rgba[i + 2] = temp;
: [2 I  }+ A9 d, j, A}
, v! [: W! N8 \; m& v; S, o  J+ b+ I
m_texFormat = GL_RGBA;7 v- M5 A: Y, P3 i$ [
return rgba;
4 {2 M( E# G4 I) v9 f7 g}7 ]0 k9 y$ X: p1 S6 L; \  D

5 A# T9 X5 I/ \7 P4 W% Qunsigned char *tgaImageFile::getRGB( FILE *s, int size )
! S! r' i' _& g; ]{2 K5 {& b- E3 P/ H/ \+ h
// Read in RGB data for a 24bit image. + Y" i6 _9 ]4 u; N6 M* f' N5 m
unsigned char *rgb;
' o- u# i/ |6 |0 s4 R, dunsigned char temp;+ N( E' Z/ r$ T6 T
int bread;5 \0 Z8 Z6 ~6 f( j  s5 u  E
int i;
0 ^( o- `4 X7 s5 e, l+ L( M* f6 `' e( T
, ~1 k, O1 s4 h: ^rgb = (unsigned char*)malloc( size * 3 );
  ]  C9 L& H9 ]' y+ L' N6 k
& v* H# D8 R) e+ i! Z$ tif( rgb == NULL )
7 u9 `9 t7 M8 H% A# A; b/ wreturn 0;
  i9 t: ]# [! m- f8 L1 j7 ]: g" u) J, E/ o
bread = fread( rgb, sizeof (unsigned char), size * 3, s );* a4 I9 `2 y' d  y8 m6 q

2 V  c$ W$ G2 P6 L2 x1 h0 l. Y1 Rif(bread != size * 3)5 v/ v' n& C4 a
{3 X" i4 v. o" d: z' I, L
free( rgb );
; ]! \" e5 s3 ~$ ]$ m3 \3 d# Treturn 0;& n0 \/ Q) P( i- U
}! Q0 u$ ^) X+ ]7 a+ }; Q
$ X2 f+ `4 A* u  T3 ]4 w
// TGA is stored in BGR, make it RGB
! S2 }1 O/ z0 d" Q" ~for( i = 0; i < size * 3; i += 3 )' V/ X4 h; O; K: l- ~
{4 ]& D; E0 V3 v  L; {- T$ T" I1 Z
temp = rgb[i];3 v8 Y/ F; X: N" b4 W% K" N
rgb[i] = rgb[i + 2];
- Y4 Y; r1 D' `4 Ergb[i + 2] = temp;
7 B$ {% ^, j7 J+ U5 t. _}
, j3 T+ ]0 n7 I$ B. Y+ o+ O2 \, Q* u: P% _# i
m_texFormat = GL_RGB;
  X2 U  J2 F- M' k5 ?# v1 Z  M: |# z" O
return rgb;1 M6 {, u% H' y) a0 r. K* W
}: `1 O. O6 H9 x9 F/ f# \$ v
: L6 G2 V& X- H% o# u
unsigned char *tgaImageFile::getGray( FILE *s, int size )
8 P3 B2 g" y+ `7 C/ L7 K5 a( }{8 h" Q9 F2 b  D
// Gets the grayscale image data. Used as an alpha channel.0 A8 l9 ?$ h1 `" m! X
unsigned char *grayData;
% P: q$ T" O; ]& t! {9 C5 V% T3 nint bread;, P. d7 J. r/ w" J8 w& G( W

6 q: W! ^% E& ~. f1 `( [grayData = (unsigned char*)malloc( size );7 u" G3 c/ ~/ [; {, M: L% Z+ U5 y  L

1 {6 s1 W2 H7 _8 H0 M* Z" Mif( grayData == NULL )
7 O  ^, m. b9 g) q* \* T8 Treturn 0;
" @* J1 _) C1 E. s$ V* `. _( q. k, T) p4 \( A( Y
bread = fread( grayData, sizeof (unsigned char), size, s );; P5 Q& P, C0 E6 ~

6 _9 X4 n' b. bif( bread != size )9 D+ J. k7 E/ ]; d# O. u+ j8 t
{* j# c* }8 N2 i: T, X
free( grayData );) B/ t* }2 e3 q3 v$ r5 ]
return 0;
  [. s! ]$ i' e}
, w, L$ L! ^2 [/ M4 F4 a" q# p
1 [7 J: [) _, z$ t* O% `m_texFormat = GL_ALPHA;
* i8 f2 n: r8 k7 N( _" u
2 y5 ~* G6 p! J3 f9 P; k( Oreturn grayData;- S( M" F0 L/ a, R: `5 J+ N0 s
}
5 a( i: a/ U! P" Q0 w8 A* ~: h* i& m9 B
tgaImageFile::TGALoadError tgaImageFile::load( char *name )
& \3 |3 f( U" u3 I8 N# s9 O{
: i; h) i7 o% S7 v! }4 f* K. _. V// Loads up a targa file. Supported types are 8, 24 and 32
2 b2 A" o! h0 F// uncompressed images.7 c! `! u( q, P" m- o! G
unsigned char type[4];" q" D% i4 R+ D8 J9 p  x, |+ Z
unsigned char info[7];9 s( m5 y  q4 h8 l. {$ H( E
FILE *s = NULL;- h/ j- b' P5 u( I
int size = 0;
0 U1 U9 {0 c8 \" Q5 W6 a  C( X0 O$ i
if( !(s = fopen( name, "rb" )) )) Z2 `2 {1 c! _) C1 ^
return TGA_FILE_NOT_FOUND;0 S( o6 j2 o7 n, B
) X8 q6 H  j) e. X2 w6 p- o
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored: I, G( k8 S# r$ x
fseek( s, 12, SEEK_SET);       // Seek past the header and useless info
9 r% N$ E/ b% @; Yfread( &info, sizeof (char), 6, s );
/ k- ]6 y# I- K: `6 W' I) O2 b" z% E+ c1 ^1 g1 g
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
- X2 E8 Z, m# YreturnError( s, TGA_BAD_IMAGE_TYPE );
9 y. s8 q, f8 t8 p' O( w4 Q0 [
% K' h/ [: {" [( Q9 Lm_nImageWidth = info[0] + info[1] * 256; 4 v8 o% t3 ?: D7 q5 q
m_nImageHeight = info[2] + info[3] * 256;
; \% n0 x$ z- p( U9 e# W% hm_nImageBits = info[4];
/ {1 k9 e; n: y4 ~2 M8 R' D
5 F/ U# q" Y) x0 gsize = m_nImageWidth * m_nImageHeight;
- v* x0 g. [' R  z& s; o7 o) l. @, z3 P! y8 Z# Z5 ?
// Make sure dimension is a power of 2 ) v! G$ R9 D$ O$ C
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))2 I3 {! ^8 v. |- x8 B" r+ K- H
returnError( s, TGA_BAD_DIMENSION);4 Y. M7 B9 k7 W& g0 O( k

1 p4 U# y8 x! n; J9 _! @" S2 Q// Make sure we are loading a supported type * g. _9 x/ i6 q3 W4 J, l# j
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )0 N( K5 R- ?; }& J/ w. G, l
returnError( s, TGA_BAD_BITS );) u& c4 W1 P& u' h! N

8 ]: {6 `- _4 `6 Rif( m_nImageBits == 32 )
# H; `' Q/ F0 T4 w  j! {m_nImageData = getRGBA( s, size );5 m% b5 u6 w1 F. O3 T; \
else if( m_nImageBits == 24 ). |+ U1 _  E7 D) q' G2 M, m* A
m_nImageData = getRGB( s, size );  ; ~; \0 \. c$ f+ [0 P* }3 M
else if( m_nImageBits == 8 )9 a! N% U* D4 ~9 {: ]3 Y
m_nImageData = getGray( s, size );
2 P* m- l/ p3 T7 C. B5 D* |% g! U3 _) }# [" ]/ Z$ v1 s8 A
// No image data
' S. k4 `& @% f' N/ A: eif( m_nImageData == NULL )2 _  I' z+ T( J: [2 p# s1 f  V
returnError( s, TGA_BAD_DATA );
$ P( |8 R7 @4 [6 ]" t2 z0 G1 ^$ r9 @$ v+ G! M
fclose( s );
: k, j' G: J* i3 g0 Q% @7 {* I) L8 n
- L& y* Z$ }2 c% ]) v8 zreturn TGA_NO_ERROR;
" y9 _! l. i$ m! Z% K}
% n/ P; v0 o! C% ~, Q( K0 `1 X5 ]* \& U4 _3 H0 l

9 I- G; s5 v& ?* o- c调用举例:6 p$ \- p, D2 h6 |
//7 ?- ]% O: `+ B6 a' k. n7 S
// For the billboard poly, load a texture of a steel sphere. We'll use a " m  M* Q3 ~6 f4 S6 R, u; `( p' l
// .tga file for this image so we can use an alpha channel.
! R5 z! r* i; n0 e% q//3 C; ], ?% b0 R; ]
5 D% E' A0 ]% B" ?
tgaImageFile tgaImage;
) b* Y6 I  ^, l; |, d7 z5 KtgaImage.load( "steel_sphere.tga" );
# D- g, u  w& X& r' O9 B! C
8 B( J; P5 H( K6 M8 jglGenTextures( 1, &g_sphereTextureID );& w* e' _, i6 }! O9 z- I) P0 W% N

4 {  `% {  @. f" c& o% f% B9 H/ DglBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
+ ~8 s( H7 X  }! C. I+ ?" E' \7 P$ g! E* O9 I8 c3 G
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
" C* ?- {# l) S% L" A9 hglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );% q. |7 v( _4 u5 P/ }2 Q# Z
) a9 X! e/ E( n& c5 U
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, . M7 a# g. s' e$ Y" o. r7 N
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, ! L- G8 {, M3 b4 Z% V) v
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, ) d' h/ W4 v  [  O
tgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 08:15 , Processed in 0.019207 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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