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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>
  E: @3 m, Q9 r0 E& F# E#include <stdlib.h>
; K2 Z2 K0 l6 `" j0 {$ h#include <string.h>
* I) a/ `" {9 C9 G1 ^4 z2 q#include <windows.h>2 O- c( T3 p6 m, P) F9 d
#include <GL/gl.h>
& t* J1 j/ y2 T0 }& |1 Y
2 g" b. t5 H3 o( y' mclass tgaImageFile5 ?' @- X) ?5 L( @3 ~$ o; S4 ~9 n
{
! [4 Y0 K2 |4 {) zpublic:
! S  _8 y% p; R
) r3 @- V) O1 p1 d* q0 StgaImageFile(void) :
1 [  F; ?. x& ~; e" S, Am_texFormat(-1),6 B! J6 e$ c0 R! H0 l; O0 _+ ~+ B
m_nImageWidth(0),
' Z" a8 F: Z0 n- |1 }m_nImageHeight(0),
0 i' y( }! i) v3 Rm_nImageBits(0),
/ o6 y- r* K0 e- c! \1 _! Bm_nImageData(NULL) {}3 w- O4 K+ u0 q' q

( L. b5 G; j! N: s; O- G~tgaImageFile(void);
$ ?; z* j4 _. t, d$ Q4 U- ~* c+ |
. [' s, t% ]: e# }3 ?5 h+ benum TGALoadError5 n$ [' N0 `( g3 z+ [& G
{3 |) z& P3 z5 }+ l; I2 d2 k/ X; I
TGA_NO_ERROR = 1, // No error
" d8 X% C7 \; d% J" S2 FTGA_FILE_NOT_FOUND, // File was not found
8 r4 D* o+ N7 i" |( OTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed- E# v; X+ S' e/ D$ ]$ Y
TGA_BAD_DIMENSION, // Dimension is not a power of 2
2 X! Q9 E0 F' I! d( q' P7 mTGA_BAD_BITS, // Image bits is not 8, 24 or 32 + ?2 S4 d3 E% d7 y8 R
TGA_BAD_DATA // Image data could not be loaded & \8 A/ U4 f) U  P
  };
. H8 K7 J$ \0 e  w! T
4 p2 C. ]0 c- B$ n3 c: mtgaImageFile::TGALoadError load( char *name );
. O& k, D1 H7 `
6 \5 s0 |# n+ m5 Z' W) ?GLenum m_texFormat;
' _+ h  B& i, J# o, mint m_nImageWidth;
. r& A- @  \1 C1 Qint m_nImageHeight;
/ A1 \9 i+ p) L* vint m_nImageBits;
3 w4 C- P9 N! Y- i. H( a. w0 L. lunsigned char * m_nImageData;
! O7 i  M  [5 W8 ^5 r& }7 ?. K) o+ g+ O, F9 _4 c
private:% J0 \% G0 Z! D  x

: r" p. p/ I7 ^' ]" d4 c/ Abool checkSize(int x);
( T, H/ j9 v9 M5 _" Y' H6 s! gint returnError(FILE *s, int error);. \8 `& x/ @( i
unsigned char *getRGBA(FILE *s, int size);
/ Y0 G& m5 |' E7 }unsigned char *getRGB(FILE *s, int size);
8 C% s, o5 N$ g+ Lunsigned char *getGray(FILE *s, int size);
) J2 g% L' o, F) @- _' U};9 Y2 k8 V: Y! ~  x5 o
+ ^3 M- u# K3 t' o  ?5 r
tgaImageFile::~tgaImageFile( void )
- e" ^' ?0 D0 L* Z2 y3 k+ {{
) Y1 [, C* ]+ xif( m_nImageData != NULL )/ x; z2 C: f" }1 Q( ~# |
{. ?$ x1 Q) l4 f! N/ K) z' @
free( m_nImageData );
* N( A2 X; h% u$ qm_nImageData = NULL;
0 a6 k2 ^  ~) @}, w& n( P5 U) m7 l
}4 Q$ R' Y- q* W7 N7 k
  w- I- d0 e6 p" U& ~5 |/ P
