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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>
/ V6 x4 M) [1 |- g4 g0 }#include <stdlib.h>1 P- S, U' W. Z9 v- E
#include <string.h>
0 m0 b- O' n1 l6 N5 a#include <windows.h>/ f  Q" d" G* q: J( l5 l
#include <GL/gl.h>: [/ r5 d- C' L: j" i
3 }4 E, @- S6 j
class tgaImageFile
% Z, G9 E- {: n' n2 C{
& @6 w( b: h0 L- tpublic:
* p* P% k* v0 ^0 Y9 f( v2 e0 r3 L+ }5 N* y
tgaImageFile(void) : ' X( |9 A$ u' c. r8 l
m_texFormat(-1),) w) z# x; r" ]1 l7 `: r
m_nImageWidth(0),
3 }0 B9 _3 R$ |4 G1 e# Zm_nImageHeight(0),
0 M- D$ G3 g; e1 l0 e2 f0 {8 {* rm_nImageBits(0),
- h* T4 N; o5 @! d3 e2 F+ Y; mm_nImageData(NULL) {}
) t4 L* z# d, \+ \, Z3 z
$ ~+ ^9 S9 e% t. \; G. h. [4 W5 o~tgaImageFile(void);
6 r& k1 h; U: I1 u. w
+ O, b) G, v; g2 O; n, o% H# jenum TGALoadError" g6 F; k" J" z. \6 V
{
. i6 T" C" Y" cTGA_NO_ERROR = 1, // No error4 b8 o+ w4 z0 W, E% t, e4 U
TGA_FILE_NOT_FOUND, // File was not found - f  s9 E1 n7 B
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed3 {( A, W+ ~" [- S8 r
TGA_BAD_DIMENSION, // Dimension is not a power of 2
, D  G. e: d2 h/ N" A; p% DTGA_BAD_BITS, // Image bits is not 8, 24 or 32
& e( h3 i8 }6 I$ uTGA_BAD_DATA // Image data could not be loaded : L5 p3 h# L6 @% Q2 B) H
  };
5 M' X5 l; ^$ ~6 \  G& y
5 R4 ]7 b, k+ X. @' @  TtgaImageFile::TGALoadError load( char *name );
% }$ i9 E6 k1 I. g% ^
$ V. B3 N& S. q, A/ b. TGLenum m_texFormat;
' y; D( F; {0 g$ f8 `int m_nImageWidth;7 d/ ^! S! F( ]1 p9 B' `1 C
int m_nImageHeight;
2 T$ ]9 O9 ?( fint m_nImageBits;8 v" D& a, |( q; i
unsigned char * m_nImageData;' }. j3 |$ R' D4 W/ W# P' e
2 ^' ^6 z. `7 z+ y! u& ?9 u# T
private:2 m0 U+ V( L* _  J3 t. e* R' g  N2 U' j
0 U" N4 v/ ]; U/ @  P: r
bool checkSize(int x);/ `- J8 C+ R! o
int returnError(FILE *s, int error);+ ~- h9 i+ v9 J& z
unsigned char *getRGBA(FILE *s, int size);
% U* j5 E- [5 A& `unsigned char *getRGB(FILE *s, int size);
' j3 v& n* T& T; D+ Sunsigned char *getGray(FILE *s, int size);" f7 ?# t. j. P; f/ ?, e$ H, @. f
};
9 Y2 x' J. |. E3 M+ x+ q; d; [; Q9 e( p# \" O
tgaImageFile::~tgaImageFile( void )& Y! U7 h% ]: V) v$ Q
{% C( `8 P5 F9 @: f$ K* ~
if( m_nImageData != NULL )0 z! f" Z& s2 f
{
# c( a3 g, o  w( D8 g0 v* cfree( m_nImageData );
* m' ~% @) d1 ]: }m_nImageData = NULL;
& [# Z( l/ x! C, Y}; _0 f" g. p2 ]  T  r  U
}
  u. y$ B& x4 c& I7 z
5 S: c7 d0 E& D) z) V) hbool tgaImageFile::checkSize( int x )- _7 G! O' x$ L) {6 v; `( E& |
{+ o, U' f+ o5 Q: B
// Make sure its a power of 2.
6 I' D- m! G% Z6 S* `& h8 I8 ?5 zif( x == 2   || x == 4 || 9 @; a  Q: c" u) P- s# B
x == 8   || x == 16 || % l& d+ M' U' ~  @  w! q9 W
x == 32 || x == 64 ||
0 B) M, {% U0 t( S- Gx == 128 || x == 256 || , s, g! X9 j. U6 N. I4 |- T  f
x == 512 )) m" i, q% ]& t0 I; I) A! X9 E
return true;
" G2 x* J6 L1 J" m6 j  m5 }: F+ P' N2 Z+ s" D
return false;. }: h9 O5 g' N7 I
}# h( l7 P; }1 V* p: I0 k- b. o" w

