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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>
5 W" p3 C, [1 P& g#include <stdlib.h>) \5 @, c  d% v4 f
#include <string.h>
- W! u9 l7 E: j#include <windows.h>
" B% e2 W5 ^! x* h- d#include <GL/gl.h>
: W4 g5 T* n- z! m1 _) x6 q% o6 n  w1 m* H
class tgaImageFile
2 A1 m  K+ z" }" P{0 t+ Z8 P; T  Z* m7 n+ s: t
public:3 X7 N0 I" i6 E
: |2 `4 y7 N5 J: d3 \# C. y; p
tgaImageFile(void) :
/ |1 @$ u. X0 q9 G8 n2 `m_texFormat(-1),. q# N3 |! [( ~2 f2 v
m_nImageWidth(0),. n9 k- I4 A4 T5 c$ W( S8 U# ~
m_nImageHeight(0),
: h/ m0 c( G, @5 Hm_nImageBits(0),
( H( R0 Y* _( V& y1 o( `5 sm_nImageData(NULL) {}; w. d  r- G( x+ `1 n' E! A1 D

7 V) |/ r3 r8 H+ Q( g9 }~tgaImageFile(void);/ T; ~) w5 R+ ^/ m6 x1 K

8 V" }9 N, f$ @4 ]enum TGALoadError9 M6 ]! L6 J* ]+ U1 p! p
{
1 M* g" W' j4 B) sTGA_NO_ERROR = 1, // No error
7 f6 x3 @. u5 r. z* b) `  @# ]TGA_FILE_NOT_FOUND, // File was not found
( u" j6 ~: @# [' q* _8 k7 y$ }TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
2 s* h, R9 b' r2 P" kTGA_BAD_DIMENSION, // Dimension is not a power of 2 4 E8 t. S! K: a# [, \- O
TGA_BAD_BITS, // Image bits is not 8, 24 or 32
' j5 F! w9 {5 dTGA_BAD_DATA // Image data could not be loaded
- u  @4 f! P3 ^- l  };4 V: }' Y+ ]2 H2 j8 f/ a: y

; j4 `# x8 N  F% JtgaImageFile::TGALoadError load( char *name );& g( F8 @. ~; I

1 P5 `4 ]4 a2 C& p& @" n5 KGLenum m_texFormat;  `& Q/ S- T" t
int m_nImageWidth;5 H3 t* d: J( o
int m_nImageHeight;
$ S$ I/ ?3 q- D/ p# g# d9 iint m_nImageBits;
* W8 ]; W3 W0 F; m8 s) d- H/ C7 Runsigned char * m_nImageData;
1 `) e1 O' y& W6 i, }  q& t% l2 d4 O5 Y
private:$ L  f. b4 X2 l$ [  q8 _
& B/ Y) c: f/ M5 H% p
bool checkSize(int x);
% n8 ^9 W/ P/ O# E2 a6 hint returnError(FILE *s, int error);* }: ]: ]# c! Z
unsigned char *getRGBA(FILE *s, int size);
8 ~4 {: j6 B$ J! ]: l! l/ Q0 zunsigned char *getRGB(FILE *s, int size);; c* I" h! K; B5 D
unsigned char *getGray(FILE *s, int size);
% j0 _( b8 ^! J3 U5 a};& }% E& F2 B; I4 O
7 o* V' f% X2 F% M0 }* |) w
tgaImageFile::~tgaImageFile( void )
, {) S4 x2 D7 K$ q, W{
. y- K+ C; Z/ R4 jif( m_nImageData != NULL )
9 K) _9 Z$ W3 ]$ o5 y{( C# G) p' I& ?+ P# e' G3 T: A' N: R& q
free( m_nImageData );; c- c. L! @/ X, g% X% M* U
m_nImageData = NULL;' o! h3 a4 c  ?; W3 v( x6 G: W5 I
}8 s3 m4 @6 j3 n0 r1 ^: O. T8 ~
}( y0 `- T0 _4 P4 j

4 C/ V" t( B6 _+ {* {* `& o+ e8 |bool tgaImageFile::checkSize( int x )
) @7 H: z9 E! Q# Y8 t. z{
& P+ W, E; a4 q! n2 L4 T// Make sure its a power of 2.) h: |5 ?* v# |
if( x == 2   || x == 4 ||
* [  W5 K# A+ Gx == 8   || x == 16 || 3 d3 ]/ ^+ o! [( x' M4 v2 [
x == 32 || x == 64 ||" S% E4 z) A6 ?+ l+ P
x == 128 || x == 256 || ; [6 ~+ e$ [& Y0 n0 v- k
x == 512 )9 k0 L  V# x5 E
return true;- o& u) i3 H) P  M
0 U, S/ c2 `$ t! I! a8 O
return false;
3 }& ~6 r: E( q0 y) [6 E}! v  \" F+ Y% g  v5 Y8 I% w. m2 T
$ @- P: o- }) @; p- \
int tgaImageFile::returnError( FILE *s, int error )
7 t: P0 l$ U5 c5 e5 m8 S{
3 w$ \2 ?# V+ w1 g% C// Called when there is an error loading the .tga texture file.( [2 C) _7 h' h- a& t
fclose( s );, f$ J; m( l5 h: Y+ s# |
return error;
" U* t4 N4 _0 y" H& ^# M: {}) y) D; F- k5 ^7 d' z
( U. E  a+ D( @4 z* L) g5 r3 a
unsigned char *tgaImageFile::getRGBA( FILE *s, int size )
" I% ^5 I- ?3 e{9 p! P7 [& W+ f- g& d( \7 K" I
// Read in RGBA data for a 32bit image.
( l$ ^$ ^8 `: }' zunsigned char *rgba;  `" }+ I$ Y6 W& `& J* c
unsigned char temp;
' a: X% B$ x8 ~4 x0 Aint bread;% N* c- U5 @. U
int i;& y+ X5 Q; I0 Q# C% ^! E
2 P4 A  C5 X! i/ ]( U
rgba = (unsigned char *)malloc( size * 4 );
: u8 ]) J% @! S# |9 G
, q" V! z: i+ `  a* z; P7 dif( rgba == NULL )8 s# l/ s' R0 {; C+ ?
return 0;. @2 L  r& Y6 }2 ?8 @9 Z
3 B  Z9 n- n9 Q
bread = fread( rgba, sizeof (unsigned char), size * 4, s ); ' n, D& g( s- o) c) L

