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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>3 ^  j6 ^7 s3 X4 E* N
#include <stdlib.h>
9 ], @; I% ]7 q2 Q, `# z7 |1 b#include <string.h>
4 F5 l' G* e, z7 h#include <windows.h>
, A' H; l) S  {, I" [( ]. L9 `+ o#include <GL/gl.h>
$ G5 t' Y  o! a  P! z
* ^& d) F: l) x, l2 c. o, ^class tgaImageFile
/ Y6 c' t; n6 m' @& J2 T{; `# @# x# b2 ~
public:
5 H8 `1 w( y6 _4 ~, B; F
* o8 r: v0 T$ c' Q9 n" O5 E( jtgaImageFile(void) :
; Q7 `/ e1 i/ k7 `8 P; um_texFormat(-1),, X# Y3 @" X! P1 {* z
m_nImageWidth(0),
. L) D0 `! S8 o+ {8 d4 I5 V0 z7 [m_nImageHeight(0),* m* ]* c$ W& L* P
m_nImageBits(0),$ P! F& Z5 j" O+ O  u- \
m_nImageData(NULL) {}9 i0 L8 A- s- H$ N. @
$ t4 {% k/ X# F- T
~tgaImageFile(void);
' e' F! M. ?8 C. x+ e# q: _9 `+ L
enum TGALoadError
, d: p& e4 b, j3 R{
& k# j# f) u4 L$ d% B2 y8 UTGA_NO_ERROR = 1, // No error
- N9 {0 A) b, r4 D% U) HTGA_FILE_NOT_FOUND, // File was not found
- V- o/ v) P9 }! o8 jTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
1 B3 H3 y8 U) p) N5 lTGA_BAD_DIMENSION, // Dimension is not a power of 2
+ z- G/ E. |" v4 o2 E  [( |TGA_BAD_BITS, // Image bits is not 8, 24 or 32 ' s2 G* T6 N- ~7 H7 }' ~
TGA_BAD_DATA // Image data could not be loaded / Y* a9 u0 x9 `: D6 d& O$ {: t
  };
