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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>. K5 c( A7 S" E* h; S# A
#include <stdlib.h>
2 I; R: j  u6 `/ M. h* ^6 e#include <string.h>% [9 D. L  Y: I' H" g0 `. I
#include <windows.h>
6 K! A8 W$ K# p- G7 t& [#include <GL/gl.h>
6 y; ]# O/ C% n. q+ V( \; s0 x& u" T: L
class tgaImageFile
# C/ ?# d- A6 ^  L{2 n9 I; C0 R0 V+ \
public:
) y( x6 f# Z3 S, m. x) w  J/ g  k0 y5 Y- N* Y7 V+ ]4 ~
tgaImageFile(void) :
: A, d9 f6 B! I0 ?# @m_texFormat(-1),
) B& M9 H: H$ n5 n' A2 X5 U9 \& ~m_nImageWidth(0),
- n) c8 S( M# {2 u% hm_nImageHeight(0),
5 [& {" |# F5 t" G- em_nImageBits(0),
: a2 c' j4 q& ^m_nImageData(NULL) {}3 K; m( j7 ~& Z9 b1 K: x3 _" T
1 X* p' U3 y  M7 a# W. p
~tgaImageFile(void);
: C# m" j& V3 B; m0 }- u- w
1 t" N. e- {" t' ]. ]enum TGALoadError
6 o9 P2 K. }2 C1 l4 _{
. q9 ?) b- F* M( I. W. cTGA_NO_ERROR = 1, // No error; @' P( |3 s% T; i
TGA_FILE_NOT_FOUND, // File was not found $ \3 n- V, D; ?' `- j# i
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
# K0 k7 R4 g% n- A( e3 f) DTGA_BAD_DIMENSION, // Dimension is not a power of 2
2 m2 I5 t7 A+ P4 C4 H) X! ~TGA_BAD_BITS, // Image bits is not 8, 24 or 32 & R8 }7 j3 G' y- b5 u
TGA_BAD_DATA // Image data could not be loaded
6 e; D* ]9 M% t' [5 a4 T  };
5 V+ D1 q+ ]) r. d  K' ^! s5 ?0 |% L2 j2 H% h1 F
tgaImageFile::TGALoadError load( char *name );
$ W, D. d+ e& M+ {. m# Y$ K9 G! p
GLenum m_texFormat;
2 Y3 I! z1 A3 `( qint m_nImageWidth;
, |* z! P# O" p; r) A' r7 o" ~int m_nImageHeight;
. ], y/ j# V2 @9 Aint m_nImageBits;
% Y1 c! ~. i0 \. k, L. Funsigned char * m_nImageData;
' q5 b; o) H! V, J4 G8 l9 h
7 C# D0 r$ U) o9 ^7 d, dprivate:
4 f/ o1 R+ Y1 ?1 C
8 D. K3 D  F3 z" {bool checkSize(int x);+ V# x9 k& D2 \
int returnError(FILE *s, int error);
: y5 s: `7 E* \7 Gunsigned char *getRGBA(FILE *s, int size);
3 x, v7 z& o" Y/ \1 f# Kunsigned char *getRGB(FILE *s, int size);
& [% s' _$ v# u4 M7 R) ?; zunsigned char *getGray(FILE *s, int size);" V) E0 N( C, Q* c" |5 c; ^# S
};  r' D0 ]# _# \7 v

3 w$ z8 z, x2 ?$ B; y7 \3 W# ZtgaImageFile::~tgaImageFile( void )
, R! u! a! A2 S: M2 y{
9 M" ?& B2 T3 F" A8 O$ @4 cif( m_nImageData != NULL )
( u! @7 i# A: {& w2 H, v, v{
0 F" D8 ?  U4 n; ~6 R( T' Sfree( m_nImageData );0 i# y! q6 ]' s: @1 W
m_nImageData = NULL;5 l% [% H( q; K/ N( V
}! }5 r- h% E. g- t" H
}
3 D: Z& {+ `$ w  z6 F% L6 S, T- B0 e$ Q3 u
bool tgaImageFile::checkSize( int x )$ S; g1 w+ p6 Y- h% L# F
{
- a. g2 v5 ?& U* v// Make sure its a power of 2.
" a/ C# U4 k! H3 Nif( x == 2   || x == 4 ||
+ L# V) Q+ z5 d  T( k# m/ v/ h! }x == 8   || x == 16 || 4 o5 g) o- V2 y& V  b2 g
x == 32 || x == 64 ||
. X4 ~8 Y$ |  [4 b- fx == 128 || x == 256 || / W% \+ K+ t9 J
x == 512 )
$ o5 @( n; r( a- v' x7 vreturn true;
8 Y1 s, D4 [8 w1 ~! W0 L
( \0 D- }" \2 Z% ~) ireturn false;0 n; q. g5 A. ~+ j* w" S
}" o/ q  I0 Q- E* W" E1 L
& {9 W* Z4 k! U  `
int tgaImageFile::returnError( FILE *s, int error )4 w( W, J4 ^$ b+ s3 m: W' c6 }
{! J7 Y& Q- l7 ?0 r) p
// Called when there is an error loading the .tga texture file.
3 b" Q! }% ~6 Z' o( z% qfclose( s );  N+ \8 Q% {& p9 r/ e
return error;( c8 _3 n/ m" a5 w3 R# E7 L/ P. I1 h6 ^
}
: o* S  n; s. t) u4 D! _
! U4 z& h! v) {7 zunsigned char *tgaImageFile::getRGBA( FILE *s, int size )
1 T* V" d; D: F/ x' D9 X! S' v{4 I- R5 [5 v5 w1 }# z/ f$ w
// Read in RGBA data for a 32bit image. : P3 r& A/ X, R& Q! Z
unsigned char *rgba;
0 h" R; Q/ }2 C0 Yunsigned char temp;' `* d' m! m# M/ ^- f3 F: F5 B
int bread;
# L- h; C. p# ^4 ?' R+ sint i;
1 L$ c  d# z8 ~+ F6 c! s3 L4 S
. g2 q; V2 I, w$ B' N; Lrgba = (unsigned char *)malloc( size * 4 );! Q" f, z$ y8 D& U4 D- s

: H& g5 E2 s& |. }0 u% j8 Kif( rgba == NULL )9 o- z0 }* t* ^- T( [, D
return 0;2 m# _2 J  P4 K0 I) q) B
: h  g* s2 `: g" r7 L9 K
bread = fread( rgba, sizeof (unsigned char), size * 4, s );
# ]. f1 |- `/ f6 C1 b1 d
: S) |" Y+ I$ H$ y; _2 C// TGA is stored in BGRA, make it RGBA / K1 C2 V6 s2 \& ?( z  J& a  [9 d
if( bread != size * 4 )0 K! K, U& s; h& a1 y2 q
{8 P) f0 d# Q, H* m
free( rgba );
0 a; C4 S3 ?, breturn 0;' Q" [0 v; q6 Z- Z3 B3 |
}5 P& i: s3 J! u: m; y7 N* H8 g
" N) L3 Y! y2 P2 u+ E8 x
for( i = 0; i < size * 4; i += 4 )9 G& M. L4 Y# |9 V
{, C* @5 y$ n+ d. W
temp = rgba[i];1 H! C$ a  Z% f( O% q9 H' U
rgba[i] = rgba[i + 2];
1 H9 Y7 L5 `: M+ T8 C) c) B2 argba[i + 2] = temp;0 g1 |% t3 A' x( z1 `% W
}
$ ^/ g0 a5 g& r6 `" f: X5 C1 g
3 V7 b- h7 ~: _3 v( zm_texFormat = GL_RGBA;7 h3 p# p1 [3 p* g: H2 F
return rgba;/ i) _1 b/ m7 x. V: l
}
" Y  [; a4 y# M* p- l7 H# k. n; F$ ^( \
unsigned char *tgaImageFile::getRGB( FILE *s, int size ). e& r$ t2 K8 M2 o6 `! S+ T
{; k1 M. f; f9 k5 P1 f* {6 y4 s
// Read in RGB data for a 24bit image. 1 D# q9 |8 T5 X; }
unsigned char *rgb;$ h  b  H9 L5 i+ f' x
unsigned char temp;+ s$ i/ S- S$ s! H
int bread;3 d! L3 s6 I0 a" P2 l7 Z9 W1 p; R7 l/ u( K
int i;
  e) d9 `& o& D( S9 P7 O
  t) k$ y/ Q2 h6 `rgb = (unsigned char*)malloc( size * 3 );
  d2 Y5 |" s( `  O  D- Z5 r8 c4 F! }, D0 |- G7 g8 l, A% [
if( rgb == NULL )
* N; \, a' ~  B; a/ Treturn 0;
! z! O$ b* t0 J2 x/ m6 L: T$ Y5 E9 W  a+ [, _) t7 P
bread = fread( rgb, sizeof (unsigned char), size * 3, s );
7 B7 ~" ^5 L& [4 m5 y$ F7 X' O" r7 w, Z: j& I
if(bread != size * 3)
: _% d6 }& f2 r$ b2 e" t{2 x' P. Z5 S* d2 }* Q
free( rgb );
0 M' V4 ~4 p! R- l8 Q0 O! ureturn 0;( i4 H& L, l/ A2 o# ]3 D" Z7 J8 f4 ^( J
}
% x% T; Y+ g+ f- f1 B0 j6 S1 U* `' m
( O0 g% J- [  q* h/ q  o/ L% T// TGA is stored in BGR, make it RGB
3 Q! z1 C2 ^  ~! ^+ Y9 Gfor( i = 0; i < size * 3; i += 3 ). ~% j1 ?* [+ u6 M
{
3 D% O( z' \% n. y* N! N. P& a8 D  otemp = rgb[i];
) V1 R% [: W2 c0 `rgb[i] = rgb[i + 2];
% I4 S, H8 b; A) U4 R/ I2 ~rgb[i + 2] = temp;& ?, O% L; N6 X4 x
}5 @; c8 U5 r6 }

