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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>& ]8 H. h) U  Z; h' }  [
#include <stdlib.h>3 t: l6 T8 W: j" p6 j; ~
#include <string.h>7 U5 g0 ]! V2 _' u: I# T
#include <windows.h>
) u+ X) J2 q5 t#include <GL/gl.h>
+ [3 ?; E7 T5 O# K
# t$ d9 i  v7 e* F9 I8 Q* hclass tgaImageFile
% V2 b% ~) [! G6 D" Z+ J2 T{& z" B, m5 D) j3 I! r
public:
9 l* L4 c$ W% T9 Y7 p/ X  y5 a2 ~! H4 F& h. F
tgaImageFile(void) :
9 ?2 A' h) @) i0 ?m_texFormat(-1),
8 ?1 a  c4 s- f2 }; U7 P* K3 L& pm_nImageWidth(0),
- C, ^- L: j1 d. [, @' O+ a5 ?3 Xm_nImageHeight(0),# Y2 N9 [; H+ i' N7 k0 O7 o! M
m_nImageBits(0),0 G1 v3 K6 t) ~+ Q
m_nImageData(NULL) {}
8 h) H6 j! ^! A# B8 s/ h5 e% ^! M: r+ ]) s- m& d
~tgaImageFile(void);
9 ~1 |6 g  _8 V" g* y
- T7 a; F# F9 j5 v3 h! Penum TGALoadError1 u. U& v! n( m2 [
{
& ?% i% Q" r2 N8 @$ w4 d9 B$ [$ JTGA_NO_ERROR = 1, // No error
9 Z; E* U. S% f# a! I1 \; l2 PTGA_FILE_NOT_FOUND, // File was not found
9 K4 ?5 @8 Z8 U9 ?; ~: l4 B0 m9 xTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
, T9 E8 g4 T1 I/ }3 GTGA_BAD_DIMENSION, // Dimension is not a power of 2 2 i* k) E' e4 p' o8 P' C0 y
TGA_BAD_BITS, // Image bits is not 8, 24 or 32
' L( }* m. ?. V% l; X7 \TGA_BAD_DATA // Image data could not be loaded
6 W2 [% a2 i5 D. ^. _" T  };
! o* s7 b, E+ p8 X8 ?% A7 n) J9 m0 @1 ?* a2 |+ j) F5 R
tgaImageFile::TGALoadError load( char *name );
" u* q" ]; M1 j# c8 ~' ]
' s6 o/ _  j1 I9 R4 U" N6 ?GLenum m_texFormat;* c. V7 Y, ^- W. K$ T
int m_nImageWidth;5 x0 _% u+ x, v$ ?
int m_nImageHeight;
6 h8 h7 t1 Q- w* t$ pint m_nImageBits;
+ Z: u# W+ X3 A/ h1 Y: y2 T3 E/ s( ~unsigned char * m_nImageData;9 L* E/ f% V# O% k# h

5 c/ s; P1 N7 r0 Xprivate:- f) b! K( f" P" i9 ^) C

