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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>
+ w0 k! J! T7 Q8 ^- D#include <stdlib.h>
$ k. ~+ A; H; H: ^/ ]#include <string.h>
% u0 }6 K. C9 i+ F) g# l#include <windows.h>
% P, _3 s4 K& ]5 Z( Q; |, V#include <GL/gl.h>
0 P' K, I/ J1 S# z7 U/ T1 m/ {" ?7 z; X7 c# d% ~- B+ U" m
class tgaImageFile
& F% `  O) X2 F- o# W{, e! V& M* _/ h" a
public:
: l: \' u( @$ L5 x0 p8 U0 w/ R+ c9 `0 r, @* w& `- _
tgaImageFile(void) :
, X" y; A3 [! T7 pm_texFormat(-1),5 p# R, ~1 a5 W& ?2 o8 h
m_nImageWidth(0),5 l9 R  k$ q  A' d9 ?4 h/ n  I
m_nImageHeight(0),$ [$ C. Y. V3 B8 t! y8 C( V8 }
m_nImageBits(0),# k% w3 D+ l5 ?4 u4 p' N& u, i# P
m_nImageData(NULL) {}
! ~6 d, C1 d" h6 o8 }
) `7 J# j5 [8 H( r2 h; {~tgaImageFile(void);
. R  n% H, }% n; g  h/ b# C
$ F* q" F  J; D  K; renum TGALoadError4 e# f6 L2 F" }0 L- P% }5 H
{! v. g' a5 t9 Y7 l3 h
TGA_NO_ERROR = 1, // No error
+ d. N6 U6 L" e! OTGA_FILE_NOT_FOUND, // File was not found
4 R6 h/ A. z  `5 ]3 }% ^TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed6 l+ N* V# e- ~7 B5 ]
TGA_BAD_DIMENSION, // Dimension is not a power of 2 5 s; r5 t+ R( P! y1 `. B) i3 t
TGA_BAD_BITS, // Image bits is not 8, 24 or 32 % ^" l" X' U1 r) S& c; D
TGA_BAD_DATA // Image data could not be loaded " A3 G/ Z& m# d  _& A* D$ C* \
  };8 |6 o( e% P5 W1 H

/ v; c  g: H- T# f' z- wtgaImageFile::TGALoadError load( char *name );
: U& x; X% H3 p2 ^  J: z7 R; G4 b$ Z4 }/ W0 F. [
GLenum m_texFormat;
6 U6 V+ D2 L+ `& vint m_nImageWidth;/ C$ x. D+ b- v
int m_nImageHeight;/ d: F/ c+ B; ^' k/ k1 [" d, d2 ^7 x
int m_nImageBits;( L% u1 J" J1 @; Z
unsigned char * m_nImageData;
& e; S5 C4 ^% V3 n0 n( k7 V3 N' }8 [* N5 Y6 U/ z, L7 E6 }
private:3 u+ c  Q: }; J* @, v* a# }

) k0 ?* A2 F! W& \% kbool checkSize(int x);
7 D; L( W. |# X3 W* Pint returnError(FILE *s, int error);5 w0 R. ]  e3 {$ K
unsigned char *getRGBA(FILE *s, int size);. k0 g% k6 E& I
unsigned char *getRGB(FILE *s, int size);9 H8 s8 M+ e3 Y. q6 K
unsigned char *getGray(FILE *s, int size);7 {' q! _1 O" d8 X
};4 P( |( s! b4 P5 ^0 M9 v8 e
& N( E- e( c' w8 F/ m
tgaImageFile::~tgaImageFile( void )7 M2 K- C6 s' }) O. f, l5 ~3 D$ u2 m$ x7 p
{
4 D1 J# c+ e2 P/ |if( m_nImageData != NULL )% b2 ]! I- _. H; g) r. U: f
{# F3 i( c5 \9 C& B
free( m_nImageData );
% R! }5 O  b+ L8 J6 T( k8 L( [m_nImageData = NULL;
) T0 u9 d8 a  k0 w}- W, Z' e2 Z0 }
}
+ i% a* _1 ?( @. X# N; T
: h% f  ?- c1 E+ L1 R) nbool tgaImageFile::checkSize( int x )
2 ~, r3 q( K( P8 F" V; V{7 t8 c' P$ L" f, m$ L& Q  |9 ^6 Z
// Make sure its a power of 2.% g* [. I1 C3 d+ e5 g5 \
if( x == 2   || x == 4 ||
( r8 x4 s/ L* ]$ ?( ^. O: Bx == 8   || x == 16 ||
# D  \$ M7 k  f: B& Bx == 32 || x == 64 ||3 @6 m$ h% H( o+ L) K1 m; n* t2 n
x == 128 || x == 256 ||
7 B; U0 f( [5 b0 l9 ]/ L' ?3 Fx == 512 )7 B% d+ j& H9 g7 z2 A- @# V# d
return true;  ?! C$ F2 l3 K2 d, z' X# i

# t) W% t) m# x! jreturn false;0 k- _9 h" W' J4 E' o1 j
}* C$ D3 I8 {" B( E, `. B
0 [, J$ w# x, d) B, g
int tgaImageFile::returnError( FILE *s, int error )2 `( \( F7 o: C: H5 o
{& R+ [3 B( O4 X
// Called when there is an error loading the .tga texture file.
+ f& c& s& P! F  ffclose( s );
+ D8 `4 y# w6 r; ?# j( {5 P* Z% nreturn error;
. f4 g5 `5 Y' b; `}1 m/ \( H1 d6 i

# f% b; r7 q3 [: Cunsigned char *tgaImageFile::getRGBA( FILE *s, int size )
1 N0 a- [0 G; S& g{! w7 a. \, C$ q0 x
// Read in RGBA data for a 32bit image. 7 z" |8 I1 W- _5 Y
unsigned char *rgba;3 _& M9 ^& O( X. {: a; x) }
unsigned char temp;' q0 ~# u! q1 f" ~
int bread;
% J1 N: u1 [4 }6 F, w; S  _9 t! ^int i;
5 g) g- |/ Y5 r2 D" W
" u9 c! M" n( G: a5 G7 ^' O; C* F0 U# _rgba = (unsigned char *)malloc( size * 4 );0 O- ?: r& S+ X

2 L+ L4 F9 {; I, l# Dif( rgba == NULL )8 Y9 V! j6 w0 y5 G- U
return 0;+ P4 t/ e' w5 D' D9 S+ k0 k
( J/ A9 @( H* R' T3 T
bread = fread( rgba, sizeof (unsigned char), size * 4, s ); % j. E- s7 |* U0 Q  A/ V

) E5 Y( J* I3 @* h// TGA is stored in BGRA, make it RGBA
: m& l) A8 B4 A* W. Uif( bread != size * 4 )) Y6 r/ x. h; y3 ?
{
7 ]0 ]) F% l% d3 l  _* @free( rgba );4 I# L) f0 f0 [# f9 t3 p; X
return 0;
# C" j  t0 w) d- M}
( ^9 c2 H  f. o$ N4 X) w6 ?, s
5 P! ]/ ]7 P. ]for( i = 0; i < size * 4; i += 4 )
& c3 z& H9 W. f8 ?{( }, a. ]. R8 X  p/ ]
temp = rgba[i];2 j6 |- X+ z5 y2 l  }; q. ?1 ^, T
rgba[i] = rgba[i + 2];
( t7 ]) M7 c+ R! Y% Brgba[i + 2] = temp;
; ~  }' _$ e- U& U}
" x% y9 _$ L' f5 l+ a+ J* _: ^) m' R2 \6 {; W' D, ~$ |. m% D" ?
m_texFormat = GL_RGBA;
6 ~3 G9 ]+ `2 o. ]. O# s7 areturn rgba;
" t% K% l) r: V}& c8 M* K- @: g7 q7 y
2 m6 l' \% R: M' N7 E, ?# e( u+ {
unsigned char *tgaImageFile::getRGB( FILE *s, int size )% y! ?, G  ^7 t. R+ K9 T6 Q; T9 {
{
2 d0 R. k  @' y6 s// Read in RGB data for a 24bit image.
2 t2 E( }3 ]! s5 z1 sunsigned char *rgb;
/ C- ~/ d1 p" E! v5 @% p2 Uunsigned char temp;
/ {% Y! M+ w) G0 `4 \3 N8 bint bread;5 X" O  {6 b# E0 S. _" y) j* W3 z2 f8 u
int i;
, ^( p  j1 @2 c3 A; F0 f
" X1 J9 b5 p0 Z4 lrgb = (unsigned char*)malloc( size * 3 );3 h- G9 {8 w6 Q% u; b8 |
* u+ t& S0 h% a( S: I" k& ~" H
if( rgb == NULL )9 M" y& U/ f4 ?/ z" D
return 0;& \7 a/ G$ m% J4 S9 m

6 [4 e4 I$ q$ ^6 B6 [! vbread = fread( rgb, sizeof (unsigned char), size * 3, s );/ t# q5 o' A) Z9 B' a6 Y) y0 C
) B/ u6 W) G/ [% I4 V
if(bread != size * 3)3 @6 g8 z) j: v( ]3 a! \' y
{
7 w" [+ ~2 z1 H8 {+ _free( rgb );9 B0 b* ~' F  _( v
return 0;( a. V) I) [, Q4 O8 }- D6 v- y
}  `" K% a. X5 T6 t: D* y# {

1 j: b2 I1 @& P) k// TGA is stored in BGR, make it RGB
8 t0 c# P8 y- K/ hfor( i = 0; i < size * 3; i += 3 )( _8 w& A7 x) Q" m
{
0 W: k7 Z7 a0 V! `  X! ]8 ^7 htemp = rgb[i];
, M. F5 S0 ^- S8 v( Zrgb[i] = rgb[i + 2];1 c/ u. w7 o2 o% _
rgb[i + 2] = temp;
% f8 k. D1 Y' t* r  w5 F' t3 S}* K3 W; l' t; b# y' d# j

