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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>, d! m6 p4 W7 E: Z
#include <stdlib.h>$ m# |2 _' n' ~% z$ p, y
#include <string.h>
, k) j3 L. w5 X7 e# N" p#include <windows.h>
8 L# r' r4 `2 l8 `) c* C#include <GL/gl.h>
* p) r  f9 @; @! F( X4 M& `( F$ {0 |
class tgaImageFile; i, B# o* w: w: V; |9 c! N& T
{, E5 F1 J9 z% n3 n! i/ x
public:
" [& H+ h9 J) P( W3 [; p$ M8 {+ k1 t: j
tgaImageFile(void) :   V% D" ]5 ]$ ^* a% t
m_texFormat(-1),  g  A  Q7 A3 a9 y9 p
m_nImageWidth(0)," T( y- h: u7 W
m_nImageHeight(0),
+ M0 C5 ~2 n2 a: Em_nImageBits(0),4 o; ]5 e4 ^% r) l5 D( N4 Q
m_nImageData(NULL) {}( w2 N8 C9 i9 r: \+ E) I
! r. T5 L+ \& u7 m0 o: ]8 I
~tgaImageFile(void);
$ x. k! ~- H0 I2 e( l
/ i2 @) h$ Z3 u+ r& c: qenum TGALoadError' S& B( @7 p( `+ n0 G! n
{, N( Y! d* N( }0 |7 W
TGA_NO_ERROR = 1, // No error
! N! B2 Y7 j+ P1 [TGA_FILE_NOT_FOUND, // File was not found
$ l9 e3 m4 Q8 w% oTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
" q) |! X: u" U3 R! zTGA_BAD_DIMENSION, // Dimension is not a power of 2 * l/ F- n8 @+ s, w
TGA_BAD_BITS, // Image bits is not 8, 24 or 32 4 F6 L) Y; }( a4 h: d: _
TGA_BAD_DATA // Image data could not be loaded
/ c1 Y  [& P0 [  I  };4 Z4 J  r2 ^! [4 `+ p6 H9 |
( D) d7 s1 _# g8 K/ g7 m* K# X8 g
tgaImageFile::TGALoadError load( char *name );4 A/ \0 M: Z$ P2 |$ m7 L: c3 m
) S0 T9 ?8 o; l1 g
GLenum m_texFormat;
# M* M) c- s+ d0 `. Gint m_nImageWidth;
) P8 L/ g+ {  ~; zint m_nImageHeight;
0 Z; y& C$ Z6 J) L% ^% s7 Tint m_nImageBits;
: [, ^% C' e, b( d/ nunsigned char * m_nImageData;
2 y' K. c8 ~) [
' C# b# ?5 ?/ p1 B* d$ mprivate:1 y3 k& I6 G9 A- N5 Y* f7 _# y

" I8 U: L; _6 d. h' W" E% Fbool checkSize(int x);, G# v( o5 o0 z) G  s5 `! y
int returnError(FILE *s, int error);
4 O3 u" l( c( F7 Zunsigned char *getRGBA(FILE *s, int size);
( |* O- ^8 s) V7 ounsigned char *getRGB(FILE *s, int size);
7 _% C: q  b0 e) X+ aunsigned char *getGray(FILE *s, int size);& m+ S' E4 d+ a
};
' R. [0 ?) N- ?$ S9 O
8 a7 f7 g4 T4 k; o+ q/ H; M* r; C# etgaImageFile::~tgaImageFile( void )
; V' c& w9 g9 X0 L{
# a% p$ I4 b- O: ?$ tif( m_nImageData != NULL )
- g+ B: X% I5 Y6 }- g{
( r  {2 X; V" G. _8 _& a2 L+ gfree( m_nImageData );
/ h9 g& _& A7 R! L2 e% o8 I" o4 E# Em_nImageData = NULL;% G0 X4 v3 b6 g( M3 Q$ I
}
2 R! J' {) ~5 |4 z; Y# ~5 j9 j}& E: O5 V3 D  _8 [% q

! D$ X; h& w3 |* ~: n+ z# V9 ~bool tgaImageFile::checkSize( int x )
0 }! r! C0 ?" O/ ^$ P+ z{
5 m9 p9 `1 q# a! ~# w// Make sure its a power of 2.
; B3 p) M# r0 M- ^/ t! Zif( x == 2   || x == 4 || + S* C( U  d2 z$ v. J' @
x == 8   || x == 16 ||
$ j" a1 y5 J& s( U7 |7 x: dx == 32 || x == 64 ||
% j& \8 Z( l+ X$ W9 V! R9 Tx == 128 || x == 256 ||
. e9 F. j2 i8 ]; c* N1 Y: b- O* t: Cx == 512 )
5 \/ W3 Q) v1 `return true;! T5 i' Y2 U% Z& \% K7 P# p; [
. q3 M; C  }  R# N* A$ J% \$ P: I
return false;
! l& R7 l& u' _3 S( g- O}
; i7 E$ w) }: p$ P8 [' ]& Y5 s
int tgaImageFile::returnError( FILE *s, int error )
# \7 @+ V7 V; A# @{
1 d+ ?/ R3 @1 ^* L' j5 F1 Y' f7 f// Called when there is an error loading the .tga texture file.% A& j" g* F" `! [9 O5 i" h
fclose( s );6 I, Z) M8 e! P6 ~
return error;
5 m1 W# U1 f" o; O}
6 T$ \8 J0 |- P0 G) L# _7 F1 N& z1 t- [2 a3 N  ]  X/ n
unsigned char *tgaImageFile::getRGBA( FILE *s, int size )
. l; m2 Y5 q/ o7 I3 n* p2 `! T{
# l/ T2 S! y# N9 J( J$ n% }* v// Read in RGBA data for a 32bit image.
' G1 _+ g  l/ N4 v* Tunsigned char *rgba;
' G; m. x; p0 T: v; a; kunsigned char temp;. }! ]; g2 F- U! T7 m% S$ @
int bread;
$ A( ~) c( b7 o2 k+ m. W% x: n1 sint i;/ e1 A( O, B. g9 {
: J9 {; W- S% z( a  _, p
rgba = (unsigned char *)malloc( size * 4 );
4 N  D4 j5 T7 Y$ ^0 {- o
5 M: ]) [* G2 B9 a9 ^9 G$ r5 c$ Vif( rgba == NULL ); {# x3 v9 U+ d! K: s$ ?) J
return 0;, e& T9 C& I& t: l7 U

- N! H% Y! E4 r+ ?bread = fread( rgba, sizeof (unsigned char), size * 4, s ); 6 q1 [" M* W# L# i# I/ e. r' q! l
, w2 k! k0 U4 U1 P1 _, \
// TGA is stored in BGRA, make it RGBA
7 j! }4 \6 S5 `: K% Vif( bread != size * 4 )1 W% n, o+ A) p0 v# l3 i
{/ O8 I  |1 y  g! X# m% K3 ~! D
free( rgba );
* d5 Q& C: {2 p# n" |& F9 dreturn 0;+ j+ b3 \- D9 s# J0 e) U4 ]( G
}
* l5 A9 @/ }; }5 ?8 o$ v. S1 K/ c# M0 F4 |) F3 D5 @
for( i = 0; i < size * 4; i += 4 ); Z# W5 {0 r; `( e4 A7 ~3 D; B; u' ]
{( L: C6 I& Z' i: g
temp = rgba[i];
3 V$ ~  C' |: L" ?rgba[i] = rgba[i + 2];
) k  Z4 ]& H1 Ergba[i + 2] = temp;
, {- a7 w; O: }6 S, N) N4 g}
* R3 X; ^$ K0 r8 `2 |  e3 N
- C# T7 r8 M: Jm_texFormat = GL_RGBA;
" Y$ i, c1 r  r, Q1 lreturn rgba;
5 _, Z' b) z+ d& n}8 t0 x9 P) V3 ~$ \: O. x, {+ H" d

  D) h0 U+ z8 ?: s) W) v* nunsigned char *tgaImageFile::getRGB( FILE *s, int size )' O* w/ Q: |1 ^5 l
{% l" @, g3 f9 G) B, B# g
// Read in RGB data for a 24bit image. 9 C- R3 \. k1 `5 M5 Y# y4 Z
unsigned char *rgb;
6 \7 d  u2 `7 K: }3 ^& d" k) Uunsigned char temp;
2 ^  c' l& H9 \( D1 X1 z& \int bread;
, @; L  ^; z4 @9 d, Mint i;
9 A/ B* d7 R- S9 ?  S  d; X) z! }$ c/ C3 J
rgb = (unsigned char*)malloc( size * 3 );
4 u2 W, L1 H8 |7 z9 C$ |( K5 e! S7 }' D3 m0 h* r( P3 r* y- d0 X
if( rgb == NULL )3 c  r' E2 @0 I; Q! D5 ^
return 0;
9 @+ K( f% c3 _# z( H0 U5 U8 Z* [/ `1 @6 d( |: e
bread = fread( rgb, sizeof (unsigned char), size * 3, s );) [4 y' D+ R* u: |/ t3 t* n( ?

+ X6 U/ h0 e5 S  N* \6 D; l& t/ xif(bread != size * 3)
: H/ o' u  n* r5 `3 w{
; [$ l' q; v5 ]4 Z+ g4 ifree( rgb );
- Y6 h1 B. Z# j. A# `return 0;" V1 r* R0 ?* U7 {/ f4 ?5 H
}
- A; P2 `  R/ y# q% Y, w, ?3 o! q
: n  Y: U% Z7 ~! Z, v2 O// TGA is stored in BGR, make it RGB
6 I  l& t$ e4 Y+ K2 F, Ufor( i = 0; i < size * 3; i += 3 )5 O/ L+ U# d$ h& J" H* T2 c7 q
{
* @2 U$ n* @9 T! ^6 Ftemp = rgb[i];2 q! {' a, R" l2 R6 A5 Q, Y
rgb[i] = rgb[i + 2];! {& P+ Y  _5 J! w
rgb[i + 2] = temp;& p1 }- M/ [" [3 R0 t; R
}( _; \3 P' S+ l; Q8 i9 Z

6 H% _9 R5 y; X3 j$ l. sm_texFormat = GL_RGB;# L! ^1 |( {2 s/ O: Z6 `
1 z* L* x6 G4 \0 L0 A/ t
return rgb;
+ L( s" f5 O+ M}8 `2 v! c" O# k' y0 g

% o; f0 M! C1 q7 _& Y0 |unsigned char *tgaImageFile::getGray( FILE *s, int size )- q0 b" X* X0 l
{) x) a. S7 G0 t" D
// Gets the grayscale image data. Used as an alpha channel.
" J# T$ Y3 H% i; X+ e) ~6 hunsigned char *grayData;; j) s9 Z  D% y& }, s
int bread;
1 r1 K( N. R3 d' v  i
" C6 h5 u% @6 X" W' ~8 J; q: dgrayData = (unsigned char*)malloc( size );+ ]; N7 p5 @2 @, R$ D
3 }6 `2 H' E7 a+ e, J
if( grayData == NULL ); f* G( T- q, L4 X/ n4 f
return 0;
8 E, b1 p5 c  W7 h# h
0 P4 c2 t5 W3 W( X" Q  Xbread = fread( grayData, sizeof (unsigned char), size, s );, Z2 n( x, A0 z; Q& s7 C0 I/ a

/ P( @4 L. R* I" W3 }+ j! @. \if( bread != size )
  d6 V- [+ S  ]5 T! `{" m$ v" ^* `) ]
free( grayData );" l) D5 k/ L. ~
return 0;9 Q! d& l! x1 j1 ^2 V1 l: d
}" j; _  j' x: I% h, G% E" a

$ B5 A: g: F* k2 _. U& Z. M0 g% Km_texFormat = GL_ALPHA;
& G1 d6 a1 m" y' H0 g3 T' L  i8 L$ Q) X6 @2 w
return grayData;
+ |* ^# @8 n3 E, U1 `}6 b  J, N- s, ]