( R0 {4 Z* n4 l5 i+ x$ cm_texFormat = GL_RGB;0 a. S/ G' ?4 A' B& X+ Q

% o/ V" S# y2 Y/ Hreturn rgb;( O* [/ |% x7 f8 l3 D9 ]
}% R" J) d+ B' |: j4 @
/ Z4 A4 b6 c0 x' e4 {: B
unsigned char *tgaImageFile::getGray( FILE *s, int size ): W- P+ l. _( C9 y
{$ M7 U& x& T# ]% d* }& X6 v* P
// Gets the grayscale image data. Used as an alpha channel.
/ U. c: a, p6 `5 `8 t* Dunsigned char *grayData;
& q( }- D5 ^4 T& W! s8 T+ tint bread;
! r: L: @  U, G  Z8 S
7 m# b* w  x2 z, X, AgrayData = (unsigned char*)malloc( size );
- P; D0 y/ r) G* q
  y3 l1 ~4 x7 j9 @( p. Bif( grayData == NULL )8 }, q& k1 p+ W4 _1 f4 v0 B
return 0;
% U0 a7 l$ T0 Z: `# ]& ^1 }' h3 u) w0 ~) d
bread = fread( grayData, sizeof (unsigned char), size, s );
" M8 y1 E/ u; q: I8 n
1 r) M  s( b9 h7 {% K1 u) e$ Fif( bread != size )2 E4 i3 w3 I3 k0 W! o
{
6 H; T5 ]* j0 `free( grayData );
, [8 d, w- p7 Z$ ^; }return 0;
8 k& v2 _4 Y" [1 l' Z. O}" b" j' Y- D" F- p4 P
2 L$ b; H3 \+ X4 O& @5 i2 g3 U
m_texFormat = GL_ALPHA;$ e. @: S" H1 [1 @- }! k4 z6 ]) M
* J& Z/ }1 N: {
return grayData;
# k0 R2 k, E4 x9 Y}" s0 i( F+ ^' T- u
! @: ~" \! p% d1 Z
tgaImageFile::TGALoadError tgaImageFile::load( char *name )& c0 d) d4 U9 Q7 f: k1 b) `& E# y
{- \) T1 v5 K' d/ A) `
// Loads up a targa file. Supported types are 8, 24 and 32 1 D/ ?( X# W( Y+ R9 p' R2 z+ k8 {
// uncompressed images.
" G7 k) |  {  C% e7 bunsigned char type[4];; k8 O& Z( u6 Q1 j  [
unsigned char info[7];
/ t4 a2 x  @$ H$ P1 f/ x0 e3 LFILE *s = NULL;$ H# _* \  @* V3 k6 ~3 D+ ~4 v
int size = 0;
+ o; r+ ]5 @* v; Z2 i
2 l  W  |! B" dif( !(s = fopen( name, "rb" )) )/ U6 l; i" V; ]. L" \
return TGA_FILE_NOT_FOUND;
2 G* u6 b& M; S9 V9 f# h- [
0 ^& L/ u: _4 s& W& a$ _fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored9 S1 n6 R1 M# Q, |+ p) h5 I
fseek( s, 12, SEEK_SET);       // Seek past the header and useless info
' m  y. J1 l- u: d: Z! K7 _- z1 B  nfread( &info, sizeof (char), 6, s );
( L- e( B: I0 y9 k7 G
# c: T: ^9 R! I$ M5 Z( c% w0 f4 zif( type[1] != 0 || (type[2] != 2 && type[2] != 3) )7 U  l7 m9 [$ @/ h6 X1 ^! ?. |
returnError( s, TGA_BAD_IMAGE_TYPE );
: a7 o5 |% d& q) Z6 ?% v7 t* M! G  a# L- M' P3 t" S
m_nImageWidth = info[0] + info[1] * 256;
! |. O5 b& w! ]m_nImageHeight = info[2] + info[3] * 256;
/ q1 T% k' L' L8 Am_nImageBits = info[4];
+ F8 k$ M4 |5 q4 q5 q
& M9 S. R: V% {( A' zsize = m_nImageWidth * m_nImageHeight;
0 ^% s$ O( i& b6 Y: G" ]3 ]3 D5 t6 H
// Make sure dimension is a power of 2
) F; _) l8 F+ W! @if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))9 r8 ^/ D1 d% x+ X4 q, j
returnError( s, TGA_BAD_DIMENSION);% l% F& ^7 @6 a7 u( T- u3 D! P1 u
, M; ^" Z3 q" h2 {! i5 t
// Make sure we are loading a supported type ! L# O+ k4 y9 v2 q
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
) O& y: ?3 z( ]2 g$ [6 u. ]returnError( s, TGA_BAD_BITS );5 K& ]( {1 K2 t
2 G" j% C/ ~& {# _- u; Q
if( m_nImageBits == 32 )3 D: m/ O$ G( p+ s2 H% W
m_nImageData = getRGBA( s, size );
+ u5 X6 n9 i9 e% C  X- gelse if( m_nImageBits == 24 )# ~4 E! g7 `2 b! n% N9 P& c
m_nImageData = getRGB( s, size );  
! o' Z7 G, V+ y( Z( T1 l. Selse if( m_nImageBits == 8 )
) {! a7 d9 [* B+ d/ \2 s5 }- ?m_nImageData = getGray( s, size );- U  i) y0 W; x; l8 R. C5 O

& P5 s+ @9 [3 x5 l+ w// No image data ) V! D1 X4 @/ N# [. L
if( m_nImageData == NULL )
/ f3 z6 ]( l& S& x: BreturnError( s, TGA_BAD_DATA );: C* Z# _8 [+ R' I3 g  f

. a0 B9 Y6 a3 N& Efclose( s );6 |1 ^3 W  C+ U( C3 a
8 H" u0 r# S- q: u: Z/ z- V
return TGA_NO_ERROR;
  p+ ]/ A) a* e7 v1 G- b* Z' j}2 }# y3 V8 r! z4 O
1 ?0 n% U: ]5 t0 g9 }) R