# P% C7 r' y2 ?) a' ]m_texFormat = GL_RGB;: S+ d5 r1 O6 H% {' J  S1 r
! m/ ~5 {/ H" M
return rgb;
+ E# C9 @" }$ c- ?( z, l4 `! A}
; q0 w, b3 |+ v0 N$ y5 p
! k- L% C, ]/ I6 f  `# m) Eunsigned char *tgaImageFile::getGray( FILE *s, int size )0 a5 S1 `4 h1 B$ i* s
{
- e+ R% g% T/ ?+ h# p2 D// Gets the grayscale image data. Used as an alpha channel.
8 H! @5 i1 j6 R( |* C% V$ p& Cunsigned char *grayData;
/ c( |8 B# F% Z( i- m' V# s% [. s2 mint bread;/ U+ _6 g5 m" N) r4 H

4 v4 n2 N) u9 `2 H* O! {grayData = (unsigned char*)malloc( size );
- }8 W, d* }2 y
* I3 X6 A0 {; z% l& G3 p" nif( grayData == NULL )
- x7 N6 p/ n( w9 P- ]6 F% Dreturn 0;. ^* U6 S  `7 z1 {9 D- x  Q/ D

: k3 f/ y" ?* \" z6 C8 ubread = fread( grayData, sizeof (unsigned char), size, s );
; c: {" j; g/ |5 n% k0 ^' h. I; c- P8 {4 y, ~: M
if( bread != size )
% t$ }! E2 U+ i3 Z1 S{
7 U: s; F/ ^! |" M: L, J# sfree( grayData );% [: D. ?1 Q5 t; [' j
return 0;
5 E; B' M& l7 r}- l$ T  d9 @3 c! k( |; g0 H

6 r, V: S6 n, X, u4 i7 E$ \% am_texFormat = GL_ALPHA;3 f7 q7 ?/ T, V( I6 b

9 d; b6 Z- A! }9 I, `! lreturn grayData;# |; T2 h  o& ?: }2 S1 y( k# a" E
}
" Y5 @/ N4 ?9 F7 i8 [* V" [) w5 }3 u( C+ P9 F  `
tgaImageFile::TGALoadError tgaImageFile::load( char *name )! E; O7 N$ M: J4 E2 w! l
{
" q& v% O# Z0 P4 s// Loads up a targa file. Supported types are 8, 24 and 32 8 V* s) X+ g- u+ q7 d+ X3 Y7 W
// uncompressed images./ f& L+ I5 z4 k" y- G9 W
unsigned char type[4];$ A$ I, t9 Z7 P& X
unsigned char info[7];+ `4 s& g' f$ z0 j5 [
FILE *s = NULL;1 g0 j+ i% s8 I9 c" B8 K, g
int size = 0;
( B; T" _8 Y2 d
6 K6 _4 Y7 z5 C5 p9 Aif( !(s = fopen( name, "rb" )) )
% C- s* C0 W  M, }3 C; f/ Lreturn TGA_FILE_NOT_FOUND;% W/ o/ ?1 N, d7 H' X+ B! Y

+ ~% g+ J8 _! y: E7 ?fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
6 ?/ Z4 k3 ]% ]fseek( s, 12, SEEK_SET);       // Seek past the header and useless info
6 Z1 [. B- d+ y6 W) u" ]& pfread( &info, sizeof (char), 6, s );
- B; ~# ], v. b, e/ u1 C1 g/ e: ^1 |/ L3 e1 \6 R% `
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
7 a9 G% `1 H# ^returnError( s, TGA_BAD_IMAGE_TYPE );8 g0 i# I2 s) g9 L. Z. Z

7 {8 ^9 s8 i, Z2 [. @! V0 qm_nImageWidth = info[0] + info[1] * 256; 1 m$ j7 s3 l2 @) T
m_nImageHeight = info[2] + info[3] * 256;9 r6 u* T! Y) N
m_nImageBits = info[4];
. ~* I3 V) r2 |* S2 P1 @* U" K# G' s8 n6 ]  s( D% e7 }
size = m_nImageWidth * m_nImageHeight;# c% W8 K& g5 l0 g4 L0 W& f
$ m' [- C; K: Z- l0 o
// Make sure dimension is a power of 2 # d% u+ l! q- N
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))% s# m% Y7 _$ p& A$ N4 L* z7 [/ N
returnError( s, TGA_BAD_DIMENSION);
# D4 \& W, ~, [; T& F# b. `& a" Y, G
// Make sure we are loading a supported type ! _. b" H! |. k
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )$ |  y2 a( n0 E3 s. \( R5 o
returnError( s, TGA_BAD_BITS );
7 n4 D* i6 ?% W5 x0 f% a
& F4 o$ _2 }/ x0 g1 Wif( m_nImageBits == 32 )8 G" @2 S0 ], j6 T& }
m_nImageData = getRGBA( s, size );! G, K  r) t2 O' B. }' s
else if( m_nImageBits == 24 )4 O$ M* r# A; X5 D: l8 T
m_nImageData = getRGB( s, size );  
, }7 Q, w; V3 I5 m/ M( [  telse if( m_nImageBits == 8 )* s" p0 U$ c1 p: ~' D0 @% V
m_nImageData = getGray( s, size );
" R9 [, F- `) f
5 r1 j& x  t; j// No image data 0 E! C, I* b, Z
if( m_nImageData == NULL )8 X" I- V0 H0 g2 }& x! Q
returnError( s, TGA_BAD_DATA );. s) J3 R8 N+ m/ r" `4 T' m

" o6 h( d1 K) O- t& Cfclose( s );
: U! ~# Y0 }. t# c
0 J3 Z2 f, Y4 {  j7 g, I$ ureturn TGA_NO_ERROR;
+ \6 m( b3 v( l: V$ Y5 l: s& J}3 L* b0 j5 h+ l& I
) Q: p% C7 u& q) Q9 u( e$ j

4 c+ z& `4 H! [* X+ V- p0 \调用举例:$ d1 j3 w8 l7 w" d& }
//
# I4 a2 P) o1 A! s- }6 v" s// For the billboard poly, load a texture of a steel sphere. We'll use a , m# Q# W3 r  x, `
// .tga file for this image so we can use an alpha channel.
) X* }$ V9 g7 d4 A//8 P4 t: ~4 w. h- P7 F2 O% F1 y' y, E

  f" N9 J8 c9 T4 g/ VtgaImageFile tgaImage;
$ [' ^/ W- @6 O$ C2 ctgaImage.load( "steel_sphere.tga" );  k* ]4 t4 z# g2 W
: [9 T* `' G, _( a
glGenTextures( 1, &g_sphereTextureID );& v4 N/ W/ H+ Z8 I2 _) m
8 G9 n5 d9 C' l, h; I! [( j
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );5 m& y5 ^! d6 [9 b5 @! G& O

" g4 H: H6 [4 _) AglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );0 e- H* y( J* m5 j
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
1 c+ Y5 T, q  {( P' k/ D; \; W! Z7 z
  V$ k& Z6 L* @, oglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, & p0 p5 e9 h, S2 F  M, x! k
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight,
4 G' R# [" N0 g2 q0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
2 g0 N% s/ I# G+ B# _, Y9 ~tgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 11:51 , Processed in 0.020236 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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