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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>8 z6 l% ^, ]1 a
#include <stdlib.h>
+ [( r6 g* R+ Y7 {9 C' A$ ?#include <string.h>
* S  i) b6 l. f! s$ ?4 L. m- T0 U#include <windows.h>
2 D" x% M: t- u1 u#include <GL/gl.h>8 p' u2 O2 k' j4 T! T% ?- w7 v

2 m, K  }+ @  x  j, ]; Cclass tgaImageFile
! U  m! d+ j& o0 w" O, U; s8 t{
: }: z$ P; K( X5 _- zpublic:0 s6 j0 y2 i7 f# n3 C5 ?
3 o1 v2 l* V4 W1 B0 U; z/ U% l
tgaImageFile(void) : ; @" X" i1 [3 H/ R% ~1 y) h
m_texFormat(-1),
7 |, i$ ]3 @% f2 ym_nImageWidth(0),
8 _( n# _' m7 S& vm_nImageHeight(0),$ q- K( n9 c2 ]: Q
m_nImageBits(0),, P  L& q7 \7 v* W
m_nImageData(NULL) {}' \+ ?& P7 T% P- _2 _/ i9 l; p+ A
; P' m3 J5 E7 }. R' z( |( T
~tgaImageFile(void);
& ?( `1 j  ~, X) C! F
% X, R! J' E5 Z  L/ G3 zenum TGALoadError
. S7 n. |9 v  v0 l* c% i& T6 _{9 S! o% g) k& e1 p0 K2 U7 Z
TGA_NO_ERROR = 1, // No error
: U' E& `  r8 [  TTGA_FILE_NOT_FOUND, // File was not found
2 E5 U% _0 S% ?  W' B: j  qTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed. G' w8 c+ z/ a! f
TGA_BAD_DIMENSION, // Dimension is not a power of 2
: B, ?+ r6 J. I- x) ETGA_BAD_BITS, // Image bits is not 8, 24 or 32 3 L% p9 f; i4 c% X, [
TGA_BAD_DATA // Image data could not be loaded
6 O; f. g# Z# o" \5 C3 Y3 T  };+ _7 L7 g% e' N' n) E  R) `

+ `3 q1 U; q2 U, g/ @, j5 ctgaImageFile::TGALoadError load( char *name );
) N2 M9 f2 P3 A3 U8 Y) x4 q3 t! e6 h8 m
GLenum m_texFormat;$ q' _7 r; t" e* H
int m_nImageWidth;
, S( n( W, k5 lint m_nImageHeight;, ~6 i/ V& V' e' K$ N4 S
int m_nImageBits;% E( T+ N7 Q% O% Y
unsigned char * m_nImageData;
6 t  o# C) A% ?2 J5 @/ |3 h
- _2 O* P, \8 v' _5 y9 gprivate:
4 j9 R& D3 y: C0 E+ R9 n/ O3 A7 P1 Y$ @. r. C9 K/ l
bool checkSize(int x);) Q. ]9 D, {6 ?7 q" e, o& s
int returnError(FILE *s, int error);
" ]2 r" _: w" W7 k- K. m5 Nunsigned char *getRGBA(FILE *s, int size);( x& A* G' d" r; `% r. o7 R
unsigned char *getRGB(FILE *s, int size);
/ M1 r7 g: S" o% W7 l. v  \$ Punsigned char *getGray(FILE *s, int size);& O. q: C. p$ a, d% M
};
. b* e# R  c1 t! a" D/ I, l2 B2 Y8 |* j' j
tgaImageFile::~tgaImageFile( void )
$ M- C  v4 x( @; o$ U; D+ G{( M. X6 {8 U; \
if( m_nImageData != NULL )
# V2 L$ u8 R3 o+ x* g1 X{
. }) R1 a0 U: X8 A" Yfree( m_nImageData );
3 G% z: m/ ~  S3 Z6 U9 {m_nImageData = NULL;
5 p5 N, p& {2 ^: l' }4 N/ `2 M}
: E2 R& W0 c' N2 E$ O6 c}4 _0 _8 i3 M/ |

, {8 U$ L2 I9 v, ~0 V7 \bool tgaImageFile::checkSize( int x )1 i. h* t2 e" Q) J  ]% l" y* @
{
6 t7 J3 q' G* L" P8 h3 ]  }1 ]// Make sure its a power of 2.
- w' a8 D6 Q( |& N) Eif( x == 2   || x == 4 || 1 U8 [* U  F; R# c
x == 8   || x == 16 || 3 c" t1 a8 F5 N! f& \
x == 32 || x == 64 ||1 {. g5 ^$ B+ _  ^7 _! n7 y
x == 128 || x == 256 ||
# g, h5 V6 O. ]6 v. Z7 i1 q9 G8 ^x == 512 )
% m; I9 O, b* |1 n5 g; Areturn true;
3 l5 G0 g6 `- A" {  m# Y; \- g  E0 Y. K( G% v1 {0 x0 G3 n
return false;
. y, _/ F" o8 r/ ^0 s8 c' T% C0 |}  {5 n' [) m% H9 ]" I. J

9 a' R, I3 {9 S( \% Z% A& lint tgaImageFile::returnError( FILE *s, int error )2 p4 n  r9 G% u
{
/ w# G' K; L$ `// Called when there is an error loading the .tga texture file.
4 R3 R: |. G: U. Ufclose( s );
; I& Y/ P8 m7 V* l' o' Rreturn error;
5 p& O  j$ ~& ^: a* {}' j* B0 s0 w6 q4 N! M" E2 u$ K

/ P9 F, L8 E' Y% h8 p' funsigned char *tgaImageFile::getRGBA( FILE *s, int size )0 b: x" u# {) W: K7 t- c8 x5 c
{
& u1 f+ v7 u* v8 ^3 G$ e* m7 E// Read in RGBA data for a 32bit image. 8 h' ]+ C4 Z: }# g& k
unsigned char *rgba;
- G) k# H9 K8 K2 J3 d1 U* |unsigned char temp;
0 I% O' O4 u4 J  ~- s% l7 z! ]int bread;
2 K  g! \( z- \$ o' Bint i;
, j% [) T4 `' p  x% @* b
$ i; _. m4 S5 d$ P  E2 V* srgba = (unsigned char *)malloc( size * 4 );
7 V; y& X! ~8 o9 ~) R9 p! G  c! s' u# j. x& J" u8 o# v
if( rgba == NULL )1 J; M: K3 \, G+ L0 S) S' S
return 0;
" B7 z6 U& K* @0 z# }7 Z3 {
' b# x9 ]; W, w$ G9 m. ]* x* T5 Gbread = fread( rgba, sizeof (unsigned char), size * 4, s );
5 c  s& v5 u4 j7 ?# Q, y4 }- R  _$ z
// TGA is stored in BGRA, make it RGBA ( [' U: ?' b# P2 b
if( bread != size * 4 )
# f* x, [3 m: N8 @% R{" e; i2 ^6 S! H% E
free( rgba );
" a: h" N! T" l) D" @return 0;
' D/ w  q4 X( F5 y" w2 Z. A}
. k3 G0 l0 Y: @- ~- _/ X" I* f$ X$ h: _$ l7 w* F+ ^
for( i = 0; i < size * 4; i += 4 )% _( J; M2 b1 E  }
{+ Y8 N. p+ j$ Y, E
temp = rgba[i];
5 h& U3 g8 I* |# vrgba[i] = rgba[i + 2];2 W( H. Q0 u  m3 a% M2 D, J) _6 p
rgba[i + 2] = temp;# T. K% p7 o& h& P) g- K# {
}
/ Z$ D. O- {: f7 D
  W, B3 i! C5 Gm_texFormat = GL_RGBA;
! Y1 j. K% Z, P5 ]) C8 Ureturn rgba;2 M; M" {3 v. S$ W
}2 `( X! b. H: P; e

9 p) R- d, `, ?! P; tunsigned char *tgaImageFile::getRGB( FILE *s, int size ): E5 R# F0 h( C  _0 j$ t
{# x1 M$ Y7 {8 @5 P9 v
// Read in RGB data for a 24bit image. ) m% \$ h# K: k& r2 s8 D" M
unsigned char *rgb;) a" g/ [/ K+ Q7 n9 B/ d" @3 Z
unsigned char temp;
" J  Y$ a# f- I* Z4 ~int bread;* d$ A6 s$ K4 J6 v6 `- `
int i;5 L( o  v" p9 h1 g/ s
6 D0 S/ J4 c4 e  L/ ]9 e7 X6 h
rgb = (unsigned char*)malloc( size * 3 );( g5 f4 L+ O6 g& w
$ p) C  E' t. x9 X, r( }$ y
if( rgb == NULL )8 d3 M: [  f# U% }8 M& l9 W
return 0;
6 E. D% L+ e/ f. V3 A- x) {: _7 R  t' @
bread = fread( rgb, sizeof (unsigned char), size * 3, s );7 E3 R! d5 I6 d+ ^/ g/ Y: }1 W

0 U0 B% q) d8 j$ c- G! Wif(bread != size * 3)/ G2 t1 a& Q0 S- A# J8 X! j
{
4 Y4 ^. G' r( t: a# Zfree( rgb );8 e# x" K  ~: x8 Q9 Q' Z! o
return 0;
$ [1 c; f. L$ e) t  u}4 K4 P* x1 O6 a7 [$ G: ]

, g* {- S7 `) s" N// TGA is stored in BGR, make it RGB 0 C* _! e& x8 x) t: H9 Z. P
for( i = 0; i < size * 3; i += 3 )* o3 _. p  p" @& x; J
{
6 V& z, e3 l  F" n, R* ~2 S8 d$ htemp = rgb[i];6 }5 P' r6 v5 Q) f. Y: W7 o
rgb[i] = rgb[i + 2];
; x- L, G3 L* _. Q& Yrgb[i + 2] = temp;9 x0 L0 n$ h9 H* g
}
) c/ d  f5 E4 L6 f! `, P
, m9 k9 Q9 o- {* b. {m_texFormat = GL_RGB;4 l' s! z; J4 Y/ _

$ _/ t5 A6 B( O4 V  h4 Sreturn rgb;
8 ]( i# r0 k9 J5 ?}- K6 j+ S" @8 v" A
4 i5 J, a! }' w' a6 f. ?' O
unsigned char *tgaImageFile::getGray( FILE *s, int size )4 @% C8 r$ c- ~* Z' c
{
* P: E0 O) [! w5 A6 j- q4 j. X// Gets the grayscale image data. Used as an alpha channel.
7 I# m3 v& U1 }$ a4 i) }unsigned char *grayData;
& r. t4 _2 Z0 N& O: l* |int bread;
5 S& c- r" |& \' [4 c6 T6 z7 W! P* u" i# a  D
grayData = (unsigned char*)malloc( size );
, j3 J9 R+ H; i6 \4 o, y% I9 Y/ s  S5 D' ]8 w) ^% ^3 P4 V
if( grayData == NULL )
* P2 v% i+ D, u7 treturn 0;
4 g4 k' d' d! a4 E5 {9 o9 J+ m, `/ d. Z4 }' ]
bread = fread( grayData, sizeof (unsigned char), size, s );$ W1 c8 u6 [. n' h. l8 ~& G; {- a
9 M6 w) V; u- o0 W* c) T1 {
if( bread != size )
) F# f1 F; b+ @# M2 [{
5 w4 I0 _5 u  d) F" z2 {" Gfree( grayData );
$ T( w8 W, @2 O  nreturn 0;
3 b, @( D1 f; K; ?9 e1 j& q. n}% t: _2 V" n. ]. |5 i: p

5 t1 e5 y) U  y- N  _m_texFormat = GL_ALPHA;
7 Y: [: ?: J9 c7 {! r' N+ H: [0 r& g' t# V7 s# u- q8 ]% ~
return grayData;
; K" B2 D6 k/ W; n& J) D" d, A}* w" |; j3 K% N9 c9 _6 N4 U
$ j5 A& y7 N! y
tgaImageFile::TGALoadError tgaImageFile::load( char *name )7 w; ~- N) U/ [" \9 {2 W
{- u+ h+ E8 r. C
// Loads up a targa file. Supported types are 8, 24 and 32
8 X. \0 T9 L, @6 u0 ^// uncompressed images.3 g, b! b( B  t" S7 A. g/ i9 B1 {# f
unsigned char type[4];
2 v* d# X- R# |; Dunsigned char info[7];
! f  @! ]# h/ m! `FILE *s = NULL;" j- u4 @, t* G3 w5 f
int size = 0;
5 C( e6 ~8 j: u3 ~4 r9 k" a, I3 e$ Y+ C, t) G# ]8 w! {
if( !(s = fopen( name, "rb" )) )
. a2 ?9 P6 O$ C5 d) ]return TGA_FILE_NOT_FOUND;
( l9 c9 b* }- e6 o$ b# p& y
2 U5 B4 U8 w5 ^5 Wfread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
) J. N7 I8 }2 r  ^$ D  c; @9 xfseek( s, 12, SEEK_SET);       // Seek past the header and useless info
; v. I+ m' A- Y; g0 q% Ifread( &info, sizeof (char), 6, s );
( i& S, n& H- H" n6 [# H3 h1 x# l/ X: L! C% p
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )1 w4 p; B0 i0 D+ V! R5 \
returnError( s, TGA_BAD_IMAGE_TYPE );
; d/ ?, _" W4 U  y3 r2 d4 l
, Q0 d$ P% h" s6 Xm_nImageWidth = info[0] + info[1] * 256; 6 n  `. @* W* c* P% e
m_nImageHeight = info[2] + info[3] * 256;
0 I, ~# e) B  V8 l+ d5 c" Rm_nImageBits = info[4]; / s8 G9 l6 C, O6 |
  c% Z, K- N( J/ r( }
size = m_nImageWidth * m_nImageHeight;3 J1 f6 ~. C1 ^6 x

+ O; V- t) E2 N# h// Make sure dimension is a power of 2
' S2 f- Q4 v; Oif( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))4 w, ~" ?7 |% }  t9 E
returnError( s, TGA_BAD_DIMENSION);, d; _% v! D3 w5 @7 S
7 W0 k# C5 D8 i4 d2 S  l" ]
// Make sure we are loading a supported type . d+ x$ S+ a& s* C+ C; J0 k
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
2 I9 U# J/ {5 C) P! I7 F7 YreturnError( s, TGA_BAD_BITS );4 p4 l% \8 s' c; E. V" X7 Y  a& T7 J3 I
* c) z& S* U: O) f
if( m_nImageBits == 32 )4 R+ i. A( a# q2 W. |! n, e; k: {1 D
m_nImageData = getRGBA( s, size );
. P" {3 y6 l# ]% k9 helse if( m_nImageBits == 24 )9 m9 x. s, _% q" D" c2 c
m_nImageData = getRGB( s, size );  $ ~% j  S/ O4 U9 l2 |
else if( m_nImageBits == 8 )- c4 I/ X* w' d3 L5 I/ m
m_nImageData = getGray( s, size );
" w7 @- g; O- E8 x2 n: I- {7 s4 L& ^8 b
// No image data ) }; o- P1 H  E- d" V
if( m_nImageData == NULL )
. F! }. \2 |! o, n, E. j1 a' p- freturnError( s, TGA_BAD_DATA );9 j3 p" Q1 U" Y
4 W3 e# L, \5 b; u$ [: P0 Y2 _
fclose( s );
: F4 P) ^& ]9 i$ I1 k2 a: h% W  Q; r% T6 a2 w: }/ T. O
return TGA_NO_ERROR;
. {0 O: ?0 g1 v; U! D5 L}0 h; e+ `% @6 k" k

) O' V& p* u# o& G4 h, }; T/ T) W8 _! y/ N+ q
调用举例:8 r# H2 f: _& W: k, L& A
//
3 v% ]5 T8 d6 ]: r// For the billboard poly, load a texture of a steel sphere. We'll use a 3 }! }( h) o) ?
// .tga file for this image so we can use an alpha channel.
: ^9 i4 d8 k2 p" G0 c4 Z9 J//* L, D% R( V% e$ c! O: z
& C5 d9 `2 B; A# U" T3 C/ u/ z
tgaImageFile tgaImage;. D+ j# }) U, Z8 N# s3 V( \
tgaImage.load( "steel_sphere.tga" );
5 F4 \" E! R5 W, t( K' C0 J3 `$ N9 P2 I: W3 l* a. K
glGenTextures( 1, &g_sphereTextureID );5 ?2 l$ ?+ k) v& i
, t! [( o. Q+ Z/ U4 D
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
2 M2 f  g* B  b3 k
& ?7 c6 L4 @, \glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );8 T& e( P/ ~/ J8 L9 Y1 L! M! V
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
6 C* s9 E. I  k3 u! i
( A; |! v, O+ `( pglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
2 v' ]5 `- t9 }) @! L7 P1 ftgaImage.m_nImageWidth, tgaImage.m_nImageHeight, ( \" S: n/ I; O- d/ J
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
; x, |. c* l5 m5 ZtgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 06:24 , Processed in 0.035345 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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