/ U0 `4 i1 z$ E9 W9 ?bool checkSize(int x);1 ~6 j2 r$ y4 j; G$ q) I
int returnError(FILE *s, int error);: q' V5 q3 _6 {' J7 c
unsigned char *getRGBA(FILE *s, int size);/ I5 {; p: q; l. V1 ?  F
unsigned char *getRGB(FILE *s, int size);- S8 v6 Q. R* k7 _( b
unsigned char *getGray(FILE *s, int size);( s* M' J( g! X: P  H& h
};$ C- L. i7 R' l+ E7 N

/ m* g' L2 ^+ |( q; ?0 UtgaImageFile::~tgaImageFile( void )
$ M! S9 z/ M7 @3 Z$ k( f{
$ S2 W. Q, ]: O/ P) Pif( m_nImageData != NULL )
" s2 e9 {- A$ `' F9 I5 e. G{5 R) l, o, R6 e3 v+ i* A9 A, L
free( m_nImageData );
/ R, h9 e9 @: ?0 _  C  a+ Qm_nImageData = NULL;0 G' J! k: w9 |& h- n# p
}" M1 ?7 Y6 x0 t* c* R
}7 p* k+ l6 p' k3 h$ L2 }7 d
4 f( R1 O  C6 Z0 n
bool tgaImageFile::checkSize( int x )
" R* _" x; W, Z( L{
8 l6 u# M% b+ F$ b1 q# v1 w- C4 a7 S// Make sure its a power of 2.
8 D- ^- Y' [$ y9 G1 ^; }1 `if( x == 2   || x == 4 ||
. r1 S) F, r0 c( Ix == 8   || x == 16 ||
9 V( K7 u0 k0 vx == 32 || x == 64 ||
$ n* I: F% Y* s7 [6 o3 [4 D2 g; Ox == 128 || x == 256 || 4 I+ t' v1 T6 g  P1 Q. {
x == 512 )
4 t+ S# h. ]2 g/ `5 zreturn true;$ J2 [1 s8 q  J% u
7 Z3 j2 V/ S8 ~& e1 T* S
return false;
8 G; k* H; `) Q" k& \1 \}( W5 D) u  ^- L" L1 V
: E0 w* E& p6 v( a! }
int tgaImageFile::returnError( FILE *s, int error )
$ a* l# z" |7 {8 I* }{# e9 w- x4 l9 C0 G, ~! L9 b
// Called when there is an error loading the .tga texture file.3 e- U5 U. P% L8 o
fclose( s );
, t- {# P$ Y& b: m; V7 q4 ~7 o8 \  yreturn error;% y3 N; Y- w% V6 ^0 d
}: Z& n% T. S5 n/ i
" [3 F7 r5 A5 h/ O( X0 y
unsigned char *tgaImageFile::getRGBA( FILE *s, int size )
* i6 y: n$ Y& Z! w{
* U1 D" E# H% x2 d// Read in RGBA data for a 32bit image. ! y" q+ f  \' w
unsigned char *rgba;' j' p: v0 h. B
unsigned char temp;
9 _$ P0 ?- n* M* A' u* T2 Pint bread;0 S1 C9 a9 Y$ v) g' H
int i;
) P! b/ {: r2 a' o; z& B6 L( t2 r  m& B6 N: a3 N( ~
rgba = (unsigned char *)malloc( size * 4 );( l- {# x# [1 g* {0 a' x" Q
; F8 i+ A" _7 `& ]. ]- z0 l. z
if( rgba == NULL )6 z' `; O( ^+ {
return 0;0 U2 [& Z3 K: R" x! a

" B% e0 N. w4 I9 h9 ?8 vbread = fread( rgba, sizeof (unsigned char), size * 4, s ); 4 e5 U0 ^) B0 H* V2 V" a6 ^6 t

' t0 _5 o6 U* d: {& M4 R* o0 q5 }9 V# z/ ~// TGA is stored in BGRA, make it RGBA * G5 H& L) g! {1 o0 f0 o9 Y/ N
if( bread != size * 4 )
, J$ c7 L6 K, @5 {{+ L$ {) g: {0 e8 f* {
free( rgba );
% p! N* [# @% Y; A! A* W2 _0 G7 Nreturn 0;4 M! q+ b( G2 b
}  u& g4 ]9 `! ^0 a
0 ]& c. J; o/ K3 J
for( i = 0; i < size * 4; i += 4 )# W1 r& ^' A7 t- P. B5 ?
{
$ {& v' o) |% z) W% M; Rtemp = rgba[i];% q* K  y/ \- Z
rgba[i] = rgba[i + 2];. O) e6 b4 {0 c( z6 D% F
rgba[i + 2] = temp;
) o# c; B0 E+ Z$ K7 G  Y}  j! X* f: H/ N6 G- X3 n' z
% {/ p5 o& ]9 ]+ Q$ l' s
m_texFormat = GL_RGBA;' z% H* E" p7 y6 ^
return rgba;
/ A1 d" I3 Q5 @9 {; ~$ G}; K  j" G: j. ~8 t; k% D, F

, A/ L- [# x! }" \unsigned char *tgaImageFile::getRGB( FILE *s, int size ). g& c, Y. j7 w. }. a: y8 A* I
{
+ K* S/ {2 c% L0 e% E// Read in RGB data for a 24bit image.
3 z, r- o2 {* ounsigned char *rgb;
1 N) a& d& r2 N; nunsigned char temp;
3 {6 I# s+ B4 p  N, P4 s  y; _0 `int bread;
* Y. m1 T$ U! Z4 j) o# m# Yint i;+ o* ~2 D0 M( M

# \% G: y. O$ e! A8 A9 Prgb = (unsigned char*)malloc( size * 3 );
4 h( S& w. y3 [+ z) [! Y% C: s$ _1 L" `5 y5 O( H
if( rgb == NULL )/ L: u; A* F% @- c! F
return 0;7 ~) D8 O" b/ s0 }# A+ _

% c# c5 ~- ?9 ^! }8 [1 F8 s  ^2 bbread = fread( rgb, sizeof (unsigned char), size * 3, s );
' h& c8 ~7 [% j
- ]0 }4 o% X- p- I- E, Vif(bread != size * 3)$ J/ V( k( s1 ]9 H; ~4 o; c% E3 d
{
+ ]/ z+ h/ R2 ^) Tfree( rgb );, C/ X! b0 w! ?. `6 f
return 0;* O" N$ `3 N# q' Z6 ]
}7 k2 i& K  o3 f) ~

8 l, T. [2 N" `9 ?// TGA is stored in BGR, make it RGB
5 D, n+ j( A$ ]" a+ B# H% Rfor( i = 0; i < size * 3; i += 3 )8 b+ a' s- A+ a/ {( `' n. q
{
5 Z9 o3 {: ?, t) b) c( _temp = rgb[i];
# J! {- w! Q3 E/ Z, r& Xrgb[i] = rgb[i + 2];
  A$ ]' I* H/ S2 A3 {7 Q/ L$ trgb[i + 2] = temp;  t4 e4 R+ ^0 B
}
; E7 H7 _1 X9 _" ^* k  ^
7 s' S* e9 ^- S8 q+ Y5 Ym_texFormat = GL_RGB;8 S9 K& x# k  ?9 k6 g  }2 f
6 V: u- {+ \5 _. a& @+ l( D+ R0 _
return rgb;
9 i$ C/ ^# X* p6 w}
) f4 j9 l; ]9 u5 X5 L# |' S+ g% L% Z  C" j  J4 P; c
unsigned char *tgaImageFile::getGray( FILE *s, int size )2 D0 r. W  y9 K2 a; n) l  y* a
{  m5 k, h3 o+ `7 _7 ~
// Gets the grayscale image data. Used as an alpha channel.
, [' b* x7 ?4 d( Uunsigned char *grayData;
+ |" ~; T) P" y4 bint bread;
& s+ h$ V/ ~; k! A& C9 E" C2 X2 t$ M, ]# C1 M
grayData = (unsigned char*)malloc( size );
; Y9 |$ S) O: B' ~+ ?
" t6 o' f" I7 \7 g& f) W5 Y, Nif( grayData == NULL )
( f4 g. i$ I% s0 b/ w/ s; X% Mreturn 0;( e6 l& ]/ y! i8 a2 [* H. l2 r
* L3 \! ~2 c% {8 A# a( Z
bread = fread( grayData, sizeof (unsigned char), size, s );
7 p/ _! X! B# C8 c& e  }! A' H5 a* E# p* o# @
if( bread != size )
1 t' t4 `, f' ]5 l4 A{# z/ }6 D  I! Y5 m0 P
free( grayData );* V) g+ F) J$ F2 L# u0 [: K$ Y
return 0;" K+ m# a4 @/ }. b; w- c6 v
}) Z( O0 z$ y' b
/ @, C$ j0 q0 v, D) n5 Z4 q- r, b
m_texFormat = GL_ALPHA;  k, s7 b2 v3 D; M8 I  {7 E

0 m7 }( H6 }. C5 w7 p! {( Sreturn grayData;5 w- Q. D, {- {9 C2 c
}6 X8 k' P% k1 ]! L; L% L1 V
. X; R0 o- y) y$ j, q
tgaImageFile::TGALoadError tgaImageFile::load( char *name )
8 D0 L1 {( j2 P: E  V& p{
: y% t5 P; m; h  Q4 z0 [; B// Loads up a targa file. Supported types are 8, 24 and 32
* K% }' R- B; M1 F" o* I0 [$ b// uncompressed images.
& d, h3 R5 h! B3 Q$ l. Qunsigned char type[4];/ k$ t$ p% L6 r; x/ b' w4 u& G4 V
unsigned char info[7];
" \& P- F9 F7 @1 y0 TFILE *s = NULL;
" C: t! R7 P2 |: m5 n0 d- w) @& E; m. rint size = 0;3 J5 o0 P/ ~9 |- v8 `
0 F) g. A3 O& g! Y
if( !(s = fopen( name, "rb" )) )- p3 J' d# k& y$ G& j( `2 p, U. p- A/ Z
return TGA_FILE_NOT_FOUND;
& z+ F) ?1 p. c2 X+ Q; j2 F# o; N9 w# C4 ?) ]: f3 b% n* a3 U
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored$ j" o" L( C, W8 J
fseek( s, 12, SEEK_SET);       // Seek past the header and useless info5 h/ K- o6 F; p/ \
fread( &info, sizeof (char), 6, s );0 {5 W& q5 I) F' w* X% d$ Y

2 O8 B1 I; e: b8 F4 w# v& iif( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
9 s( R0 V* p. [+ `returnError( s, TGA_BAD_IMAGE_TYPE );
* d; h9 Q; m; A1 i$ y, t: ?4 A
# ^/ p8 Y' w  a5 t& U7 f) T- Cm_nImageWidth = info[0] + info[1] * 256;
& f' \9 x6 {3 J/ j3 p" h' o1 um_nImageHeight = info[2] + info[3] * 256;1 S+ Q% D. @; ^, @% e- c' a% m' }
m_nImageBits = info[4]; % @, ~3 }' w5 ~, F
6 b8 y/ P' X0 S8 `) t9 ~2 r% \! J7 ]4 A
size = m_nImageWidth * m_nImageHeight;
2 Q1 p  Z1 @/ [& u0 J% g- ^, ?" i3 w$ z: d- p7 i/ T+ `% K
// Make sure dimension is a power of 2
' h. j; M& L5 T/ v- V: zif( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))+ B3 l) C9 y# X: Z9 j
returnError( s, TGA_BAD_DIMENSION);& _  J) ~: a: [2 x% O! u0 s

* `' I) W$ A1 t: V2 r// Make sure we are loading a supported type
) I- M& y- u7 @1 U! q6 nif( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
4 _3 e( n1 O) f$ @7 S2 f% i8 OreturnError( s, TGA_BAD_BITS );5 y3 f$ I8 X7 g& @! y3 z
" g# ?6 ~" e( _8 m
if( m_nImageBits == 32 )
& v# D# n. X( {8 c; Tm_nImageData = getRGBA( s, size );. X! j2 `0 Q0 }% j* Q9 d% [
else if( m_nImageBits == 24 )! E! @8 q3 A- o5 }- z
m_nImageData = getRGB( s, size );  ( |9 o- j0 H  ]/ E
else if( m_nImageBits == 8 )
: _! s1 p5 ^' Qm_nImageData = getGray( s, size );
6 H" `" _& [2 s, H+ m- P
% n4 E5 S3 q* m$ f; |// No image data
0 @4 b5 o. b( `& ]. M% yif( m_nImageData == NULL )4 F9 L6 [4 p: a8 G% i
returnError( s, TGA_BAD_DATA );; Q6 o) t2 Q+ P: P) {. y
. o  {9 c- D5 f# S; ^; g2 J% U9 U
fclose( s );
* C$ z3 z# Z- m% h% J: |7 Q8 q% m
return TGA_NO_ERROR;: q/ g5 G$ K3 ?
}3 X5 d0 B4 r, ]6 g  Y, w3 `3 m

4 C" U% i& f9 W# n
( k, D' u( L! Q% h- d, G  Y调用举例:, W  w3 X: [% L& l6 m) {3 J
//3 s' w8 g7 b- S
// For the billboard poly, load a texture of a steel sphere. We'll use a
' s8 K/ y% p" X0 v) Z// .tga file for this image so we can use an alpha channel.
' \" K! j3 O4 a2 s7 o+ t//7 Z: q7 t- x( P

( [5 T7 t9 c3 r& ?5 D! d* a8 A9 DtgaImageFile tgaImage;& @+ L5 t$ u0 C7 Y2 r
tgaImage.load( "steel_sphere.tga" );
$ ?7 F% a9 ^* A7 r: x' \5 Z. |6 u7 w& L$ s' u* Q& F* V3 U  l3 l- O
glGenTextures( 1, &g_sphereTextureID );( r* r7 U* O  ]0 d5 `, p8 L7 e
7 Y) {2 }& x/ G( e) j
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );+ O& T+ B/ q% x) |  J* l, [
& B  r7 @& E  o! v' D/ V
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );5 x* d0 j( l0 i0 T1 b
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
% w' ~  g$ w4 e+ i! y6 o. w. C/ n  w
1 p: J) F7 V  D7 ?& Q7 _2 @5 {glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, 9 e$ [3 D4 n1 I1 P* E0 t: X5 o
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, ' ]/ ?# b5 |7 J# [
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, 0 ^0 D, [: H# H+ P, u
tgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-15 03:12 , Processed in 0.017590 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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