全部博文(135)
2010年(135)
分类: LINUX
2010-07-15 16:09:26
1 //我已经写了一个非常简单的类来封装PVRTC,包括读取文件,分析格式,定义成OpenGL ES纹理等。如下:
2 // @ Project : PVRTC Example
3 // @ File Name : texturepvr.cpp
4 // @ Date : 2007-8-30
5 // @ Author : kongfu.yang
6 // @ Company :
7 // @ Copyright : 2007-8, Example source license. By keep this header comment,
you may use this source file in your project for non-commicial or commicial purpose.
8
9 #include "main.h"
10 #include "PVRTexture.h"
11
12 EGLWrapper * egl;
13 PVRTexture * g_tex = 0;
14
15 bool g_wireframe;
16 GLfixed g_rx, g_ry;
17 GLfixed zoom = Float2Fixed(1.0);
18
19 #define TEXTURE_COUNT 9
20 char * fileNames[TEXTURE_COUNT] = {
21 "yuquan4.pvr", "yuquan4mip.pvr", "yuquan4a.pvr", "yuquan4amip.pvr",
22 "yuquan4gl.pvr", "yuquan4mipgl.pvr", "yuquan4agl.pvr", "yuquan4amipgl.pvr",
23 "yuquan4mip_intel.pvr"
24 };
25
26 #define MAX_TEX_MODE 5
27 int modeIdx = 0;
28 GLfixed texModes[MAX_TEX_MODE] = {
29 GL_REPLACE, GL_MODULATE, GL_DECAL, GL_BLEND, GL_ADD
30 };
31 LPTSTR texModeNames[MAX_TEX_MODE] = {
32 L"GL_REPLACE", L"GL_MODULATE", L"GL_DECAL", L"GL_BLEND", L"GL_ADD"
33 };
34
35 void nextMode(void)
36 {
37 if ( ++modeIdx >= MAX_TEX_MODE ) modeIdx = 0;
38 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texModes[modeIdx]);
39 }
40
41 void nextTexture(void)
42 {
43 static int idx = 3;
44 if ( g_tex != 0 ) delete g_tex;
45 g_tex = new PVRTexture(fileNames[idx++]);
46 g_tex->upload();
47
48 if ( idx >= TEXTURE_COUNT ) idx = 0;
49
50 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
51 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
52 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
53 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
54
55 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texModes[modeIdx]);
56 }
57
58 void init(HWND hWnd, EGLWrapper *g_egl)
59 {
60 egl = g_egl;
61 egl->init(hWnd, 16, true);
62
63 glDisable(GL_LIGHTING);
64
65 glEnable(GL_TEXTURE_2D);
66 glEnable(GL_BLEND);
67
68 nextTexture();
69
70 glClearColorx(0, 0, Float2Fixed(1.0f), Float2Fixed(0.5f));
71 glColor4x(Float2Fixed(1.0f), 0, 0, Float2Fixed(0.5f));
72 }
73
74 GLfixed rect[] = { Float2Fixed(-1.0f), Float2Fixed(-1.0f),0,
75 Float2Fixed(1.0f), Float2Fixed(-1.0f), 0,
76 Float2Fixed(1.0f), Float2Fixed(1.0f), 0,
77
78 Float2Fixed(-1.0f), Float2Fixed(-1.0f),0,
79 Float2Fixed(1.0f), Float2Fixed(1.0f), 0,
80 Float2Fixed(-1.0f), Float2Fixed(1.0f) , 0
81 };
82 GLfixed rnormal[] = {
83 0, Float2Fixed(1.0f), 0,
84 0, Float2Fixed(1.0f), 0,
85 0, Float2Fixed(1.0f), 0,
86
87 0, Float2Fixed(1.0f), 0,
88 0, Float2Fixed(1.0f), 0,
89 0, Float2Fixed(1.0f), 0 };
90 GLfixed rectuv[] = {
91 Float2Fixed(0.0f), Float2Fixed(0.0f),
92 Float2Fixed(1.0f), Float2Fixed(0.0f),
93 Float2Fixed(1.0f), Float2Fixed(1.0f),
94
95 Float2Fixed(0.0f), Float2Fixed(0.0f),
96 Float2Fixed(1.0f), Float2Fixed(1.0f),
97 Float2Fixed(0.0f), Float2Fixed(1.0f)
98 };
99
100 void testPVRTC()
101 {
102 //glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 128, 128 , 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, embTex);
103 glEnableClientState( GL_VERTEX_ARRAY );
104 //glEnableClientState( GL_NORMAL_ARRAY );
105 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
106 glVertexPointer( 3, GL_FIXED, 0, rect );
107 //glNormalPointer( GL_FIXED, 0, rnormal);
108 glTexCoordPointer( 2, GL_FIXED, 0, rectuv );
109
110 glActiveTexture( g_tex->id );
111 glDrawArrays( GL_TRIANGLES, 0, 6);
112 }
113
114 void draw(HWND hWnd, HDC hdc)
115 {
116 if ( ! egl->isInitialized() ) return;
117
118 if ( egl->makeCurrent() )
119 {
120 glEnable(GL_DEPTH_TEST);
121 glDepthFunc(GL_LEQUAL);
122
123 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
124 glPushMatrix();
125
126 //glRotatex( g_rx, Float2Fixed(1.0f), 0, 0 );
127 //glRotatex( g_ry, 0, Float2Fixed(1.0f), 0 );
128
129 glScalex( zoom, zoom, Float2Fixed(1.0f) );
130
131 // draw here
132 testPVRTC();
133
134 glPopMatrix();
135 egl->swapBuffers();
136 }
137
138 reportError();
139 }
140
141 bool msgHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
142 {
143 TCHAR wbuf[1024];
144
145 switch (message)
146 {
147 case WM_CHAR:
148 switch(wParam){
149 case 'f':
150 case 'F':
151 g_wireframe = ! g_wireframe;
152 InvalidateRect(hWnd, 0, false);
153 break;
154 case 't':
155 nextTexture();
156 ZeroMemory( wbuf, 1024 );
157 MultiByteToWideChar(CP_ACP, 0, g_tex->fileName, strlen(g_tex->fileName), wbuf, 1024);
158 SetWindowText(hWnd, wbuf);
159 InvalidateRect(hWnd, 0, false);
160 break;
161 case 'm':
162 nextMode();
163 SetWindowText(hWnd, texModeNames[modeIdx]);
164 InvalidateRect(hWnd, 0, false);
165 break;
166 case '+':
167 // zoom in to exam mipmap
168 zoom += Float2Fixed(0.1);
169 InvalidateRect(hWnd, 0, false);
170 break;
171 case '-':
172 // zoom out to exam mipmap
173 zoom -= Float2Fixed(0.1);
174 InvalidateRect(hWnd, 0, false);
175 break;
176 default:
177 ;
178 }
179 break;
180 case WM_KEYDOWN:
181 switch(wParam)
182 {
183 case VK_UP:
184 g_rx = Float2Fixed(Fixed2Float(g_rx) + 10.0f);
185 InvalidateRect( hWnd, 0, false );
186 break;
187 case VK_DOWN:
188 g_rx = Float2Fixed(Fixed2Float(g_rx) - 10.0f);
189 InvalidateRect( hWnd, 0, false );
190 break;
191 case VK_LEFT:
192 g_ry = Float2Fixed(Fixed2Float(g_ry) + 10.0f);
193 InvalidateRect( hWnd, 0, false );
194 break;
195 case VK_RIGHT:
196 g_ry = Float2Fixed(Fixed2Float(g_ry) - 10.0f);
197 InvalidateRect( hWnd, 0, false );
198 break;
199 default:
200 ;
201 }
202 break;
203 default:
204 ;
205 }
206
207 return false;
208 }
1 //文件格式相关的结构和常量在一个单独的文件里:
2 // @ Project : PVRTC Wrapper
3 // @ File Name : PVRTexture.h
4 // @ Date : 2007-8-30
5 // @ Author : kongfu.yang
6 // @ Company :
7 // @ Copyright : 2007-8, Example source license.
By keep this header comment, you may use this source file in your project for non-commicial or commicial purpose.
8
9 #ifndef PVR_TEXTURE_H
10 #define PVR_TEXTURE_H
11
12 #include "gles/gl.h"
13 #include "gles/glext.h"
14 #include "string.h"
15 #include "PVRTCFile.h"
16
17 extern void reportError(void);
18
19 class PVRTexture
20 {
21 public:
22 PVRTexture(char * fname){ fileName = _strdup(fname); id=0; data=0; size=0; }
23 ~PVRTexture(){ free(fileName); if ( data != 0 ) free(data); }
24
25 public:
26 char * fileName;
27 unsigned int id;
28
29 void upload(void)
30 {
31 load();
32 glGenTextures(1, &id);
33 glBindTexture(GL_TEXTURE_2D, id);
34 glCompressedTexImage2D(GL_TEXTURE_2D, levels, format, width, height, 0, size, data);
35 reportError();
36 }
37
38 protected:
39 int format; // .pvr format map to gles format
40 int width;
41 int height;
42 int levels; // mipmap levels
43
44 long size;
45 unsigned char * data;
46
47 void load(void)
48 {
49 FILE *fp = fopen(fileName, "rb");
50 PVR_Header h;
.pvr文件头部是可变长度的,其头部长度由第一个DWORD记录,这个长度已经将该DWORD自己计算在内了:
51 fread(& h.dwHeaderSize, sizeof(DWORD), 1, fp);
读取头部的剩余部分:
52 fread(& h.dwHeight, h.dwHeaderSize - sizeof(DWORD), 1, fp);
53
54 // format info
55 width = h.dwWidth;
56 height = h.dwHeight;
57 levels = h.dwMipMapCount;
58 size = h.dwTextureDataSize;
59
Flags由两部份组成,0x100以上是位掩码,记录制作时的选项,低位部分是格式代号:
60 h.dwpfFlags &= ~PVRTC_MIPMap; // redundant with levels?
61 h.dwpfFlags &= ~PVRTC_Twiddle; // todo : record?
62 h.dwpfFlags &= ~PVRTC_NormalMap; // todo : handle?
63
头部有一个dwAlphaBitMask字段,用来记录图片每个单元里有几个位是用来记录alpha信息的。
PVRTextureTool 1.x生成的纹理似乎总是不含alpha通道的,而3.x则可以控制是否生成。
目前如果有alpha通道,这个alpha bit总是1。
64 bool hasAlpha = h.dwAlphaBitMask != 0;
65 switch( h.dwpfFlags )
66 {
PVRTC4是用PVRTC 4BPP算法压缩的:
67 case PVRTC_PVRTC4:
如果纹理数据中有alpha通道,那就映射到GL_RGBA格式,否则映射到GL_RGB格式。
68 format = hasAlpha? GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG : GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
69 //if the texture contains alpha information, then use it.
70 break;
PVRTC2是用PVRTC 2BPP算法压缩的,压缩比更高,失真也更厉害:
71 case PVRTC_PVRTC2:
如果纹理数据中有alpha通道,那就映射到GL_RGBA格式,否则映射到GL_RGB格式。
72 format = hasAlpha? GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG : GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
73 //if the texture contains alpha information, then use it.
74 break;
75 // _GL format: the order of scan lines are reverted.
76 case PVRTC_PVRTC4_GL:
77 format = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
78 break;
79 case PVRTC_PVRTC2_GL:
80 format = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
81 break;
82 default:
83 // if not special compressed, why use PVRTC format?
84 // todo : mapping more PVR possible content to GLES internal format
唔,虽然写了个TODO,但是不知道啥时候才DO,所以如果需要的话自己先写吧, 写好了如果不介意公开的话, 发到论坛上或email我,我会补充到这个页面上的。
85 format = -1;
86 ;
87 }
88
89 data = (unsigned char *) malloc( h.dwTextureDataSize );
90 fread( data, h.dwTextureDataSize, 1, fp );
91 fclose(fp);
92 }
93 };
94
95 #endif // PVR_TEXTURE_H
1 //
2 // @ Project : PVRTC Wrapper
3 // @ File Name : PVRTCFile.h
4 // @ Date : 2007-8-30
5 // @ Author : kongfu.yang
6 // @ Company :
7 // @ Copyright : 2007-8, Example source license.
By keep this header comment, you may use this source file in your project for non-commicial or commicial purpose.
8
9 #ifndef PVR_TC_FILE_H
10 #define PVR_TC_FILE_H
11
12 typedef struct PVR_Header_TAG
13 {
14 DWORD dwHeaderSize; /* size of the structure */
15 DWORD dwHeight; /* height of surface to be created */
16 DWORD dwWidth; /* width of input surface */
17 DWORD dwMipMapCount; /* Number of additional mipmap levels */
18 DWORD dwpfFlags; /* pixel format flags */
19 DWORD dwTextureDataSize; /* Total size in bytes */
20 DWORD dwBitCount; /* number of bits per pixel */
21 DWORD dwRBitMask; /* mask for red bit */
22 DWORD dwGBitMask; /* mask for green bits */
23 DWORD dwBBitMask; /* mask for blue bits */
24 DWORD dwAlphaBitMask; /* mask for alpha channel */
25 } PVR_Header;
26
27 #define PVRTC_ARGB_4444 0x00000000
28 #define PVRTC_ARGB_1555 0x00000001
29 #define PVRTC_RGB_565 0x00000002
30 #define PVRTC_RGB_555 0x00000003
31 #define PVRTC_RGB_888 0x00000004
32 #define PVRTC_ARGB_8888 0x00000005
33 #define PVRTC_ARGB_8332 0x00000006
34 #define PVRTC_I_8 0x00000007
35 #define PVRTC_AI_88 0x00000008
36 #define PVRTC_1_BPP 0x00000009
37 #define PVRTC_VY1UY0 0x0000000A
38 #define PVRTC_Y1VY0U 0x0000000B
39 #define PVRTC_PVRTC2 0x0000000C
40 #define PVRTC_PVRTC4 0x0000000D
41 #define PVRTC_RGBA_4444 0x00000010
42 #define PVRTC_RGBA_5551 0x00000011
43 #define PVRTC_RGBA_8888 0x00000012
44 #define PVRTC_PVRTC2_GL 0x00000018
45 #define PVRTC_PVRTC4_GL 0x00000019
46 #define PVRTC_MIPMap 0x00000100
47 #define PVRTC_Twiddle 0x00000200
48 #define PVRTC_NormalMap 0x00000400
49
50
51 #endif // PVR_TC_FILE_H
52