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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>8 m" p9 @8 ]* S' m+ R
#include <stdlib.h>8 N' e( r: n* v8 j; I" u) F
#include <string.h>" Z- {  Q, e; X! f& J
#include <windows.h>
8 j7 w, T) d& X- V#include <GL/gl.h>  z# K8 D; G  i5 ~

' C2 R% A7 U3 O: b$ {9 Z, hclass tgaImageFile
! `# T" q4 ?- F{% M5 B* f, G" k4 A1 ?
public:0 Z( H9 b( I" c0 c8 R6 m7 I, D
5 u5 p; x. _+ E8 P% j) f
tgaImageFile(void) : " E. ]* X( @( R8 _9 Q
m_texFormat(-1),$ _: Q0 H% t' B( V" O3 h
m_nImageWidth(0),- Y' v9 i! o- F  I$ P& ]  Y
m_nImageHeight(0),6 [+ t, G" L, X: h+ _, v0 h
m_nImageBits(0),
, _( U( K! z! R; p6 G* im_nImageData(NULL) {}
( U- |' n/ E- ^1 L) w* }
1 ?2 f- V% s" E~tgaImageFile(void);: X5 e; r0 I6 \% o% L0 W+ A

% q/ b( U$ C: J6 u% uenum TGALoadError. v5 z5 N9 Y% _8 q! J$ j
{! j, p* J; g* f3 @9 m# x
TGA_NO_ERROR = 1, // No error
" s. t# u3 N/ P! ]9 `3 u4 dTGA_FILE_NOT_FOUND, // File was not found
  H* G3 E& g, g+ Q/ j0 j0 D5 NTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