bool tgaImageFile::checkSize( int x )2 B! Y  E1 x, |( a6 {
{; S% |: {, }9 o0 M8 ~* Z
// Make sure its a power of 2.
$ b: ?: w. i. k: U# cif( x == 2   || x == 4 ||
* W  g  @$ E% A3 B: Q/ I9 b  f. o$ bx == 8   || x == 16 ||
- t# U0 a) }  ^* R. R/ \' Zx == 32 || x == 64 ||2 G. ?: f! k- a1 w7 r' ~
x == 128 || x == 256 ||   W6 z& {, b' A) O2 |% M5 b
x == 512 )* {/ H: K4 g8 y' A, I4 H6 ]
return true;
- k) T& m% ]+ G2 S1 O! @2 f9 p
7 s- ~6 k9 d% {" Q7 S7 Jreturn false;
3 |( q! C  W4 h+ P- W}. s- O4 n5 ]# m+ L
! F3 O; M& T; L' J% v; T1 }
int tgaImageFile::returnError( FILE *s, int error )6 L) Z- i7 g3 d) }- `
{( N. U$ Z$ s/ B( W1 H
// Called when there is an error loading the .tga texture file.
( ?6 o" g0 x! Q8 L& S5 X7 cfclose( s );1 i# C( ]& L2 ^5 o6 `; L" }
return error;$ _6 S/ w6 C- N7 ?& p
}- D. r! I, M2 Q# O

