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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>
5 V- o5 A. S( C  ^7 u4 u! X#include <stdlib.h>& K6 e& \* Y/ k# l" D
#include <string.h>
. @$ j  p5 S% [+ w#include <windows.h>7 a# v/ s$ D/ N% o: u/ [
#include <GL/gl.h>, U* h6 u' N8 S" [3 {
5 L; M- `5 F5 A6 b" O! i
class tgaImageFile( Q, S4 q0 W& O5 E, V: W# {9 x) F: d
{/ p0 M# A& _5 i( |
public:
7 l/ S% ]* R: t8 k7 R8 z1 _) v  \$ T/ ?+ c% P9 b
tgaImageFile(void) :
1 r. Z" E+ L1 ]- p4 x9 Nm_texFormat(-1),
( T( r: t: ^* u5 e4 s$ tm_nImageWidth(0),- f  N7 O7 a* V' ^3 a' p, v
m_nImageHeight(0),
5 m0 h; h2 B! A4 e' G/ }m_nImageBits(0),/ F$ \2 B- n% o- w+ E0 v) e
m_nImageData(NULL) {}
% {- G. u, `. s5 B0 H6 a4 f0 r  r4 @" [4 [
~tgaImageFile(void);
) B' c, A! z( T% f, W
* F9 M4 ]* p; denum TGALoadError
& s8 `! A$ e9 n1 `{
5 Q: k2 Q3 D! G0 l! a# L8 N, g* m6 |TGA_NO_ERROR = 1, // No error# J) n4 `2 f/ e2 N; x' b
TGA_FILE_NOT_FOUND, // File was not found + V5 _3 W& T' I/ J
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed/ O0 W; b6 O; S0 b; H. Y, l0 }
TGA_BAD_DIMENSION, // Dimension is not a power of 2
: B' z/ H" i6 TTGA_BAD_BITS, // Image bits is not 8, 24 or 32
2 C, d* e$ k2 {$ E+ }, lTGA_BAD_DATA // Image data could not be loaded
2 y7 d7 I& {7 w9 m  };
5 e( r4 J' g4 l6 \- u7 k7 z$ u# e. i% Z2 p# f
tgaImageFile::TGALoadError load( char *name );
- q6 N& ~# b( [7 F1 \/ n) ]1 K/ t( b+ D0 K
GLenum m_texFormat;
! B2 e4 q. i$ G: f- Jint m_nImageWidth;
, r1 i: d& c/ g, m+ nint m_nImageHeight;
& l: j3 q* k. |6 ~int m_nImageBits;
; y+ G% O( f) }* i: M" Dunsigned char * m_nImageData;8 g+ _0 T9 r4 L/ X+ N/ \: H; t