& V& c# Q& X$ _6 ktgaImageFile::TGALoadError tgaImageFile::load( char *name )
& W7 Z# F9 T) i0 n- y7 ~: r9 r{
* _* k2 r3 X# m, z$ O" O9 a// Loads up a targa file. Supported types are 8, 24 and 32
  C, r: u+ d' ]% B// uncompressed images.0 E3 G' Q2 q0 g- L8 s7 k5 e4 e
unsigned char type[4];
& L) ]4 }1 ?! S% E$ u, [# k! Eunsigned char info[7];/ M2 F1 G* S' M$ D
FILE *s = NULL;
: S- C) I& K4 H1 P8 i. uint size = 0;
- D$ M' i' R: p$ M- b+ {, e
1 k* h7 W  |0 aif( !(s = fopen( name, "rb" )) )
$ q$ r  Z) a  q/ h0 }return TGA_FILE_NOT_FOUND;
- I6 H( P$ E3 a! a( U5 N; \% Y
* U& q: T8 {3 M5 w) nfread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored0 m1 ?& S) F. Z# p& L$ n
fseek( s, 12, SEEK_SET);       // Seek past the header and useless info
6 M7 h+ }: Y$ k8 i7 _, w3 Hfread( &info, sizeof (char), 6, s );8 W9 g1 Y' y0 k  U8 ^9 l& ^7 o, T
5 `& S+ X' I" {
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )& ^% \' M# ]& Q9 _
returnError( s, TGA_BAD_IMAGE_TYPE );5 r( t( V- a; l) u4 M

# T9 P5 W+ x, |- Pm_nImageWidth = info[0] + info[1] * 256; ' e, y: e: J* y, J9 h2 Z) g
m_nImageHeight = info[2] + info[3] * 256;1 h) O  i: [# ~+ D/ P1 J8 X" F
m_nImageBits = info[4];
: @4 L  f2 w% r
4 c8 g5 L+ H! g. d8 ^6 r: C: @size = m_nImageWidth * m_nImageHeight;2 l# K! B  v& H# z8 ^& ^
9 T7 J9 p3 e2 q
// Make sure dimension is a power of 2 * y& E7 s+ V' s0 A* A; i
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))
" [; u# z- A! ^' b% f) EreturnError( s, TGA_BAD_DIMENSION);/ P9 I9 X$ b$ |% X* a( Y& {6 W! h3 m

+ W0 r2 D8 Q* C// Make sure we are loading a supported type ' H- I5 D) H1 F4 K  i. j+ g# {! Z
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
9 r0 N: x9 U1 s: l, t6 ZreturnError( s, TGA_BAD_BITS );
1 q6 y4 y0 y! n- V( B4 |# N
' [; @2 a! ~9 G- \  l7 a7 Pif( m_nImageBits == 32 )7 ^5 z/ o. k8 C+ y' H
m_nImageData = getRGBA( s, size );
( C3 Z$ C& D2 z7 zelse if( m_nImageBits == 24 )
6 f. J# e2 O' T! o9 z8 {! pm_nImageData = getRGB( s, size );  
3 R1 a3 u2 V- G: d2 f# t* |/ s+ qelse if( m_nImageBits == 8 )
2 z% V  x" D: K( J  Y% k- V' um_nImageData = getGray( s, size );0 C5 g5 N3 n: x4 s# }9 ~

; @4 I1 U, K5 t// No image data
. N7 P& b# ~/ \7 B4 nif( m_nImageData == NULL )
# X/ i; w  G6 Z) W3 |0 YreturnError( s, TGA_BAD_DATA );- [% d( G3 L0 @+ n' m; K1 q
5 @: z9 J/ _9 S* [; N8 v
fclose( s );1 m. L+ `5 ?9 q, ], f

