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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>
) E  W+ t, C* ~  D* d6 b& ~) x#include <stdlib.h>% f% |4 z& d7 n. R: y2 o; ~
#include <string.h>! V; l, K$ G9 `. s2 T
#include <windows.h>
0 o" t  X. ~9 X9 ?4 T- N#include <GL/gl.h>* Q3 s9 g, ~: s! l5 V# H
; `( b, a6 c; X! z5 u. Z
class tgaImageFile
6 K+ d4 ^0 n# H& D: Q{9 W' l- G- P( t) s9 f# I
public:
% ~; o2 e  ^2 {, i. h  q  Z) p+ P4 f
7 f1 R& A" O0 G/ Q% FtgaImageFile(void) : 9 a6 G' q, i' \% ~; A  L6 L1 g1 n- n
m_texFormat(-1)," m5 y& |- j; B8 {: j
m_nImageWidth(0),: D. \3 F+ i" y* D  x
m_nImageHeight(0),! H5 ~) i, {3 k* V7 T8 i
m_nImageBits(0),* L1 L8 A- G1 s( T
m_nImageData(NULL) {}
% w. j! `% X# V  N. r$ [; d& }$ f* a/ D3 |, n  W: S
~tgaImageFile(void);* }% x% q, C, d- U/ q9 W0 k6 _: ^+ c
; a1 G# W: j4 H4 K
enum TGALoadError
: a  h: ^3 C( O8 k{5 @( _3 o5 o) y( k1 m" q, r
TGA_NO_ERROR = 1, // No error  S4 @8 w7 z6 ^2 O% o5 f8 T
TGA_FILE_NOT_FOUND, // File was not found & f2 G2 H: h* z& H( i# H
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
! K; \% b3 b+ E; q; ~) oTGA_BAD_DIMENSION, // Dimension is not a power of 2 - x& D$ y1 o6 H9 r. ^! U* B
TGA_BAD_BITS, // Image bits is not 8, 24 or 32
$ [* x# d+ q! }9 D# l( I2 Y' t1 ATGA_BAD_DATA // Image data could not be loaded
1 e; c/ a7 I- ~  };& }# R" u6 b0 @9 L2 f( ~$ i
/ _$ N& \. P. ?. v2 K3 S
tgaImageFile::TGALoadError load( char *name );! i  @, l% {( H# T4 y; ]
: F  w7 p" I% i0 B5 H3 b7 f
GLenum m_texFormat;
! a0 e/ I! F) I+ v% Zint m_nImageWidth;
$ a7 K& P! N, L9 x: u# |  E- mint m_nImageHeight;
" R  l3 P' n2 {5 @$ Q* N8 Rint m_nImageBits;
. ^* V  G3 F, x1 j* l% s- S1 d+ W  lunsigned char * m_nImageData;  v9 Q2 ?- h; B' L' ]
) o$ n8 A4 l" ]& k/ b
private:* ~" ^$ M/ N/ x3 e4 F6 d

