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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>( `% `- Q. `3 X) f! B
#include <stdlib.h>
+ E. Q& b8 e2 d0 B% L- `; V2 B% c#include <string.h>1 i' h: _8 u/ j% F' w$ l6 x
#include <windows.h>
" h' l# H& C+ A0 @0 D* v#include <GL/gl.h>
# h6 n8 U; N5 B6 T7 Y; ]' x& M7 u5 Z6 k% ?
class tgaImageFile* N* e# j7 H6 \$ Z7 E0 [, q
{+ I; L" U; W& s+ n
public:
0 o  C+ T+ D) q. N" q- t9 u+ J3 R1 ~$ ?* s; Z
tgaImageFile(void) : ( r; t/ h. G" L& g8 n+ R6 n" i
m_texFormat(-1),9 z0 V5 \3 z6 T) [2 f1 c
m_nImageWidth(0),
. @! r( N5 F# c, E: s/ Um_nImageHeight(0),' g; \+ P: V* ~0 ?
m_nImageBits(0),
9 A. ~  Q. w# |4 fm_nImageData(NULL) {}  ]; u1 Q2 Z& u% L

6 L4 w; j1 l8 V: V( F2 c9 Y~tgaImageFile(void);0 f0 A7 s3 J/ \% g9 [! {

. a. E+ r; f9 Z; ~/ e# A/ V4 _enum TGALoadError
! D% P7 k3 u: D0 m* n{2 g. N5 h" {+ F
TGA_NO_ERROR = 1, // No error! n  J4 w( o& I$ A: p  T
TGA_FILE_NOT_FOUND, // File was not found
, S( W' c/ F+ b2 D' u. wTGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
5 U/ Z  C7 H" q* u# ITGA_BAD_DIMENSION, // Dimension is not a power of 2
. p/ h" S7 g  tTGA_BAD_BITS, // Image bits is not 8, 24 or 32 2 J" w. j5 I5 n
TGA_BAD_DATA // Image data could not be loaded 5 H6 S! |0 Z5 `3 J
  };
7 k7 v; b7 K& S6 s5 G
) d% T5 b3 F$ }$ ntgaImageFile::TGALoadError load( char *name );
, z  k9 E  f' N* M- S
4 O4 g" b$ Y9 t0 x% mGLenum m_texFormat;* ?, A* g! ?) ?' {* _
int m_nImageWidth;
( \( j/ o. C- Gint m_nImageHeight;
1 i  `0 h3 y" {2 H) b6 yint m_nImageBits;
& X1 }+ B* u" v+ eunsigned char * m_nImageData;
  A2 |4 e; C- v( ]; \: a6 t9 O% D
private:7 }, R& K2 O- C( j

1 @4 b  w, `6 hbool checkSize(int x);0 \% z% `9 B" s( h; q
int returnError(FILE *s, int error);- f! [- i0 l. j7 I! \
unsigned char *getRGBA(FILE *s, int size);2 b! l5 b( f) ?$ G
unsigned char *getRGB(FILE *s, int size);
4 [/ y( S" N6 [- }# Eunsigned char *getGray(FILE *s, int size);2 ^$ @$ ?8 ?6 F  n
};5 p2 `4 j+ ~9 o% f2 f

7 L) s% z% T0 C9 x- U# s1 xtgaImageFile::~tgaImageFile( void )7 V  \! C1 B2 E; I7 x2 `
{* D* q/ q6 I0 ~+ J/ Q+ x4 m! Q
if( m_nImageData != NULL )4 G5 G6 M1 T+ Z1 J3 a: W
{
: `! s* m- O1 e4 ^& Rfree( m_nImageData );
7 m  R( P# t/ ], m' T, dm_nImageData = NULL;- p& s) Y' h  E6 L5 K) i5 A
}
/ T: s9 x# u: v/ ?  |( H# s7 v; f1 O}) K5 J: [( B9 |
$ l6 Y# c4 r3 l- R5 U" K( P6 C
bool tgaImageFile::checkSize( int x )
1 c) h- _; n/ v& k( ^# `& c{
" C& t: g: E0 H' R1 K// Make sure its a power of 2.4 N2 Z7 n* R; f9 \
if( x == 2   || x == 4 ||
8 E; Q6 a: T: Z/ N6 o( T) Xx == 8   || x == 16 || 3 I5 q3 J$ m; ]# T4 G6 u, h! P+ K# t
x == 32 || x == 64 ||$ n/ C* f+ d& D6 G$ V# Y# Y( _
x == 128 || x == 256 ||
6 t! i  E. b! J( R+ ?* D$ Mx == 512 )
1 r- ^# p$ w! ?7 X/ Sreturn true;
$ L1 g! c2 _: L" J0 L, h: V1 L) {2 D: u3 n9 a" ]
return false;
( I0 P. R* E5 J+ a}
  q5 o+ G" U* C% A) M8 n1 \0 @. O% Q6 D
int tgaImageFile::returnError( FILE *s, int error )8 _3 N2 G5 u9 m( |
{3 K, \$ o2 w" B3 A8 n" ~
// Called when there is an error loading the .tga texture file.
( u5 S1 [( R8 G1 r  Z7 `1 \8 Z9 }fclose( s );0 R2 Z  U+ f/ r: y  w
return error;( I7 [# @) t5 x" ~9 o, ?
}) o3 R/ f9 K4 j5 R) G6 \; k) z

- K+ {: f/ m, b/ s  p0 _unsigned char *tgaImageFile::getRGBA( FILE *s, int size )
6 `' _8 ]2 s' J' T/ J: U" N{" j0 U6 `" N4 h. i' k
// Read in RGBA data for a 32bit image. ' D6 ^: w! s! |% w: d
unsigned char *rgba;$ F& p& H9 S* ^# g' _  b, _
unsigned char temp;) Q1 N. Z' G! i; x# r9 R7 o. ^
int bread;
: m1 n9 l* V1 m" ~! vint i;8 T( p7 z5 r6 t

! C/ M- ]# z8 U3 m+ n# [; orgba = (unsigned char *)malloc( size * 4 );
0 L& P" r, w: j) s  a* M' Y- X5 o  u! v/ k3 X) z/ M. L& Y
if( rgba == NULL )
# m" v7 t  \8 h6 I& A5 h) mreturn 0;, a* P8 w2 s2 L3 Y
% E1 J- b7 j* Q+ V# C
bread = fread( rgba, sizeof (unsigned char), size * 4, s ); . A. V3 l+ @, Q0 r' e3 O7 q
, Y' n# q# _% \. E
// TGA is stored in BGRA, make it RGBA 0 T9 D6 Y5 u) v; Q" {
if( bread != size * 4 )7 y% A/ e0 q4 V
{. H7 D% f3 w/ F$ t0 x
free( rgba );
5 @7 e  L9 p% k2 L! Lreturn 0;
$ `0 e8 ~% l  r9 s( P+ J. x/ [}
3 s6 j5 u6 {; l; K3 ^
5 {( N. g, N& D8 {; Hfor( i = 0; i < size * 4; i += 4 )
. @, A4 H$ s: f" ?5 a7 _{
# K; O  R) n4 ~  N, atemp = rgba[i];  @( c( v: y+ K; _
rgba[i] = rgba[i + 2];: H2 d; W( x+ t4 Q6 S1 S
rgba[i + 2] = temp;8 W  w- y7 K3 [) Q9 N' z# e& P
}
% l- ?0 g/ |  q# F1 g" ~  ^0 e7 e% h6 v
m_texFormat = GL_RGBA;
7 e1 O, S2 L/ L3 wreturn rgba;
2 _5 l) c' D/ ^, F1 d  j& A}7 ~2 _, O: F$ [0 p

( z/ |, h* Q. ]/ N4 |& Runsigned char *tgaImageFile::getRGB( FILE *s, int size )& c7 N! {5 U+ w7 A- t
{
' N! T- U/ U8 G5 _1 i) `// Read in RGB data for a 24bit image.
2 `0 C" L0 K, tunsigned char *rgb;, ^: Z/ E7 y* U8 _: I9 _8 t* `
unsigned char temp;
. g6 b! a6 \6 f9 L& yint bread;8 _% A  p. Y# q/ I
int i;
* u4 l; _% o# w& R: ~
# N3 F2 f5 @0 A+ Frgb = (unsigned char*)malloc( size * 3 );* l. u! B1 }6 {" [  G9 u# r
& h1 _/ P9 L) C
if( rgb == NULL )9 d) T: ^9 j) Y; R
return 0;: r! G4 ^. x5 F' N

$ e) Z5 F. r# vbread = fread( rgb, sizeof (unsigned char), size * 3, s );
' T1 e% ~- o8 W* f# X6 L, G1 @0 e& n
if(bread != size * 3)6 e' D+ k/ V8 |: a2 `* T$ d# ~) z& J
{
* O7 j3 \% o1 r: ~* Hfree( rgb );
- m5 G0 N3 D7 H. y6 d* W! wreturn 0;1 p" C) J0 o( C& h2 G0 k
}
& |; G4 ^7 c" T
, g/ E( x5 G1 r! }// TGA is stored in BGR, make it RGB & W3 s9 X/ n% Y" k+ }
for( i = 0; i < size * 3; i += 3 )
) }( t7 q1 n6 _* p4 D{
% z1 J2 u% w+ b; S: X  Etemp = rgb[i];1 c8 G2 x' o# o3 V* A
rgb[i] = rgb[i + 2];! T& H  @1 v) j7 z* m1 I
rgb[i + 2] = temp;
; b! {4 z! y+ J0 N0 b}
- w" P' c9 o8 b8 ]2 R2 A
6 y& u/ Y3 ^9 N! {m_texFormat = GL_RGB;* n' I+ T' K* X( c& r& o

& M. I3 w5 d: G- H" y2 \return rgb;4 x! [5 I7 k" l1 N1 k* y1 M0 p* d
}3 @. J( F3 n3 h$ {0 k

0 U" e4 R: o, l9 g' |9 l  Kunsigned char *tgaImageFile::getGray( FILE *s, int size ): I, A$ ^: J+ _
{
9 T6 v. r  C/ L4 R' e, H" x$ N// Gets the grayscale image data. Used as an alpha channel.# i1 w9 D1 ~5 J) B( W
unsigned char *grayData;6 p. `" o# d: b( j3 H- z3 n+ ]7 L
int bread;! s- ]) o, Z4 J; G. l2 E2 `

" b3 v$ G9 q' dgrayData = (unsigned char*)malloc( size );* k/ [/ Z" S- i5 f6 o1 M
4 E4 D( a" A9 L5 [. q# E1 H* C
if( grayData == NULL )
8 `! H7 a* |4 ^4 S4 vreturn 0;
4 I) M8 E$ U+ x& P
5 p0 ?/ n$ @) g+ k$ Q4 F, ybread = fread( grayData, sizeof (unsigned char), size, s );+ F6 _; f1 C% a: _0 W+ V
7 ]) v/ `  e8 i8 C2 ]; l" w
if( bread != size )
. x; i% y+ j) g5 ~( x8 F{
8 Q% |: [! \* E4 I: n! e) cfree( grayData );+ @$ f0 P& d- T; Z2 @/ b
return 0;
/ I" A) ?3 z' m0 l% K  A, L}
" n8 p: O' _! R+ ?( u# H9 V) i; v. n% ]; G- E, o0 z
m_texFormat = GL_ALPHA;) i5 |6 F" t7 F: [7 G3 ~' j
2 A# s, i  Q! k' I- C" ~) D
return grayData;
! M% z6 R5 ^! |3 t, w+ J}
' T7 L. {$ o# |
' d7 V; @5 p# X0 htgaImageFile::TGALoadError tgaImageFile::load( char *name )3 y& {  V& M  w( p- |
{$ i4 z9 q* R3 b4 f
// Loads up a targa file. Supported types are 8, 24 and 32
  C% x+ x) t* e% Y2 U( X// uncompressed images.3 g1 G3 e! X+ V5 v" I, X' v! N
unsigned char type[4];
9 I, ~! I/ p& Iunsigned char info[7];! v! j( t+ Z/ }5 c9 Z3 t* [$ G
FILE *s = NULL;
# Q  o( b  j) O+ p# l; w9 F% r  Tint size = 0;
6 v4 P5 o5 {, K- s, j
( P% E8 \' p4 f% D: b/ Fif( !(s = fopen( name, "rb" )) )
- [3 _! k2 I, hreturn TGA_FILE_NOT_FOUND;
( T" a) q% D' D4 {. D/ N' [8 C6 I. d0 k$ U. U
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored% k& {# E1 a& J! J: x; d
fseek( s, 12, SEEK_SET);       // Seek past the header and useless info
3 D/ h: O# i5 t) l' Jfread( &info, sizeof (char), 6, s );! H9 p/ N0 r. i1 z1 }

, A! f7 u: z1 r: t  {! zif( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
# S* k7 w& U. h- ]2 ], s% q5 yreturnError( s, TGA_BAD_IMAGE_TYPE );4 R9 T& a! ~, u% M+ g
, C6 ]! s% d6 Q6 A6 U  n) y; \
m_nImageWidth = info[0] + info[1] * 256; 8 J4 Y7 S! v% S. `0 [6 T
m_nImageHeight = info[2] + info[3] * 256;
# B. D8 e- |  e! O" s% I- z! Um_nImageBits = info[4];
8 z5 a/ f$ w! B! I% H
# o* c2 ]' E% D9 ksize = m_nImageWidth * m_nImageHeight;
+ E, W2 L( N: x  a3 D- O, T
" x" g+ R9 b; r) j% m// Make sure dimension is a power of 2
! |6 A) P# Q( ~$ nif( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))
! {3 \. o8 g4 y! ~3 ]returnError( s, TGA_BAD_DIMENSION);
8 F6 o  H) Q$ e. S* a" j$ f
. O* I- S- \# b6 V! L// Make sure we are loading a supported type
1 t4 \- Z9 g8 u, A# ^if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
, y) ^7 u" z2 Y2 _- C1 LreturnError( s, TGA_BAD_BITS );
8 T4 y3 e4 `1 {6 a- ?' U! v7 W5 ~* W5 ~1 Z$ z
if( m_nImageBits == 32 )4 Y2 x5 _' N8 Y, ]
m_nImageData = getRGBA( s, size );6 v# X* u6 k& [2 ^$ ^
else if( m_nImageBits == 24 )
: y) s, w# y' R$ T( d" J) W) k+ D( zm_nImageData = getRGB( s, size );  
+ O7 s4 n- L* d3 p* M2 Relse if( m_nImageBits == 8 )# R' F5 E: k- `- ~: u& R
m_nImageData = getGray( s, size );
# e; E5 y# e0 v( _7 i: c7 M+ S9 A7 u  q! h: D2 y1 n) J! V/ l
// No image data
' W; m9 K( G( X8 Tif( m_nImageData == NULL )7 V7 ?! O/ N2 S9 J# S- c  ~2 s2 |
returnError( s, TGA_BAD_DATA );
! H1 K0 |5 {% K$ a1 s- c* i) |6 X0 J5 H1 T
fclose( s );
6 a: N7 o5 B# w- {$ P  {; L8 d9 h2 R1 r& \
return TGA_NO_ERROR;
+ M# S3 }7 s/ D7 N}
6 v/ l1 z) y4 X: k' b, L1 `4 c2 N; y

6 i, \# _9 @7 W+ Y  o+ R- C$ h调用举例:
/ W1 [" S3 P, h$ W/ C6 F3 j//% X. O3 n" Z3 [% X
// For the billboard poly, load a texture of a steel sphere. We'll use a
! R2 A+ w/ V( b' ]// .tga file for this image so we can use an alpha channel.) C' q+ @4 J9 s5 l5 J4 ~
//1 y  h# d0 i9 U  M+ r; y7 D
8 H& k( D! p% B
tgaImageFile tgaImage;
( F5 ~4 w7 C. WtgaImage.load( "steel_sphere.tga" );
6 |9 Y- t" @" v6 I% }2 o1 s- m2 w3 L: G1 k; u5 w8 V! z
glGenTextures( 1, &g_sphereTextureID );5 N, y! G2 A+ D# S

  l: G. B0 M/ L3 z' ?2 l3 IglBindTexture( GL_TEXTURE_2D, g_sphereTextureID );* M: c/ p, A+ N- D* w, x
" C5 N7 a$ W) E; f
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );2 ]! H: p  E' y% B5 v- l
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
% J9 z4 E- C! K, i$ y1 v; ^0 c3 p! [* x0 f3 m
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
2 E& `, M, ~8 T' `# ?. f3 Q: e4 ptgaImage.m_nImageWidth, tgaImage.m_nImageHeight,
+ {. X; `' A3 G' w6 |0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
. V( v4 q1 Z+ x+ F2 a; h' ]tgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 11:47 , Processed in 0.016407 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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