# Q0 \7 k& b8 [$ A. Zint tgaImageFile::returnError( FILE *s, int error )
& E3 L. ]# A9 a{1 B" \- j. [9 l* {' k
// Called when there is an error loading the .tga texture file.. J/ @. r& l0 X' {
fclose( s );
+ A) E0 M: D- N  zreturn error;8 G* X% Y9 b* \0 C
}' B" _; L4 y* ^, @" R* o$ F9 ^* U

1 x9 M/ @% X# J$ O- Junsigned char *tgaImageFile::getRGBA( FILE *s, int size )0 y. n  G! m) G( h- P
{
4 q, I. @: z" z( T" j// Read in RGBA data for a 32bit image. " I- \; {3 N' J. F$ j! V
unsigned char *rgba;
" [+ r' o5 x: Q& k+ Qunsigned char temp;
" q; m, W$ o  L1 B& `- Xint bread;
6 M2 s3 H( E" T( _" `4 Aint i;( `) S$ `) S# d
( I5 d" R" T! S
rgba = (unsigned char *)malloc( size * 4 );
: h7 _- V* J0 R# ^9 q2 X1 I
* b7 d, o& o' l" Aif( rgba == NULL )
7 P3 S. ^- b* N( Creturn 0;+ Y, K9 p2 [& e

& x$ G- M; O. D' @8 P3 qbread = fread( rgba, sizeof (unsigned char), size * 4, s ); 3 t% F9 g: J$ ^1 w/ y/ U  E8 r

) q( R! A+ M( @' p1 \' B4 u// TGA is stored in BGRA, make it RGBA
6 Z; b6 k# \7 n0 O2 _0 Hif( bread != size * 4 )
5 z' i2 f4 S& N  B& v- O{
2 b( V; q' P. p# e8 K6 A$ J& qfree( rgba );# }/ g! o/ J) v* q) v, Q9 {" B
return 0;
% K1 q) S6 V) Z$ X& @}
$ n* \+ V+ E: z- V
1 r5 s) X* z" r% y9 }for( i = 0; i < size * 4; i += 4 )
- T  T' k5 G4 ^' L* [0 R{
; o" g9 W7 P! J4 i% _3 y2 }  k4 E7 S5 s. Atemp = rgba[i];
4 k! s, i- A5 ?" Y- Y. rrgba[i] = rgba[i + 2];( I1 V: L9 B# l9 m- ^
rgba[i + 2] = temp;# J! b! s$ Y4 M4 F7 e8 F/ h
}& U' V/ G8 C' e4 m
% Y0 w3 e& o8 F( j- i' Y1 n9 m  }
m_texFormat = GL_RGBA;2 @/ p' m$ F/ m1 j7 d- w% d
return rgba;
& q4 {. O" ~) d3 d7 _$ I}$ v& v' F6 k1 U4 K0 F
6 {! H' m+ I( W. T
unsigned char *tgaImageFile::getRGB( FILE *s, int size )
# y' c/ z! P' U5 W* y. |{( \/ B& h! w  n4 \
// Read in RGB data for a 24bit image.
) u/ c! R" [8 junsigned char *rgb;
1 W8 k5 U2 t, s5 [" x3 Ounsigned char temp;
/ z4 s0 R! C: F7 u% O% o& pint bread;7 K3 f1 y* H/ D
int i;; l, s3 m( u" D: R- Y/ p5 F
$ Z' H$ L: ~, X0 `7 f$ Q
rgb = (unsigned char*)malloc( size * 3 );' K+ V7 G  s% ]9 X4 H, i
& N4 y* ^& U" v. g+ {1 Z2 j" l
if( rgb == NULL )
3 o  @5 g2 |; [) C2 f/ E& {% Yreturn 0;! r+ p  t1 P7 ~& J9 ?
, p) ^" e4 X- `9 j9 o% ]  f7 l, V0 b
bread = fread( rgb, sizeof (unsigned char), size * 3, s );
* M7 ]; _6 F2 V9 i+ S- M9 T! L8 M/ p( I
if(bread != size * 3)
; m3 T  S) u1 B+ T{/ @5 R( X" {. E+ L
free( rgb );
  d. X/ X5 n( [4 X- \9 |return 0;4 Y1 S3 i0 U) X( B' x
}2 d0 u  u6 I: w- j

8 O% u+ B9 F- ]! {// TGA is stored in BGR, make it RGB 5 A( Y0 W+ _/ x2 u+ x9 {
for( i = 0; i < size * 3; i += 3 )! E+ H8 x2 `2 `1 B( ]6 i% U' O2 {' s) B
{
" N) j6 U5 l8 [; v5 [8 ?: Ktemp = rgb[i];
: q8 |- S. R+ K0 x. j3 L  Brgb[i] = rgb[i + 2];2 W# s9 C( m" D5 l# b8 N3 K
rgb[i + 2] = temp;
' ^* L4 G3 f5 Z3 i/ W}8 y) Y2 V( _: e
# _$ B5 ?  G$ F$ m9 r. m! G: \
m_texFormat = GL_RGB;
3 j3 x0 t: `7 Q) B- g; X0 R
' t, o. M1 m* e7 ~" g# \# Rreturn rgb;; R3 c3 ~9 d* T5 C' N9 T
}3 z2 Y  n/ `9 u% b+ v8 ^; i

% ]0 a$ b6 h2 q9 D+ lunsigned char *tgaImageFile::getGray( FILE *s, int size )4 V% u* u% k4 s
{7 d( S! y' Q% m
// Gets the grayscale image data. Used as an alpha channel.
4 i6 ]+ m& `* W  [, r4 h. yunsigned char *grayData;
! {8 Y% k1 \7 M6 r0 ^int bread;. @! w( y9 P, n+ i& x. K

+ e5 m6 g- H7 o* j- F% I, S4 PgrayData = (unsigned char*)malloc( size );8 W( @0 T" f0 a; J2 Z2 a( [0 r. J( S

' a+ r% m3 w- Sif( grayData == NULL )
" \5 v* @# `; ?9 z# s+ S7 Dreturn 0;
: a  w$ O3 r0 ^+ r
( g8 p$ j$ X& e" mbread = fread( grayData, sizeof (unsigned char), size, s );
3 W( {/ s+ X5 {+ u  [! V: z% v, l, ~; }- v
if( bread != size )5 R0 v& G3 U# H, u1 L
{
' G# H) P6 Z. ~, g0 C& ~. Ffree( grayData );
- S0 Q. K5 C& c8 e8 Z; E( w* _9 |return 0;
+ h: s" I2 c* G! Y}
3 p; W+ r1 ?; ~2 @7 ^3 I9 w% G
: Z5 x9 ?) Y) Q, Z! L5 Z3 S+ `' c; Um_texFormat = GL_ALPHA;0 Y6 P# W8 r) I) `+ e% e

& J& O& a3 w; L) f! E% p7 Kreturn grayData;
+ {1 ]% C5 j- M}
- a2 T: o: R6 A  S; B2 l0 O
6 x+ ]6 ]( V" u$ \3 [. L$ rtgaImageFile::TGALoadError tgaImageFile::load( char *name )( S  m$ o' m5 a! ~3 ~1 d" t& \
{" ~- j' S: i- Y6 l% L. D
// Loads up a targa file. Supported types are 8, 24 and 32 % ?, j" W5 V/ U( l! K
// uncompressed images.& i& h0 U: V7 x! r6 O3 J6 L
unsigned char type[4];/ M7 s( m; U1 T6 w& q$ g
unsigned char info[7];
+ e+ _, d+ U% T- M+ J" }FILE *s = NULL;
" {* t2 y4 h1 @, y$ F4 Z% [. Wint size = 0;. }$ Y8 k( K+ |( t) a
1 l/ T( ?, u5 f
if( !(s = fopen( name, "rb" )) )
+ }) a& }3 y5 u9 m1 oreturn TGA_FILE_NOT_FOUND;% i, i# I9 F8 [  I6 L: O0 Y/ X0 z

& _; j9 Q( r' |$ W( Z+ |# efread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
2 |' _7 q+ x1 V  O1 e  p# w, W4 ]' yfseek( s, 12, SEEK_SET);       // Seek past the header and useless info7 s* u# ]" a; A2 S4 d
fread( &info, sizeof (char), 6, s );& A2 p3 p/ M9 v* B9 [' s  y
* `6 I: O$ i# Y  n- {' l2 E* b
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )! U% p) Y# A5 w. R8 }# s; f
returnError( s, TGA_BAD_IMAGE_TYPE );
8 I" X4 Y/ T' t, ~2 e. X6 z7 Z+ B6 f& I  Q" i& G5 Y) ~3 Y
m_nImageWidth = info[0] + info[1] * 256; 6 W5 F8 w! p0 a, e' _4 h. \  ^2 `% l
m_nImageHeight = info[2] + info[3] * 256;6 D' I+ t' Z3 R9 t- e% E0 y
m_nImageBits = info[4];
# v5 ^+ K/ G) Y5 h  b& X. m' p( Z$ C( h/ ]& W8 C
size = m_nImageWidth * m_nImageHeight;* n; n0 ]$ L) Z, O0 C+ x, L

: g( J* L' P5 R+ w! p// Make sure dimension is a power of 2
9 X+ j  r' F* H- rif( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))( R/ f& d) a" N3 _1 v
returnError( s, TGA_BAD_DIMENSION);
5 ]9 R$ O7 |4 W  G7 n8 z8 Z  [
2 g) G" n( \* {4 A2 k// Make sure we are loading a supported type
, v. Q4 E: a: X/ P0 k2 l0 Dif( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )9 G' `, F: V6 V6 ?. W
returnError( s, TGA_BAD_BITS );
: _: p! f( z  q
$ q8 l2 B( r; h5 _3 |8 Cif( m_nImageBits == 32 )* i7 V# N7 v, e2 A  s
m_nImageData = getRGBA( s, size );0 p% n9 N9 P* \- h. ~" }
else if( m_nImageBits == 24 )
% A* }/ U, z1 j& o7 D1 ?4 \; [m_nImageData = getRGB( s, size );  8 H1 H$ W$ }* S$ G
else if( m_nImageBits == 8 )
; |2 E; r/ f4 q" S+ zm_nImageData = getGray( s, size );& V9 `  W& z' o1 {8 A- A# y- s1 H

1 F0 c! v  u$ ~: g. k' c7 W// No image data
/ b7 G" a% a* P5 p0 Lif( m_nImageData == NULL )
2 v  e& R1 R9 q3 {% V( RreturnError( s, TGA_BAD_DATA );
5 F+ S( j6 r1 [/ |+ t3 {, Y" S6 ]/ N& k  U
fclose( s );9 s  T1 x$ D$ G( f; L
2 m" o& r/ z: r5 n
return TGA_NO_ERROR;
. S, |+ J3 a/ N; h}- `  z4 K7 N' [

" n& s( R- `3 Q1 i3 N6 E
) D# u9 z1 x0 ~: ?/ ]+ ~调用举例:9 {8 C& T9 U& T4 n2 }
//; K% }9 e% s7 M. N: P1 B5 ?
// For the billboard poly, load a texture of a steel sphere. We'll use a
/ p( {1 v5 r( m$ L$ w// .tga file for this image so we can use an alpha channel.! A$ Q. H( Q9 X
//7 m3 f+ T6 k' h, @" R; R
/ X4 N: V8 R4 E4 l$ h: P9 s' a
tgaImageFile tgaImage;7 ~+ `( h8 B0 {6 t
tgaImage.load( "steel_sphere.tga" );
' K$ Z# c. U5 B% e4 h2 k. J
9 W) Q; ~" r/ d5 g% o: H8 z9 EglGenTextures( 1, &g_sphereTextureID );( j- H, i" \6 i& j, ^- Z: n
% h/ R6 X( l- X- O
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
$ F8 M6 y0 P- s- Z; @9 p$ e- ^; ~  K7 l0 F1 k2 T/ e
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );0 `* W8 ?3 u7 H/ F) }, R8 Y
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
6 K3 K! d# j- U  A7 H" Y3 b, M  f9 @9 u$ q- U
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
, B* y0 H1 F- r$ P: `tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, $ x. }7 w7 @' |. t' F- n5 |9 {
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, : G) D) ]  A( r) _* m: J
tgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 21:47 , Processed in 0.018238 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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