|
|
#include <stdio.h>( b4 o9 j3 ]7 V) T7 [9 |
#include <stdlib.h>
* ~8 h1 `+ ^# _+ i7 z4 p#include <string.h># b6 @8 _4 M4 R" x5 s( V/ Z4 I3 K, h
#include <windows.h>
3 ~' f) u0 V% v# n#include <GL/gl.h># y9 q, t0 o- X
& u" o! Y4 o; H1 ]' {+ {" z
class tgaImageFile* {9 N: M; o1 u
{) }% r f& W' x' U) Z" p
public:8 ?- \( C d9 \0 j& c8 \) X, `! L
* F$ C! w) c e7 U
tgaImageFile(void) : 9 _/ b3 _0 A0 y: B. G! ]9 q
m_texFormat(-1),
5 {+ N8 }7 o) A: `+ a! U* r5 m8 pm_nImageWidth(0),. A6 f# r! c! _% ]4 e9 ^
m_nImageHeight(0),- F. ~' s0 T9 `) z
m_nImageBits(0),
$ W+ X. R' M1 V9 K2 ]m_nImageData(NULL) {}8 O# m2 j6 M9 k" n
c' m5 n5 t" M, X
~tgaImageFile(void);3 ^& `, i8 X* V5 e8 y( o
' j# e5 }: b' C6 q, z* G
enum TGALoadError1 R' q, A5 d/ x* n
{7 S. B, T6 @0 E& q3 }: Q) d
TGA_NO_ERROR = 1, // No error0 X& b% k& F3 b; P6 e7 M3 Y1 z
TGA_FILE_NOT_FOUND, // File was not found - \' e# ^/ Q# L3 `6 _# Y% A9 C. A
TGA_BAD_IMAGE_TYPE, // Color mapped image or image is not uncompressed
3 K4 w$ S# C( Q' {# F/ YTGA_BAD_DIMENSION, // Dimension is not a power of 2
. q8 s: Z6 X7 @! M. R# _! xTGA_BAD_BITS, // Image bits is not 8, 24 or 32
3 v( y1 _5 \5 u" {, dTGA_BAD_DATA // Image data could not be loaded
+ \7 Y j; y" q% T0 K3 z4 f$ |9 H( h };
, C: \) z3 I# v: v" |
$ B$ N) a2 U: x% j& P3 t1 C! wtgaImageFile::TGALoadError load( char *name );0 h0 q- F1 a5 }! Z& B
, Z. F. s+ Z" d, U; ]) E; A
GLenum m_texFormat;* c$ ^8 O9 C0 {) B. P
int m_nImageWidth;
# [" ?1 U' L5 A7 e1 `) G" E3 ?int m_nImageHeight;
5 S8 {+ L8 Q( ]# l8 q1 x& {4 Vint m_nImageBits;
+ i1 y' R* v. {! r6 c- x" Nunsigned char * m_nImageData;
, m: j+ @2 W% t8 A, B
6 ^2 \1 F, F9 h9 R7 w( Sprivate:
8 r" H$ z9 r$ W7 b r0 {; {4 p3 F. r0 T) s( y( i9 q5 A* R r
bool checkSize(int x);
2 ?3 C& Z+ c1 Sint returnError(FILE *s, int error); R5 }: T; K" d7 z: \, C# ?4 F
unsigned char *getRGBA(FILE *s, int size);6 J7 q3 G4 P: ^7 c1 |# c( M/ P
unsigned char *getRGB(FILE *s, int size);
/ g* `+ z* o' c/ l# u/ \unsigned char *getGray(FILE *s, int size);( a# d* K3 a+ J+ [- a
};( U5 q1 O$ b6 {7 o
+ T5 A; q# E) T# C5 I7 B& {
tgaImageFile::~tgaImageFile( void )
7 d* w0 V' n. f7 f" ?/ F7 x' n{
) W1 C8 m* W7 O. T1 ?' [1 l8 Pif( m_nImageData != NULL )
6 h" U# H3 ]& J1 q, p; y3 K9 l{
4 }" }/ |1 Q# f3 J( S2 M# k* Qfree( m_nImageData );2 v! n, d) |- P) S: [
m_nImageData = NULL;1 r# X2 S8 A( h% c4 p
}, k4 `+ E: b; f+ b; ^8 l! s! i
}2 R% w* m* {. Z4 R$ w
1 ]% n2 j8 k! _8 N# ubool tgaImageFile::checkSize( int x )
& g% M, U+ d$ N% g% u1 q6 G" b{
6 ]7 h3 U2 n2 h8 H6 ~; W4 m! T// Make sure its a power of 2.
; ^. U! C8 @( @: Y' t* Wif( x == 2 || x == 4 ||
+ d9 D& p% v( o$ }6 `x == 8 || x == 16 || / p/ P: G5 U" Z3 ^1 O9 X" `
x == 32 || x == 64 ||
! n2 v( n: M( Y7 j: Kx == 128 || x == 256 ||
5 b0 O8 W( B, k7 ^ rx == 512 )
3 x- X* d% s5 freturn true;( q1 d) Z' h3 w5 G# k9 w
3 i1 O+ C; L8 X0 c& w; {return false;
. b2 [& r2 T6 K# U}1 u9 \) ?. [8 w% T# O/ w
# j3 O% g6 U+ ?6 X0 \
int tgaImageFile::returnError( FILE *s, int error ); |' L+ j# M& E' [# L. W# C. s
{6 r1 U0 Q9 S: U c' m' ]
// Called when there is an error loading the .tga texture file.
' }& V8 n1 w* I# F. l# Ufclose( s );
( U( C# ?" b1 C/ t5 @return error;
# W# D3 ^+ _- {3 v}
( [) }, q8 ~9 s
z- h) d* r! c' ?: \" p% qunsigned char *tgaImageFile::getRGBA( FILE *s, int size )
1 ?* d9 } L e& K/ X( D: b {3 d{
2 L" |0 e8 q9 N// Read in RGBA data for a 32bit image.
% C0 ^) z% E. m, J3 P/ yunsigned char *rgba;/ e) A. x7 X& G0 i, j6 U0 c
unsigned char temp;. W/ `3 R* w% r9 O
int bread;
/ U# h) @. x% O' Q; |# [+ y; r) r/ rint i;
, T! X' w( y1 {3 O% J5 k9 I; u0 D* ~3 X: I O8 s4 U' `: {5 x
rgba = (unsigned char *)malloc( size * 4 );
0 N, c6 q# D9 ]) a8 p* R8 p, [
5 @) q0 N0 I6 K1 {+ F7 Uif( rgba == NULL )5 G* {# ^8 Q6 r9 ]( z8 u3 h7 h6 r& @
return 0;
2 q1 B c& G! Q# \: n% g! y# n& c6 |' K: V* [7 T& u |9 @. d
bread = fread( rgba, sizeof (unsigned char), size * 4, s );
" u2 v4 y$ J, Z, G2 ~
3 m- F: L& c+ I! E// TGA is stored in BGRA, make it RGBA 9 x2 V. j- K9 C. a6 Z# ~
if( bread != size * 4 )
5 W4 k7 s+ m8 g7 Q0 G& W0 v{
) U( s) V6 h) L. i/ E2 H$ cfree( rgba );
4 E5 w2 A G+ Y$ c% N0 vreturn 0;
) a) W5 s1 P' n- ^) |: M- n}2 f; V' t7 n, `9 S N
& z8 S9 D* f( O' _# afor( i = 0; i < size * 4; i += 4 )( K9 p7 n7 B* Q" v
{
3 Q1 T( G i; X; S9 |1 K7 `temp = rgba[i];
5 f$ W" Y! a, T2 {0 drgba[i] = rgba[i + 2];+ B- T/ ?" J5 H R5 b
rgba[i + 2] = temp;: U$ Q0 E% x) |" \
}
0 w9 d/ T0 ~9 q: _( \
' `1 @( ^7 a2 Mm_texFormat = GL_RGBA;3 k# D5 I) k( E ~, N& F g
return rgba;
% u6 C1 e3 R: H4 [}
9 Y2 m E* g9 E6 W
, y: g) c7 R9 Uunsigned char *tgaImageFile::getRGB( FILE *s, int size )# o: n, M+ ?; {( c Y7 U# A- S5 @
{
! B# p& Z/ r. d1 G) k% h# U6 D// Read in RGB data for a 24bit image.
4 M( \& \% `0 y7 ]( Qunsigned char *rgb;- F3 `. e. p8 L! d
unsigned char temp;
% r' T) y2 J* F6 }5 pint bread;6 p$ \8 R7 Q1 u6 {8 c( O
int i;
: h, F5 ~: x+ ?; x2 R: E# ]. N" O0 c" `% E7 c$ S1 o0 ~ ^
rgb = (unsigned char*)malloc( size * 3 );
( w4 I: j2 b3 ^' ^
1 u% H0 E2 {3 u! b; r# W7 q8 r" ^if( rgb == NULL )6 [! C6 N" z( p
return 0;* K8 b8 O+ G& t+ p' K3 W
) j" x' F6 b) M6 _/ A9 Y
bread = fread( rgb, sizeof (unsigned char), size * 3, s );
5 u3 A I& j. z/ o, `5 Y9 j; z' V8 s; T& D p. n% E
if(bread != size * 3)
. ^, e5 \$ |, I0 R* K9 B, F{
( k" X R5 P" x1 kfree( rgb );
. _' T* r& W; j+ Areturn 0;3 D2 Z1 Y& e( Y
}% F7 Y! i. f, W5 _: o
C! T, ~+ @' W+ S' [: z# S// TGA is stored in BGR, make it RGB
6 ^( H5 {0 I+ { P% s! G) T' ~for( i = 0; i < size * 3; i += 3 )+ a, z- F O- k/ w
{, ^+ f9 L1 _/ r9 X; `$ k
temp = rgb[i];4 b& j! a+ D) }6 f$ S; W
rgb[i] = rgb[i + 2];9 g2 [6 ]1 r3 R0 c- ?( g& C
rgb[i + 2] = temp;% s( _* m W/ \, X
}
% J' a) M `6 l$ z3 H" f. M! m
( g/ g* [$ j5 g% dm_texFormat = GL_RGB;7 u1 C8 Y0 t- z6 X7 o
: N" Z- `- G( w, N. u/ treturn rgb;
8 k, M( S% c7 ] U. |5 }. S}
_1 L$ a8 Y+ d4 k
6 M; y$ o$ F I" I7 kunsigned char *tgaImageFile::getGray( FILE *s, int size )& H ~0 `3 z2 p+ k4 p
{
% I" |5 [ `6 e// Gets the grayscale image data. Used as an alpha channel.( H, Y3 v! |1 p4 U
unsigned char *grayData;9 D: a/ r8 U$ N! U t! a
int bread;4 W4 [( q- @ w. _1 h% h8 W6 e% J% \% q
: c8 R* }" h) x# _$ c, z# T
grayData = (unsigned char*)malloc( size );, z( M, x8 C# C
L4 o* a, L% @0 x0 A; mif( grayData == NULL )
, {. `5 i* f9 _5 greturn 0;! A% b/ u0 ~: ^# Z [2 K
: o* l/ ~1 r- D/ D' z2 L$ X& Z6 N% }
bread = fread( grayData, sizeof (unsigned char), size, s );
, B+ t& ^" S; B. ^
/ p: P3 c7 k4 g! {if( bread != size ), F( P: f/ e0 D% W7 T/ u
{. [. g" ?' V, b: \. j* r
free( grayData );6 u- }4 F" q$ [; f, t2 J
return 0;
6 [) B$ C6 a; k}
- K" }% w, W, |& ~: L
: o9 t" U' c+ f& R' \m_texFormat = GL_ALPHA;+ E( [& ~" Z! [9 K
- }+ D3 b! k8 n' ?8 hreturn grayData;
d* {* ]+ D% x3 |$ H5 ?}! c5 }$ m/ `8 N% E" L4 ]
. K. s' \0 L7 JtgaImageFile::TGALoadError tgaImageFile::load( char *name )+ R- ^! k( F1 ?( e
{; x9 p/ N0 Y. ]7 @' W- [
// Loads up a targa file. Supported types are 8, 24 and 32
3 o4 p8 y. e! z2 s8 k6 h* C// uncompressed images.
6 N! p: k$ e4 Iunsigned char type[4];3 C# b: B( D+ L2 P* J6 y
unsigned char info[7];
: |( r, `$ Y2 [! uFILE *s = NULL;0 u+ }' C* a m# c" E) @7 N8 y% @
int size = 0;# @! v5 b$ P3 G9 V; [3 E! ?+ ^
0 I Q$ |! M. h' ]
if( !(s = fopen( name, "rb" )) )9 w. r: m4 S: @0 n2 N& a8 s+ D9 ]/ ~
return TGA_FILE_NOT_FOUND;- P, P8 _4 S" v3 V$ Y
Q4 H& o) G+ p0 C
fread( &type, sizeof (char), 3, s ); // Read in colormap info and image type, byte 0 ignored
/ d6 \7 o; u* G" {# Rfseek( s, 12, SEEK_SET); // Seek past the header and useless info9 J6 u5 \$ w# j/ z: i
fread( &info, sizeof (char), 6, s );, p$ z) F' L: P6 _) E
! E/ m/ P5 Q3 Wif( type[1] != 0 || (type[2] != 2 && type[2] != 3) )
+ q6 U! C; _" C. areturnError( s, TGA_BAD_IMAGE_TYPE );
: X6 j! {/ x, D! ~ j5 }
U& P" b8 T' cm_nImageWidth = info[0] + info[1] * 256; k& }3 F+ L1 h2 U
m_nImageHeight = info[2] + info[3] * 256;
! T5 S' v9 m- S( T Wm_nImageBits = info[4];
9 O7 ?' v6 T3 g" c- c- Z: r2 V0 ?& i
size = m_nImageWidth * m_nImageHeight;
2 A7 f6 T: _$ g, z" S# C( ]/ e" C
// Make sure dimension is a power of 2 ; q4 I/ b b# W5 V" ]
if( !checkSize(m_nImageWidth) || !checkSize(m_nImageHeight)): v0 w+ d" P4 b# E+ e
returnError( s, TGA_BAD_DIMENSION);
' U( f3 E* k( @6 l
) G3 S4 N# Q7 o// Make sure we are loading a supported type % I/ G) `! d' r4 E
if( m_nImageBits != 32 && m_nImageBits != 24 && m_nImageBits != 8 )
3 V. [/ k7 H, f$ ~8 P5 Q8 S: l" VreturnError( s, TGA_BAD_BITS );8 }; q( y7 y5 y
+ r% {4 R& e$ u4 ]# oif( m_nImageBits == 32 )' g! a: K( s. Y; {) m P6 A0 \; n
m_nImageData = getRGBA( s, size );" \ r2 b) u+ e
else if( m_nImageBits == 24 )5 f1 |+ F- Q/ Z k
m_nImageData = getRGB( s, size );
& z8 s% E( g# z- p- ?, ?else if( m_nImageBits == 8 )
7 U) p& h- e K5 |m_nImageData = getGray( s, size );
- t; a/ G" c5 T6 A$ k3 R7 d2 l
; ^ A5 ?! w$ D6 M// No image data % A" x0 m* F3 x1 ]9 f
if( m_nImageData == NULL ): i6 F" t, G! l" U. q0 L
returnError( s, TGA_BAD_DATA );- n, H: F1 }* B
0 v9 C* ~" u3 y3 M3 {, Vfclose( s );* Q# `- {6 U8 W+ E9 F# Y% ]
7 H' i9 i' g5 i# t3 c0 qreturn TGA_NO_ERROR;
! i8 v$ @+ C8 Q}* y0 S# J0 V, {; h6 l g
) \1 b. ?: \) g2 d) c* W1 f9 \8 g- [! V' f
调用举例:
* P3 i, ]9 c! u3 S, I//
; X. c. z6 e# b2 | X, c$ ~0 {5 `8 ^// For the billboard poly, load a texture of a steel sphere. We'll use a % N) C! F% |& Y' @5 G6 e' N
// .tga file for this image so we can use an alpha channel.
5 J3 Y2 U7 y5 X" b; e//5 R9 a |& _; g1 r/ l
/ N# i1 j- y S/ b0 Z
tgaImageFile tgaImage;. P z; L t0 ?) e
tgaImage.load( "steel_sphere.tga" );
- ?6 }& ? Z+ C) i& a F6 K0 w: E* Y0 k: z# l
glGenTextures( 1, &g_sphereTextureID );
2 }9 e' T. K$ T2 K1 Y* {) f6 w3 ~: n1 S. S3 N
glBindTexture( GL_TEXTURE_2D, g_sphereTextureID );
& V/ P& f9 u+ p6 e: K8 a9 c
3 I( C- i5 c& X0 `glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
( t2 y( i1 U5 ~+ A4 {- yglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- |! _7 c, ~: K
}; ^, V& Q& [( jglTexImage2D( GL_TEXTURE_2D, 0, tgaImage.m_texFormat,
1 P8 N& H. v; K" Y( Q& ytgaImage.m_nImageWidth, tgaImage.m_nImageHeight, 2 \* Z% W, a7 @5 {# i$ W1 U
0, tgaImage.m_texFormat, GL_UNSIGNED_BYTE, * _$ S. E+ ]: r; c
tgaImage.m_nImageData );[/i][/i][/i][/i] |
|