1 y3 y: J% \; a调用举例:
1 K0 i  I; h; e0 V7 E//7 z$ |) D9 i( E
// For the billboard poly, load a texture of a steel sphere. We'll use a + Y( X/ q8 {- |2 t0 f( _* A% ?
// .tga file for this image so we can use an alpha channel.
$ f" [7 S5 ^( s//% n- u1 O2 W& B$ @4 C9 }. X
/ \5 c# l' I! }7 t; w
tgaImageFile tgaImage;
& y; V0 ^6 F; O' w, PtgaImage.load( "steel_sphere.tga" );/ m: |6 [. c+ X- M0 X2 v7 Q6 g
. t7 X8 c# [  b% F4 m
glGenTextures( 1, &g_sphereTextureID );; y7 [7 u+ w) R) H+ W6 k. r
* c$ i4 B* l1 t/ I7 F! V6 X2 s
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );# ]% C/ R, P1 R
  P. J* g9 s. j) |" o# a
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );& e( i' ?4 a/ Q& ^: G1 f
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
2 X, N, J" ^. W/ ]
+ r. a- t/ o7 b4 z5 ]6 W- i& B6 IglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
8 A! L! Y( e& w& {  u2 {9 x0 ftgaImage.m_nImageWidth, tgaImage.m_nImageHeight,   `( _* D/ Z+ }
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, 8 E0 B3 j/ D2 m0 e: B  g9 I$ G
tgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 04:22 , Processed in 0.034467 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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