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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>
8 F8 G0 E& _/ }' t1 R$ K#include <stdlib.h>
; u2 @8 _8 Q8 w" \#include <string.h>* _; W4 g! j' R' c. f9 V3 F8 N6 c
#include <windows.h>
* `! |* `- ]1 z. I#include <GL/gl.h>
! F2 Z3 r& w& I
9 b. t3 O1 |; A* b* \8 T; Sclass tgaImageFile
$ @* \7 L$ t- x: I9 ?6 z4 A5 S{% V! f  k/ v; u! H4 }2 Z2 _
public:
# C( H$ |" c! M: ]; q3 l& t, z
$ I' M; m, {& P! p& R: atgaImageFile(void) :
  b8 q" C& ]* {. \' Sm_texFormat(-1),, s3 c& A% {* d
m_nImageWidth(0),3 t7 s0 s) I5 s+ Y' R; @, {
m_nImageHeight(0),
5 B' O. ]& d! {5 am_nImageBits(0),3 }' ~; e  Z6 o4 y0 b& E, z
m_nImageData(NULL) {}
( D2 Q( b% n9 t  D( W& X! I1 `- X$ r$ U* p% b
~tgaImageFile(void);
( a; H! I0 \$ U) R# q5 o* o
' Y; `! r' I- m, fenum TGALoadError! Q) a, d; f" E6 a. }* y
{2 c- w% q$ K8 o) b
TGA_NO_ERROR = 1, // No error
# H8 I, `- m: A: a7 ETGA_FILE_NOT_FOUND, // File was not found , J/ C9 b1 _1 ?4 N, g: V. f2 X
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
& P' K, ^( |, ?. rTGA_BAD_DIMENSION, // Dimension is not a power of 2 ) S! Y% ^; j; Z6 ^5 [
TGA_BAD_BITS, // Image bits is not 8, 24 or 32
1 K8 \1 \5 o' i& V7 B# Y+ pTGA_BAD_DATA // Image data could not be loaded
# O# Q9 C( y3 u) M  };3 U8 L7 F& F* N$ d
5 {7 z1 I3 Z1 G
tgaImageFile::TGALoadError load( char *name );' d) P; |+ M7 d5 u( R" q( x# [
* M7 {* [- O- t9 V3 }0 U
GLenum m_texFormat;/ r/ T: c3 Q* ]  y
int m_nImageWidth;7 d; F9 O5 g$ k6 k  X0 s1 C
int m_nImageHeight;) `% a4 l8 T, L; `/ e' q: C. r  N5 {
int m_nImageBits;; i! p! u% H1 c5 E
unsigned char * m_nImageData;
2 C4 p! x# D$ G& O0 t6 l2 F+ J% Y- h* V& M4 M
private:( w& E# r4 T. r- s" ^& s+ E
5 i8 M4 ?+ q" N7 Z
bool checkSize(int x);9 j- g6 J" u; M: R8 F3 ^8 Z) z
int returnError(FILE *s, int error);
0 a& Q; T6 P4 _0 t1 lunsigned char *getRGBA(FILE *s, int size);
8 Y2 I; w2 e& R  i9 Tunsigned char *getRGB(FILE *s, int size);6 p5 f+ _$ q6 F# Z
unsigned char *getGray(FILE *s, int size);
. m3 J! O: B( G8 A8 n};
* ~# o6 d, t/ \3 \" W$ v
, z* u2 _4 Y$ w) R9 ?. g$ GtgaImageFile::~tgaImageFile( void )
7 P- R+ P) X; P6 U6 [7 C! ]; j# u* R{
  A: W  N( C: A: X# Q$ m3 Q: wif( m_nImageData != NULL )! V! r& b1 G+ o6 i3 d
{
1 C$ `; [" L( i7 }) J4 Q/ ifree( m_nImageData );
! i6 d, y" W+ d& g  xm_nImageData = NULL;# F# a4 n, {3 H6 f* W% a! U
}. b: g! o5 F, L' Q" ^. A
}; g  T7 A3 P' i  E' u2 N

: i6 d! U8 D3 C! ~9 sbool tgaImageFile::checkSize( int x )0 h% e8 J% m* V, L7 E) Z9 P: t9 k7 K
{9 _+ [( q% t) ~: L1 U9 [+ ]% Y. ~
// Make sure its a power of 2.
) N) ^$ m4 j' r' g6 k# ]3 [! Z& \! Kif( x == 2   || x == 4 || / j" O9 }) D  {, f- x$ K: P5 g3 U
x == 8   || x == 16 || 1 W* J  E) @; P2 C& }
x == 32 || x == 64 ||4 H, R; Z& I2 P  a, ?
x == 128 || x == 256 ||
* p. _; Y9 S$ z1 t( R" bx == 512 )
& m0 ]; E& H2 O6 sreturn true;( U; I- g: x1 R- f0 q4 u

  F( z# W" ]: v* g; x1 @# D& ?  mreturn false;
2 H. N. e4 G/ w. u  }% }" j7 @}3 H, D, D+ i+ A+ P: l
) Z5 n% H) r  Y  y+ Q
int tgaImageFile::returnError( FILE *s, int error )4 b7 B6 Y9 @: |' {7 |
{
/ _. v! p$ n% p* N7 A: f; N// Called when there is an error loading the .tga texture file.
  ]- U+ ?# C! W! {fclose( s );
4 y/ d6 W* Q3 i5 Q% T8 hreturn error;' n& s) Q" i- [2 ?/ k  a
}
4 l% H1 p/ b$ F2 i4 I: U0 P: l+ D- f( V
unsigned char *tgaImageFile::getRGBA( FILE *s, int size )" K3 U' R( x! I; O3 I9 M
{% P0 u( S9 d+ T, Z0 w# W; R7 d
// Read in RGBA data for a 32bit image. : B  s$ a3 c( ^) J
unsigned char *rgba;
0 l# n' f/ i$ \; v  N( d- sunsigned char temp;
# k1 h3 D# q; O1 Gint bread;
8 c) |" q2 I2 i# z& z) W8 K$ F) [int i;
: X& S. V3 V7 a4 X3 h0 b8 V0 D) M( N. Q1 Y
rgba = (unsigned char *)malloc( size * 4 );8 b0 G* {( C# {+ B# j. q" _/ q9 ?0 r

! Q$ `: ~- m9 b' Eif( rgba == NULL )0 p% F$ s. P1 t! o
return 0;6 f! i' o2 ~3 r4 R2 Q2 X) |6 B

& e" k" L0 x: Sbread = fread( rgba, sizeof (unsigned char), size * 4, s ); 7 k  G, y" L7 O9 P, m7 ^& I

9 c7 ?/ L% X& {+ T, @  w# u4 s* ?// TGA is stored in BGRA, make it RGBA
% J; {& {( ~3 z# Y' C+ zif( bread != size * 4 )
' r) g& P2 y) w- e{
3 o# g( X* w  b- n- i8 }5 }free( rgba );3 R* i% z$ G5 u! q3 u0 M, E
return 0;) W4 T! d4 ?7 s9 Z4 Z( e+ }+ X+ V
}- u, M' R$ j( ]; \+ B5 O2 M4 v

. y5 G2 N" v3 `3 t1 ]/ {9 ~for( i = 0; i < size * 4; i += 4 )$ a5 W7 A3 J, V5 w: Q# `2 U% u; p
{  f! I- m# |5 {9 h  H
temp = rgba[i];  j1 v( n/ c- y, b; H
rgba[i] = rgba[i + 2];3 ?0 L0 B' M4 o
rgba[i + 2] = temp;3 i. q! _/ c  Z* d! d
}
) Q2 y8 S% v1 ~% U0 p% b% y* H2 h# H
6 p1 i& t  ?1 {8 W7 Em_texFormat = GL_RGBA;1 S8 h( Y% w" W+ b/ f
return rgba;& ?) @' u. Y& b! }1 H0 `
}9 ~% y; n# T* q/ r3 k

& u$ j( l5 b6 Runsigned char *tgaImageFile::getRGB( FILE *s, int size )
; _, Z2 z- F; ~: ~1 z{
$ m  z4 L8 g; o* T9 h8 A// Read in RGB data for a 24bit image. , C" U/ G% T8 z8 q9 t2 [
unsigned char *rgb;- G1 s% X- ^* o+ x- o
unsigned char temp;
  V( ]8 k6 U5 z! c5 T0 W9 U  ?0 Bint bread;
9 m& b9 |  z: f3 A4 j6 a% H& a4 P1 D4 dint i;9 \- p6 d6 X7 ]- F8 n+ X

3 V/ T4 Q- K  P. d; v  D4 P- `1 Irgb = (unsigned char*)malloc( size * 3 );; `5 h: V& ~! ]1 h# r7 k
  r' n/ N. ^/ k* W
if( rgb == NULL )2 v" M: ~/ E5 y1 x: c0 L4 ~7 {
return 0;$ B5 b, d" N' U5 W4 \; v  q: G
/ Q! Q! l  R2 _% N7 @
bread = fread( rgb, sizeof (unsigned char), size * 3, s );! e# O* Y% K$ G3 b$ l! D

6 M& H: o% q6 B2 e3 ]% C  lif(bread != size * 3)
' P& T2 A) `$ \- _: D{: ]9 k6 \% o% s- I" o6 [
free( rgb );5 T( u: B$ D8 [  q: V' Q- P
return 0;4 z: H1 O; P: z
}
) [6 i1 f7 @/ _# g6 {9 O! T' S7 I9 n' P: P! f9 Z! A
// TGA is stored in BGR, make it RGB
9 F; ^. a" Z& {8 d  w+ tfor( i = 0; i < size * 3; i += 3 )& b! @0 _/ R! O/ n) h
{
3 W# `3 m+ V; y8 X. ~( L- [, b: r9 d# ptemp = rgb[i];2 t) \5 B5 {' |) }; y) @% V& j+ M
rgb[i] = rgb[i + 2];3 j. v  j  h- }+ \
rgb[i + 2] = temp;  a9 {3 P: ]' g2 A6 @+ W; S1 y
}
% B1 V, u% @# @. I% x+ Q- S/ O: e6 b- j6 p
m_texFormat = GL_RGB;. P& T) s4 [0 f  x/ ]0 c- L

1 A  w7 c/ _% y- F1 _9 W5 p; Rreturn rgb;
4 V, {( v, L' m1 ]( h}
5 G6 S* G  S4 O! K' w* D8 {
0 [" O! z. ]& S' b  c6 Hunsigned char *tgaImageFile::getGray( FILE *s, int size )% O! @) ^  [# R7 J3 l; F" c' X
{/ R/ t! C, n8 \9 D
// Gets the grayscale image data. Used as an alpha channel.8 u; |; G. Z" J' Y; u9 k1 E5 c1 j
unsigned char *grayData;
! \+ u4 f% |0 o* P9 Kint bread;' a7 ^  C0 ^! ~
8 H5 _4 b0 X. v1 u4 Z
grayData = (unsigned char*)malloc( size );
/ o( h# I5 [7 B7 S/ f: S$ S" S
8 P& t, @8 H9 _, Iif( grayData == NULL )
' ^( P3 j: s. L& a: z! [return 0;7 S' Y, F4 X6 C+ U7 h6 l
, P1 \% _. Z. `
bread = fread( grayData, sizeof (unsigned char), size, s );
0 e9 ]9 ?3 B: ^- Z6 d" P
* }- a2 x; ^* [4 O/ P, V' jif( bread != size )
1 m( w( q) v2 N: U{$ i9 f. I2 p2 `/ L1 }6 X
free( grayData );+ H5 X; u, n% x. q- i& d/ z2 Y
return 0;* h1 v! N' P: W3 W+ |' y
}4 M+ ~: w5 `3 _7 o) Q# R5 }
' N* P1 c- w: k! v, ]3 C$ N3 C) v1 j
m_texFormat = GL_ALPHA;  c6 V8 P+ C; L% d

! W9 Q9 I1 P$ s5 N0 E5 _return grayData;
6 O# H5 L2 [% o0 @. @( _5 C9 e; p}7 ~8 D7 }6 M+ |" ?' M0 R4 E4 p- Y
! I7 A* O  d) Y; R0 y
tgaImageFile::TGALoadError tgaImageFile::load( char *name )
5 D5 M. U6 K- i1 B+ U% M{2 b5 Q' i  A& `; K' L( O5 n& F
// Loads up a targa file. Supported types are 8, 24 and 32 ( P' k( O" e5 H
// uncompressed images.
$ t1 ~; r+ @6 m; @( U; w/ Bunsigned char type[4];
/ o( q3 \) |. Y0 punsigned char info[7];. {, {  C1 _; b1 h- i' K
FILE *s = NULL;: M, S* I1 A1 U' s) d% c
int size = 0;
9 K- }) u6 k' n1 ?, W$ l. N5 i6 m1 R# X
if( !(s = fopen( name, "rb" )) ), H& M) r" C' ^: Q4 X! n" O3 G+ I
return TGA_FILE_NOT_FOUND;
- Q; I4 w- |4 n# ]  ~
) n. A/ Z3 R4 m2 J9 `5 _fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
8 \$ {3 p. t) N$ hfseek( s, 12, SEEK_SET);       // Seek past the header and useless info$ d! J/ P& k0 h. N
fread( &info, sizeof (char), 6, s );
1 G, W8 A) \& t2 t; N: E) N( k- ?0 C# d
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) ), B' \3 ?9 o3 L( s1 k% i2 }0 M! `
returnError( s, TGA_BAD_IMAGE_TYPE );+ r: Y0 T( \" A! L/ D7 X. N

, l: x& _1 d/ ~$ e& a7 wm_nImageWidth = info[0] + info[1] * 256;
" d8 O# O, l+ o" Z9 ?. H: d" Vm_nImageHeight = info[2] + info[3] * 256;
" b* j- E5 R& a% ?( y7 J3 T3 Im_nImageBits = info[4];
' P* M" g. R. \1 V
" `$ ?. {4 ^1 F% Osize = m_nImageWidth * m_nImageHeight;( b9 x2 |- s& [, S
/ ]9 K6 D- H3 _1 }( t4 U# y, V
// Make sure dimension is a power of 2
! p( m5 x: s  x/ D" q7 G2 _" @if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))
+ \4 w# @" ?% D3 `! \% O; UreturnError( s, TGA_BAD_DIMENSION);  b3 ?& S" h, u5 j( i4 z
/ C3 ]5 r, M# U9 A9 ~7 w
// Make sure we are loading a supported type 2 Q$ w/ h6 k. c. N1 K* c! V$ l) _
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )/ v( ^2 _1 x) Z9 C! I; o
returnError( s, TGA_BAD_BITS );
* w" k7 }) F2 J$ z- d7 M
- @( B8 b- o+ r2 f  R0 Vif( m_nImageBits == 32 )
2 p' L: m6 z- T, r3 E! I' Um_nImageData = getRGBA( s, size );# [. J# |& {7 u$ A( }
else if( m_nImageBits == 24 )
- l# `0 Q0 Z* }$ A2 Tm_nImageData = getRGB( s, size );  , s% a; [/ w0 \
else if( m_nImageBits == 8 )5 u8 N% @. D/ T0 j
m_nImageData = getGray( s, size );. W1 T" t9 E+ T  y. N; c  I1 z7 ?
  }$ R9 b8 w/ g1 z1 q% X
// No image data
& K/ b$ Q( Q1 @$ T/ g6 u7 zif( m_nImageData == NULL )
4 i( t7 `& b4 H+ t) kreturnError( s, TGA_BAD_DATA );
. V0 X% r% X& s9 R6 S# y; l9 A- X: O1 W2 r% `+ u1 v
fclose( s );
- h# R! _5 p* T4 j0 c; r
$ U0 g2 ]& B; P8 h+ u: wreturn TGA_NO_ERROR;
. q+ w, Z3 r7 Z3 O# H) y7 F}
) g7 @' P  S5 n! }$ J9 g. V. }) `9 @

9 n4 F7 a  P3 l9 @调用举例:0 Q& A! c: I4 j; t5 W# T1 ]% {
//) O( ^; y. |& R$ ~
// For the billboard poly, load a texture of a steel sphere. We'll use a
% C* c4 c. T$ w- w; q// .tga file for this image so we can use an alpha channel.
8 g! n" s% N( O: `& c5 X5 a% R//
+ F4 A& V1 \3 M( s* N5 \0 m* f7 {7 R- B( C; k- P
tgaImageFile tgaImage;6 j4 @* A$ `* \- h( n) ?( q" U
tgaImage.load( "steel_sphere.tga" );2 o9 ~( @, p+ J2 Q+ a0 b
. l7 O$ o# d; B4 g6 q( i/ n# ]
glGenTextures( 1, &g_sphereTextureID );6 n( {+ p8 v  E- {
, L! q7 h- R- L& I) M# f. J
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
' h9 ?. p' ?& l$ x
$ c0 m# N3 Q6 r* i5 cglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
" l. r( t; V! {$ X2 S5 ]5 g) i: lglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );6 ]* S/ J6 a: F! i! ~
; e% m" ]0 Q+ v
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
2 }: @! J3 w4 C# b2 TtgaImage.m_nImageWidth, tgaImage.m_nImageHeight, 3 S& y' H2 X4 N& Q7 a  X! @
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
" t0 ^5 D1 c6 r& A# K& StgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 10:28 , Processed in 0.020043 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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