最近程序用到了天气预报的东西,网上百度,查了一些资料参考(
http://g.kehou.com/t1029846752.html)。
根据资料中的提示,写了个程序,用于抓取所有省及所属城市代码并写入到c:\CityList.mxl 文件中。
代码如下:
1 /********************************************************************
2 created: 2013/06/11
3 created: 11:6:2013 19:11
4 filename: d:\HETU\Test\WIFetch\WIFetch\main.cpp
5 file path: d:\HETU\Test\WIFetch\WIFetch
6 file base: main
7 file ext: cpp
8 author: Fanze
9
10 purpose: 从weather.com.cn抓取城市名称和代码信息
11 *********************************************************************/
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <Windows.h>
16 #include <WinInet.h>
17 #include <vector>
18 #include "ZCharSetUtil.h"
19 using namespace std ;
20
21 #pragma comment(lib ,"Wininet")
22
23 struct NCInfo
24 {
25 char Name[32] ;
26 char Code[32] ;
27 };
28
29 typedef vector<NCInfo*> VTNCInfo ;
30 typedef vector<NCInfo*>::iterator VTNCInfoIT ;
31
32 struct SLInfo : public NCInfo
33 {
34 VTNCInfo VTCityInfo ;
35 };
36 typedef vector<SLInfo*> VTSLInfo ;
37 typedef vector<SLInfo*>::iterator VTSLInfoIT ;
38
39 enum TASK_DOWNRET
40 {
41 TASK_DOWN_OK = 0,
42 TASK_DOWN_FAIL = 1,
43 TASK_DOWN_CANCEL = 2,
44 };
45
46 const char* pStartToken = "line-content\">" ;
47 const char* pEndToken = "</td>" ;
48
49 const char* g_strXMLHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" ;
50 const char* g_strRootTag = "<list>\r\n" ;
51
52 const char* g_strCityListURL = "http://www.weather.com.cn/data/list3/" ;
53 static char* g_strSLURL = "http://www.weather.com.cn/data/list3/city.xml?level=1" ;
54
55 ///< 利用wininet下载文件
56 static inline TASK_DOWNRET InetDownFile(const TCHAR* strSoureURL ,unsigned char* pResultBuf ,int nResultBufLen ,int* ResultLen)
57 {
58 HINTERNET hInternet ;
59 HINTERNET hURLInternet ;
60 BYTE Buf[2048] ={0} ;
61 DWORD dwReads = 0 ;
62 DWORD dwTotal = 0 ;
63 int nSize = 0 ;
64 TASK_DOWNRET Ret = TASK_DOWN_OK ;
65
66 if(strSoureURL == NULL || pResultBuf == NULL || ResultLen == 0){
67 return TASK_DOWN_FAIL ;
68 }
69
70 ///< 删除URL缓存,总是从服务器下载最新的文件。
71 DeleteUrlCacheEntry(strSoureURL) ;
72
73 hInternet = InternetOpen(NULL ,INTERNET_OPEN_TYPE_DIRECT ,
74 NULL ,NULL ,0) ;
75 if(hInternet == NULL){
76 return TASK_DOWN_FAIL ;
77 }
78
79 hURLInternet = InternetOpenUrl(hInternet ,strSoureURL ,NULL ,0
80 ,INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_NO_CACHE_WRITE ,NULL) ;
81 if(hURLInternet == NULL)
82 {
83 InternetCloseHandle(hInternet) ;
84 DWORD dwErr = GetLastError() ;
85 return TASK_DOWN_FAIL ;
86 }
87
88 while(InternetReadFile(hURLInternet ,Buf ,2048 ,&dwReads))
89 {
90 if(dwReads == 0){
91 Ret = TASK_DOWN_OK ;
92 break ;
93 }
94 nSize = ((dwTotal + dwReads) > (nResultBufLen - dwTotal)) ? (nResultBufLen - dwTotal) : dwReads ;
95 memcpy(pResultBuf + dwTotal ,Buf ,dwReads) ;
96 dwTotal += dwReads ;
97 }
98
99 *ResultLen = dwTotal ;
100
101 InternetCloseHandle(hURLInternet) ;
102 InternetCloseHandle(hInternet) ;
103 return Ret ;
104 }
105
106 void ParseItem(char* str ,NCInfo* pInfo)
107 {
108 char* pPos = str ;
109 char* pSave = NULL ;
110 char Temp[32] ={0} ;
111 if(str == NULL || pInfo == NULL)
112 return ;
113
114 pSave = pInfo->Code ;
115 while(*pPos != '\0')
116 {
117 if(*pPos =='|')
118 {
119 pInfo->Code[pInfo->Code - pSave] ;
120 pSave = pInfo->Name ;
121 }else
122 {
123 *pSave = *pPos ;
124 pSave++ ;
125 }
126 pPos++ ;
127 }
128 UTF82ASCII(pInfo->Name ,Temp) ;
129 printf("Name:%s \r\n" ,Temp) ;
130 UTF82ASCII(pInfo->Code ,Temp) ;
131 printf("Code:%s \r\n" ,Temp) ;
132 }
133
134 void Parse(char* str ,VTNCInfo* pVTInfo)
135 {
136 char* pPos = str ;
137 char Temp[32] ;
138 int nIndex = 0 ;
139 NCInfo* pInfo = NULL ;
140 while(*pPos != '\0')
141 {
142 if(*pPos == ',')
143 {
144 Temp[nIndex] = '\0' ;
145 ///< 解析一小段
146 pInfo = new NCInfo ;
147 memset(pInfo ,0 ,sizeof(NCInfo)) ;
148 ParseItem(Temp ,pInfo) ;
149 pVTInfo->push_back(pInfo) ;
150 nIndex = 0 ;
151 }else
152 {
153 Temp[nIndex] = *pPos ;
154 nIndex ++ ;
155 }
156 pPos++ ;
157 }
158 if(nIndex != 0)
159 {
160 Temp[nIndex] = '\0' ;
161 pInfo = new NCInfo ;
162 memset(pInfo ,0 ,sizeof(NCInfo)) ;
163 ParseItem(Temp ,pInfo) ;
164 pVTInfo->push_back(pInfo) ;
165 }
166 }
167
168 void ProcReplyContent(char* pSrc ,char* pSaveBuffer)
169 {
170 char* pPos = NULL ;
171 char* pEndPos = NULL ;
172 pPos = strstr(pSrc ,pStartToken) ;
173 if(pPos == NULL)
174 return ;
175 pPos += strlen(pStartToken) ;
176 pEndPos = strstr(pPos ,pEndToken) ;
177 if(pEndPos == NULL)
178 return ;
179
180 strncpy(pSaveBuffer ,pPos ,pEndPos - pPos) ;
181 pSaveBuffer[pEndPos - pPos] = '\0' ;
182 }
183
184 ///< 解析省级代码,获取城市列表代码
185 void ParseSLCityInfo(SLInfo* pSLInfo ,VTNCInfo* pCityList)
186 {
187 char RequestURL[128] ={0} ;
188 char Buf[2048+1] ;
189 char Content[1024] ;
190 int nResultLen = 0 ;
191
192 if(pSLInfo == NULL || pCityList == NULL)
193 {
194 return ;
195 }
196 ///< 生成请求URL
197 sprintf(RequestURL ,"%scity%s.xml?level=2" ,g_strCityListURL ,pSLInfo->Code) ;
198 if(InetDownFile(RequestURL ,(unsigned char*)Buf ,2048 ,&nResultLen) != TASK_DOWN_OK){
199 return ;
200 }
201 Buf[nResultLen] ='\0' ;
202 Parse(Buf ,pCityList) ;
203 }
204
205 ///< 根据省一级的代码获取,所有城市列表
206 void ParseSLInfo(VTNCInfo* pVTSLList ,VTSLInfo* pVTSLInfoList)
207 {
208 VTNCInfoIT IT ;
209 SLInfo* pSLInfo = NULL ;
210 NCInfo* pNCInfo = NULL ;
211 int nIndex = 0 ;
212
213 for(IT = pVTSLList->begin() ; IT != pVTSLList->end() ; IT++)
214 {
215 pNCInfo = *IT ;
216 if(pNCInfo == NULL)
217 continue ;
218
219 pSLInfo = new SLInfo ;
220 strcpy(pSLInfo->Name ,pNCInfo->Name) ;
221 strcpy(pSLInfo->Code ,pNCInfo->Code) ;
222 Sleep(1000) ;
223 ParseSLCityInfo(pSLInfo ,&pSLInfo->VTCityInfo) ;
224
225 pVTSLInfoList->push_back(pSLInfo) ;
226 nIndex ++ ;
227 }
228 }
229
230 ///< 写入XML文件头
231 void WriteXMLHeader(FILE* fp)
232 {
233 fwrite(g_strXMLHeader ,1 ,strlen(g_strXMLHeader) ,fp) ;
234 fwrite(g_strRootTag ,1 ,strlen(g_strRootTag) ,fp) ;
235 }
236
237 ///< 写入XML文件尾
238 void WriteXMLTail(FILE* fp)
239 {
240 fprintf(fp ,"</list>\r\n") ;
241 }
242
243 ///< 写入一个省、城市列表信息
244 void WriteXMLSLItem(FILE* fp ,SLInfo* pSLInfo)
245 {
246 VTNCInfoIT itt ;
247 NCInfo* pNCInfo = NULL ;
248 fprintf(fp ,"\t<sl>\r\n") ;
249 fprintf(fp ,"\t\t<name>%s</name>\r\n" ,pSLInfo->Name) ;
250 fprintf(fp ,"\t\t<code>%s</code>\r\n" ,pSLInfo->Code) ;
251 fprintf(fp ,"\t\t<city>\r\n") ;
252 for(itt = pSLInfo->VTCityInfo.begin() ; itt != pSLInfo->VTCityInfo.end() ; itt++)
253 {
254 pNCInfo = *itt ;
255 if(pNCInfo == NULL)
256 continue ;
257 fprintf(fp ,"\t\t\t<item name=\"%s\" code=\"%s\" />\r\n" ,pNCInfo->Name ,pNCInfo->Code) ;
258 }
259 fprintf(fp ,"\t\t</city>\r\n") ;
260 fprintf(fp ,"\t</sl>\r\n") ;
261
262 }
263
264 ///< 将结果保存至文件
265 void SaveToFile(char* strDstFile ,VTSLInfo* pSLInfoVT)
266 {
267 FILE* pSaveFile = NULL ;
268 VTSLInfoIT itt ;
269 SLInfo* pInfo = NULL ;
270 pSaveFile = fopen(strDstFile ,"wb+") ;
271 WriteXMLHeader(pSaveFile) ;
272 for(itt = pSLInfoVT->begin() ; itt != pSLInfoVT->end() ; itt++)
273 {
274 pInfo = *itt ;
275 if(pInfo == NULL)
276 continue ;
277 WriteXMLSLItem(pSaveFile ,pInfo) ;
278 }
279 WriteXMLTail(pSaveFile) ;
280 fclose(pSaveFile) ;
281 }
282
283 void FreeNCVt(VTNCInfo* pVTInfo)
284 {
285 VTNCInfoIT it ;
286 NCInfo* pInfo = NULL ;
287 for(it = pVTInfo->begin() ; it != pVTInfo->end() ; it++)
288 {
289 pInfo = *it ;
290 if(pInfo != NULL)
291 {
292 delete pInfo ;
293 }
294 }
295 pVTInfo->clear() ;
296 }
297
298 int main()
299 {
300 FILE* fp = NULL ;
301 char strSLFile[128] ;
302 char *pBuffer = new char[1024*4+1] ;
303 int nReadLen = 0 ;
304 VTNCInfo VTInfo ;
305 VTSLInfo VSLInfo ;
306
307 if(InetDownFile(g_strSLURL ,(unsigned char*)pBuffer ,1024*4 ,&nReadLen) != TASK_DOWN_OK){
308 printf("下载省级列表失败 \r\n") ;
309 return 1 ;
310 }
311 pBuffer[nReadLen] = '\0' ;
312
313 ///< 解析省级城市和代码
314 Parse(pBuffer ,&VTInfo) ;
315
316 ///< 开始处理省级文件
317 ParseSLInfo(&VTInfo ,&VSLInfo) ;
318
319 ///< 写入文件
320 printf("开始将文件存入c:\\CityList.xml\r\n") ;
321 SaveToFile("c:\\CityList.xml" ,&VSLInfo) ;
322 delete[] pBuffer ;
323
324 VTSLInfoIT it ;
325 SLInfo* pSLInfo = NULL ;
326 for(it = VSLInfo.begin() ; it != VSLInfo.end() ; it ++)
327 {
328 pSLInfo = *it ;
329 if(pSLInfo == NULL)
330 continue ;
331 FreeNCVt(&pSLInfo->VTCityInfo) ;
332 delete pSLInfo ;
333 }
334
335 FreeNCVt(&VTInfo) ;
336
337 printf("所有处理已完成,按任意键结束。") ;
338 getchar() ;
339 return 0 ;
340 }
CTabLayoutUI tabselect 调用SelectItem选择了某一项时通知。
CActiveXUI showactivex 创建完成后,显示时通知。
CCombUI itemselect 调用SelectItem选择改变时通知。
CCombUI dropdown 调用Activate时通知。
CButtonUI menu 当按钮的事件类型为,VIEWENT_CONTEXTMENU即上下文菜单时通知。
CButtonUI click 按钮激活时通知。
COptonUI selectchanged 当调用Selected,选择项更改后通知。
CTextUI link 暂未知
CliderUI valuechanged 当鼠标按钮弹起时通知。
CEditWnd return 当按下回车按键后通知。
CEditWnd textchanged 当文本改变时通知。
CScrollbarUI scroll 当双击或单击滚动条时通知。
CControlUI timer 定时器触发通知。
CControlUI menu 上下文菜单通知。
CListUI itemselect 当选择更改时通知。
CListUI headerclick 当单击列表的头(column header)时通知。
CListUI itemactivate 当某一项激活时,通知。
CListUI itemclick 当单击某一项时通知。
CListTextElementUI link 未知。
CListContainerElementUI itemactivate 激活事件。
CListContainerElementUI itemclick 当单击左键或右键时通知。
CPaintManagerUI windowinit WM_PAINT消息响应时,若为第一个布局,则通知。
CPaintManagerUI killfocus (设置焦点时,若设置的控件指针为空,则不再是焦点窗口)失去焦点时通知。
CPaintManagerUI setfocus 设置焦点时通知。
CRitchEditUI return 输入回车键时通知。
可利用IPHELPAPI进行获取
MIB_IFROW Info ; // 存放获取到的Adapter参数
memset(&Info ,0 ,sizeof(MIB_IFROW)) ;
Info.dwIndex = dwIndex ; // dwIndex是需要获取的Adapter的索引,可以通过GetAdaptersInfo和其他相关函数获取
if(GetIfEntry(&Info) != NOERROR){
printf("ErrorCode = %d\n" ,GetLastError()) ;
return ;
}
MIB_IFROW 中有一项 dwOperStatus的参数,它表明当前接口的操作状态
其值如下:
Value Meaning
IF_OPER_STATUS_NON_OPERATIONAL
LAN adapter has been disabled, for example because of an address conflict.
局域网适配器禁用,例如地址冲突
IF_OPER_STATUS_UNREACHABLE
WAN adapter that is not connected.
WAN适配器未连接
IF_OPER_STATUS_DISCONNECTED
For LAN adapters: network cable disconnected. For WAN adapters: no carrier
局域网适配器:网线未插入。WAN适配器:无信号
IF_OPER_STATUS_CONNECTING
WAN adapter that is in the process of connecting.
IF_OPER_STATUS_CONNECTED
WAN adapter that is connected to a remote peer.
已连接远端
IF_OPER_STATUS_OPERATIONAL
Default status for LAN adapters 默认状态
参考:ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/iphlp/iphlp/getifentry.htm
经测试
拔下网线时,dwOperStatus 值为IF_OPER_STATUS_NON_OPERATIONAL
连接网线时,dwOperStatus 值为IF_OPER_STATUS_OPERATIONAL
此笔记用于记录D3D中的HLSL学习过程和重点============================================================================
HLSL : High Level Shader Language 译为:高级着色语言
HLSL语言的语法类似于C语言
1. 数据类型
HLSL中的数据类型有:标准数据类型、向量、矩阵和复杂数据类型。
———|———————————————————————————————————|
类型 取值
———|———————————————————————————————————|
bool TRUE或FALSE
———|———————————————————————————————————|
int 32位signed整形
———|———————————————————————————————————|
half 16位float数值
———|———————————————————————————————————|
double 64位float数值
———|———————————————————————————————————|
float 32位float数值
———|———————————————————————————————————|
1.1 变量声明
常规声明 float fVar ;
声明时初始化 float fVar = 1.0f ;
数组声明 int iVar[3] = {1 ,2 ,3} ; // 声明一个大小为3的整型数组,并初始化为1 ,2,3.
1.2 类型修饰符
(1) const 常量 其值不可改
此类型修饰符表明一个变量的数值不可被渲染代码修改。例如:
const float fConstant = 2.0f ;
同C语言一样,其声明时徐初始化。
1.3 row_major与col_major
这一对修饰符出现在定义一个矩阵时。将其放在矩阵之前,例如:
row_major float 4x4 WorldMatrix ;
其作用在于指定当前定义的矩阵中的元素,使用行主序还是列主序进行存放(矩阵的行列式)。
示例:
col_major 11 12 13 14
21 22 23 24
31 32 33 34
41 42 43 44
row_major 11 21 31 41
12 22 32 42
13 23 33 43
14 24 34 44
行或者列主序决定了从常量表或从渲染器输入中读取矩阵元素的顺序。
1.4 寄存器类型修饰符
寄存器类型修饰符用于高速编译器变量的作用域和生命期
(1) static
static float fVale = 1.11f ;
具全局作用。Static关键字防止渲染器变量暴露给应用程序。
同C语言一样,在函数内部的变量,其值保存到下一次调用。
(2) extern
extern float4 fExternal ;
与Static相反。其义同C语言关键字。
(3) uniform
uniform float fUniforVal = 3.0f ;
只可使用API方法改变它,且只在两次绘制间改变。
(4) shared
shared修饰全局Shader变量表明它在不同的效果中被共享。
shared float fSharedVal ;
2 向量
(1) 向量类型是一种特殊的数据结构,一个向量可能包含1-4个元素。例如:
注意:数据类型后跟的数字,表明向量的维度。
声明1
bool bVector ; 标量 1个bool型数据
bool1 bVector ; 向量,包含一个bool变量
int1 iVector ; 向量,包含一个int变量
half2 hVector ; 向量,包含两个half变量
float3 fVector ; 向量,包含三个float变量
double4 fVector ; 向量,包含四个double变量
变量声明初始化可以同时进行
bool1 bVector = FALSE ;
int1 iVector = 1 ;
half2 hVector = {0.2 ,0.3} ;
float3 fVector = {0.3f ,0.4f ,0.5f} ;
double4 dVector = {0.2 ,0.3 ,0.4 ,0.5} ;
声明2
当声明向量时,可以在一个尖括号中指定该向量的类型和向量中的元素个数。
vector<bool ,1> bVector = TRUE ;
vector<int ,1> iVector = 1 ;
vector<half ,2> hVector = {0.2 ,0.3 } ;
vector<float ,3> fVector = {1.0f ,2.0f ,3.0f} ;
vector<double ,4> dVector = {1.0 ,2.0 ,3.0 ,4.0} ;
(2)向量元素的存取
一个向量最多包含4个元素。可使用位置x、y、z、w和颜色r、g、b、a进行寻址。
float4 Pos = float4{0.0f ,1.0f ,2.0f ,3.0f} ;
对于向量Pos,使用Pos.z和Pos.b都返回第三个元素,即2.0f。
在一次存取过程中,可以使用一个命名集合获取一个或多个元素,但命名集合不能混用。
如:
float4 Pos = float4(1.0f ,2.0f ,3.0f ,4.0f) ;
float2 Temp ;
Temp = Pos.xy ; // 正确 x y命名相同
Temp = Pos.rg ; // 正确 r g命名相同
Temp = Pos.xb ; // 错误x b命名混用
(3)向量元素的混合存取
将读取一个或多个指定的向量元素,称之为混合存取(swizzling).
存取示例:
float4 pos = float4(0 , 0 , 2 ,1) ;
float2 f_2D ;
f_2D = pos.xy ; // 读取两个元素x和y,并赋值给f_2D
f_2D = pos.xz ; // 读取pos的x和z,赋值给f_2D,可以以任何顺序读取元素
f_2D = pos.zx ; // 元素可逆序读取
f_2D = pos.xx ; // 重复读取,元素可以多次读取
f_2D = pos.yy ; // 同上
赋值操作
float4 pos = float4(0 ,0 ,2 ,1) ;
float4 f_4D ;
f_4D = pos ; // 相当于f_4D.x = pos.x ; f_4D.y = pos.y ; f_4D.z = pos.z ;f_4D.w = pos.w ;
f_4D.xz = pos.xz ; // 等同于f_4D.x = pos.x ; f_4D.z = pos.z ;
f_4D.zx = pos.xz ; // 等同于f_4D.z = pos.x ; f_4D.x = pos.z ;
f_4D.xyzw = pos.w ;// 等同于f_4D.x = pos.w ; f_4D.y = pos.y ;f_4D.z = pos.z ;
f_4D.wzyx = pos ; //等同于 f_4D.w = pos.x ; f_4D.z = pos.y ;f_4D.y = pos.z ; f_4D.x = pos.x ;
以下语句无效
f_4D.xx = pos.xy ;
f_4D.xg = pos.rg ;
(4)向量的数学运算
乘法符号为“*“
假设a ,b都为float4类型
float4 v = a * b ;
可视为:
v.x = a.x * b.x ;
v.y = a.y * b.y ;
v.z = a.z * b.z ;
v.w = a.w * b.w ;
此为点乘
3 矩阵
(1)
矩阵是一种以行和列将数据组织起来的数据结构。
矩阵数据类型后紧跟x指明该矩阵的行和列。例如:
int1x1 iMatrix 整形矩阵,1行1列
int2x1 iMatrix 整形矩阵,2行1列
int4x1 iMatrix 整形矩阵,4行1列
int1x4 iMatrix 整形矩阵,1行4列
double1x1 dMatrix double型矩阵,1行1列
double2x2 dMatrix double型矩阵,2行2列
double3x3 dMatrix double型矩阵,3行3列
double4x4 dMatrix double型矩阵,4行4列
HLSL中矩阵的行和列数最大为4,最小为1
矩阵的声明和初始化
float2x2 fMatrix ={0.0f ,0.1f , // 第一行
2.1f ,2.2f} ; // 第二行
matrix <float ,2 ,2> fMatrix ={0.0f ,0.1 // 第一行
2.1f ,2.2f } ; // 第二行
使用关键字matrix声明。这是一个矩阵,其类型为float,行数和列数都为2。
(2) 矩阵元素的存取
矩阵时以行和列将数据组织起来的,可以通过结构体操作符"."来存取其中的数据。
存取方法有两种
1. 0基准行列位置法
_m00, _m01, _m02 ,_m03
_m10 ,m_11 ,_m12 ,_m13
_m20 ,m_21 ,_m22 ,_m23
_m30 ,m_31 ,_m32 ,_m33
2. 1基准行列位置法
_11 ,_12 ,_13 ,_14
_21 ,_22 ,_23 ,_24
_31 ,_32 ,_33 ,_34
_41 ,_42 ,_43 ,_44
两种方法中,每个元素的标识都是以下划线开始的,后跟行号和列号。
0基准位置法中,行号和列号前还有一个字母m。
访问示例:
float2x2 fMatrix ={1.0f ,1.1f ,2.0f ,2.1f} ;
float f_1D ;
f_1D = fMatrix._m00 ; // 取行1、列1数据 1.0f
f_1D = fMatrix._m11 ; // 取行2、列2数据 2.1f
f_1D = fMatrix._11 ; // 取行1、列1数据 1.0f
f_1D = fMatrix._22 ; // 取行2,、列2数据 2.1f
访问矩阵多个元素
float2x2 fMatrix ={1.0f ,1.1f ,2.0f ,2.1f} ;
float temp ;
temp = fMatrix._m00_m11 ;
temp = fMatrix._m11_m00 ;
temp = fMatrix._11_22 ;
temp = fMatrix._22_11 ;
(3) 矩阵的混合存取
与向量类似,对矩阵一个以上的元素进行读取或复制操作,称为混合存取(swizzling)。
float4x4 worldMatrix= float4({0 ,0 ,0 ,0} ,{1 ,1 ,1 ,1} ,{2 ,2 ,2 ,2} ,{3 ,3 ,3 ,3}) ;
float4x4 tempMatrix ;
tempMatrix._m00_m11 = worldMatrix._m00_m11 ;
tempMatrix._m00_m11 = worldMatrix._m13_m33 ;
tempMatrix._11_22_33 = worldMatrix._11_22_33 ;
tempMatrix._11_22_33 = worldMatrix._24_23_22 ;
不正确的赋值
tempMatrix._11_m23 = worldMatrix._11_12 ; // 两种基准方式混用
tempMatrix._m00_m00 = worldMatrix.m_00_m11 ; // 不可在一次赋值对一个元素进行两次赋值
(4) 矩阵的数组存取方式
矩阵也可以使用类似访问数组的方式对其进行访问,此时基准为0,不是1.
4X4矩阵,可通过如下索引来访问其中的每个元素
[0][0], [0][1] , [0][2], [0][3]
[1][0], [1][1], [1][2], [1][3]
[2][0], [2][1], [2][2], [2][3],
[3][0], [3][1], [3][2], [3][3],
赋值
float2x2 fMatrix ={1.0f ,1.1.f ,2.0f ,2.1f} ;
float temp ;
temp = fMatrix[0][0] ;
temp = fMatrix[0][1] ;
数组存取方式可以用来存取多元素的向量
float2 temp ;
float2x2 fMatrix ;
temp = fMatrix[0] ; // 将矩阵fMatrix的第一行赋值给向量temp
(5) 矩阵的存放顺序
矩阵中数据的存放方式具体采用行主序还是列主序可以在编译的指定。
使用语句 #pragma pack_matrix(row_major) 或 #pragma pack_matrix(col_major)指定。
列主序效率高于行主序
(6) 矩阵的数学运算
HLSL中,矩阵的数学原酸也是逐元素进行的
float3x3 mat1 ,mat2 ;
float3x3 mat3 = mat1 * mat2 ;
其结果mat3中的值,是两个矩阵mat1和mat2的元素逐个进行相乘后的值
mat3.m00 = mat1._m00 * mat._m00 ;
(7) 复杂数据类型
HLSL支持复杂的数据类型来处理类似采样器(sampler)、结构体(structure)、渲染器(shader)这样的对象
采样器
在阅读一些程序的时候,发现C/C++宏定义中,有两个##符号的语句。其意为:字符连接,即在通过##符号连接字符串。
如:
#define Q(TEXT) "a"##TEXT
示例代码:
1
2 #define Q(TEXT) "a"##TEXT
3 #include <stdio.h>
4 int main()
5 {
6 printf(Q("bcdefg")) ; // 本条语句输出为:abcdefg
7 }
注:示例代码在VC2008中测试通过
注2:GCC中测试未通过