. @4 `# k) Y6 a% w& o& N& x' i$ i// TGA is stored in BGRA, make it RGBA
' v3 o+ V- @* r6 H' V9 _- Lif( bread != size * 4 )" h! u- D) _2 O1 L5 i: u
{
& K' R" K/ X* V# h1 nfree( rgba );
1 S, d3 M: I; @return 0;
7 `; M" r5 t" f2 E6 X1 _, ]+ }}' A" v! o( U! W' B
, h  M2 v/ j- H1 s2 l! h
for( i = 0; i < size * 4; i += 4 ), m: b' B6 T  R4 w
{: @- ~% L' ]6 t% C
temp = rgba[i];% x- i; a9 i) y) {# X: E
rgba[i] = rgba[i + 2];, x- K# c) v. G# S, X( l  v
rgba[i + 2] = temp;
9 o% |" c3 q8 ?' L) r  U}% I2 x4 B' [3 h: j( E- _- |( {

. n- W" ]# j- ^$ N' A5 Gm_texFormat = GL_RGBA;$ B7 |- a! \0 L: y! B
return rgba;
0 z0 y! `) ]+ G}/ T" L+ W9 p: }4 Y' |$ T
: y# r( A+ s, L* `
unsigned char *tgaImageFile::getRGB( FILE *s, int size )
, K7 p4 O, ~. ^/ q! L! a8 m! i2 ?{6 Y( I! B* [/ |+ k3 t1 l: }
// Read in RGB data for a 24bit image.
/ ?. d! b+ B8 N* xunsigned char *rgb;
0 o" r  E8 c  b# ?3 Tunsigned char temp;; R. E2 n) T' Z
int bread;
& u! b( l/ ?/ [! ]( o) xint i;  e7 m! q' O1 P# I8 g

6 }3 \# E3 ]5 ]6 b( zrgb = (unsigned char*)malloc( size * 3 );
2 ?, d6 o' Q  r
2 d; ]3 j8 r9 P. i+ fif( rgb == NULL )
9 R% }$ o! u' Sreturn 0;
/ v4 Q2 u( B& z, u
: K# w& M( h- o8 w6 h" ~bread = fread( rgb, sizeof (unsigned char), size * 3, s );
0 e$ s- I+ ?, c; [, @
/ t# e5 E# `0 T% g5 K- uif(bread != size * 3)
5 t% y: ?! l7 ^, W8 p{/ o+ S7 }% c* l3 @3 D4 c
free( rgb );+ U/ d+ P6 |3 v( [: G
return 0;
; n: Y' g* }" F* q# B/ V0 }; X}
# S7 v; _% F: Y3 I9 N- x% D- n7 z" ^5 S$ k3 m+ Y
// TGA is stored in BGR, make it RGB
* c8 Q# E( U. e  Bfor( i = 0; i < size * 3; i += 3 ), U! Y! v0 z& v2 ]3 D' v
{
3 K% B. U, e9 D3 N$ `  a! btemp = rgb[i];
0 e$ a+ e# U. n. Q; Y- u. Vrgb[i] = rgb[i + 2];
2 u- M# ~+ C, |/ Q! v4 [& R$ @rgb[i + 2] = temp;# l" x2 S& F1 m% z5 ]
}
  i0 ]% E; V8 i2 g3 Y
" G& s! j1 V9 l4 @- X, Jm_texFormat = GL_RGB;
# J0 l; u1 ?. l. z) R1 h
! L% g/ m) v, u4 Z- }+ A* nreturn rgb;+ _1 m( O% j, r5 g( U/ T
}
6 b/ C/ }5 R7 F/ ]9 r( s
; `2 l9 H4 p  Munsigned char *tgaImageFile::getGray( FILE *s, int size )
% G  K6 |& h/ D  S, j{
5 `2 z6 |/ i  s: O/ y* n3 H5 q' f// Gets the grayscale image data. Used as an alpha channel.
& o+ Y. O% [' G# X9 Xunsigned char *grayData;# w& ]9 K4 Z; |% y
int bread;
7 f. X7 R/ n9 h4 E% J$ j" y5 R8 T
* e1 Z8 n2 V4 ?) T( q! dgrayData = (unsigned char*)malloc( size );
$ Z% y, l+ _1 ]: y# m4 Y# f. o; v1 F3 t0 s3 K5 ?3 a& a
if( grayData == NULL )
$ z; X! h. H8 ]5 d7 j) u! w. breturn 0;% @6 K/ x/ E9 |( F; T: a& P

; `9 i' Q9 Z; _! w' b/ N1 g5 Bbread = fread( grayData, sizeof (unsigned char), size, s );# ]+ P6 F& l; V7 z2 n2 E
/ k2 B# K  S# h  s' U5 P
if( bread != size ); E1 V3 E  j0 O
{4 ~3 |7 ]! C: Q- E" B$ C# ]
free( grayData );  E% h$ \7 u2 ~) D# J) c
return 0;
+ Y4 Z& X; A& t' q/ |7 M}: y$ |+ o7 S7 s( ^8 e, L8 M) b/ a! d

& q( _4 ]/ P6 `1 i- Pm_texFormat = GL_ALPHA;7 b" q3 X- t7 |* h4 f) _
* E9 \; s# X( Y: m7 I6 r
return grayData;
$ e* [: \$ M7 @: T  {# l  t}
- M  A3 j& Z7 P7 a. X+ X7 j
3 W1 |" C% }. r7 ?tgaImageFile::TGALoadError tgaImageFile::load( char *name )
0 ?5 |& O$ R4 M{5 J$ z8 Y% g+ U$ j9 R
// Loads up a targa file. Supported types are 8, 24 and 32
2 r" V$ b6 f. y' Q4 _// uncompressed images.
8 B8 P4 U/ J- m1 a/ I5 Nunsigned char type[4];3 c) u& c1 V2 S! Z- L) J
unsigned char info[7];
( m  W/ c* d/ ?8 T+ Q1 T0 rFILE *s = NULL;% e: q3 f6 y* l7 w
int size = 0;$ F! H# P5 O( `7 K5 ?% l9 I+ ^" _

. s) r7 ^- p! R+ _% U) {. |if( !(s = fopen( name, "rb" )) )
4 V; o9 L/ r  i; P0 Q/ K( Lreturn TGA_FILE_NOT_FOUND;6 {, D( G! \% p* n) x4 b( h2 X
2 B' i. ]' u) ]
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored4 i9 ?- M# N, P( H/ k! S
fseek( s, 12, SEEK_SET);       // Seek past the header and useless info6 g4 \5 `8 _. \" M4 B- g
fread( &info, sizeof (char), 6, s );
- ^/ ?/ B1 Z7 ~% ~/ m0 l- @5 u" k
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )) Q! ]0 s$ q8 F& y& P1 [
returnError( s, TGA_BAD_IMAGE_TYPE );; w, Q5 y) S5 f1 {  g( ]. L: v7 V
! F; o" F8 o+ J! B3 C4 e
m_nImageWidth = info[0] + info[1] * 256; . W, l- d- t' {2 g8 `7 y9 Y
m_nImageHeight = info[2] + info[3] * 256;
. t/ U# ]! V2 xm_nImageBits = info[4];
7 v1 |1 s; @0 J# R. e9 |$ T! B3 D  d% k: \' r1 u1 A3 y, d
size = m_nImageWidth * m_nImageHeight;
$ u3 x) E; i1 p+ e0 o4 |. c" ?
3 `' |8 C( x/ U7 W8 Z  A// Make sure dimension is a power of 2
! ?2 I$ z9 _/ R/ H  bif( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))- t% s4 _* p4 k2 g
returnError( s, TGA_BAD_DIMENSION);0 ?- k. o, @: [2 {% d$ X
/ ~3 x1 t3 }+ r4 N6 B) y$ a
// Make sure we are loading a supported type
- @/ ^. S7 D. |- uif( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )4 E' v. O! d4 W8 _
returnError( s, TGA_BAD_BITS );8 K7 q% }7 d! u& f3 J* ^

! ?* v8 S! m8 Eif( m_nImageBits == 32 )
1 E1 C4 c5 Z1 {- Z$ Zm_nImageData = getRGBA( s, size );
) K/ `# h5 f8 z$ Felse if( m_nImageBits == 24 )
: s" @; E/ D7 ^0 E6 D4 e: nm_nImageData = getRGB( s, size );  
/ H0 o  d0 @/ K" a% c/ o# _, xelse if( m_nImageBits == 8 )
2 b3 }" B( ^' M7 `m_nImageData = getGray( s, size );
+ T; [2 \- |6 p* f9 V4 Y- i3 e& F4 b! P# d; v+ @
// No image data ' b/ n4 P( t. q+ o9 T
if( m_nImageData == NULL )
2 C+ I1 W4 b8 r7 kreturnError( s, TGA_BAD_DATA );
- p, `  g, d0 ]* c) h8 P9 r3 M7 B# `/ K+ Z7 O8 D2 {  t
fclose( s );
1 _7 W3 Z6 K0 p  m* f0 J
  F/ X0 L/ R# T. xreturn TGA_NO_ERROR;
! l7 c4 N' L* T+ q& o+ ?- C, u6 n& D}
+ A* U1 _- |% M' }9 C* t- b. y- E2 I2 X3 |" ~9 s# t8 v( J9 w3 K; c
, w: O# |2 N, D2 G. H/ i# O$ E
调用举例:
0 z& Q7 [. j- M/ ?; S+ S//( |9 M# f% A6 e# V5 s( ?
// For the billboard poly, load a texture of a steel sphere. We'll use a
+ _' q5 T1 m2 A/ G5 B# N$ w  ^, Y// .tga file for this image so we can use an alpha channel.# M8 t' t  z: U+ c& W3 W: G9 ]
//
- k7 f& B+ _! G& h8 l) G+ q
: C7 R, U0 _/ w/ s( TtgaImageFile tgaImage;( G$ i. B9 L4 b5 X( y- k' R; a
tgaImage.load( "steel_sphere.tga" );
4 H8 l5 x+ P, l! Z6 `8 O; p3 a1 D) ^5 C( H: p2 x
glGenTextures( 1, &g_sphereTextureID );
, _" T- T, [' d9 O7 J
+ [6 q) E9 N8 g9 |8 `glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );( J- l% h3 P0 z6 m
4 n' X. ^1 Z+ m, n/ `0 y' S1 G& F
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );* ]( I  F! _* Z/ S: p( k# j
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );% F! a  {; J$ k

$ Y3 S% N* n+ K. Q. \glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, 0 @3 I# y' T. G9 t, z
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, - H* V. q- H& O5 o9 Q0 h% m
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, 6 N* h* K4 s. u. z  R# H2 c! ~
tgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 22:41 , Processed in 0.037186 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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