重劍無鋒,大巧不工
常有人詢問,編程需要天賦嗎?啊,任何事情走往極致,都需要天賦。任何一個軟件產品的極致成功,都需要創意天賦、編程天賦、管理天賦、行銷天賦……。然而,只需用心模仿,再加一點匠心獨具,任何人都能夠把編程路走得穩當順遂。能讀千賦則善賦,能觀千劍則曉劍,巧者不過習者之門也。你把名家源碼融為己用,別人也會贊嘆一聲“你有編程天賦”。子曾經曰過:編程無他,唯手熟爾!
C++博客
首頁
新隨筆
聯系
聚合
管理
隨筆 - 505 文章 - 1034 trackbacks - 0
<
2007年10月
>
日
一
二
三
四
五
六
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
子曾經曰過:編程無他,唯手熟爾!
常用鏈接
我的隨筆
我的評論
我參與的隨筆
留言簿
(94)
給我留言
查看公開留言
查看私人留言
隨筆分類
(649)
C++ lib -- ACE(1)
C++ lib -- Boost(2)
C++ lib -- CEGUI(10)
C++ lib -- Loki(2)
C++ lib -- MFC (2)
C++ lib -- Qt(39)
C++ lib -- STL(1)
C++ lib -- wxWidgets
Debug(2)
Encrypt & Decrypt(3)
Enjoy Hardware(16)
Enjoy Software(3)
Everyday Life(10)
Flash Scaleform GFx(13)
Game Engine(18)
Game Graphics(160)
Game Music & Sound(18)
GameDevStory(12)
GameResManagement
HLSL&ShaderMonkey(27)
IDE -- c++ builder(6)
IDE -- visual c++(37)
Kungfu(4)
Movie & TV(2)
Multi Threads(1)
Network Programming(2)
Nokia S60(1)
OGRE(14)
OS -- Vista(5)
P2P(4)
PL--c/c++(63)
PL--Lua(15)
PL--Python(4)
PL--WindowsShell(3)
Secret(13)
Text Editor(2)
Unreal(2)
大話IT(4)
亂七八糟(118)
面試筆試(7)
自動更新(3)
隨筆檔案
(505)
2018年6月 (1)
2016年10月 (1)
2015年1月 (1)
2012年6月 (1)
2012年4月 (1)
2012年3月 (1)
2011年8月 (1)
2011年4月 (1)
2011年2月 (2)
2010年8月 (1)
2009年9月 (8)
2009年8月 (5)
2009年7月 (9)
2009年6月 (2)
2009年5月 (3)
2009年4月 (5)
2009年3月 (6)
2009年1月 (6)
2008年12月 (23)
2008年11月 (25)
2008年10月 (16)
2008年9月 (5)
2008年8月 (5)
2008年7月 (6)
2008年6月 (10)
2008年5月 (10)
2008年4月 (52)
2008年3月 (42)
2008年2月 (16)
2008年1月 (24)
2007年12月 (31)
2007年11月 (27)
2007年10月 (38)
2007年9月 (24)
2007年8月 (25)
2007年7月 (15)
2007年6月 (3)
2007年5月 (3)
2007年4月 (6)
2007年3月 (1)
2007年2月 (10)
2006年12月 (3)
2006年11月 (16)
2006年10月 (4)
2006年9月 (1)
2006年7月 (9)
相冊
劍
BCB
C++ Builder研究
Crytek
crymod
Crytek's Offical Modding Portal
Game Industry
AMD Developer Central
Welcome to AMD Developer Central
BeautifulPixels
A guy who works on the game engine Gamebryo at Emergent Game Technologies.
CGJOY
Develop
Breaking news and the lastest jobs for European games developers
Emergent Game Technologies in Asia
Emergent sales type guy
Gamasutra
Gamasutra
GameIndustry
GameIndustry
NVIDIA Developer Zone
Programming Vertex, Geometry, and Pixel Shaders
OGRE
Ogre3d API
Ogre官網
Ogre中文Wiki
Ogre中文社區
other
Google代碼搜索
搜索代碼,搜索Loki::試試
Windows7之家
季莊新聞
a guy in America whose old hometown is in ShanDong Province
維基百科
我的豆瓣
read books
陽光牛牛 的個人空間
中國青年
Programmers
Qt
Qt Center
Qt的信息和資源,很全
Qt Forum
Qtopia.org.cn
中國人討論Qt的地方
Qt簡體中文
有“Qt簡體中文文檔“
Qt中文論壇
貌似人氣很高啊
Qwt
好多QT控件,開源項目,哈哈,爽
QwtPlot3D
用Qt和OpenGL實現的Qt控件庫,3D的,震撼死了
Trolltech
Qt老家
Trolltech Labs
齊亮博客
一個正在挪威奧斯陸工作的中國軟件工程師
WOW Stuff
WoW Wiki
搜索
積分與排名
積分 - 911346
排名 - 14
最新隨筆
1.?2018年再更新下
2.?2016年更新下
3.?離開天朝,跑到新加坡了
4.?一個中國窮人在美國的生活
5.?用Windows批處理啟動需要更改系統時間破解的程序
6.?程序中添加某個目錄的路徑
7.?網游客戶端彈出個“Runtime Error”不產生dump文件的解決辦法
8.?招聘UI帝,客戶端邏輯,熟悉OGRE/CEGUI/Lua優先,薪水給力
9.?reinterpret_cast相關
10.?const相關
11.?滔滔備份
12.?搬家到博客園去了
13.?理解D3D--(0)批次batch
14.?工程師和科學家
15.?文章分類
16.?[轉]尋找遺失的同步類視圖
17.?《天驕3》不錯
18.?Vertex Formats
19.?3D地形多層紋理混合加陰影渲染方法
20.?山寨Dota之路--(0)起始
最新評論
1.?re: 2016年更新下
之前考察下來,ios職位薪水budget太低了,后勁不足,這個技術方向已經放棄了
--七星重劍
2.?re: 2016年更新下
2020年了,再看當初這篇blog,欣然一笑,原來當時我是這么想的,哈哈。現在坡縣綠卡已到手,是不是該有新的規劃和選擇了?:)
--七星重劍
3.?re: 每天花30分鐘看OGRE--(5) Demo_TextureFX(超強4個ViewPort測試)
11年多過去了! How time flies!
--七星重劍
4.?re: 在for循環里對std::map進行元素移除
過了11年多,再回來復習下,哈哈
--七星重劍
5.?re: [metaprogramming] 求一個數Num的N次方
還能這樣,多年后的今天都不記得了
--七星重劍
6.?re: [zt]一步一步學習Vim 全圖解釋 (強烈推薦)
這個要撿起來重新熟悉下
--七星重劍
7.?re: 用p2p優化網絡游戲客戶端自動更新工具
我擦,我居然10幾年前還研究過這個
--七星重劍
8.?re: 2016年更新下
@炮灰九段
新加坡啊,先在這待幾年再說了
--七星重劍
9.?re: 2016年更新下
現在在哪個國家呢?沒想過回國再發展發展啊
--炮灰九段
10.?re: 2016年更新下
@思月行云
一直待在天朝的話,就堅持游戲領域了,畢竟搞了十年游戲開發了。但是現在跑到國外了,游戲職位實在太少了。
一起加油吧!:)
--七星重劍
閱讀排行榜
1.?每天30分鐘看Shader--(1)HLSL固有函數 【Intrinsic Functions (DirectX HLSL)】(25482)
2.?3D MAX 插件的基本知識和安裝方法(20770)
3.?AlienBrain初體驗(12266)
4.?python網絡編程學習初步(11922)
5.?圖形學掃盲--(4)3D圖形學的學習策略(11558)
評論排行榜
1.?【下載】Qt 4.3 商業版(41)
2.?華為某牛人的超強言論.年輕的可以看看(27)
3.?Qwt 終于可以調試它的examples了(猛圖,重劍開發環境大曝光)(18)
4.?求Gamebryo 2.3(18)
5.?PerfHud Scaleform GFx(17)
WOW m2模型與WowModelViewer
好長時間沒學shader了,拿這個
物件的邊緣高亮(Entity edge highlight)
練習了下,用render monkey,參照逍遙劍客的blog,很快就看到效果了,但是在現在的項目中實現的話有點麻煩,主要是對目前項目的Model還不熟悉,shader是怎么用的也不清楚,看了好幾天,依然是迷迷糊糊,真他媽的菜啊!
現在的項目兼容m2模型,因為這引擎朝哥寫的時候用的就是wow的資源,呵呵,山寨版wow。所以搞清楚了m2模型也就搞清楚了目前項目的model.開始看WowModelViewer.
MPQ Archives The
StormLib
library
魔獸世界m2模型文件分析及wowModelView代碼閱讀心得
Title
1、由于是瀏覽器,所以讀取數據的函數再ModelViewer::OnTreeSelect方法中。選擇分為角色模型和非角色模型,如下:
if (isChar) {
modelAtt = canvas->LoadCharModel(rootfn.fn_str());
canvas->modelType = MT_CHAR;
} else {
modelAtt = canvas->LoadModel(rootfn.fn_str());
canvas->modelType = MT_NORMAL;
}
其中的canvas是ModelCanvas *canvas,是ModelViewer類的一個屬性;
然后ModelCanvas::LoadCharModel再調用ModelCanvas::LoadModel方法讀取模型數據;
ModelCanvas::LoadModel新建了一個Modal,把傳入的文件地址const char *fn傳給了Modal的構造函數。
Modal的構造函數通過新建一個MPQFile類: MPQFile f(tempname);來讀取模型文件數據;
MPQFile構造函數中用file.Read(buffer, size)實際讀取了模型文件;
然后再Model::isAnimated中讀取了骨骼、頂點等模型數據(通過從上一條中的 buffer=后來的header 中拷貝);
2、這個瀏覽器是用opgl來開發圖像部分的,瀏覽器有一些坐標轉換函數,瀏覽器中的轉換函數在:
model.cpp中的Vec3D fixCoordSystem(Vec3D v)函數。
調用這個函數的函數是:Model::initCommon,initAnimated函數調用的它。
而initAnimated函數就在Model::isAnimated之后不久調用,被Model的構造函數調用。
if (animated)
initAnimated(f);
3、在initCommon中,依次讀取vertices,normals,bounds(包括boundTris),textures
這些都經過了上一條說的fixCoordSystem坐標轉換。
4、紋理是和頂點綁定的,一個頂點就有一個紋理坐標。讀取頂點數據同時就要讀取紋理坐標。
然后再實際渲染之前,設置相應的紋理對象。
這個是dx的紋理處理方案,opgl也應該差不多。
5、在initCommon接下來的繼續讀取中,我發現了一件事。那就是在讀取attachments、colors和transparency的時候,initCommon先把數據讀入ModelAttachmentDef、ModelColorDef和ModelTransDef等結構中,然后再讀入到ModelAttachment、ModelColor和ModelTransparency這些具體的、直接可以使用的數據結構中。我推測帶Def后綴的數據結構大部分都是一種過渡用的數據結構。
6、在initCommon之后,initAnimaited繼續讀取了bone、初始化了bones、texcoords、animTextures、particle systems(粒子系統)、ribbon、Camera和初始化了light。
在讀取這些數據的時候,都用到了第5條所說的讀取方式。
7、很多數據結構再讀入數據后,里面都包含一種數據結構:Animated類。由于這寫數據結構都與動畫有關,所以每當讀取玩自己的數據后都要調用Animated::init方法進行對自己相關的動畫部分進行初始化。
8、推測AnimManager類是真正管理動畫(播放、選擇等)。推測ModelAnimation類讀取得動畫數據就是按照關鍵幀來排列的。
9、在ModelViewer::OnTreeSelect中load模型的所有數據之后,通過animControl->UpdateModel(canvas->model)來設置(不是渲染!)選擇的非玩家角色模型;而通過charControl->UpdateModel(modelAtt)來設置(不是渲染!)玩家角色模型。
在第1條中(關于模型讀取的部分),讀取模型后,數據存放在Attachment*modelAtt和canvas->model中,然后如果設置(不是渲染!)非玩家角色模型就用nimControl->UpdateModel(canvas->model);設置(不是渲染!)玩家角色模型就用charControl->UpdateModel(modelAtt)。
10、真正的渲染模型工作是在ModelCanvas::OnPaint中調用ModelCanvas::Render。
然后ModelCanvas::Render中調用Attachment::draw;Attachment::draw中通過判定ModelCanvas的drawModel(bool變量,事先在ModelViewer::OnToggleCommand中給出,這個部分就是消息函數);然后Attachment::draw調用model::draw;model::draw調用Model::drawModel
最后的實際渲染在Model::drawModel中。
11、實際渲染模型的Model::drawModel中關鍵的參數passes,是在Model::initCommon的結尾處賦給的值,通過一個pass的值。
12、在人物自定義上,以DBCFile類為基類,CharHairGeosetsDB、CharRacesDB、CharFacialHairDB、CharClassesDB、HelmGeosetDB類為子類,利用DBCFile類的瀏覽器Iterator類,來操作人物的自定義。在CharControl::RefreshModel中。
for (CharHairGeosetsDB::Iterator it = hairdb.begin(); it != hairdb.end(); ++it)
這個選擇人物的各種發型、面部特征的原理是,把這些特殊的發型、特征等做成一個數組,然后選好后顯示其中的一個,其它的不現實,這樣就達到了自定義的效果。
for (size_t j=0; j<model->geosets.size(); j++) {
if (model->geosets[j].id == id) {
model->showGeosets[j] = (cd.hairStyle==section) && showHair;
}
}
在每個子類中的// Fields 部分,都是指的dbc.mpq中每個子項內部的字段。
DBCFile::begin把data中的數據讀入Iterator瀏覽器類中
13、CharControl::UpdateModel被ModelViewer::OnTreeSelect調用,負責自定義角色的工作,第12條所說的。
14、 在animated.h文件中的inline T interpolate(const float r, const T &v1, const T &v2)函數將v1和v2做了線性插值。整個Animated::getValue就是為了做特定的類的插值有關鍵幀的信息。比如做平移的變換矩陣,在2個關鍵幀之間用這個getValve做差值,返回去就是做成了當前的平移變換矩陣
if (trans.used) {
Vec3D tr = trans.getValue(anim, time);
m *= Matrix::newTranslation(tr);
}
15、動畫中的頂點變換是在Model::animate中(Model::draw調用),先根據數據產生bone的3中變換矩陣(這里可以確定wow用的是關鍵幀骨骼動畫技術。同時,這個工作每幀都要做),然后用這3個矩陣乘以頂點,還有法線。定點變換代碼如下:
// transform vertices
ModelVertex *ov = origVertices;
for (size_t i=0,k=0; i<header.nVertices; ++i,++ov) {
Vec3D v(0,0,0), n(0,0,0);
for (size_t b=0; b<4; b++) {
if (ov->weights[b]>0) {
Vec3D tv = bones[ov->bones[b]].mat * ov->pos;
Vec3D tn = bones[ov->bones[b]].mrot * ov->normal;
v += tv * ((float)ov->weights[b] / 255.0f);
n += tn * ((float)ov->weights[b] / 255.0f);
}
}
vertices[i] = v;
if (supportVBO)
vertices[header.nVertices + i] = n.normalize(); // shouldn't these be normal by default?
else
normals[i] = n;
}
16、gl中設置環境光強度的函數是:glLightModelfv(GL_LIGHT_MODEL_AMBIENT, la)。其中la是一個Vec4D變量,是事先設定好的值,作為環境光的強度。這個函數在ModelCanvas::Render中被調用。
glEnable(GL_COLOR_MATERIAL)容許程序將材質顏色加入到當前顏色中,然后調用glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)來實際把材質顏色放入當前顏色中。接著,程序調用glColor來實際設置和操作當前顏色。
glLightf(light, GL_CONSTANT_ATTENUATION, 0.0f);
glLightf(light, GL_LINEAR_ATTENUATION, 0.7f);
glLightf(light, GL_QUADRATIC_ATTENUATION, 0.03f);
這3個語句設置了點光源和聚光燈的3個衰減因子(常數、一次系數、二次系數)
17、已經證實AnimManager::Frame就是一個動畫幀序列中的某一幀,可以說是當前幀把。
更新這個Frame就可以實現動畫,這里骨骼起了至關重要的作用。
18、TextureManager::add函數實際讀取了紋理圖片(BLP格式),在Model::initCommon中被調用
19、opgl的紋理繪制似乎是這樣的:首先讀取紋理文件,然后glGenTextures生成紋理對象,在要渲染之前調用glBindTexture綁定紋理,用glTexParameteri設置一些參數
20、Iterator類重載了->,重載函數返回的是(return &record)Iterator的一個屬性,就是一個Record對象的指針;同時又重載了*,返回return record,所以能夠讓*i返回為Record對象
21、在CharControl::Init中初始化了hairdb、chardb等這些要讀取dbc.mpq文件包的數據結構,通過DBCFile::open方法讀取。而CharControl類的那些hairdb、chardb等對象都是在其構造函數中直接寫明了自己所要讀取的文件數據的路徑,由于這些對象是DBCFile類的字類,所以直接在自己構造函數后調用父類的構造函數來把自己的讀取文件數據的路徑告訴父類(CharSectionsDB(): DBCFile("DBFilesClient\\CharSections.dbc") {}),以便讓父類在其open方法中直接使用這個路徑為他們準確的讀取數據。
Character\Scourge\Male\ScourgeMale.m2
Record類是最終程序直接使用的dbc.mpq中數據的數據結構。
CharRacesDB::Record CharRacesDB::getByName(wxString name)
{
for(Iterator i=begin(); i!=end(); ++i)
{
if (name.IsSameAs(i->getString(Name),false) == true)
return (*i);
}
throw NotFound();
}
類似這樣的程序段都是把當前的DBCFile放到i中,然后返回。這樣Record類就能發揮儲存器的作用。
22、自定義角色的外貌是通過cd這個變量,事先再UpdateModel里設定的,然后再通過RefreshModel讀取實際的blp紋理文件。先通過CharSectionsDB::Record rec = chardb.getByParams這樣的函數來從dbc.mpq的腳本文件里讀取相應的紋理腳本數據;然后通過rec.getString翻譯這些腳本語句,接著通過furtex = texturemanager.add來實際讀取紋理數據
我只要只改寫實際讀取紋理的函數就可以了,就是在texturemanager.add中的LoadBlp函數,在這里應該改寫成d3d的api:CreateTextureFromFileEx
23、Model::animate中的頂點變換(15中提到的),每個頂點被4個骨骼所影響,所以在變換的時候分別把影響每個頂點的骨骼矩陣都乘以頂點向量,然后在加合,這樣就把4個骨骼的影響合在一起了。
for (size_t b=0; b<4; b++)
{
if (ov->weights[b]>0)
{
Vec3D tv = bones[ov->bones[b]].mat * ov->pos;
Vec3D tn = bones[ov->bones[b]].mrot * ov->normal;
v += tv * ((float)ov->weights[b] / 255.0f);
n += tn * ((float)ov->weights[b] / 255.0f);
}
}
以上代碼中的v和n,就是用來整合影響每個頂點的4個骨骼的影響的。
24、ModelGeoset結構就是設置人物角色自定義的數據結構。CCharModel::InitCommon函數的最后創建了一系列的ModelRenderPass結構,我推測每一個此結構的對象都是一種角色自定義中的一種具體的實例,每一個都是占據了頂點數據中的一段(pass.indexstart)
25、原來渲染角色的方式是通過依次渲染模型的sub部分來實現的,24中所說的ModelRenderPass結構就是用來儲存每個sub部分的數據結構的。然后在實際渲染的時候(Model::drawModel函數負責實際渲染工作),通過其一個方法init(Model*m)來選擇是否渲染當前的sub部分,在init方法的最后:
return m->showGeosets[geoset] && ( (ocol.w > 0) && (color==-1 || (ecol.w > 0)) );
其中的m->showGeosets[geoset]就是Model類中的選擇人物模型的sub部分的標志結構,這個結構在CharControl的UpdateModel方法和RefreshModel中被設置,這2個方法自定義了模型的實際外貌
26、類Attachment就是裝備(手上的武器和副手,或者披風等)的數據結構(里面包含一個model類指針),渲染的時候每個Attachment對象實例就包含一個Model對象實例,就是說單獨依次渲染每個Attachment里的Model對象,然后根據主Model(人物角色Model)的坐標來給這些附屬Model對象來進行世界坐標變換,這樣就能解釋Attachment::draw中的setup的作用(包含了ModelAttachment::setup),再ModelAttachment::setup中包含了一個世界坐標變換,就很有可能是根據人物角色的坐標來變換這些附屬模型(手上的武器和副手,或者披風等)的坐標
27、在CCharModel::DrawModel中的
m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0,
0,
// number of vertices
p.vertexEnd - p.vertexStart,
p.indexStart,
// number of primitives
p.indexCount/3);
函數,最后一個參數,這里需要將p.indexCount除以3,因為這個indexCount是索引的數量,而不是要渲染的圖元(三角形)的數量(3個頂點一個三角形)
28、CharTexture::compose函數,就是在CharControl::RefreshModel后部調用的、用來混合紋理的函數,有這樣一段代碼:
TextureID temptex = texturemanager.add(comp.name);
Texture &tex = *((Texture*)texturemanager.items[temptex]);
第一行用來從事先讀取號、創建好的紋理儲存器中(TextureManager類)通過從std::vector<CharTextureComponent>容器(事先add紋理層的容器類)通過紋理名字(comp.name)來讀取id(temptex),然后通過這個id調用真正存儲這紋理數據的TextureManager類中的紋理數據。
29、CharControl::RefreshModel()中的代碼:
// select hairstyle geoset(s)
for (CharHairGeosetsDB::Iterator it = hairdb.begin(); it != hairdb.end(); ++it) {
if (it->getUInt(CharHairGeosetsDB::Race)==cd.race && it->getUInt(CharHairGeosetsDB::Gender)==cd.gender) {
unsigned int id = it->getUInt(CharHairGeosetsDB::Geoset);
unsigned int section = it->getUInt(CharHairGeosetsDB::Section);
if (id!=0) {
for (size_t j=0; j<model->geosets.size(); j++) {
if (model->geosets[j].id == id) {
//std::cout << "Hair:\t" << id << "\t" << section << "\t" << ((cd.hairStyle==section) && cd.showHair) << "\n";
model->showGeosets[j] = (cd.hairStyle==section) && showHair;
}
}
} else if (cd.hairStyle==section)
bald = true;
}
}
CharHairGeosetsDB::Geoset這個field值的意思是:當前record屬于角色模型那個sub類(比如頭發?胡須?等等);
CharHairGeosetsDB::Section這個field值的意思是:當前record所儲存的某類sub中是哪種,比如頭發sub類中的第幾種頭型;
30、CharControl::RefreshItem()是用來處理頭部、肩部、雙手處的模型的——需要用另外的模型文件——相對于手套、鞋子和衣服等直接從人物模型本身就能獲取的;
而CharControl::AddEquipment()則處理的是手套、鞋子和衣服等直接從人物模型本身就能獲取的模型裝備的添加、刪除修改等
31、當用戶選擇了裝備時候,調用CharControl::OnUpdateItem(),然后事件設為UPDATE_ITEM,執行如下代碼:
switch (type) {
case UPDATE_ITEM:
cd.equipment[choosingSlot] = numbers[id];
if (slotHasModel(choosingSlot))
RefreshItem(choosingSlot);
choosingSlot就是角色的裝備槽代號,比如肩膀、頭部、雙手等等;cd.equipment[choosingSlot]就是用裝備槽代號代表的裝備序列號(每個裝備單獨的id號,是唯一的)
WoWModelViewer分析
終于完成魔獸世界的換裝系統
2009-7-12 Sunday
從google code上svn最新的wowmodelviewer,用vs2008生成直接通過,不需要任何改動!我靠!0.48e,0.5.08,……唉!折騰啊!
就是裝個VS2008費勁啊!幸虧以前大林同志給了個VS2008的安裝文件(現在找不到了),裝在家里筆記本上體驗了下然后一直沒用,這次派上用場了!公司的外網機懶得裝了!
posted on 2009-07-03 01:12
七星重劍
閱讀(4908)
評論(0)
編輯
收藏
引用
所屬分類:
Game Graphics
只有注冊用戶
登錄
后才能發表評論。
【推薦】100%開源!大型工業跨平臺軟件C++源碼提供,建模,組態!
相關文章:
理解D3D--(0)批次batch
《天驕3》不錯
Vertex Formats
3D地形多層紋理混合加陰影渲染方法
在游戲全屏模式下調試的解決辦法
《Advanced Animation with DirectX》源碼編譯不過的解決辦法
WildMagic4p7
野豬寫的《游戲程序中的骨骼插件》
WOW m2模型與WowModelViewer
圖形學掃盲--(6)凹凸貼圖Bump mapping
網站導航:
博客園
IT新聞
BlogJava
博問
Chat2DB
管理
Copyright ©2025 七星重劍 Powered by:
博客園
模板提供:
滬江博客
久久99亚洲网美利坚合众国
|
亚洲国产一成久久精品国产成人综合
|
亚洲AV无码成人网站久久精品大
|
中文字幕无码久久人妻
|
99久久精品免费看国产一区二区三区
|
亚洲人成电影网站久久
|
久久妇女高潮几次MBA
|
996久久国产精品线观看
|
久久精品人妻一区二区三区
|
久久久午夜精品
|
国产午夜精品久久久久九九
|
国产精品乱码久久久久久软件
|
精品乱码久久久久久久
|
亚洲Av无码国产情品久久
|
99精品国产在热久久无毒不卡
|
国产精品永久久久久久久久久
|
久久天天躁狠狠躁夜夜不卡
|
久久综合狠狠综合久久激情
|
久久无码人妻精品一区二区三区
|
色偷偷88888欧美精品久久久
|
精品久久8x国产免费观看
|
人妻无码久久精品
|
97久久精品无码一区二区
|
久久青青草视频
|
开心久久婷婷综合中文字幕
|
AV无码久久久久不卡网站下载
|
亚洲国产精品综合久久网络
|
中文字幕亚洲综合久久2
|
国产精品久久久久jk制服
|
伊人久久大香线蕉亚洲
|
精品久久人人做人人爽综合
|
国产精品视频久久
|
丁香狠狠色婷婷久久综合
|
久久精品国产久精国产思思
|
久久久久久久久久久
|
国产精品久久久久久久app
|
色婷婷综合久久久久中文字幕
|
国产精品久久久天天影视香蕉
|
精品久久久一二三区
|
蜜桃麻豆www久久国产精品
|
中文成人无码精品久久久不卡
|