" }; t9 \, F" tbool checkSize(int x);8 `0 z7 ^! Z; j$ v
int returnError(FILE *s, int error);$ g& i! g/ H: c6 t5 ^# |
unsigned char *getRGBA(FILE *s, int size);, m5 s& k( v+ V" F
unsigned char *getRGB(FILE *s, int size);. _( u( A: M& a9 q* ]' L
unsigned char *getGray(FILE *s, int size);8 Y& ^& M3 {, {# R
};4 Z$ {; O: x6 J9 ^3 s  P
7 S( c% H6 J" m+ l' b$ B
tgaImageFile::~tgaImageFile( void )2 ?( R9 x" d0 L# y* ]/ V
{
' D! N! }/ n2 t6 V0 X  u( k' N# aif( m_nImageData != NULL )
0 u  i6 r2 m( d: C{
( `- H. g4 @! N& _2 O: Gfree( m_nImageData );
# [$ o% `6 t4 L8 Rm_nImageData = NULL;3 f4 n" f$ L: n& z! X5 Q/ z1 V* {
}6 Q# w3 I- |7 f+ Y
}
& R4 H, Y: d5 m6 r; C$ H7 x9 W
- S% r9 ^( s" C" x5 g% Bbool tgaImageFile::checkSize( int x )/ j- z) _( H5 Y: d) \- o9 e
{
; r3 p: g1 D# c// Make sure its a power of 2.) a' q2 A2 L4 P7 O1 N
if( x == 2   || x == 4 ||
2 k3 G: n9 m: L& t( Sx == 8   || x == 16 || / C* p; o* T$ ~) c5 S; o
x == 32 || x == 64 ||
  _1 a+ q5 D, kx == 128 || x == 256 || 3 I  o' Y) {( r7 q
x == 512 )9 j, O6 I5 u' n1 |9 Q% Y4 W
return true;. l8 c+ f. M0 Z8 T: ]( H

* ?+ b+ S- i8 P9 j% q' oreturn false;
  D: c% N3 A# p1 O4 P/ X* u+ g}
1 x0 r$ Z8 d$ e' F' }* I. C# Z) Z" x; [6 p5 f6 t
int tgaImageFile::returnError( FILE *s, int error )
; U5 a' n5 A, y! D: [$ W9 F7 f5 _{5 p0 K0 }/ r5 F  \: `4 H
// Called when there is an error loading the .tga texture file.
+ _! m5 Q3 y8 |2 Gfclose( s );
) M! n4 {& {0 R* breturn error;
# J" p+ k* X* m. }9 ?' ]/ z% b* g}6 S5 z) d+ O; a, b7 O( y
  p$ N; K2 U+ _8 [5 v
unsigned char *tgaImageFile::getRGBA( FILE *s, int size )0 G. \7 w3 l4 u  G- Z
{/ g3 G1 \2 f! s3 [# k. Q
// Read in RGBA data for a 32bit image.
# q' i$ q; s5 b3 Q, ]1 Funsigned char *rgba;
2 s  |/ v5 X9 w( y* q5 Kunsigned char temp;
1 \: m) s7 ]8 {7 b5 ^- v' gint bread;
8 o$ Z7 D: n! K# \( vint i;
2 }5 R( ~/ \; g  W3 [
0 y% g' `) A+ S4 t' U  ]rgba = (unsigned char *)malloc( size * 4 );
3 |; X4 {0 k. f4 }' i6 J' M( A! S0 j" h5 e
if( rgba == NULL ); k6 P  Z2 D' p# h# p. @5 Z
return 0;
$ h7 B" s) F0 y$ \2 V6 x5 V! B* c/ l1 X/ Y4 w+ O+ n8 k4 T
bread = fread( rgba, sizeof (unsigned char), size * 4, s );
# J/ r0 C$ \7 n4 G* _3 E
) d4 l3 O- o- u2 m/ f// TGA is stored in BGRA, make it RGBA ( {1 \$ A3 u- i$ w
if( bread != size * 4 )
! w( t- }# [# W4 ^0 a# W{# p! T4 [# m7 \! E, G
free( rgba );
7 `2 V4 a+ m+ ^/ B: K$ Wreturn 0;6 J( O- d2 Z$ i6 \3 y) L" ~
}
) U7 m+ A7 ]" q* }4 I( H4 f
% K! u  I! Q% t* J2 J5 D& t! q. ~, hfor( i = 0; i < size * 4; i += 4 ): X7 N# Z9 f  }4 O
{8 }8 p# [# P5 E; p; {
temp = rgba[i];
! U% [  {+ {' [2 Y  l- crgba[i] = rgba[i + 2];
6 q9 T: {- q5 {) }, f6 brgba[i + 2] = temp;
+ b' k/ q. G/ b3 J& P( W}
; l4 G* B1 o; ^, N6 X: P8 K$ k5 z
  L8 g* q. Y) d' t+ Rm_texFormat = GL_RGBA;) J6 U1 c8 D) ~5 F  d4 ?
return rgba;
/ ~  y" f3 k* {5 L}
' l) B# W1 I) [5 H% j* z3 _6 \; {3 `* S
unsigned char *tgaImageFile::getRGB( FILE *s, int size )* _3 s2 o1 R* m4 ~
{
) j: ?* y5 |% @$ k// Read in RGB data for a 24bit image. 0 Y8 ^1 T: ^6 M
unsigned char *rgb;& k, \9 b2 d+ f" `* @" F8 Y6 V
unsigned char temp;
! Z" \' N. M$ T1 m* rint bread;! V6 D  `; I3 O. i* t
int i;6 U" P. [5 T8 i* s& Y0 F- q3 Y
" v$ t) S. y: l/ Z0 X
rgb = (unsigned char*)malloc( size * 3 );
  r$ {9 P, h+ S* w) Q2 m9 j6 W1 V* _
if( rgb == NULL )+ C/ f/ s' s1 m* V' n& s
return 0;
" E* e1 e9 D( Z
5 X; W' y8 d  Q* Q1 D/ O4 }% qbread = fread( rgb, sizeof (unsigned char), size * 3, s );
5 T4 u% G, ~7 p0 q" M
9 O7 }( v- o% R4 W, N+ h+ rif(bread != size * 3)  \9 e$ t+ B8 j
{7 n. H# [6 j1 b' f. j* `
free( rgb );! y1 r* j+ q4 }/ P3 m
return 0;
2 l/ L; H8 ^* a2 k& t; q}
; ]! g8 @& G, q* E' D" Y  E7 f7 ^( f3 K1 [" F
// TGA is stored in BGR, make it RGB / s  e+ T2 K9 n  ?: F- ?4 h( o
for( i = 0; i < size * 3; i += 3 )
. {* ~: R2 h! D3 S5 Q{
& U; ?0 m$ m: r7 t% N9 J' ^) [" }: ?temp = rgb[i];
4 V9 p9 M& k3 K+ G0 \! k6 frgb[i] = rgb[i + 2];5 J1 t$ Z, U0 T/ q
rgb[i + 2] = temp;
0 f! J5 B( k9 @4 j}
3 O, @/ N$ c; R( Y: }& [, j  }" Y1 u$ R. J0 ~# W
m_texFormat = GL_RGB;
7 }) Q/ l- U. E: C  G" j* l, U9 V. G0 g$ Y& S0 V* `
return rgb;# `7 a% I+ t* p' A+ }' R
}
3 N1 O9 i# @$ N, `% n* Y( \, u" ?  g6 C; M' e
unsigned char *tgaImageFile::getGray( FILE *s, int size )% ]% {) g% H( e
{; U/ Z! _( K) Y6 g2 h- R* _( f, |
// Gets the grayscale image data. Used as an alpha channel.$ I/ [' R' L" Y7 }/ }5 G- r% e$ V
unsigned char *grayData;/ T: l+ W* {4 M- ?% K* s, G
int bread;& ]) U; w; a; e! L) g
9 P, ?# I1 ?% O* q8 K$ C5 R
grayData = (unsigned char*)malloc( size );0 U) d0 E' Q! E  W9 j: k6 g
4 g. X2 N! K0 ?
if( grayData == NULL )" y+ e6 D. R) z' O
return 0;
3 l2 x9 S) B% d3 W2 R+ N5 {8 e6 j+ `0 \" @( Q1 t9 R
bread = fread( grayData, sizeof (unsigned char), size, s );9 w7 u0 b* {& z
+ O( W' a$ G: @5 ^, h# [" \- B
if( bread != size )& E; |  {. H/ s* C5 l0 V
{' f9 I+ W9 j( u
free( grayData );) c' A+ _: H8 m) x% a
return 0;. C6 T9 N) i" O& i1 z# N* n( M9 |
}+ X( C* M0 Y6 v2 U" ^. @2 ]
" W& g. x; P' `7 X; o
m_texFormat = GL_ALPHA;9 }( B8 s% A5 _1 w. q: W; \4 ^( p

/ E/ G2 H0 E+ t1 \# h: S8 ?return grayData;
9 Q8 m, |2 o3 @& Z) d}4 s6 v) l" X9 ^* m' P* G0 ?" p6 L( W
- n( v, M0 H" U: \: `" w1 n( R7 C. `% U
tgaImageFile::TGALoadError tgaImageFile::load( char *name )  W+ r; J7 C' u! y
{
$ `& L3 }$ i7 P+ h- x7 j// Loads up a targa file. Supported types are 8, 24 and 32 * S1 j1 w; Q1 ]$ {$ Q* \# j6 t' c8 v
// uncompressed images.) m% y' h0 f" I8 L
unsigned char type[4];5 m7 I) |' ?3 u  @# z) ?
unsigned char info[7];
+ s  z- w% G: t. `FILE *s = NULL;0 B; u. I$ n5 F6 s2 T
int size = 0;
1 F4 }( Z9 x$ j) I! P$ Q
) @: S9 q6 X7 k+ N/ xif( !(s = fopen( name, "rb" )) )
. `) L9 q* r! u* N( preturn TGA_FILE_NOT_FOUND;. {4 y, T5 F  _5 r  `9 @
3 t; D3 ~. ]8 h3 @$ M
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
5 e' J, H; Z& T0 h% m' x5 yfseek( s, 12, SEEK_SET);       // Seek past the header and useless info9 _- a' K4 g% j2 P
fread( &info, sizeof (char), 6, s );
2 R9 @0 R# Z& H  J  L8 F' j2 i# j% M' n1 R" n" s, ^: F
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )+ s' s  }' _" J3 K! K) o9 {* Y9 P! D
returnError( s, TGA_BAD_IMAGE_TYPE );3 b. @" T4 R7 t6 J

: X; g$ k4 o/ em_nImageWidth = info[0] + info[1] * 256;
6 w4 U5 ?" J( w% ]m_nImageHeight = info[2] + info[3] * 256;& E% M; Y; R' F  L
m_nImageBits = info[4];
# H7 Y: H3 E: V. ]$ E; d9 L3 t) B$ h: C0 ^
size = m_nImageWidth * m_nImageHeight;* V& c* K! }- l9 _9 V
8 U8 n+ o7 f- z9 ^1 h& a
// Make sure dimension is a power of 2 4 X% ^: ~: W# y( h$ j) y! T
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))2 n7 ?/ a# ]& X* C: S+ l0 R
returnError( s, TGA_BAD_DIMENSION);7 d' L( d* e! i, G. M
$ E5 S' K; ]) Y! e& L* G! T* D/ \
// Make sure we are loading a supported type
/ i& z2 I/ |0 r) Y! N( y4 ~if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
7 j9 t9 c; j4 g1 freturnError( s, TGA_BAD_BITS );
$ A" P1 X/ L9 X6 e5 T, z
5 U% m  p0 x* ]5 y+ R) ?if( m_nImageBits == 32 ). z2 l4 m/ d! I! e0 j
m_nImageData = getRGBA( s, size );
0 _! w  _6 Z( A. r- I5 h; B/ f9 o' Kelse if( m_nImageBits == 24 )# I3 F+ d: ^* v& [3 h* ~
m_nImageData = getRGB( s, size );  + H4 A5 b$ n/ x5 g
else if( m_nImageBits == 8 )0 K! X( p4 W) `" k) D+ N& y- m; Z
m_nImageData = getGray( s, size );* j+ C, m1 F' {

# o5 u5 \' j4 m" ?// No image data 0 b* `! ?" R1 M% }1 p: \! k
if( m_nImageData == NULL ); l$ C4 X) v$ a+ I+ J: B2 b( z( a
returnError( s, TGA_BAD_DATA );1 l- ]! E# r& w- o' D
: q; N/ K8 J. v' s# a
fclose( s );
/ r$ S7 Y1 c( r5 e; Q
" ]8 f. A7 e  q+ e' W; G; i) Dreturn TGA_NO_ERROR;  c$ `9 L$ s$ i' B" J
}4 ?. a; m9 U8 X' g
1 m6 W7 Z1 [; V/ a) ]
" U6 F8 c0 Z- }' r2 L
调用举例:# U. l# N, j2 k, c* b
//
' {- _, T; i; k+ R5 C// For the billboard poly, load a texture of a steel sphere. We'll use a ; a: [1 A! v, t& q% M. R
// .tga file for this image so we can use an alpha channel.) L0 m2 T$ J2 o6 [2 T& N
//0 Y% k0 j3 E9 ~' ~  S, m3 C
) n/ N! h* k" u, y, p
tgaImageFile tgaImage;
) Y( D% R/ m. y# V- DtgaImage.load( "steel_sphere.tga" );, Y- E) w  _/ ^" a
2 p9 N- k7 u, l4 a0 @2 Z. x
glGenTextures( 1, &g_sphereTextureID );
( [7 d# C/ c4 l# T# R& w5 d- M! z. N0 C
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
6 i) J: u- ~+ V" b# R, `1 U& G% U, s5 B  |$ t
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );  ~, R; B- d. b
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
# ?  f) k! |, u- H& ?+ G3 L9 G& K. V
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, ( J# t6 B4 @' ?! x
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, ; ]3 c/ p+ k6 c( Z! G* J
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
: z7 ]7 m# p2 I' etgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-13 22:46 , Processed in 0.018627 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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