$ \2 i6 q+ U  _! }unsigned char *tgaImageFile::getRGBA( FILE *s, int size )
( |7 w0 x/ l1 n! H{( S9 r2 i, j1 j/ z/ B/ Z/ \- s
// Read in RGBA data for a 32bit image.
8 M  F! X. R; j* @4 Cunsigned char *rgba;
3 r5 i1 p- l- |  F$ @+ t. e* }unsigned char temp;& p" D+ n. B: S1 w4 s2 \
int bread;$ m4 m, ]) f2 L0 X5 P$ v  M
int i;
/ ?9 d6 n( y- ?: R) S. L
# n$ T" }' i, ~1 B9 urgba = (unsigned char *)malloc( size * 4 );
! s8 K* W7 L3 J# N% w/ S4 k
/ n" ?; Z1 y2 x& W3 S+ qif( rgba == NULL )
+ `" q3 U; \5 F# W/ w1 u' C9 _return 0;
/ ?3 D5 Q7 S. g$ Y7 X/ T  [% q" n2 s
bread = fread( rgba, sizeof (unsigned char), size * 4, s );
0 g6 c' \5 ~2 T0 k: l9 U! f8 L4 T* N
// TGA is stored in BGRA, make it RGBA 3 s/ J" W: e2 `# S& d& E
if( bread != size * 4 )4 G* [# C0 ^1 i' Z$ E' {2 N; v
{/ E! N- Q$ ?( ?
free( rgba );- i. ?( |! |3 k% P0 ^
return 0;# l2 p' O3 D: x' Q# T: a
}( m5 Y6 m2 r2 g% q

2 W" _5 C, n% E- U$ t2 Bfor( i = 0; i < size * 4; i += 4 )
7 x$ h- H$ L+ M$ Q; |& E{: n8 q% _1 G- C
temp = rgba[i];3 z5 b) |4 ?1 h( I
rgba[i] = rgba[i + 2];
4 l. A/ ?0 }7 frgba[i + 2] = temp;
: H( Q( U0 v# L" W8 y* _3 d) M}5 ~" e  ^% H7 R9 j# \+ T2 ^. Z
0 D, _  c: F' z- `9 [
m_texFormat = GL_RGBA;
& t& I9 N* j, |% A" m, ~: greturn rgba;& j8 l/ U! K( s8 f7 p; d
}
% z# G1 {8 d) ^* F8 H" ?7 u
' D' j' ~4 n$ x0 Y: u4 Aunsigned char *tgaImageFile::getRGB( FILE *s, int size )" P& t; v) ~  |) ?6 h' i
{
, a! j2 b2 Z! E* B// Read in RGB data for a 24bit image.
3 N4 v$ H7 e5 s; y2 Y* p* }unsigned char *rgb;) J: I+ ^/ r: W- V! W3 r  c
unsigned char temp;
; n  H5 a! W" ?, ^int bread;
' `2 H3 Z$ W8 eint i;( R- b2 \  |. ?7 P! Q! f' I/ a! t% A
+ p* c5 A2 B& t# p0 {! k  D
rgb = (unsigned char*)malloc( size * 3 );
  z) m$ `7 @- N3 G* I5 ^9 e  `3 d- g0 m; g% K1 V+ L' c
if( rgb == NULL )
8 S- I/ }- `! p3 q% r$ L, ureturn 0;3 E5 t; W+ }- p6 \0 C

: J) f& w- v. f& Vbread = fread( rgb, sizeof (unsigned char), size * 3, s );, D: t: F2 A+ g  G# T

( U, n3 P5 N" m2 ~+ N0 I' Tif(bread != size * 3)8 l! o$ N! U0 a8 h* B2 B
{
  |( n( E- B% f+ {% `$ j0 `free( rgb );7 u  H6 U8 _8 {
return 0;
( e8 o& U! f# W9 }# Y}  _# k, B, r1 }) r/ c

/ Z8 f4 Q8 C# g2 g7 k6 O' W// TGA is stored in BGR, make it RGB + C3 q+ A/ q5 h! J0 Z- y1 i
for( i = 0; i < size * 3; i += 3 )& s; p0 U' ~/ T. c3 J) ~
{- u, D* T" [: V: U" ^
temp = rgb[i];
; O( r0 ?/ r" a2 d9 C5 ~7 p* ]rgb[i] = rgb[i + 2];) W5 E% c4 H# a5 m; T
rgb[i + 2] = temp;  ^; |- T9 D6 M' Y
}
3 g9 \- V5 m( h( j9 R* ^6 \; ?/ i0 s" ^; [8 z1 e1 X+ d& g/ b1 r" M
m_texFormat = GL_RGB;0 Z, |, L, q  P3 M0 d/ F% B' G
  }! T5 f' e7 h$ Z4 C* B1 n
return rgb;
3 ^. m2 z5 G* P; \- t& C4 p}: R! p& j, x. ^. D1 @

* T  H" j) m& I% B9 j$ `unsigned char *tgaImageFile::getGray( FILE *s, int size )
- x6 I, m7 t, E{
, Y2 h5 z' A3 ~% U// Gets the grayscale image data. Used as an alpha channel.' C8 ?* n# ]/ `# T# C6 O) {
unsigned char *grayData;
& z9 [9 g2 S; w1 H, `$ B7 bint bread;
% u5 F' h& F: @" m' E
. F. T  x3 e3 V$ L% K. d; BgrayData = (unsigned char*)malloc( size );5 O' s5 E8 n0 R' {9 a
" @! H6 Q2 I4 Z' R. G+ C% s
if( grayData == NULL )( |7 M5 W3 I. t. H( y
return 0;
8 @3 t; w+ x& E4 `  R
( T" f% A- h% C8 lbread = fread( grayData, sizeof (unsigned char), size, s );
8 x9 Z& j/ B  m, h+ h
% {4 G7 W% |* Fif( bread != size )3 w# {: }" X$ y" i& \  M$ {* Q$ ^( I
{5 r6 a' D3 h) Y! M% `
free( grayData );( a: I/ v  N* A$ Q% s7 `" ~$ ]
return 0;
/ d5 I& ^: M5 t: L+ t  A/ x}  f* H3 e4 j, e, j4 P# D" K
0 `$ g5 Y8 d  i. O
m_texFormat = GL_ALPHA;
, l# X( G1 E$ |4 J* ~/ Q5 A0 @% Q6 C% M2 Z$ g2 ~7 G' {4 p
return grayData;& l# [, F/ G' o9 M9 g# K+ ~! }; v' e$ P
}
1 T  W& x1 L! g" f8 R
# w0 w  M5 n( a- y+ q% xtgaImageFile::TGALoadError tgaImageFile::load( char *name )8 f  k- A$ {& @! D
{' }5 H9 f$ O1 f+ X4 x" A
// Loads up a targa file. Supported types are 8, 24 and 32
: J( g+ ~5 K0 h8 b5 T. r3 T; b// uncompressed images.* h  `; g! c# O9 M* l$ J
unsigned char type[4];
9 |8 S& t0 S9 \+ ?9 Z& yunsigned char info[7];
* L4 B- ~4 M/ k# Z* `% \+ p  v. _FILE *s = NULL;
2 a8 O+ T; m& c# t0 `2 E& h! Rint size = 0;/ `, P! w0 t: M  x$ r, K+ e

; m5 e4 H; v( |" m2 P) y7 ^) w3 eif( !(s = fopen( name, "rb" )) )" M) Y6 @1 z/ e9 a4 X1 N5 o
return TGA_FILE_NOT_FOUND;, V- `" B& m. |. N; k

8 a' ]8 ]$ t5 |/ N* W4 v: y# qfread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored( `& H5 }# F0 U8 E8 T
fseek( s, 12, SEEK_SET);       // Seek past the header and useless info
2 }. B, D$ X0 j' Y# N& @& ^/ [fread( &info, sizeof (char), 6, s );
: h% H* I& H, \. a$ c/ h$ l' h/ e2 w/ M: ?  }3 c! h! d
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )( Q& v* y/ C. A! I1 p
returnError( s, TGA_BAD_IMAGE_TYPE );
- P) R  B: V# d7 ^% }! Z/ `: j' s7 S  Z; p- A
m_nImageWidth = info[0] + info[1] * 256;
& J! D( g! _, _2 a$ }m_nImageHeight = info[2] + info[3] * 256;- X1 S( j% q$ i- W- y9 y( B. O$ J) S
m_nImageBits = info[4]; 3 F/ d, a- N& K/ s3 I+ A& c

) A& Q# b% [6 p, {! W  Bsize = m_nImageWidth * m_nImageHeight;' Z1 M5 S8 @* T

3 C  f! o! h# z. d6 d/ n% A+ [// Make sure dimension is a power of 2 0 Z# v* F0 D& ^+ \. U9 K
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))7 S6 i: t: e  }6 e
returnError( s, TGA_BAD_DIMENSION);
! Z7 t7 h% d7 {) k
" W  V+ Y7 b' W// Make sure we are loading a supported type $ [: P' ]4 z2 A7 ~: ^
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
8 X/ {0 f3 K4 m* c7 h% h2 f+ w7 _( ureturnError( s, TGA_BAD_BITS );
8 g$ @4 m% D& g) W
" U7 K4 z9 N- B: U9 |0 Tif( m_nImageBits == 32 )
' C1 v. `' w1 _' I) B) ^- mm_nImageData = getRGBA( s, size );4 s. k2 a: s: z2 ]4 d
else if( m_nImageBits == 24 )
6 }. @8 ~6 u, W5 i3 C, xm_nImageData = getRGB( s, size );  - \$ N. Z' T# _3 @+ u  n
else if( m_nImageBits == 8 )
% `2 D* S" d# Y6 T* Y% T; [# xm_nImageData = getGray( s, size );
! t( _0 [8 v( _% |& I1 I- ^
) }4 M4 @0 b8 L$ F8 V# V6 D0 t// No image data
! y; }( D3 `& g  e6 F! {if( m_nImageData == NULL )1 s7 |" {7 G5 d! Y9 D( e! `0 }
returnError( s, TGA_BAD_DATA );
# i2 H5 y. p) L; F+ D8 q+ k6 G# ^) ?6 m  W& D7 N
fclose( s );* b$ G6 h3 E0 H  N0 |) V
% |+ H+ ?( K8 U$ j& M
return TGA_NO_ERROR;
) [* |- `: ~0 `}
8 }' e3 D8 L: q: Z
% m( Q7 }' }$ x, H  I8 \
& U+ h8 u: u3 y4 N; O$ @调用举例:
0 P+ Q2 A& e1 R5 K) U//
! c& B& E- E4 d* d. o// For the billboard poly, load a texture of a steel sphere. We'll use a
* Q% ^  L& N* T// .tga file for this image so we can use an alpha channel.
# _  Q9 A7 f; ~5 C//8 M2 T; a7 t4 ]8 m

0 e$ Q7 p6 k2 `tgaImageFile tgaImage;
; V- w/ |) n, }, T7 qtgaImage.load( "steel_sphere.tga" );. C0 d7 W8 Q6 F/ d3 B' M' d
0 [# T* W& h/ w. p, g3 u1 N; `
glGenTextures( 1, &g_sphereTextureID );
3 d) k9 J( X6 [. r. r3 n) U+ N( ]# }" ^( T- ^. j( H
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
8 v- w8 m$ [: B* j+ X2 ?6 c1 H7 d4 n' h8 [
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
8 ^+ }: {! K. dglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );$ o4 O& m& [7 c; `

9 _& Y/ F% ]. q. `8 ~! a0 gglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, 2 i: C# t8 |. T5 U0 \) K
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, . T: E- ]# v4 q/ l9 J
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, 0 v5 H9 n% y* L2 ]$ p  ^. Z; G: Z
tgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-13 10:10 , Processed in 0.018590 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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