, M+ f$ h. o& h. q: w$ I- Bprivate:9 ^* \+ a$ o$ H# n7 C7 ]% S
6 B/ W/ }* }! [& N  c
bool checkSize(int x);
5 P  X; Z$ Y( Aint returnError(FILE *s, int error);
, V4 V# F& b' s8 w8 Z: V4 n: ^unsigned char *getRGBA(FILE *s, int size);
8 @3 p7 Z) ^( Q- O  Runsigned char *getRGB(FILE *s, int size);
/ u, X4 l1 u2 V! g3 p4 aunsigned char *getGray(FILE *s, int size);* G' m( u" Z5 w, f# W9 r
};
4 p+ u( \' T8 x$ G6 R8 D" y2 k- ]. ?9 H
tgaImageFile::~tgaImageFile( void )( u* g& D7 X% z& y  D
{8 |: q$ W. e" i8 o5 q* `, l# F9 R
if( m_nImageData != NULL )' q4 \" _9 G5 Y! A4 k0 d0 V
{" M7 ]5 B+ J9 e4 o" D/ q
free( m_nImageData );
- Y2 i9 a/ {" \; f# H' y2 zm_nImageData = NULL;  s* x# s) f- N1 ?% B4 G- }
}
1 J, H: J$ v1 f$ r$ e* {}
$ S! [3 J+ ~2 V! J. j& {
% c3 M2 Y; F0 c) `9 S/ O* e8 ybool tgaImageFile::checkSize( int x )
/ {; Y- o6 ?$ s5 i) O{# F. G7 V# r3 u
// Make sure its a power of 2.. j: o. L+ K5 S1 U: b
if( x == 2   || x == 4 ||
/ }$ w4 q9 M4 \- x1 n/ Bx == 8   || x == 16 ||
9 i! _) [+ O8 s: [1 w* Gx == 32 || x == 64 ||. N% F# L& s0 h5 M/ O9 {/ i8 S
x == 128 || x == 256 ||
" ^! @' q+ k- D+ U+ I- U) dx == 512 ); p# ~/ b% H* ~9 \1 K, Q
return true;
$ ]4 r( E4 i( W6 v2 N- s( _
2 g8 Q5 W( [# r% a0 h8 jreturn false;
2 M2 _! u% e9 u0 |1 h' \* a}) K3 o0 n, r: K7 b4 S( _0 }0 X% Z
: R3 G, J2 d+ |& h; @
int tgaImageFile::returnError( FILE *s, int error )
5 Q3 n$ o$ R& X) k( @6 ]6 w: X{+ g% x/ @. r+ C
// Called when there is an error loading the .tga texture file.- \2 l% v) K% h# L7 b$ e$ R
fclose( s );
6 M3 @( i5 \6 q& G* f  zreturn error;
' k+ p9 ~  A4 s& a}
; H8 O& [- U( F2 z/ ?
8 L* f+ X1 L. F8 Funsigned char *tgaImageFile::getRGBA( FILE *s, int size )
  M2 S# C, A" i8 v{- h2 J+ U! C6 S" ]
// Read in RGBA data for a 32bit image.
4 c' I/ |: h: c" E4 b* t  p4 Bunsigned char *rgba;
4 j/ W/ b7 `4 D9 z% h4 r6 funsigned char temp;/ A% x& d5 z+ X2 K7 t1 f6 \
int bread;
! h, L& `1 A  s. S7 jint i;
, ~6 l8 t* u8 _" I3 w
' z5 K. S- J6 T: X2 p- J# ergba = (unsigned char *)malloc( size * 4 );% M7 X7 K/ u* G9 R2 I& P

8 U) R! W% `7 [if( rgba == NULL )4 g/ {3 q0 a4 w
return 0;4 U" q& O% g8 t, C, w) Q3 X8 n, B% K$ c

) R. [0 A1 |0 V# m: wbread = fread( rgba, sizeof (unsigned char), size * 4, s );
# i  \- X5 m+ Z+ Q& ]
- \  N/ Z- t1 t// TGA is stored in BGRA, make it RGBA 2 P; U. I9 a9 L6 x% [* J
if( bread != size * 4 )4 r5 t# Y! z8 C; E3 U5 i! V  [3 i
{" g* U# O( f6 s
free( rgba );
$ v! V. g' U/ Q! t, x% i3 W) Kreturn 0;0 X* j+ Z5 i. _" w+ i
}
' l$ Y! R  `2 y$ P: \* Y4 O' R
  h$ Z1 w3 j+ V5 q6 f" efor( i = 0; i < size * 4; i += 4 )8 o# A8 h0 L/ [, ~- o/ a
{
+ d- b0 Z' P7 ?9 v& ?temp = rgba[i];0 J8 F0 Q% |# q0 K" e6 G! M
rgba[i] = rgba[i + 2];* I8 ]/ [$ ^# H$ b
rgba[i + 2] = temp;4 _6 i! H2 f/ h9 x8 L
}
" e# Z+ D2 o& p8 R
: v, n$ v; B) I' q- v5 v  b  im_texFormat = GL_RGBA;6 F! D# a) H' w6 G! `3 W
return rgba;
  B1 |. S! h3 a2 ~* v5 `9 r2 N}, S9 S* Q$ I/ E1 {: e  E5 t

9 L) h8 |# a3 O9 O5 D$ a8 ]3 [2 uunsigned char *tgaImageFile::getRGB( FILE *s, int size ): @6 g) }  }+ _5 {2 j; \
{
+ N; F# @0 D; k5 L) _// Read in RGB data for a 24bit image. . t& `8 H! E$ ]% ?6 @5 r
unsigned char *rgb;
7 |$ U: j5 G& e1 S5 X2 Y1 eunsigned char temp;
7 f: ?. e# l/ j( {int bread;
% f% I% b' b5 t3 X0 q  ~7 O7 y! Xint i;: q0 Q: k- L# R: ?! P' w

( w1 X4 w* f# {* g& n! `+ |rgb = (unsigned char*)malloc( size * 3 );7 m" y7 D0 ?0 D6 d, x

1 R8 |1 Y) k0 n; [1 H. |- wif( rgb == NULL )  O6 M+ v. i% i8 ^5 I) L# d
return 0;; L6 A" v* d; c/ t5 Z
2 ~# w8 K% F' I2 p" S
bread = fread( rgb, sizeof (unsigned char), size * 3, s );7 W. v2 @6 l7 o
& P- l+ L- I5 ^% ~/ r9 g  ^1 q
if(bread != size * 3)1 _; ]. \; |* M) S6 G: L% ^
{
6 t: B9 T& {2 L+ ^free( rgb );
: m4 D% m% B/ l) b6 ]+ X8 sreturn 0;4 S" S; L) T) `3 j( S" ]9 t9 p
}
" `5 v$ N/ e: S) X1 |2 l# i0 L6 ?4 s0 C0 p& b2 A
// TGA is stored in BGR, make it RGB
, ^: L/ \1 L1 l" {3 S  x# rfor( i = 0; i < size * 3; i += 3 )  H; x4 K' h' |* T0 Z9 `7 o' k. f3 M
{7 h! [; n2 K5 K  O4 U
temp = rgb[i];
* L8 ]) T3 w! U' |# V8 prgb[i] = rgb[i + 2];$ @! I" Z% B5 T) o6 A4 `
rgb[i + 2] = temp;
9 z6 ?) b5 A1 r3 _}
1 H: f% x6 }9 R7 o: a5 y' m
. G- o; Q5 {1 r' y0 |m_texFormat = GL_RGB;5 I8 F3 q$ G) n+ A# h/ n0 D0 E

: w: ~7 g6 U  Z; ureturn rgb;
$ w+ F0 p; J9 y1 I3 G- J2 |! `& Y}
2 M$ M0 s4 W6 L. \  A6 \' h1 @% n$ I9 L# H& k$ B" `, M
unsigned char *tgaImageFile::getGray( FILE *s, int size )
. m* j$ ]; z5 o$ y5 M0 Z{& Q8 o) n# U/ d. T7 K0 j1 J
// Gets the grayscale image data. Used as an alpha channel.( q. \/ `9 I; B5 \& D- a
unsigned char *grayData;( n# v8 \/ w: Q" i+ O
int bread;  `/ m7 h  y# D! K: U

/ H! P. n: o1 }grayData = (unsigned char*)malloc( size );' _& B2 [. A5 X) S7 s1 w
. R: G- d- R- R+ p# M
if( grayData == NULL )3 f2 p0 c  W: B! X2 c( v" P/ `2 a
return 0;# \% b& z  v% `$ G- k

" X" I& T$ f# e/ qbread = fread( grayData, sizeof (unsigned char), size, s );
# v+ n9 e, y  ~4 ]  l+ r1 N9 Y. o
5 P: n: D$ h% N2 F/ S" f- ], M0 bif( bread != size )# \1 c( n, U  g$ ^
{1 e. C# e# j+ l
free( grayData );
2 Q4 K  A6 V; l6 x. F! Q6 R1 Xreturn 0;
4 d$ d* x: ^9 @  j5 a' _  h1 p}/ G' F5 ?( h+ s  X% u1 {

% f8 q: r& f. s; H" Tm_texFormat = GL_ALPHA;' ~& D' S9 O: I( O' d7 ^. A
# {! Y7 u6 e( J) h( ~7 w
return grayData;) X# P9 C) V) F
}5 [- B) @8 R; D1 e$ D: \
" b/ z8 |$ Q$ V: P. y
tgaImageFile::TGALoadError tgaImageFile::load( char *name ), K2 }" Y7 n" E4 Q% p. \3 Z: H
{
' d  g% @$ B; {( [' p// Loads up a targa file. Supported types are 8, 24 and 32
3 g5 Z* h: w, i; [4 r  ]4 A+ b* f// uncompressed images.
5 l4 Y; v) C( ~. `# O. B$ s4 sunsigned char type[4];' m" E, ^: s6 X& Z8 r
unsigned char info[7];$ x4 {- n  @- s0 z, L, ?1 o' h
FILE *s = NULL;# I7 }/ }* V* z
int size = 0;( h$ ]$ ~' V3 p6 `9 c! @

  h6 `4 K8 H0 I6 V6 uif( !(s = fopen( name, "rb" )) )
( _9 S" R" h& j9 e( S% s6 Greturn TGA_FILE_NOT_FOUND;# \4 o& C& ]6 A& Q) u$ p

; U/ E( G) @5 y9 pfread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
' C7 p# ^3 V8 ]$ N! T% C0 f2 ]fseek( s, 12, SEEK_SET);       // Seek past the header and useless info
7 K' e1 w  Z+ u4 q( ~fread( &info, sizeof (char), 6, s );
1 r/ a2 s* G7 l
' o3 |6 G0 s' \3 Rif( type[1] != 0 || (type[2] != 2 && type[2] != 3) ); a" ]# L9 ~: B+ c% [
returnError( s, TGA_BAD_IMAGE_TYPE );
& i7 C( w3 w2 i' J5 R- n  B' @  t  d! y1 V4 e7 t
m_nImageWidth = info[0] + info[1] * 256;
2 H4 @1 ~+ d$ J! U8 n' g- E9 }m_nImageHeight = info[2] + info[3] * 256;
- P$ k  Q: E) ^3 o6 ^  ~m_nImageBits = info[4]; # F" A9 D; t  _3 R

. v$ V. v3 u3 w5 A9 D$ jsize = m_nImageWidth * m_nImageHeight;* i. ?3 J1 I+ u* ^
1 j& r: `0 }4 j4 L4 ^; g& M6 P
// Make sure dimension is a power of 2 7 W7 N$ F0 _# I! q+ I
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))' T) C( M2 L4 P) _5 q
returnError( s, TGA_BAD_DIMENSION);# l8 x# i1 Y* u% y1 y' ?  k