/ ^" B9 t% j" UTGA_BAD_DIMENSION, // Dimension is not a power of 2 4 [/ g) J! p8 H! j: Y! P. F
TGA_BAD_BITS, // Image bits is not 8, 24 or 32 9 C2 F! w  z+ X$ e8 x% Z  c
TGA_BAD_DATA // Image data could not be loaded
% s1 u% {% Y% A  };7 E4 \# F% o2 V# E6 \; |3 U
) ^& R  F  ?, s8 @2 z9 ~
tgaImageFile::TGALoadError load( char *name );
5 f: ^' o" {8 [3 A0 b
5 s% P. h4 W- Y# A. X+ P5 aGLenum m_texFormat;- `8 U: P, i6 r, e% |
int m_nImageWidth;
6 P6 M- \$ O) w1 O6 p: x: E1 Z6 E8 Hint m_nImageHeight;; a1 s" ?; r, \0 W' M$ n+ Y9 F( m
int m_nImageBits;
2 l, P0 F6 u8 E) S6 Munsigned char * m_nImageData;
: r& o9 E* X$ u( z' e
& r& Q! P$ p. cprivate:
8 U, t5 r3 R! G, w; T$ f5 g& {( E# g! x: ~2 ~' K9 W$ C
bool checkSize(int x);. F% d# I! A! p- Z7 N
int returnError(FILE *s, int error);
, p6 F. Q9 y2 [& T  e  v: |unsigned char *getRGBA(FILE *s, int size);3 i  H* Z7 d$ j) a8 t
unsigned char *getRGB(FILE *s, int size);: ^4 Q) p$ d3 h% O0 e3 H
unsigned char *getGray(FILE *s, int size);
, X/ k7 s. F& Y1 h; e};
5 w- A1 a2 U8 N$ d( t5 F8 [% M) e# j% y9 R) D
tgaImageFile::~tgaImageFile( void )- `8 N" }7 ]; x6 U
{  x( O6 x& ~, M  C5 W" [* S
if( m_nImageData != NULL )
2 e/ W  l& p! ~) M{' c, y8 T* R1 b) l. X  K
free( m_nImageData );
  R6 H$ w' X( A  e# }* y* n4 m  E8 lm_nImageData = NULL;
; U1 t  s( C' l2 y1 V! e3 R}' v1 q+ t5 N+ R/ F2 n3 q
}' O3 L" P8 M+ H3 {
+ B* f7 V/ P; K- f* R
bool tgaImageFile::checkSize( int x )
4 v3 ^/ W, T4 u. V4 j{. m* I2 P, q( T6 U  e4 F
// Make sure its a power of 2.3 b! [6 O; ^/ e' T1 ]) D
if( x == 2   || x == 4 || + q$ [7 K) P! b# _9 w6 q& n
x == 8   || x == 16 || ! N+ x' C0 N9 c
x == 32 || x == 64 ||/ j3 U0 G1 x/ c6 e$ ]
x == 128 || x == 256 || , z8 E1 x& O9 i: I7 y  r1 a8 s
x == 512 )5 @& L. J5 q% U; m
return true;
5 H' V0 y0 c2 l# L1 D; I4 M2 Q2 y" e: R; ]/ e! v
return false;
6 \/ ]% {4 i+ V% N}- h+ r3 o+ s8 q6 z, }! d% y

$ l- k8 `" B* F4 @4 D  Bint tgaImageFile::returnError( FILE *s, int error )5 z, {! |9 V! L$ S: e% T3 V( L
{
5 X; s) Y7 C# d+ _2 G/ t% r; N; {// Called when there is an error loading the .tga texture file.7 R# G) z; J3 [7 \9 b8 I( }
fclose( s );
* a+ v! t7 W- }" t2 Q# i/ P' {return error;
+ b0 ~; j' A& b/ U: N% l- ~8 r7 I}% J3 n% a0 }. I# ^$ v
2 i' G6 N- P6 A+ n
unsigned char *tgaImageFile::getRGBA( FILE *s, int size )
0 s3 }7 |. m( w0 U% D; Q0 R{5 `$ R& [$ _) w0 n. k
// Read in RGBA data for a 32bit image. + ~) h4 G& s# H7 z
unsigned char *rgba;
# M9 r2 D* z2 K0 c( \$ B6 Tunsigned char temp;
) J# C" Z) t7 a, L8 Z& Kint bread;, M1 m. Q' Z; q$ f! J2 r7 q3 r# |
int i;
0 w+ l8 e' J, n" z  _+ J9 r9 l; ^- ?1 A6 r
rgba = (unsigned char *)malloc( size * 4 );
* o6 @. D# |1 z! D! c, P, K$ J9 x1 s! s7 K" ]
if( rgba == NULL )4 z# j" Z7 r; W  B: [( ^- ]
return 0;
- Z6 F$ w% ?, ?1 o& A4 |2 J* y: A3 O5 A1 q' S1 A
bread = fread( rgba, sizeof (unsigned char), size * 4, s );
' v' q4 v5 y, }5 F( X9 h. F# ^1 V/ J$ E
// TGA is stored in BGRA, make it RGBA
! Z* d: s) N3 [/ `! C% E& Kif( bread != size * 4 )  i1 O. y* O, O; A) ^
{" v0 f- _# _, x! J' l5 [
free( rgba );# V0 \8 y+ d4 ?1 S  Y
return 0;% t& ?1 `) J8 t$ X# `
}- k: D' A" @' f6 i* V# [
$ Q2 [2 g* k& U8 d2 V( Y& F
for( i = 0; i < size * 4; i += 4 )
% `" j7 s) N' ~; j& \8 O6 J) W4 H{
( ?2 Q7 Q$ `" p+ N9 D* V( ?# \temp = rgba[i];
+ R- u. l( m" b* e! S, G, Mrgba[i] = rgba[i + 2];
; f" T' I/ h0 s7 N2 c- frgba[i + 2] = temp;$ ]# V  x8 E5 a8 {! O6 J8 C$ w4 T
}
# l" J# t0 e% k6 [! Z
: {% W+ K  S" K2 d" r4 Rm_texFormat = GL_RGBA;
% E' x0 \6 x: D' s  freturn rgba;
$ s0 |% l" g7 F! C% R}
( ?7 O: P5 d1 I1 D7 L
# k. W& P) V8 `* K. zunsigned char *tgaImageFile::getRGB( FILE *s, int size )
' a) F9 h* O* B( s{
2 T) L% b7 q  {- h% t- [5 a& L// Read in RGB data for a 24bit image. " G3 u/ p+ K4 Y" L: O  h
unsigned char *rgb;5 S) q9 m1 l+ c5 }) z7 [
unsigned char temp;
$ Y5 p9 O( c- W3 Dint bread;5 c+ w9 N( [* P/ h
int i;5 G. Y: w5 E  C6 D0 I7 D

$ p* b1 h4 E% ?- [  }rgb = (unsigned char*)malloc( size * 3 );3 b1 H4 \% R1 ^. `2 L+ w. h  Z
! ^- u7 m: }3 S# M
if( rgb == NULL )# r2 d# N0 y: |% }0 [0 e
return 0;/ B! J4 _5 L6 X' P$ x

1 D# O- G2 Q# E" A+ f# ^6 ~9 gbread = fread( rgb, sizeof (unsigned char), size * 3, s );
& y% `6 k8 ]! T: g' y' l8 L
& s: Z/ Q  `* e% {+ ?if(bread != size * 3); s) N: W/ \8 m8 ]2 v
{
1 K+ f/ w% Z/ nfree( rgb );
* E( i* C( m" A6 e5 _return 0;
% s  v. R: X2 {+ F" e}
- l5 |5 Z7 k5 U- O+ F
3 c& c+ W: H+ V5 R5 S( {// TGA is stored in BGR, make it RGB
* o" ?9 n; @) r& T8 e- t; Wfor( i = 0; i < size * 3; i += 3 )
6 y8 o1 }, @# V' ]0 [* l0 \" d% u7 }{
9 \$ u; `1 o& @3 O' S+ [temp = rgb[i];
# ~6 t+ i0 g9 a- m1 Y1 Mrgb[i] = rgb[i + 2];
6 \/ l( R9 g* J0 z/ ergb[i + 2] = temp;
0 n6 Q/ j# g  V& {. W}+ D# x3 `5 Q: \, m

6 [2 j1 V3 z1 q" L9 Qm_texFormat = GL_RGB;
0 D: N& z3 Q- P2 \, S+ r$ v7 L
- [$ I9 X$ Y8 T* A( Yreturn rgb;' ?. k& i% R, N4 g" h) t. I8 V5 R
}
, j/ l1 D/ j+ k8 J3 U9 P7 G; c+ m6 ?1 r9 \# O
unsigned char *tgaImageFile::getGray( FILE *s, int size )
) h4 F0 ^6 O6 h! E{( l5 _+ |: \4 B% r
// Gets the grayscale image data. Used as an alpha channel.# k/ M% ^$ d, r' F  m
unsigned char *grayData;& t  _6 ^7 a6 J( R
int bread;
% X8 a2 b0 ^3 V- P2 f6 |+ r, Q# T3 ^: j" Q
grayData = (unsigned char*)malloc( size );( b- ?( L# K1 \1 a
+ o3 F( Q9 n% U, S1 {& H: O
if( grayData == NULL ). {: }4 i" B0 N; x# Z$ m# W% S
return 0;. Q5 x8 A2 _: r5 F
2 y4 X) L( Q+ ?! e: s, p
bread = fread( grayData, sizeof (unsigned char), size, s );! P8 E' s, r1 O' u" }/ ~
# j! b$ j6 O4 y3 P  V
if( bread != size )3 l  r1 ?; y5 K5 E
{9 d$ `) v: K8 ?  N" g
free( grayData );
5 [1 f/ K8 \3 @2 {- W1 ^. nreturn 0;8 B# m6 e/ Q- t% b& [' C. g( Z
}
( I3 O# v  i+ }2 S
4 B: c. a# e8 V5 T+ E2 f- R6 ^; km_texFormat = GL_ALPHA;
. A+ x8 f+ O" b5 x7 r
* p: r) b$ w% vreturn grayData;
9 ?1 X5 N$ n$ t}
$ `4 e8 }7 z: U7 z3 o" z' K. l4 i
tgaImageFile::TGALoadError tgaImageFile::load( char *name ), q. ^3 `& r  _9 G9 t9 D
{5 D& s+ S" a' g8 @  b
// Loads up a targa file. Supported types are 8, 24 and 32 + h. }5 i- u) z6 ^' W
// uncompressed images.
: i5 m9 g* z8 q( Q6 ?unsigned char type[4];& O' h" I. ^! u. A7 @) r  ?2 M% k
unsigned char info[7];8 \" r; k) |1 H
FILE *s = NULL;4 f/ B  d; w5 ~9 z' c3 B
int size = 0;
& `8 v! |! j6 k- C1 e7 S
5 C* n% m, ~2 W* i) f5 Iif( !(s = fopen( name, "rb" )) )! O- E4 e2 |4 V# \
return TGA_FILE_NOT_FOUND;" Q- u& @6 t/ B& e
. {( X' b2 P' H* a7 G! s0 p
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored5 E( I6 z2 L- k& d# P! `
fseek( s, 12, SEEK_SET);       // Seek past the header and useless info
0 i+ |( O1 j" c6 l* f: [fread( &info, sizeof (char), 6, s );
7 m' A! q* q, S( M. W# \, O6 Q, k. L! I2 x1 B
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
/ G. a) k# ^4 m5 i& [; \8 ureturnError( s, TGA_BAD_IMAGE_TYPE );( ~% K9 R) o. f- P$ ?) I
+ l' F' P" j; L
m_nImageWidth = info[0] + info[1] * 256; $ D% w8 Q% Z, k3 u, F
m_nImageHeight = info[2] + info[3] * 256;
5 `. j4 d0 B# _( a1 }# o! gm_nImageBits = info[4]; : \9 U" Y- j1 W8 e7 [  B
( T/ q1 U- }( t8 s1 {# f7 P
size = m_nImageWidth * m_nImageHeight;
8 b" |6 }2 v* T) U' N0 t4 S; {" D6 H1 ^6 ~7 w# h0 i
// Make sure dimension is a power of 2
* `# y  D2 }3 [0 s2 k# Gif( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))
6 H. y  d( _% J# b2 ~+ n7 ]* P: m/ \returnError( s, TGA_BAD_DIMENSION);
' ~% A' a- J# C1 N3 X7 T) _- g/ E
4 \, K0 z, g2 Q# v// Make sure we are loading a supported type 4 O/ w0 ?% I( v3 r
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
$ B2 L; H( A, }' b" OreturnError( s, TGA_BAD_BITS );
# u0 _' G' f3 @5 B4 R! c  ~8 H4 z, _8 w% j) ?
if( m_nImageBits == 32 )
9 @. T* @( u( z( d' ^3 w* U/ G$ wm_nImageData = getRGBA( s, size );
3 V* b1 l2 @' O9 d- a' L8 Q& qelse if( m_nImageBits == 24 )( z& \, k# o8 u" p  [5 E
m_nImageData = getRGB( s, size );  1 m; X4 `$ M' q/ g
else if( m_nImageBits == 8 )2 |  b% `, n2 }7 x
m_nImageData = getGray( s, size );: H' l1 \/ e4 Y% V* F
% A, O& w; }* @
// No image data 4 T. @) A2 t4 W
if( m_nImageData == NULL )
- H+ L8 A: T# A  A  E; k9 p. yreturnError( s, TGA_BAD_DATA );: F: C- Y7 Z# Q9 U+ i' P
" w7 A/ Q; D7 E* V+ W2 V4 \- |: {
fclose( s );3 ]  U+ \. f+ M

; W! Q- r# r# U. w- L9 G2 p$ n: Zreturn TGA_NO_ERROR;
2 {( I/ Z/ K$ H0 W5 t$ i  n' R}) V( q4 T: S0 |9 H* ]

! f! Z6 W+ m3 K0 T( N9 E5 T( N5 k2 L: d; ?
调用举例:1 U: ~! Y7 d# i0 K% x/ l# i
//" x7 s: h; ?3 u' V
// For the billboard poly, load a texture of a steel sphere. We'll use a / S( _# ?, z! {0 l1 `! A8 A  a
// .tga file for this image so we can use an alpha channel.
! j) n% P5 z' W//5 Z9 [" D* s. @* A" k! m8 Q+ f
; ^* ?) t# {( A# }2 m, y
tgaImageFile tgaImage;+ y3 [% N1 L- F% W
tgaImage.load( "steel_sphere.tga" );
* a2 K, u. S; j/ w; m) I$ Z+ Y. _/ x& \5 \
glGenTextures( 1, &g_sphereTextureID );8 k& n8 f% [/ a! v0 u0 L
4 c2 K3 m5 h; ]- Y- d* x
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
/ k8 X' c6 C, r' g: f4 D. P0 j" j( _5 `7 U9 v* Q
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );: u$ G" m2 ?' N6 T# G7 r# E, c
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );( q% t" g. P. A5 `- z$ U

7 d0 e( ]5 d4 y/ xglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
7 b8 D; Y" G! M  R  e6 s! EtgaImage.m_nImageWidth, tgaImage.m_nImageHeight,
) U' [3 u2 j) m4 ~' n0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
$ j: s9 x2 C& ?) ytgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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