$ q$ Y& u( n( P4 }5 Q% W3 \3 k; |7 ^! m" t1 d- F6 |2 r
tgaImageFile::TGALoadError load( char *name );9 j3 Q& t  ?% J/ @
; P; _0 i$ `) W- ^0 }& ^2 t
GLenum m_texFormat;7 a% N% |' L) V
int m_nImageWidth;  ]9 Y# t; K! g
int m_nImageHeight;( l( F. [0 Y' U. }5 c( L& m2 c
int m_nImageBits;3 O8 o& Y( m* |3 s1 w
unsigned char * m_nImageData;
5 P' w; B+ \* R! Y0 o9 [+ O
- U( c# }0 f2 J' M% N# fprivate:7 H9 X7 e. O4 k; S* p

9 W- x' ]" s( f- bbool checkSize(int x);
8 h5 `3 V' X, U% `5 Wint returnError(FILE *s, int error);$ W6 p' }& k4 O! i8 M- C2 L
unsigned char *getRGBA(FILE *s, int size);
9 x9 s1 v8 v& }unsigned char *getRGB(FILE *s, int size);
; ^; _3 V- ]$ j9 Munsigned char *getGray(FILE *s, int size);
1 p% K4 [2 s4 ~7 F};
/ c+ e- \0 b; q. V' q% t# t& f( |- y0 @- R
tgaImageFile::~tgaImageFile( void )
! Y4 ^; o) x1 o4 d4 }{0 o0 q/ m9 q( {$ A3 \
if( m_nImageData != NULL )
/ j  I, B% ?9 n4 Z% y8 ?. w{) E' Z4 ?: ^5 d3 |
free( m_nImageData );
, y3 m, n5 n' A: n7 zm_nImageData = NULL;
; t5 G4 p& j+ a7 q2 X: Y}4 _0 F- C/ a- L: P8 v
}! A9 f& P8 b+ L8 Q; J: V: F
  f# W1 J9 V  z( v1 g: S
bool tgaImageFile::checkSize( int x )
3 L9 T! e' x2 k4 P9 o/ }6 w{, K1 X3 P; G( i" t
// Make sure its a power of 2.
" S; k4 M" a/ J+ Z" cif( x == 2   || x == 4 || , I; V) ~- v1 y4 H
x == 8   || x == 16 ||
6 v$ _  m0 g/ a4 Ux == 32 || x == 64 ||
* {( ^8 h  D0 f( Ax == 128 || x == 256 || $ g; D5 a# i, W2 h
x == 512 )8 p5 T( \( }) w7 y0 F# o
return true;
1 {- i, @& Y+ ?1 Q
3 K3 Q( c/ c: a1 P. [3 l0 I) u. Qreturn false;9 f) ]- L1 S4 Z6 L( o
}
' R' J0 M' z& Z) H7 G  E; C( E" r6 Q! T' I% L: d8 [
int tgaImageFile::returnError( FILE *s, int error )
; ?3 [' q; v  y1 a: [6 e{
, I( _. i$ w" U$ m/ C// Called when there is an error loading the .tga texture file.4 h0 c8 Z5 s) S: ?9 O) Q
fclose( s );
2 }7 t. L8 |: }- b! T& z  creturn error;
/ q5 G# m1 C3 r) B" S}, j' b0 a- K* l9 t

% B' g3 w9 |* J9 Sunsigned char *tgaImageFile::getRGBA( FILE *s, int size )0 @7 y' L& r% e% a
{( P) `; ?6 Y! \$ I! k4 I* d
// Read in RGBA data for a 32bit image.
/ s2 ~/ `+ t! ?7 Munsigned char *rgba;
2 D6 O4 V4 L% k. G1 Uunsigned char temp;. l  L) K: ]8 ^5 o4 Y
int bread;
% P  W! |+ Y, N2 j5 J9 Hint i;- S- R9 Z  K: g6 w# n( }. s" ?
$ ^. z. N0 X6 j( e  F- r: u
rgba = (unsigned char *)malloc( size * 4 );$ {& ?5 U; m3 m/ C5 W
  j8 C* ^+ a" Q  [: _# L7 [+ M' p
if( rgba == NULL )& d* _# y5 |1 O+ P2 X! r8 O$ `
return 0;
9 u: z7 q6 a* s- [
% Y/ P& O7 v5 W  ^bread = fread( rgba, sizeof (unsigned char), size * 4, s ); ( d1 z0 Q, k* }/ U

% R3 E+ \9 I+ L1 T2 L' b5 k// TGA is stored in BGRA, make it RGBA
, z0 \* S6 R# {) Yif( bread != size * 4 )
0 _: q3 Q1 H4 d, n4 j+ q' @{8 n0 I( k4 ?# S/ \
free( rgba );
- j4 _7 w' q. _9 E4 e* Breturn 0;
! V8 c7 M4 V/ B$ T}
: M3 m. D" @1 f: _- h/ g: F9 w9 Q7 \8 Z4 v
for( i = 0; i < size * 4; i += 4 )
) x8 o' r* N7 [7 m% Y& q{+ g, C6 M9 s, ?) M  B+ w- S' e
temp = rgba[i];
; W* c, M; ?0 O$ Nrgba[i] = rgba[i + 2];1 x+ ~* ~! U: n
rgba[i + 2] = temp;, o) B, J; ^# l( O5 J
}0 J# o" T) N5 y/ O; r3 P2 Y( @& b
* f8 }4 V6 N6 q' M% D" X- J1 ^
m_texFormat = GL_RGBA;
1 S0 P% B( }& e$ W1 B4 t1 M0 p, wreturn rgba;) r3 S2 e, v( D, k" D; ?4 F
}
* R4 J. p$ y* \& V0 s- s5 @/ J0 o6 t7 G- @: o  l% }/ b4 L' x
unsigned char *tgaImageFile::getRGB( FILE *s, int size )
7 q' Q0 h# O& I- T' ]( W# S{
* n. X9 u7 n/ \( D// Read in RGB data for a 24bit image. / ?+ B5 E$ H5 A3 U' F! W  ~
unsigned char *rgb;
. o9 t' ?% R  P$ g9 [unsigned char temp;
2 B' l9 b& B7 I6 ^0 o, a0 Yint bread;- o4 u, h7 A- R5 M8 f  c# b
int i;9 w0 h8 R3 R8 s  _1 m. s$ f

# P# ]' o: ~# V6 F4 K; F4 `rgb = (unsigned char*)malloc( size * 3 );) W$ a6 r. X  o% l

, r8 Y+ W2 D% g! V( i/ z, |* o' R1 Lif( rgb == NULL )
4 J( o8 m8 h+ x. K8 zreturn 0;% ~3 M1 a) b/ O! w4 D, e3 O# G

0 d( B' o7 N, p3 Xbread = fread( rgb, sizeof (unsigned char), size * 3, s );" h1 |  H' o  e/ o# T0 I

$ E: U9 z$ B- u' ~4 [  a1 [if(bread != size * 3)/ D0 ?2 T! b4 ?
{
7 p) ^3 B. r( l5 K* `/ |- ]5 U6 bfree( rgb );" w: Q6 r' n( \  D; D4 s
return 0;3 l+ O' s' d1 B" m
}, b# T9 m  d6 i( a+ N# O
5 m3 H& Q6 ^; X- C9 \
// TGA is stored in BGR, make it RGB
! o* y* y2 ^' J$ R2 ]! kfor( i = 0; i < size * 3; i += 3 )
2 ]' o  z+ |- ~) |' ]" K{1 c7 E7 ?+ ~3 |& A4 \0 k
temp = rgb[i];; ?/ u: |4 ?8 d+ S6 c
rgb[i] = rgb[i + 2];
2 `! z: w' ]) d, k7 K1 Lrgb[i + 2] = temp;
5 y* L' Y. R$ q2 ~}  s  ^" ]& I7 r, @0 x; e
  f- H5 R+ ^- J. o4 Z. ?0 v
m_texFormat = GL_RGB;
, i6 e7 N8 U3 c8 i* ?
% M4 s8 h. F, g7 m$ jreturn rgb;7 d. g) O# D3 @; n
}3 ~) i% o3 J  h. Z. X+ u

' S& |8 b, y6 p+ hunsigned char *tgaImageFile::getGray( FILE *s, int size )& p) U  w9 V0 p! p2 W
{
! O' N( W5 G, m/ f# r6 N$ p// Gets the grayscale image data. Used as an alpha channel.& F) W% H3 p# Z
unsigned char *grayData;
9 K! I' w: Q, n8 v& G9 `int bread;
: g# Y- m( ?$ v7 i7 B
. p1 e% f2 o" f" k$ t5 tgrayData = (unsigned char*)malloc( size );
* ~3 h& [' f, i; X! q- W+ {3 {1 E0 L+ h8 M1 |  F! f/ I# t7 f
if( grayData == NULL ); ^3 z& v( i# i: U2 O
return 0;  h9 [. N2 M# C5 B% o
6 R8 y( u$ k6 i% Q, ^7 v7 M( x
bread = fread( grayData, sizeof (unsigned char), size, s );
# v: g* }0 ^3 V" a6 Y. O
- ]3 Z& H! K8 K4 P1 z6 [5 Eif( bread != size )6 H" _( S" b  |
{" T2 M5 m( X. r. G$ g& x
free( grayData );
0 i" I1 d& I- V$ r6 Breturn 0;
( h4 K; l# k. {  o7 e$ W}
* H+ h! m5 u# @, q3 ?6 V* G8 j7 M2 U3 Z. N
m_texFormat = GL_ALPHA;
0 y, a# R" J+ a& n2 k. ~( e$ x8 o6 p# X6 e( @
return grayData;
1 e! o$ n7 J% s, |}
# S$ c! d5 I  i% _6 [" d" \# J& E$ a' z: e  o
tgaImageFile::TGALoadError tgaImageFile::load( char *name )6 v6 Z0 T  n& _0 E
{
2 g  ~/ }+ f: _5 x- I// Loads up a targa file. Supported types are 8, 24 and 32
, w- S# G9 o! T* c6 |$ O' Q// uncompressed images.8 Q% t$ T5 G/ V* P
unsigned char type[4];4 M! q( e, h" {5 {: q9 c1 s7 M9 [1 v
unsigned char info[7];; s7 K5 @& v( h/ k, }+ ~- Y
FILE *s = NULL;
9 C5 g8 t3 e, z  i2 X+ }7 t- _/ ?int size = 0;. J$ A8 F2 P" L# `% N
) Q9 W  L( m' R$ q& u
if( !(s = fopen( name, "rb" )) )
+ s. r: X% y4 r" f  Preturn TGA_FILE_NOT_FOUND;' l. r* r4 d- L" H- q# N4 e

# w/ |8 n) e4 S' g' c6 y" rfread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored; k7 C& p" a9 M0 s' o9 ?" f+ W* k
fseek( s, 12, SEEK_SET);       // Seek past the header and useless info
# f' q! S1 ]' E$ ~6 F. lfread( &info, sizeof (char), 6, s );. T% Z4 `' j$ O& q: i  G% V

3 T. o0 i& T9 Z/ r; y9 \! J9 pif( type[1] != 0 || (type[2] != 2 && type[2] != 3) )3 t/ u0 \' o: S6 ]7 P- M( ~% l9 q$ }
returnError( s, TGA_BAD_IMAGE_TYPE );
) Q" c8 p2 c# o* u+ @
2 \9 B: |0 Y& W  Am_nImageWidth = info[0] + info[1] * 256; $ M. D% [& g9 e
m_nImageHeight = info[2] + info[3] * 256;
: T% r: \! O& a" r+ Wm_nImageBits = info[4]; ) X) f3 g9 |& V' m4 t5 k. D
6 |5 P$ K! E$ ?7 W  v; y2 {
size = m_nImageWidth * m_nImageHeight;& |/ d  f$ B+ Y2 ?2 N5 O( m

5 r/ k/ t/ p: O7 i  c// Make sure dimension is a power of 2 + Z) U' Y% K$ {! [$ i
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))  }. [6 r9 a- L2 S% Q
returnError( s, TGA_BAD_DIMENSION);
5 H! i" }1 Z5 l: ]0 l! `) i1 d: E
// Make sure we are loading a supported type
/ B& e& M! P, s+ ]0 q* ?if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
# s" k/ p1 i5 N5 X) KreturnError( s, TGA_BAD_BITS );
8 C" Y2 M1 W, N. J; G/ o1 O- y; x2 a1 w0 n
if( m_nImageBits == 32 )8 s1 Q+ B# f; e) H- ~) P
m_nImageData = getRGBA( s, size );, ]5 v& `# m  d7 l6 Z2 u5 ]
else if( m_nImageBits == 24 )+ I! P# B; N9 Q: k9 h' }
m_nImageData = getRGB( s, size );  " R& `7 P4 K- F4 w, _; N% x
else if( m_nImageBits == 8 )/ S1 A" g5 x- l+ s$ c1 Q
m_nImageData = getGray( s, size );9 ]" f( J3 T. Y: u$ Q1 G/ h4 L/ n5 V" Y5 Y

3 \) u$ W) a& a8 e( u; {, p// No image data
: ]% ?) ~. V3 @9 ~, zif( m_nImageData == NULL ), h7 U$ J1 F4 f9 w
returnError( s, TGA_BAD_DATA );% B& n) X& F7 h
0 k1 c8 I: w, X; a- F( }
fclose( s );
, N4 G0 R3 D7 p: {1 \5 T% w) I8 h3 n+ b& v& j4 s
return TGA_NO_ERROR;) Q2 m, c& q; A. F$ z
}6 J* n' ^2 X; s% Z3 T3 \5 l
1 k( L; ?0 [" h

) e# g% {  Q0 C7 j/ }- J调用举例:
: l) t- |! z! ^) X: Z* A. ]//! r3 I6 O7 F$ d* p+ b1 {
// For the billboard poly, load a texture of a steel sphere. We'll use a & n+ s6 ?, V$ N  X9 [8 K9 t3 [
// .tga file for this image so we can use an alpha channel.
3 L/ H& F0 ?9 ~9 `//% \% `, e; _+ s% Q( C
: A& B- s5 ^+ v3 [1 G
tgaImageFile tgaImage;
! T' g& p! v" L8 O  i0 R2 M. ~: ftgaImage.load( "steel_sphere.tga" );
. ~% u: d7 y, N- c9 F; J3 U/ q# f7 w
glGenTextures( 1, &g_sphereTextureID );: J' e, \+ W4 S. {# K& V1 {

' i# Z: m; ]! f# g. F  k4 eglBindTexture( GL_TEXTURE_2D, g_sphereTextureID );& z) g  Y: p3 ^

  Z! B9 t" ^; d' F/ BglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );4 h- e1 K. G" f+ z  Q" [
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
: T3 d) D( ]' x& D& s8 M
, e2 p/ U9 t8 [$ wglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
9 n  K2 A6 o9 u8 n/ O3 v- QtgaImage.m_nImageWidth, tgaImage.m_nImageHeight, ; @7 B$ m4 g/ L7 _3 G: f
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, ) d( I8 w. [- ]# K) {1 C3 X% F& |* r3 V
tgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 09:17 , Processed in 0.018385 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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