9 O! C6 C. h8 x// Make sure we are loading a supported type
5 B( P8 t( @  g- gif( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )+ J! p5 C5 b1 R+ ?6 i
returnError( s, TGA_BAD_BITS );
5 L9 \0 V% T- P' Y6 h- @1 f& S& \- J. M6 U1 k9 N
if( m_nImageBits == 32 )9 j8 |' e' q: o! N
m_nImageData = getRGBA( s, size );0 c/ Z: F# t  E, m- V: G
else if( m_nImageBits == 24 )
7 ~, ~1 X1 d  @5 `+ Q3 Gm_nImageData = getRGB( s, size );  
0 F) @1 J& l1 Y+ @else if( m_nImageBits == 8 )
. y% v6 {) J" i% ?- Sm_nImageData = getGray( s, size );; c3 p5 v/ a& x$ d  b8 o- c
* f# k, G' z+ O2 j3 s$ s
// No image data / e* O; r2 t/ o* w0 e9 M
if( m_nImageData == NULL )2 r1 ^. J. r3 ?- v  X: t
returnError( s, TGA_BAD_DATA );
5 N6 S- A5 u2 h
8 q. C. s+ C( n/ e" {8 pfclose( s );
& I5 v' E4 v' \5 L; D. e7 B" q6 G- E3 y8 Z& C6 j* L
return TGA_NO_ERROR;) n$ p8 ]7 q' ]6 p5 k
}
& u8 C) A7 c) X# o
# V( c/ R2 e' d8 d$ v% ?6 a+ a1 K! w5 z8 I: Q- G
调用举例:
$ Z# E/ [( m7 g1 P! S4 _: H//' W9 P0 b/ ^, R
// For the billboard poly, load a texture of a steel sphere. We'll use a
  p: c1 t! a  [$ Z$ x# G* I0 @- K* t// .tga file for this image so we can use an alpha channel.
7 ^( M5 W2 o5 S. N% S5 C  R! N//( M- ~. q2 L" K
) B0 u0 |8 F0 ]- R
tgaImageFile tgaImage;3 E# M0 ^: }' h. }3 ^' b
tgaImage.load( "steel_sphere.tga" );
- b& {3 D& i: K. ?2 e# \) u
8 o8 @- {7 q; a6 x1 @. \glGenTextures( 1, &g_sphereTextureID );# @# m$ x" z" Q+ [2 u9 R+ g# e7 U

2 D4 W8 o3 K: k4 T# ~glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );/ F8 `1 K% `4 e) v: S0 {
! X1 N% U6 S7 m$ P- K1 Q
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
1 {; ~6 l1 Y7 d; f) gglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );& v0 T2 C( c( ?

1 u( I7 A/ I. ]. k5 @; C8 sglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
( M- a% a* v( i- R) R; \+ RtgaImage.m_nImageWidth, tgaImage.m_nImageHeight, 1 Q% r* C1 R( u9 t& i) ?
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, ( m+ `) k# ~% X$ X% O+ _5 ~$ J
tgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-9-30 13:07 , Processed in 0.036318 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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