+ v9 F( e# e! j  e- Breturn TGA_NO_ERROR;
" h: A% l- ?+ r}; n, D4 ^# ~+ B  K& \, D/ |: F

3 H6 ^5 L% w0 N2 s% B% g, h4 \; {( h4 n& ^
调用举例:4 e5 A" ~. b  x3 ?
//6 x$ L+ {2 r6 {/ Q) B
// For the billboard poly, load a texture of a steel sphere. We'll use a
% u/ t3 ?4 N" }/ L// .tga file for this image so we can use an alpha channel.
; g4 h# v$ B2 S& p8 u//* r0 U% E* Y) ?8 ^& q
5 v: }0 `6 f2 `! W/ D9 |- ?2 ^( `
tgaImageFile tgaImage;
* t  i9 c) l6 \: C* ~tgaImage.load( "steel_sphere.tga" );
& P1 A% l- c# `% U! ?0 p2 M; y  S" ?
' N/ F2 Y3 K/ Z  D! m2 sglGenTextures( 1, &g_sphereTextureID );
  y9 R* g. f1 C" K% ^$ _- P6 y* j& D9 E( `! |1 N
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
& ~9 k' x3 c% S, ?9 G( i; ~8 A+ n9 n* j  t2 N9 }
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );0 f  f, M; l' w) ~1 x
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
* F2 x8 s" p8 @$ n9 }# {3 Z$ t) b3 V7 X+ j% w% s8 B
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, , q% ^9 A  _2 x- y" @
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, $ k* g0 y1 Z5 f" a1 ?
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
+ e- L' h9 r4 w/ o9 ptgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 09:31 , Processed in 0.035075 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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