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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>+ {' }8 u4 T8 L& X" `
#include <stdlib.h>
! y! {$ `" k# m- U; U#include <string.h>
, `$ n& V+ Z- f. c#include <windows.h>
7 D$ O$ o) e- ]4 D#include <GL/gl.h>
' H# |, L) r+ ]' X+ n
+ y! m' w- X6 ?* {class tgaImageFile
. I. M4 Z1 W% K$ F% b{: c( U* {7 a. W  W$ L4 h
public:
- x" D; Z+ f/ B
% j- |$ Y* D- m% l; ^  `4 [* Y' BtgaImageFile(void) :
$ j3 c9 x3 V$ Y$ n4 H3 \m_texFormat(-1),3 N8 z+ K4 i$ b8 G3 H
m_nImageWidth(0),8 H  q) b3 c' u
m_nImageHeight(0),9 l* N" k& U4 m9 Z2 X; x% _" {/ h
m_nImageBits(0),# d! \" q; k9 f: f1 W
m_nImageData(NULL) {}# b) ^' j  Z8 }4 K
" @/ `7 E  U; e' W1 I* V4 j
~tgaImageFile(void);
( x- Y( v, E1 {$ j: F( V1 H
6 @. i+ j6 V! ^' yenum TGALoadError
( I, I/ d& p$ r% f{( u( H" M/ X+ e
TGA_NO_ERROR = 1, // No error8 {7 \* U- S7 R! p/ t
TGA_FILE_NOT_FOUND, // File was not found ) @' }# g. j' i7 N  p4 d
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed: Z- x( {3 G4 a/ r
TGA_BAD_DIMENSION, // Dimension is not a power of 2 + `; d6 |6 E/ u( D3 e9 U' x
TGA_BAD_BITS, // Image bits is not 8, 24 or 32 0 N# _6 b) I$ n/ Q; Y8 J1 |
TGA_BAD_DATA // Image data could not be loaded
9 I# o* j- W) q0 W% K7 F& c  };
8 |4 S( O7 |+ X9 R  C6 Y, B1 f3 a  Y! F( y7 \0 x, t( m: r8 }
tgaImageFile::TGALoadError load( char *name );: s+ J" f) T' A! b" U& ^0 \
' K( T$ i) O  F. I, H' `- g
GLenum m_texFormat;
, ^0 j, X6 |+ [1 C- U7 wint m_nImageWidth;
% W* e7 q  y& n' E7 N* Vint m_nImageHeight;
% E- ?8 X: q9 T5 h! h+ pint m_nImageBits;3 j. P2 ~% z$ u6 n8 a, x/ O# R1 T
unsigned char * m_nImageData;
$ X; z( e. m/ h. y8 Z! P+ b/ _' [7 C9 u" k" z$ m
private:
% J1 V4 [3 {( t% H' P! i2 ]# J' a) t8 |9 R
bool checkSize(int x);
& v, A" i! _8 N: o4 Nint returnError(FILE *s, int error);
& r! e3 D9 q/ s( A* D1 N/ `unsigned char *getRGBA(FILE *s, int size);/ A, m& N8 G6 w$ w6 W' H* I  j
unsigned char *getRGB(FILE *s, int size);6 M) b, T& |9 _  o  U! i
unsigned char *getGray(FILE *s, int size);
% V0 t% O/ r) W$ }! J4 j% K' b};
. s. A4 x% p! h2 x) I$ j2 \
# q  s; k" }8 n! O. MtgaImageFile::~tgaImageFile( void )+ Y/ t, N0 n. R" ^3 o* t
{
: |% W; C# w% ^+ Y3 xif( m_nImageData != NULL )5 n7 w4 b' w7 C" N
{% O- j/ Q5 `4 n
free( m_nImageData );
' @  ?& n1 |. A/ K* d, P) |m_nImageData = NULL;
! D( {, |1 `% d2 x1 z  H, C}
& O5 S1 Y! U, t  s; V. j0 X}% l. Z: f6 W  {
9 E  A) b3 M" w1 w; p5 L# }+ D4 V
bool tgaImageFile::checkSize( int x )
+ d* G$ g6 j" l{! C( K9 t2 j# m, F) s; D/ Q4 y7 a' L
// Make sure its a power of 2.5 w' M- q" E. R4 C
if( x == 2   || x == 4 || 5 Y9 B/ H6 L. m. J  d/ Y) J& ~
x == 8   || x == 16 || / H  C) f9 x* Q# T3 X
x == 32 || x == 64 ||
: q; R6 c# h" r5 `5 `  Q; T' gx == 128 || x == 256 ||
" n9 a4 L6 K8 u% px == 512 )/ I4 Q* O9 Y/ a/ g* a/ b( k
return true;
8 W, y* A9 ~3 P6 U, ?! ^4 ]4 P0 q+ h4 @7 }8 m
return false;
  j( g4 L- I# R* H' N}, y1 U$ n6 g( i. P$ x# U; k
  m8 u- p/ ^% x4 j0 o, H* d
int tgaImageFile::returnError( FILE *s, int error )7 F; x& A. ^! d/ f2 B0 Z. C
{4 Q3 [9 e/ ?7 g) R9 P! X  s# _
// Called when there is an error loading the .tga texture file.
. v. U" P6 G; X' H( p, efclose( s );
# S( c8 x1 z4 areturn error;  n' k/ @- Y2 Z& Y' I
}
( R6 J0 Z' b: Y4 K* @* k$ k
* j: ~( k. Q( c  funsigned char *tgaImageFile::getRGBA( FILE *s, int size )
% p  H4 Z) A" T" [3 f4 Z{
1 m& p1 {# d7 p% r: [$ [, G// Read in RGBA data for a 32bit image.
8 [, [* E9 T: Y  _6 T7 ], _/ F& hunsigned char *rgba;
( B8 x9 C0 T+ J& ~' lunsigned char temp;
( ~$ z0 d, O3 L  ?/ U' e$ Iint bread;& ]+ Q0 }! {& i# {. y
int i;! }% [' k5 d; O- g6 U- ?+ H
& F! V; O  K( m* I& o
rgba = (unsigned char *)malloc( size * 4 );
2 w0 b8 L7 [7 R$ a8 [! o7 l4 S" |
0 i( A& Q, P% Pif( rgba == NULL )
6 Q$ M8 }- F6 n8 K6 f( Preturn 0;: x! `8 F3 b" I; E
3 p) Q8 F) J" G9 `
bread = fread( rgba, sizeof (unsigned char), size * 4, s ); , A7 Q- t/ G6 {5 V- t
- r- P6 r  e- a" G% B1 t$ `
// TGA is stored in BGRA, make it RGBA
/ |! V' M  G/ a6 B( x4 N- dif( bread != size * 4 )
" I* I% ]8 R6 E8 _0 _, h{
1 J2 x8 w' e2 e/ t3 c% ]free( rgba );2 @" X4 M6 Z3 j! O2 f
return 0;" {; r$ A; q( W" A& B* m" i. w0 G# j
}( w# Y% B! O! e9 o$ ]# L! B
& \# @) O' R4 A" t" k$ _) }
for( i = 0; i < size * 4; i += 4 )" l$ v$ T* w( G" O' J  Q7 E* ^
{
% q- d% q; S2 B# m3 H  b+ Htemp = rgba[i];$ Y9 ?  }7 y$ S" N1 G3 F9 `+ E+ ?# j9 A
rgba[i] = rgba[i + 2];  B7 q0 ^7 p' k) m- R
rgba[i + 2] = temp;2 ]# T0 S$ G! b" v" v) f6 G" ~
}
4 y' F6 a  d# ]& ^- E+ X2 P8 X
5 B+ R# n" a2 K* v( d+ z) R4 wm_texFormat = GL_RGBA;
$ g6 W- _/ c  k4 w/ q% {return rgba;8 \8 W- \7 K. }( t0 k# v$ K
}
8 A' q; f, C/ `# n2 ~* Z8 A5 w4 L1 e; t3 y% Q% u" S5 d6 l# y
unsigned char *tgaImageFile::getRGB( FILE *s, int size )
4 E# ?& x7 G$ Y{8 n4 v; s4 U% V$ `
// Read in RGB data for a 24bit image. % c  O- n# |  Q4 l6 j+ t& S! Q
unsigned char *rgb;$ ]0 v7 S/ K5 o' }: [, \
unsigned char temp;, Q$ ^3 T- W" [1 ^1 l/ G) n) Z
int bread;8 c: r0 }' }; G7 w! F- j
int i;
9 U$ G  r6 B4 m, z6 x  r* \/ g% n; r
rgb = (unsigned char*)malloc( size * 3 );+ U3 e% j# h' b9 C
6 R" i: c# M# P! {
if( rgb == NULL )6 }" @4 X8 O7 A3 Q# [/ q
return 0;( _3 p. C/ H; m, `7 i8 C. T" R

% s8 _/ Q5 n) Y) Gbread = fread( rgb, sizeof (unsigned char), size * 3, s );$ ~- h6 y9 e$ E! t8 k5 Y4 M
* t; q, h- g  D
if(bread != size * 3)1 k& D' i& l6 v6 i( S
{& f5 `' u0 u3 J1 t! C% X+ t
free( rgb );
1 e, h3 @! ^4 b9 q2 y, ]% v9 b% ^return 0;
- ?% K* H# x6 I1 E% p}
6 A  n& e1 W1 ^& |9 `  G7 k5 q$ N. e* M3 H- h0 `
// TGA is stored in BGR, make it RGB   L' ^/ T$ x& b
for( i = 0; i < size * 3; i += 3 )' z2 V& ?2 w1 d8 ?& q- y# ?5 k
{$ X" R  |( {, a8 p7 _' l( z1 ^/ w
temp = rgb[i];
" m+ v+ h* O8 rrgb[i] = rgb[i + 2];
! s) D' m5 ^) D. {: g5 d2 zrgb[i + 2] = temp;
9 I4 g  }) c* E1 K0 I) K}
, P3 |( P1 I0 i  ~  [! T4 {' D# x( W' k) P
m_texFormat = GL_RGB;( X) E, Q- ?& p, W# w
) v* t8 a& `+ g. E% _# `
return rgb;) }2 @4 M% A+ O( G& d! ^
}
- \" y6 s9 c5 X7 ^: i3 x& q( d) b* ~7 }# R, Z* P! }
unsigned char *tgaImageFile::getGray( FILE *s, int size )
& X; s: T: ^9 p- q. m1 i{7 k' I$ Z6 l) V0 e  r8 y% `. `, q
// Gets the grayscale image data. Used as an alpha channel.
5 _9 Q2 U% X; h0 ~* {* ~unsigned char *grayData;2 f1 r' b" `/ x2 O4 p" V
int bread;: X9 h% k; ^6 V  ?7 f) ]+ u
& B* x% F4 m& W4 a) ~+ i% [
grayData = (unsigned char*)malloc( size );4 B2 C% f! l$ ]0 W: N
7 e% n! `5 M$ B1 Y7 @
if( grayData == NULL ); [0 H- X" }7 E; J3 k5 Z
return 0;
4 I# }2 }1 k, m- _7 g5 ?4 [% i* t$ d
bread = fread( grayData, sizeof (unsigned char), size, s );% R2 C: b( Z$ R# t

- q+ W4 o7 E+ ~- D8 xif( bread != size )3 P' }* W5 l6 r% B
{
3 P, B1 ^7 f7 z5 T; Kfree( grayData );
8 _/ I( A9 ~) Areturn 0;, }! Y( G1 [8 X
}
! v2 G, n- l( Q' ]/ J, L* _* L4 X1 A- t1 c$ B
m_texFormat = GL_ALPHA;
7 \/ @# A5 m% ^% E
- U; n1 D) S7 V9 p4 F& A  Z. [" H  treturn grayData;
. s- ?% D. i" d* X' W}* r8 C) E1 |7 U0 p  R- B1 E7 E8 o
1 \0 v) y" @; x' N- s
tgaImageFile::TGALoadError tgaImageFile::load( char *name )+ K# C5 Q5 e  U9 X7 V8 l
{9 v$ K- [% S  s' J  i) x# L# e0 T
// Loads up a targa file. Supported types are 8, 24 and 32
# x3 s& {- r4 }) q, z& P/ `// uncompressed images.
; U4 j: C+ a( J) q* D( A2 iunsigned char type[4];8 o  d0 m' g" ]
unsigned char info[7];
, @. W+ ?3 e* z9 bFILE *s = NULL;$ y/ O6 T9 h, o; S0 f
int size = 0;
6 n, a0 S) ~3 i: A' {0 R
# S) V- T; s! Mif( !(s = fopen( name, "rb" )) )5 D' I% R1 F- |' z( H% z- m5 p" i
return TGA_FILE_NOT_FOUND;
. y) s1 D5 t3 |! `0 X* X5 |$ b# y4 I  v+ ]6 T. Y& c
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
& q3 E5 p9 k7 i: V+ ~/ Ifseek( s, 12, SEEK_SET);       // Seek past the header and useless info
+ t* `0 G2 F& Sfread( &info, sizeof (char), 6, s );# Q, c# A! o2 h. M: u, j( j
3 ~7 \+ M2 y3 S% Q0 S. _
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )* D, \( T( H# n! E( S. ]4 E- t
returnError( s, TGA_BAD_IMAGE_TYPE );
: w& Q8 ~- U4 g" `
. E! M% x: ]+ u' ?9 hm_nImageWidth = info[0] + info[1] * 256;   z! ~4 K4 ~+ T
m_nImageHeight = info[2] + info[3] * 256;2 p7 O( u; d: o; f' ?) N
m_nImageBits = info[4];
0 @* k' m' c$ Q: J8 @! Z& {" p- d" N( I9 V
size = m_nImageWidth * m_nImageHeight;
3 |, w; R, T! u8 u! u. Y* B7 Y" q- A! I' W
// Make sure dimension is a power of 2 / ?/ L8 N4 M" i3 j) I7 H! ?9 N8 x
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))& R7 s. ?  q) [7 m& ^1 H7 f* @7 {9 h4 N
returnError( s, TGA_BAD_DIMENSION);, H& a- [. @2 f! V& F! S8 G

: s$ \! l) C; Q// Make sure we are loading a supported type
  Z6 c. A' t, ~# Q4 T5 n! {# {/ H: u' cif( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
# e7 Q9 e: f' N' j8 ]returnError( s, TGA_BAD_BITS );
/ A8 U5 D# b! R* e3 }: ]* O
; u, i& }, ]/ X* e4 E3 xif( m_nImageBits == 32 )) m3 @! O2 d, N+ ^. g2 w
m_nImageData = getRGBA( s, size );/ {8 A, Y  F# I0 c4 H
else if( m_nImageBits == 24 )2 d& W# h! }" D/ X- h9 ^0 a
m_nImageData = getRGB( s, size );  
1 z, q. q( l& d; ^; H+ N7 felse if( m_nImageBits == 8 )
4 P" s+ o) K( f- a- `& I6 p* Bm_nImageData = getGray( s, size );2 f+ \1 f  u. a' B3 S9 q2 |3 d
' i9 B2 B5 k4 s6 d
// No image data 5 C+ s2 ?' q4 e. x0 ]
if( m_nImageData == NULL )% n9 A$ J$ g, n1 f9 ]
returnError( s, TGA_BAD_DATA );
: ]; T! I6 U, X$ Y2 o8 x+ G5 L' q2 h
1 N0 ^9 [: {2 ]- w  L# m8 I+ ?fclose( s );: u  \3 w1 q* T% X* N; X
, e9 {6 z( _; T$ ^- m: o
return TGA_NO_ERROR;. O0 i5 |7 u5 q2 V5 B' x
}0 R% W; {6 ?6 ]
; ]. g( I( Q" C$ H" H& h
. {- i% ]" r" O
调用举例:
. M! Q1 ^0 j/ O/ \//" H2 ]' |$ M0 g- L0 f
// For the billboard poly, load a texture of a steel sphere. We'll use a ( w& \4 }- a/ k5 D; n0 x  p( u
// .tga file for this image so we can use an alpha channel.
6 h" c* `( G  K( ?//& G) }; [! [% h; g. k5 B" m
& v6 y# v0 f+ @
tgaImageFile tgaImage;
, n6 \3 {* X& j* h/ r. x/ stgaImage.load( "steel_sphere.tga" );
; S* g/ E+ u6 |
. L% i3 d) E5 cglGenTextures( 1, &g_sphereTextureID );
" F2 m0 w( E: C7 s) }' n2 w; E
0 \& A# B& ^$ [2 x" ?' T$ N& u/ P6 TglBindTexture( GL_TEXTURE_2D, g_sphereTextureID );$ o5 N7 B& C0 o$ N3 a

, m* Y7 O9 w- P9 V7 L4 B. d* s/ JglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
: W* U) q7 Y8 S! l! y# g5 A- vglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );* e  U1 q* N/ z8 f! {' ~
$ Q/ _4 W( E' o; p( H4 j4 V
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,   A) G9 n  ^" q0 y) v
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight,
* ~2 Q1 Q3 S7 o. Y- D0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
1 F- T5 e; ~  h+ W9 h+ k. C9 ptgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 01:36 , Processed in 0.043587 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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