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

一个读tga格式的类

[复制链接]
发表于 2008-1-19 21:12:08 | 显示全部楼层 |阅读模式
#include <stdio.h>
  k3 d/ W* V5 q5 ^: K0 ]#include <stdlib.h>
+ C- D, g$ a) d2 h( {8 D#include <string.h>
$ f/ j/ ?. f8 I9 r- A#include <windows.h>
: z" H: q1 ~( N- j  M, }7 B#include <GL/gl.h>
, e+ N6 ?8 e+ a  f& C& x( g1 L! G0 O$ k' u3 l' u
class tgaImageFile. O2 v2 X, e; W
{
# Q9 s; G7 W1 `% rpublic:5 |/ Y8 g3 S! X) s) \; |

' p2 N9 [0 s6 ^2 VtgaImageFile(void) :
! G/ v! X3 R' P8 X* Z& i) x/ am_texFormat(-1),1 d# H; `" ^" X' w0 K9 @  _7 q
m_nImageWidth(0),
* N% T0 \9 |- h- X3 i# S  K; w6 Cm_nImageHeight(0),
. m- d, M7 ]0 s& g! qm_nImageBits(0),8 ^2 I9 X, F9 J) S6 ~  `
m_nImageData(NULL) {}
, M2 E5 Q0 S- @; g3 H( c1 f7 a8 i# |4 m+ p* I" N; N) a, r4 ^8 l
~tgaImageFile(void);
$ z6 p! p. ~5 T( F" V. ?
' z9 \' O$ m1 Q( s& v9 Genum TGALoadError
& N: ?' j1 r( [" M1 Z) U. F{! D% r% q$ S8 ?, ]
TGA_NO_ERROR = 1, // No error
$ M' E/ E: y% NTGA_FILE_NOT_FOUND, // File was not found ( Y. k% z5 Y: x' C* ?
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed. N& S; ?7 ~" y/ m. w/ |3 o9 Z! W
TGA_BAD_DIMENSION, // Dimension is not a power of 2 5 R; ?  I% Z: S" p' }
TGA_BAD_BITS, // Image bits is not 8, 24 or 32 8 U" i9 G1 k& z0 o" \! O, i( g) p
TGA_BAD_DATA // Image data could not be loaded 8 d& }; ]7 h! B" N  c
  };, |$ F( I. x* I5 U
& k# W% x+ D- y8 B  B# R
tgaImageFile::TGALoadError load( char *name );* i. ?4 b1 z- d7 g/ [6 R5 @! G
! a: z5 `: X% @! N
GLenum m_texFormat;
# }# l( q" P$ }% w0 ?9 oint m_nImageWidth;4 x% _4 U; ], \% x! X4 [
int m_nImageHeight;
. Q+ z3 G. H" }8 f  Bint m_nImageBits;
8 F' \$ A) O  j! U& X1 C2 tunsigned char * m_nImageData;% }; I/ F* o8 \( s( L# {

5 K: L) i1 K0 R8 [' Zprivate:
& p: p0 c8 I1 ]4 q5 Z# a1 o$ ~# q7 Z  a: `0 j9 }7 E$ Z# f3 a6 U' d
bool checkSize(int x);
# D) |) h. G+ c5 o* v5 ?int returnError(FILE *s, int error);
9 |# i" @1 i: N+ O  q6 Kunsigned char *getRGBA(FILE *s, int size);
5 A6 v* H5 o6 \+ Dunsigned char *getRGB(FILE *s, int size);
. v1 W$ ~9 F# {' \$ k$ F& T' I+ O! Runsigned char *getGray(FILE *s, int size);2 ]3 e8 ^( h3 u8 K8 m6 s% O3 b
};- g! W5 P7 G6 A3 y
6 o& H9 a4 J  B* j8 m0 ]: u
tgaImageFile::~tgaImageFile( void )
- w1 d) _6 R& R. H) R! U{4 q8 V( s# U: ]' q6 g' K6 s
if( m_nImageData != NULL )
) u9 W; Z3 a0 x7 N% q& E; d{
5 O0 n6 M( B) Ifree( m_nImageData );' c+ z9 ?) {* N) `: E3 m
m_nImageData = NULL;
& ^$ L. b* y1 t! h6 \2 X4 q9 n}1 f* c- I# k7 t" w
}
) G; w( P7 N/ R6 R0 |; T: q" B" N. E0 K$ K  c: S
bool tgaImageFile::checkSize( int x ), h" D& x( u! P
{/ I4 A3 s1 z" z3 |1 S& j- C; _
// Make sure its a power of 2.; P: ~% r: v: L7 T
if( x == 2   || x == 4 || % T" {# u: [& ~  H0 l2 y8 G& h
x == 8   || x == 16 || " j5 q4 w2 Y7 n' W% r+ U* x+ n
x == 32 || x == 64 ||
# F/ E9 }9 ~: @. W" [# }8 _+ ax == 128 || x == 256 ||
  F% `6 K: }- Sx == 512 )
; Q6 M8 {7 D* breturn true;" s6 Z2 D  k5 |/ l1 Q/ _: {# M

/ I: A8 w0 @2 |: V* creturn false;: f0 N  S% h- Z/ y" J% H
}
6 W' D" k& X) q' ^: u- p$ C, Y# ]$ s- u" {9 N5 f! K
int tgaImageFile::returnError( FILE *s, int error )
' N: \4 `: `8 l0 I{
+ c$ O4 i" M1 x; f+ l5 k7 `( H# a1 P// Called when there is an error loading the .tga texture file.
1 f3 B/ B3 ~0 p  k: p$ m! ^fclose( s );
) I2 q3 E( [, i) m3 R+ nreturn error;8 V; V/ U6 N# `  f+ h, ~* P
}
; I; Y( m; i: x- \% J+ W: w0 x+ B
unsigned char *tgaImageFile::getRGBA( FILE *s, int size )* y2 O/ @5 b% R  D, U! Y. P
{; }8 I: ]4 B: t8 l: G/ P. g' B$ k; R% `
// Read in RGBA data for a 32bit image.
* D2 Q- u4 w9 O! L% m$ tunsigned char *rgba;
8 D2 r/ g8 f) z: eunsigned char temp;  T$ S* Z! u) @; W0 v) ~: W  G
int bread;
& X( x. {5 U- o) I. s  }  Q1 Dint i;
9 t3 C* q! M% T5 c& d5 ^& \
, y% g) K& \, ~9 T0 Frgba = (unsigned char *)malloc( size * 4 );
2 a. ~2 K% L% s8 d( \
, h9 c5 M9 P% O+ L+ Oif( rgba == NULL )
& L5 ~5 o% _2 G+ Creturn 0;; _# ]5 x) w' d% w

' r  O0 b6 `2 A. G- ~bread = fread( rgba, sizeof (unsigned char), size * 4, s );
! ~- O1 U# y, F1 y1 k7 t' p
  l  P# C0 k6 P' t0 X* [& k! d3 N// TGA is stored in BGRA, make it RGBA
7 v. O5 ?: W+ W4 ]2 i% aif( bread != size * 4 )/ x+ ^4 p  S1 C9 F
{6 l5 \# S/ @1 R! S% S
free( rgba );& K5 k# U/ Z% X. a' l) z
return 0;
/ V9 A' k  z& o4 {4 G% ~}
5 ]& c0 I, {7 \- Z+ f6 B
2 Y9 j" }* {& l" X0 Ifor( i = 0; i < size * 4; i += 4 )/ k& L; Y" O0 Y4 Z( V1 D
{
% `0 C, ^0 L! ftemp = rgba[i];* s/ F# G- _2 T, n" O9 e
rgba[i] = rgba[i + 2];
, K9 a% u  @: O! d2 [2 g: [rgba[i + 2] = temp;% u9 L0 v" h+ i- G0 l3 O' t
}
. h+ K% o, P) p/ w' v. v  A* W$ u/ F. p/ f6 L# I% F, I% p+ r
m_texFormat = GL_RGBA;6 a* T& T$ X* p# u1 Y
return rgba;% G; V- q, F/ [
}2 X7 w1 N" P' x( L; ?! z

$ e& ~  d: O! ^1 B, ]3 E% b% \unsigned char *tgaImageFile::getRGB( FILE *s, int size )0 [2 K; Y8 h% Z0 z8 m
{$ N! \; H. @/ R- e: ]- E) D/ g' ?
// Read in RGB data for a 24bit image. ! t% ]  D# p( O, ~, e% }. W& _1 F! I
unsigned char *rgb;; C* }- w, _2 M6 w' W- u2 |
unsigned char temp;' s1 h! J# F/ p
int bread;0 g. _% d% z# @$ s1 Q
int i;& [4 y4 F5 L" c* J' S* P7 ]
6 k" u+ b/ Z9 ]: v# [
rgb = (unsigned char*)malloc( size * 3 );, |6 L1 _! [+ ]2 \0 _3 x: m

; k1 E; x& t) F$ c0 H6 x! Oif( rgb == NULL )) y. x8 M- w+ N8 Q& L5 Z  e  G4 I
return 0;: X" N7 t! x! I* N0 B
: W" c3 X# v4 n) j* k
bread = fread( rgb, sizeof (unsigned char), size * 3, s );
$ Q7 {( |/ m, Z4 r  g1 r- f0 l* A. ~* x3 b) _
if(bread != size * 3)- h  {; h: [8 g
{
, `; `& Q; p' C& ~" t; h. Ifree( rgb );
) g4 G1 N. P3 greturn 0;
9 [; i5 O- [4 N' {) o, g7 h" ~! W6 X}" r: C  H. w$ C5 p$ u

. [' a1 q8 V) ~9 F// TGA is stored in BGR, make it RGB
# f/ [+ U; a1 x- I* z& _* Ofor( i = 0; i < size * 3; i += 3 )9 V0 f# d4 K% p: r+ L* a6 s
{7 X7 j5 G2 w% ?; L1 W3 E/ G7 ~; Z
temp = rgb[i];7 k- l) D0 t% g; Q6 Q# l& {1 R
rgb[i] = rgb[i + 2];
& o$ \+ i7 |( S0 s( X! N, Vrgb[i + 2] = temp;: s, w3 q  i4 d- p. y
}
0 K, c+ P( {; ?# o7 I) O9 c7 r9 W# ?8 \" _! j& L% s: s
m_texFormat = GL_RGB;0 J' c- U6 D# Y2 N) t+ i% t

5 V( n! v7 L9 @& G+ C+ greturn rgb;
4 \9 ^7 f! b. z0 _  S6 i}) e: P, N. _& v9 ^9 M% o
3 E9 K9 x# x" o4 |
unsigned char *tgaImageFile::getGray( FILE *s, int size )
5 g6 ]" m( t0 Q$ k' `{3 x1 D" N1 l& S
// Gets the grayscale image data. Used as an alpha channel.- A# c0 V' s6 |% Y3 _6 Q% w+ _
unsigned char *grayData;
" H4 Q( R& O( ]0 xint bread;( ]& x5 A7 D; Z4 k. d; a2 ]

* F. M5 s( @- v4 J0 u3 G: e( W4 qgrayData = (unsigned char*)malloc( size );
/ w4 \  J5 C: G* ^5 n' `8 E3 A( ]$ Q( o
if( grayData == NULL )
3 y/ M$ `7 F9 e; Y$ }return 0;( M6 K5 Q0 d1 J: N; h

0 y. H+ r) e5 {; P; x( D9 Y# Y' [bread = fread( grayData, sizeof (unsigned char), size, s );  P! v' ]1 ?7 ]4 Y9 C

7 ]3 P8 _4 u$ S, j, cif( bread != size )& @2 K1 ~9 F4 h6 ^# W( D' R* W
{& O! A4 W$ s! z6 V) Z7 a( h. W' g3 o
free( grayData );
1 n  O3 e: q% B! e4 ?return 0;
3 t( t$ O, |$ S. }4 R}5 n1 C9 X9 t. q6 ?5 F
: c1 u$ ?9 Z& w$ ~& Z; W
m_texFormat = GL_ALPHA;
" E, U6 R5 h/ h1 Z
# O0 d" i5 R9 z/ i) c" F$ qreturn grayData;6 u6 M4 }- ?1 U2 e/ T
}
$ G6 Y& y1 i3 m. ~3 _8 E( Q8 @2 u& N: \4 D* w3 d
tgaImageFile::TGALoadError tgaImageFile::load( char *name )
4 c1 Y+ @: n% o4 W{8 z( y' x0 ^" t
// Loads up a targa file. Supported types are 8, 24 and 32 7 V! M+ [' A: O- Q7 Z- _. `6 O% g
// uncompressed images.! H3 k7 K" d5 _8 C1 `6 w
unsigned char type[4];4 E- m: v# q- c. q# A/ S8 l9 h
unsigned char info[7];
  Y, S. _- E$ xFILE *s = NULL;
5 A  \* X  \2 X% I/ w2 k7 K' L+ x, hint size = 0;
9 R# x( z. J) \4 O% S9 X! r" Y/ G: a9 r6 R6 ]
if( !(s = fopen( name, "rb" )) )
% G# h% M) f9 C! R$ M  l" ireturn TGA_FILE_NOT_FOUND;
) @, B! e3 i- k& S2 E. G) ]& v( e* F" g3 G2 H
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
- S9 v! ^! Q+ X* V  Pfseek( s, 12, SEEK_SET);       // Seek past the header and useless info3 X- K* L; ^" A3 L$ T- ]
fread( &info, sizeof (char), 6, s );( u7 [$ t/ \4 f+ W- W$ A, P6 |& t+ J
3 l3 d) ~* k# k
if( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
' T9 i3 v3 B8 r) N8 v7 v1 y3 ]returnError( s, TGA_BAD_IMAGE_TYPE );9 q- |7 ^* B: i; \8 k
6 w1 {2 v$ H. L9 t8 W
m_nImageWidth = info[0] + info[1] * 256;
5 r7 C, Y$ }5 Q7 Q" B: hm_nImageHeight = info[2] + info[3] * 256;& e' r% d; ?1 g* `; D. z: U" L( [
m_nImageBits = info[4];
, D1 B7 ?6 Y0 a  M  V) H2 P& a. H; W: ^
- o' z! B/ }- l+ }' J; H, ^6 l7 y- fsize = m_nImageWidth * m_nImageHeight;
3 j( t/ V% B4 l; B/ u- p7 c0 e  V1 K! A0 R- h
// Make sure dimension is a power of 2 4 y7 s  ]9 M# J- z2 t
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight))
! q  w' g. \$ rreturnError( s, TGA_BAD_DIMENSION);" Q- ^1 k/ v$ P# o
4 i3 n) D. ^3 v: t! O) o5 i) Z8 N
// Make sure we are loading a supported type
, A# B9 Z6 Z6 w) U. C; Q8 j& Yif( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )+ k3 j# l% X1 l, R
returnError( s, TGA_BAD_BITS );8 I; x* p7 c: g: g
7 M) L* O. B4 Q' X
if( m_nImageBits == 32 )
! r9 `4 ~2 |' ]; ^+ sm_nImageData = getRGBA( s, size );
& q5 Q  x" w4 a9 o7 M8 celse if( m_nImageBits == 24 )/ d7 `8 v" Q6 L, M; I* @- U0 k: b; z
m_nImageData = getRGB( s, size );  4 \- X3 a2 @% [* l6 H: U
else if( m_nImageBits == 8 )" H1 f( d$ B" o; T3 r! z
m_nImageData = getGray( s, size );
$ q" F& e* k3 D% X8 _
( z8 N. Y' F3 A0 B* j// No image data - a1 D" y  G9 N" g( W+ J( V; u
if( m_nImageData == NULL )& h7 s* r) ]* {+ s  S, R
returnError( s, TGA_BAD_DATA );
, @* F1 ^2 I1 `$ H: z( o6 ?
3 ]" f7 c; P  {fclose( s );
. R1 @' }4 H+ I" }/ g/ z2 k  X4 L5 g9 v0 k% W! Z
return TGA_NO_ERROR;# T4 E0 @; r, M7 T, L% G
}+ t" Y& P- j- @; C7 b( W
* L8 ?! X+ U) q! u1 ^- W! j8 Y! E
5 k+ _+ f  d( ?. N
调用举例:
9 _  B& v- Z7 z; D) O) d: t//
' B7 T8 c3 Y& j. U// For the billboard poly, load a texture of a steel sphere. We'll use a 7 K( R5 n5 N! |8 Z: [+ h
// .tga file for this image so we can use an alpha channel.3 P# A! M, N0 A" R
//  D: N( ?. r( o7 r

! m- X0 C* r3 {tgaImageFile tgaImage;
: n6 m1 M3 H7 Y8 Q4 W7 FtgaImage.load( "steel_sphere.tga" );) L0 X) w4 ?- g
* r7 d. P5 p: ]/ r; {
glGenTextures( 1, &g_sphereTextureID );2 w5 u0 A2 [+ g" i( }: w( ?1 I
4 U& D6 y5 O4 e5 ]0 p, v' B8 }5 u
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
* d. X& `0 B, i: m9 d  u. i
  B6 x# N3 w: R4 o$ k8 F( e% Q6 bglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
* m2 \1 u. ^# r3 b, rglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
5 i5 @) u" R* L( B8 t) r3 P' J0 m1 D) h
glTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat, 5 U' A9 \; r* i: \* e7 T6 |0 b
tgaImage.m_nImageWidth, tgaImage.m_nImageHeight, 2 p0 l: j: `: t3 M. [, `
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE,
% W3 g& P5 h% h7 |$ ztgaImage.m_nImageData );[/i][/i][/i][/i]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 10:18 , Processed in 0.020490 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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