Revision | e20b4b8a0ac2db10b27cf6f60c68bdac4e94edbc (tree) |
---|---|
Time | 2019-11-05 09:28:42 |
Author | <jarmonik@c0f5...> |
- Clened up a mesh buffer handling, implemented a proper templates, optimized mesh add/insert mesh operations.
- Fixed a few material manager bugs.
@@ -5,8 +5,8 @@ | ||
5 | 5 | MWaveDep = 1 |
6 | 6 | ScaleHeight = 8 |
7 | 7 | DepthClamp = 0.0042 |
8 | -Exposure = 1.3055 | |
9 | -TGamma = 0.5292 | |
8 | +Exposure = 1.004 | |
9 | +TGamma = 0.606 | |
10 | 10 | OutScatter = 0.592 |
11 | 11 | InScatter = 1 |
12 | 12 | RayleighPhase = 0.3395 |
@@ -16,7 +16,7 @@ | ||
16 | 16 | BumpMapAmplitude = 1 |
17 | 17 | PlanetGlow = 0.4 |
18 | 18 | EnvMapSize = 512 |
19 | -EnvMapMode = 1 | |
19 | +EnvMapMode = 2 | |
20 | 20 | EnvMapFaces = 1 |
21 | 21 | ShadowMapMode = 3 |
22 | 22 | ShadowMapFilter = 2 |
@@ -31,7 +31,7 @@ | ||
31 | 31 | StereoConvergence = 0.2 |
32 | 32 | DebugLvl = 1 |
33 | 33 | VCNearPlane = 0.1 |
34 | -LightCongiguration = 2 | |
34 | +LightConfiguration = 2 | |
35 | 35 | DisableDrvMgm = 0 |
36 | 36 | NVPerfHUD = 0 |
37 | 37 | DebugLineFontSize = 18 |
@@ -39,13 +39,15 @@ | ||
39 | 39 | LODBias = 0.6 |
40 | 40 | MeshRes = 1 |
41 | 41 | MicroMode = 1 |
42 | -MicroFilter = 3 | |
42 | +MicroFilter = 5 | |
43 | 43 | BlendMode = 1 |
44 | 44 | MicroBias = 3 |
45 | -PostProcess = 1 | |
45 | +CloudMicro = 1 | |
46 | +PostProcess = 0 | |
46 | 47 | ShaderDebug = 0 |
47 | 48 | PresentLocation = 1 |
48 | 49 | PlanetTileLoadFlags = 3 |
49 | 50 | LabelDisplayFlags = 3 |
51 | +OrbitalShadowMult = 0.85 | |
50 | 52 | SolCfg = Sol |
51 | 53 | DebugLineFont = Fixed |
@@ -1521,6 +1521,7 @@ | ||
1521 | 1521 | DebugControls::SelectMesh(pick.pMesh); |
1522 | 1522 | DebugControls::SelectGroup(pick.group); |
1523 | 1523 | DebugControls::SetGroupHighlight(true); |
1524 | + DebugControls::SetPickPos(pick.pos); | |
1524 | 1525 | } |
1525 | 1526 | } |
1526 | 1527 | } |
@@ -142,6 +142,19 @@ | ||
142 | 142 | pOut->ModFlags = 0; |
143 | 143 | } |
144 | 144 | |
145 | +void CreateDefaultMat(D3D9MatExt *pOut) | |
146 | +{ | |
147 | + pOut->Ambient = D3DXVECTOR3(0, 0, 0); | |
148 | + pOut->Diffuse = D3DXVECTOR4(1, 1, 1, 1); | |
149 | + pOut->Emissive = D3DXVECTOR3(0, 0, 0); | |
150 | + pOut->Specular = D3DXVECTOR4(0.2, 0.2, 0.2, 50.0); | |
151 | + pOut->Reflect = D3DXVECTOR3(0, 0, 0); | |
152 | + pOut->Fresnel = D3DXVECTOR3(1, 0, 1024.0f); | |
153 | + pOut->Emission2 = D3DXVECTOR3(1, 1, 1); | |
154 | + pOut->Roughness = 0.0f; | |
155 | + pOut->ModFlags = 0; | |
156 | +} | |
157 | + | |
145 | 158 | void D3D9TuneInit(D3D9Tune *pTune) |
146 | 159 | { |
147 | 160 | pTune->Albedo = D3DXCOLOR(1, 1, 1, 1); |
@@ -273,8 +273,8 @@ | ||
273 | 273 | class vObject *vObj; ///< Visual handle |
274 | 274 | float dist; ///< Distance to a pick point |
275 | 275 | int group; ///< Mesh group that was picked |
276 | - D3DXVECTOR3 normal; ///< Normal vector | |
277 | - D3DXVECTOR3 pos; ///< Position from camera | |
276 | + D3DXVECTOR3 normal; ///< Normal vector in local vessel coordinates | |
277 | + D3DXVECTOR3 pos; ///< Position in local vessel coordinates | |
278 | 278 | int idx; ///< Index that was picked |
279 | 279 | float u, v; ///< Barycentric coords |
280 | 280 | } D3D9Pick; |
@@ -437,6 +437,7 @@ | ||
437 | 437 | |
438 | 438 | void CreateMatExt(const D3DMATERIAL9 *pIn, D3D9MatExt *pOut); |
439 | 439 | void UpdateMatExt(const D3DMATERIAL9 *pIn, D3D9MatExt *pOut); |
440 | +void CreateDefaultMat(D3D9MatExt *pOut); | |
440 | 441 | void GetMatExt(const D3D9MatExt *pIn, D3DMATERIAL9 *pOut); |
441 | 442 | bool CopyBuffer(LPDIRECT3DRESOURCE9 _pDst, LPDIRECT3DRESOURCE9 _pSrc); |
442 | 443 | void D3D9TuneInit(D3D9Tune *); |
@@ -40,6 +40,7 @@ | ||
40 | 40 | HWND hDataWnd = NULL; |
41 | 41 | vObject *vObj = NULL; |
42 | 42 | std::string buffer(""); |
43 | +D3DXVECTOR3 PickLocation; | |
43 | 44 | |
44 | 45 | HWND hTipRed, hTipGrn, hTipBlu, hTipAlp; |
45 | 46 |
@@ -145,6 +146,7 @@ | ||
145 | 146 | camMode = 0; |
146 | 147 | dspMode = 0; |
147 | 148 | SelColor = 0; |
149 | + PickLocation = D3DXVECTOR3(0,0,0); | |
148 | 150 | |
149 | 151 | cpr = cpg = cpb = cpa = 0.0f; |
150 | 152 |
@@ -1027,6 +1029,11 @@ | ||
1027 | 1029 | return sMesh; |
1028 | 1030 | } |
1029 | 1031 | |
1032 | +void SetPickPos(D3DXVECTOR3 pos) | |
1033 | +{ | |
1034 | + PickLocation = pos; | |
1035 | +} | |
1036 | + | |
1030 | 1037 | // ============================================================================================= |
1031 | 1038 | // |
1032 | 1039 | void SelectGroup(DWORD idx) |
@@ -1391,6 +1398,9 @@ | ||
1391 | 1398 | void Refresh() |
1392 | 1399 | { |
1393 | 1400 | if (hDataWnd == NULL) return; |
1401 | + | |
1402 | + Append("LocalPos = [%f, %f, %f]", PickLocation.x, PickLocation.y, PickLocation.z); | |
1403 | + | |
1394 | 1404 | SetWindowTextA(GetDlgItem(hDataWnd, IDC_DBG_DATAVIEW), buffer.c_str()); |
1395 | 1405 | buffer.clear(); |
1396 | 1406 | } |
@@ -104,6 +104,7 @@ | ||
104 | 104 | void SetVisual(vObject *vo); |
105 | 105 | void RemoveVisual(vObject *vo); |
106 | 106 | vObject * GetVisual(); |
107 | + void SetPickPos(D3DXVECTOR3 pos); | |
107 | 108 | |
108 | 109 | void SetupMeshGroups(); |
109 | 110 | void UpdateVisual(); |
@@ -365,6 +365,8 @@ | ||
365 | 365 | return false; |
366 | 366 | } |
367 | 367 | |
368 | + fprintf(file.pFile, "CONFIG_VERSION 2\n"); | |
369 | + | |
368 | 370 | for (DWORD k=0;k<nRec;k++) pRecord[k].bSaved = false; |
369 | 371 | |
370 | 372 | for (DWORD k=0;k<nRec;k++) { |
@@ -397,7 +399,7 @@ | ||
397 | 399 | if (flags&D3D9MATEX_REFLECT) fprintf(file.pFile,"REFLECT %f %f %f\n", pM->Reflect.x, pM->Reflect.y, pM->Reflect.z); |
398 | 400 | if (flags&D3D9MATEX_FRESNEL) fprintf(file.pFile,"FRESNEL %f %f %f\n", pM->Fresnel.x, pM->Fresnel.z, pM->Fresnel.y); |
399 | 401 | if (flags&D3D9MATEX_EMISSION2) fprintf(file.pFile, "EMISSION2 %f %f %f\n", pM->Emission2.x, pM->Emission2.y, pM->Emission2.z); |
400 | - if (flags&D3D9MATEX_ROUGHNESS) fprintf(file.pFile, "ROUGHNESS %f\n", pM->Roughness); | |
402 | + if (flags&D3D9MATEX_ROUGHNESS) fprintf(file.pFile, "ROUGHNESS %f\n", pM->Roughness); | |
401 | 403 | } |
402 | 404 | } |
403 | 405 | return true; |
@@ -31,21 +31,136 @@ | ||
31 | 31 | return 0; |
32 | 32 | } |
33 | 33 | |
34 | -// =========================================================================================== | |
34 | + | |
35 | + | |
36 | +// ====================================================================================== | |
37 | +// Buffer Object Implementation | |
38 | +// ====================================================================================== | |
39 | +// | |
40 | + | |
41 | +MeshBuffer::MeshBuffer(DWORD _nVtx, DWORD _nFace, const class D3D9Mesh *_pRoot) | |
42 | +{ | |
43 | + nVtx = _nVtx; | |
44 | + nIdx = _nFace * 3; | |
45 | + | |
46 | + pVB = NULL; | |
47 | + pIB = NULL; | |
48 | + pGB = NULL; | |
49 | + | |
50 | + pVBSys = new NMVERTEX[nVtx]; | |
51 | + pIBSys = new WORD[nIdx]; | |
52 | + pGBSys = new D3DXVECTOR4[nVtx]; | |
53 | + | |
54 | + pRoot = _pRoot; | |
55 | + mapMode = MAPMODE_STATIC; | |
56 | + bMustRemap = true; | |
57 | +} | |
58 | + | |
59 | + | |
60 | +MeshBuffer::MeshBuffer(MeshBuffer *pSrc, const class D3D9Mesh *_pRoot) | |
61 | +{ | |
62 | + nVtx = pSrc->nVtx; | |
63 | + nIdx = pSrc->nIdx; | |
64 | + | |
65 | + pVB = NULL; | |
66 | + pIB = NULL; | |
67 | + pGB = NULL; | |
68 | + | |
69 | + pVBSys = new NMVERTEX[nVtx]; | |
70 | + pIBSys = new WORD[nIdx]; | |
71 | + pGBSys = new D3DXVECTOR4[nVtx]; | |
72 | + | |
73 | + memcpy(pVBSys, pSrc->pVBSys, sizeof(NMVERTEX) * nVtx); | |
74 | + memcpy(pGBSys, pSrc->pGBSys, sizeof(D3DXVECTOR4) * nVtx); | |
75 | + memcpy(pIBSys, pSrc->pIBSys, sizeof(WORD) * nIdx); | |
76 | + | |
77 | + pRoot = _pRoot; | |
78 | + mapMode = MAPMODE_STATIC; | |
79 | + bMustRemap = true; | |
80 | +} | |
81 | + | |
82 | + | |
83 | +MeshBuffer::~MeshBuffer() | |
84 | +{ | |
85 | + SAFE_DELETEA(pGBSys); | |
86 | + SAFE_DELETEA(pIBSys); | |
87 | + SAFE_DELETEA(pVBSys); | |
88 | + SAFE_RELEASE(pIB); | |
89 | + SAFE_RELEASE(pVB); | |
90 | + SAFE_RELEASE(pGB); | |
91 | +} | |
92 | + | |
93 | +void MeshBuffer::MustRemap(DWORD mode) | |
94 | +{ | |
95 | + if (mode == MAPMODE_CURRENT) mode = mapMode; | |
96 | + | |
97 | + if (mode != mapMode) { | |
98 | + SAFE_RELEASE(pIB); | |
99 | + SAFE_RELEASE(pVB); | |
100 | + SAFE_RELEASE(pGB); | |
101 | + mapMode = mode; | |
102 | + } | |
103 | + | |
104 | + bMustRemap = true; | |
105 | +} | |
106 | + | |
107 | +void MeshBuffer::Map(LPDIRECT3DDEVICE9 pDev) | |
108 | +{ | |
109 | + | |
110 | + if (!bMustRemap) return; | |
111 | + | |
112 | + bMustRemap = false; | |
113 | + | |
114 | + DWORD Usage = 0; | |
115 | + DWORD Lock = 0; | |
116 | + | |
117 | + if (mapMode == MAPMODE_DYNAMIC) Usage = D3DUSAGE_DYNAMIC, Lock = D3DLOCK_DISCARD; | |
118 | + | |
119 | + if (!pVB) { | |
120 | + HR(pDev->CreateVertexBuffer(nVtx * sizeof(NMVERTEX), Usage, 0, D3DPOOL_DEFAULT, &pVB, NULL)); | |
121 | + } | |
122 | + if (!pGB) { | |
123 | + HR(pDev->CreateVertexBuffer(nVtx * sizeof(D3DXVECTOR4), Usage, 0, D3DPOOL_DEFAULT, &pGB, NULL)); | |
124 | + } | |
125 | + if (!pIB) { | |
126 | + HR(pDev->CreateIndexBuffer(nIdx * sizeof(WORD), Usage, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &pIB, NULL)); | |
127 | + } | |
128 | + | |
129 | + LPVOID pTgt; | |
130 | + | |
131 | + HR(pVB->Lock(0, 0, (LPVOID*)&pTgt, Lock)); | |
132 | + memcpy2(pTgt, pVBSys, nVtx * sizeof(NMVERTEX)); | |
133 | + HR(pVB->Unlock()); | |
134 | + | |
135 | + HR(pGB->Lock(0, 0, (LPVOID*)&pTgt, Lock)); | |
136 | + memcpy2(pTgt, pGBSys, nVtx * sizeof(D3DXVECTOR4)); | |
137 | + HR(pGB->Unlock()); | |
138 | + | |
139 | + HR(pIB->Lock(0, 0, (LPVOID*)&pTgt, Lock)); | |
140 | + memcpy2(pTgt, pIBSys, nIdx * sizeof(WORD)); | |
141 | + HR(pIB->Unlock()); | |
142 | +} | |
143 | + | |
144 | + | |
145 | + | |
146 | + | |
147 | + | |
148 | + | |
149 | + | |
150 | + | |
151 | +// ====================================================================================== | |
152 | +// Mesh Implementation | |
153 | +// ====================================================================================== | |
35 | 154 | // |
36 | 155 | void D3D9Mesh::Null() |
37 | 156 | { |
38 | - pVB = NULL; | |
39 | - pIB = NULL; | |
40 | - pGB = NULL; | |
41 | - pGBSys = NULL; | |
42 | - pIBSys = NULL; | |
43 | 157 | nGrp = 0; |
44 | 158 | Grp = NULL; |
45 | 159 | nTex = 0; |
46 | 160 | Tex = NULL; |
47 | 161 | pTune = NULL; |
48 | 162 | nMtrl = 0; |
163 | + pBuf = NULL; | |
49 | 164 | Mtrl = NULL; |
50 | 165 | pGrpTF = NULL; |
51 | 166 | sunLight = NULL; |
@@ -53,7 +168,8 @@ | ||
53 | 168 | MaxFace = 0; |
54 | 169 | MaxVert = 0; |
55 | 170 | vClass = 0; |
56 | - bDynamic = false; | |
171 | + | |
172 | + bIsTemplate = false; | |
57 | 173 | bGlobalTF = false; |
58 | 174 | bBSRecompute = true; |
59 | 175 | bBSRecomputeAll = true; |
@@ -80,6 +196,9 @@ | ||
80 | 196 | LoadMeshFromHandle(hMesh); |
81 | 197 | oapiDeleteMesh(hMesh); |
82 | 198 | } |
199 | + | |
200 | + MeshCatalog->Add(this); | |
201 | + pBuf->Map(pDev); | |
83 | 202 | } |
84 | 203 | |
85 | 204 | // =========================================================================================== |
@@ -88,6 +207,9 @@ | ||
88 | 207 | { |
89 | 208 | Null(); |
90 | 209 | LoadMeshFromHandle(hMesh, reorig, scale); |
210 | + bIsTemplate = asTemplate; | |
211 | + MeshCatalog->Add(this); | |
212 | + pBuf->Map(pDev); | |
91 | 213 | } |
92 | 214 | |
93 | 215 |
@@ -107,9 +229,6 @@ | ||
107 | 229 | Grp[i].MtrlIdx = SPEC_DEFAULT; |
108 | 230 | } |
109 | 231 | |
110 | - HR(pDev->CreateVertexBuffer(MaxVert*sizeof(NMVERTEX), 0, 0, D3DPOOL_DEFAULT, &pVB, NULL)); | |
111 | - HR(pDev->CreateIndexBuffer(MaxFace*sizeof(WORD)*3, 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &pIB, NULL)); | |
112 | - | |
113 | 232 | nMtrl = 0; |
114 | 233 | nTex = nGrp+1; |
115 | 234 | Tex = new LPD3D9CLIENTSURFACE[nTex]; |
@@ -118,6 +237,8 @@ | ||
118 | 237 | |
119 | 238 | ProcessInherit(); |
120 | 239 | |
240 | + pBuf = new MeshBuffer(MaxVert, MaxFace, this); | |
241 | + | |
121 | 242 | for (DWORD i=0;i<nGrp;i++) CopyVertices(&Grp[i], hGroup[i]); |
122 | 243 | |
123 | 244 | pGrpTF = new D3DXMATRIX[nGrp]; |
@@ -127,8 +248,9 @@ | ||
127 | 248 | MeshCatalog->Add(this); |
128 | 249 | |
129 | 250 | UpdateBoundingBox(); |
130 | - UpdateGeometryBuffer(); | |
131 | 251 | CheckMeshStatus(); |
252 | + | |
253 | + pBuf->Map(pDev); | |
132 | 254 | } |
133 | 255 | |
134 | 256 |
@@ -151,8 +273,7 @@ | ||
151 | 273 | |
152 | 274 | SetGroupRec(0, pGroup); |
153 | 275 | |
154 | - HR(pDev->CreateVertexBuffer(MaxVert*sizeof(NMVERTEX), 0, 0, D3DPOOL_DEFAULT, &pVB, NULL)); | |
155 | - HR(pDev->CreateIndexBuffer(MaxFace*sizeof(WORD)*3, 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &pIB, NULL)); | |
276 | + pBuf = new MeshBuffer(MaxVert, MaxFace, this); | |
156 | 277 | |
157 | 278 | SetMaterial((const D3DMATERIAL9*)pMat, 0, false); |
158 | 279 | CopyVertices(&Grp[0], pGroup); |
@@ -162,93 +283,62 @@ | ||
162 | 283 | MeshCatalog->Add(this); |
163 | 284 | |
164 | 285 | UpdateBoundingBox(); |
165 | - UpdateGeometryBuffer(); | |
166 | 286 | CheckMeshStatus(); |
287 | + | |
288 | + pBuf->Map(pDev); | |
167 | 289 | } |
168 | 290 | |
169 | 291 | |
170 | 292 | // =========================================================================================== |
293 | +// Create new Instance from a template mesh | |
171 | 294 | // |
172 | -void D3D9Mesh::Copy(const D3D9Mesh &mesh) | |
295 | +D3D9Mesh::D3D9Mesh(MESHHANDLE hMesh, const D3D9Mesh &hTemp) | |
173 | 296 | { |
174 | 297 | Null(); |
175 | 298 | |
176 | - bModulateMatAlpha = mesh.bModulateMatAlpha; | |
177 | - strcpy_s(name, 128, mesh.name); | |
178 | - | |
179 | - nGrp = mesh.nGrp; | |
180 | - Grp = new GROUPREC[nGrp]; | |
181 | - pGrpTF = new D3DXMATRIX[nGrp]; | |
182 | - | |
183 | - MaxFace = mesh.MaxFace; | |
184 | - MaxVert = mesh.MaxVert; | |
185 | - | |
186 | - memcpy2(Grp, mesh.Grp, sizeof(GROUPREC)*nGrp); | |
187 | - | |
188 | - HR(pDev->CreateVertexBuffer(MaxVert*sizeof(NMVERTEX), 0, 0, D3DPOOL_DEFAULT, &pVB, NULL)); | |
189 | - HR(pDev->CreateIndexBuffer(MaxFace*sizeof(WORD)*3, 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &pIB, NULL)); | |
190 | - | |
191 | - // ---------------------------------------------------------------- | |
192 | - | |
193 | - LPVOID pVSrc, pVTgt; | |
194 | - LPVOID pISrc, pITgt; | |
195 | - | |
196 | - HR(mesh.pIB->Lock(0, 0, &pISrc, 0)); | |
197 | - HR(pIB->Lock(0, 0, &pITgt, 0)); | |
198 | - memcpy2(pITgt, pISrc, MaxFace*6); | |
199 | - HR(mesh.pIB->Unlock()); | |
200 | - HR(pIB->Unlock()); | |
299 | + // Confirm the source is global template | |
300 | + assert(hTemp.bIsTemplate == true); | |
301 | + | |
302 | + nGrp = oapiMeshGroupCount(hMesh); assert(nGrp == hTemp.nGrp); | |
303 | + | |
304 | + if (nGrp == 0) return; | |
305 | + | |
306 | + strcpy_s(name, 128, hTemp.name); | |
307 | + | |
308 | + // Use Template's Vertex Data directly, no need for a local copy unless locally modified. | |
309 | + pBuf = hTemp.pBuf; | |
310 | + | |
311 | + MaxVert = hTemp.MaxVert; | |
312 | + MaxFace = hTemp.MaxFace; | |
201 | 313 | |
202 | - | |
203 | - HR(mesh.pVB->Lock(0, 0, (LPVOID*)&pVSrc, 0)); | |
204 | - HR(pVB->Lock(0, 0, (LPVOID*)&pVTgt, 0)); | |
205 | - memcpy2(pVTgt, pVSrc, MaxVert*sizeof(NMVERTEX)); | |
206 | - HR(mesh.pVB->Unlock()); | |
207 | - HR(pVB->Unlock()); | |
208 | - | |
209 | - // ---------------------------------------------------------------- | |
210 | - | |
211 | - if (mesh.pGB) { | |
212 | - | |
213 | - // Create Geometry Buffers | |
214 | - HR(pDev->CreateVertexBuffer(MaxVert*sizeof(D3DXVECTOR4), 0, 0, D3DPOOL_DEFAULT, &pGB, NULL)); | |
215 | - | |
216 | - HR(mesh.pGB->Lock(0, 0, (LPVOID*)&pVSrc, 0)); | |
217 | - HR(pGB->Lock(0, 0, (LPVOID*)&pVTgt, 0)); | |
218 | - memcpy2(pVTgt, pVSrc, MaxVert*sizeof(D3DXVECTOR4)); | |
219 | - HR(mesh.pGB->Unlock()); | |
220 | - HR(pGB->Unlock()); | |
221 | - | |
222 | - if (mesh.pGBSys) { | |
223 | - pGBSys = new D3DXVECTOR3[MaxVert]; | |
224 | - memcpy2(pGBSys, mesh.pGBSys, MaxVert * sizeof(D3DXVECTOR3)); | |
225 | - } | |
226 | - | |
227 | - if (mesh.pIBSys) { | |
228 | - pIBSys = new WORD[MaxFace * 3]; | |
229 | - memcpy2(pIBSys, mesh.pIBSys, MaxFace * 3 * sizeof(WORD)); | |
230 | - } | |
231 | - } | |
232 | - | |
233 | - // ---------------------------------------------------------------- | |
234 | - | |
235 | - nTex = mesh.nTex; | |
314 | + // Clone group records from a tremplate | |
315 | + Grp = new GROUPREC[nGrp]; | |
316 | + memcpy(Grp, hTemp.Grp, sizeof(GROUPREC)*nGrp); | |
317 | + | |
318 | + if (MaxVert == 0 || MaxFace == 0) return; | |
319 | + | |
320 | + // ----------------------------------------------------------------------- | |
321 | + nTex = oapiMeshTextureCount(hMesh) + 1; assert(nTex == hTemp.nTex); | |
236 | 322 | Tex = new LPD3D9CLIENTSURFACE[nTex]; |
237 | - | |
238 | - for (DWORD i=0;i<nTex;i++) Tex[i] = mesh.Tex[i]; | |
239 | - | |
240 | - nMtrl = mesh.nMtrl; | |
323 | + Tex[0] = 0; // 'no texture' | |
324 | + for (DWORD i = 1; i<nTex; i++) Tex[i] = SURFACE(oapiGetTextureHandle(hMesh, i)); | |
325 | + | |
326 | + // ----------------------------------------------------------------------- | |
327 | + nMtrl = oapiMeshMaterialCount(hMesh); assert(nMtrl == hTemp.nMtrl); | |
241 | 328 | if (nMtrl) Mtrl = new D3D9MatExt[nMtrl]; |
242 | - memcpy2 (Mtrl, mesh.Mtrl, nMtrl*sizeof(D3D9MatExt)); | |
243 | - | |
244 | - mTransform = mesh.mTransform; | |
245 | - mTransformInv = mesh.mTransformInv; | |
246 | - bGlobalTF = mesh.bGlobalTF; | |
329 | + for (DWORD i = 0; i<nMtrl; i++) SetMaterial((const D3DMATERIAL9*)oapiMeshMaterial(hMesh, i), i, false); | |
330 | + | |
331 | + pGrpTF = new D3DXMATRIX[nGrp]; | |
332 | + | |
333 | + D3DXMatrixIdentity(&mTransform); | |
334 | + D3DXMatrixIdentity(&mTransformInv); | |
247 | 335 | |
248 | 336 | MeshCatalog->Add(this); |
249 | 337 | |
250 | 338 | UpdateBoundingBox(); |
251 | 339 | CheckMeshStatus(); |
340 | + | |
341 | + // No need to "pBuf->Map(pDev)" here, source template is already mapped | |
252 | 342 | } |
253 | 343 | |
254 | 344 |
@@ -257,7 +347,6 @@ | ||
257 | 347 | D3D9Mesh::~D3D9Mesh() |
258 | 348 | { |
259 | 349 | _TRACE; |
260 | - if (!pVB) return; | |
261 | 350 | |
262 | 351 | if (MeshCatalog->Remove(this)) LogAlw("Mesh 0x%X Removed from catalog",this); |
263 | 352 | else LogErr("Mesh 0x%X wasn't in meshcatalog",this); |
@@ -278,22 +367,70 @@ | ||
278 | 367 | SAFE_DELETEA(Mtrl); |
279 | 368 | SAFE_DELETEA(pGrpTF); |
280 | 369 | SAFE_DELETEA(pTune); |
281 | - SAFE_RELEASE(pIB); | |
282 | - SAFE_RELEASE(pVB); | |
283 | - SAFE_RELEASE(pGB); | |
284 | - | |
285 | - SAFE_DELETEA(pGBSys); | |
286 | - SAFE_DELETEA(pIBSys); | |
370 | + | |
371 | + if (pBuf) if (pBuf->IsLocalTo(this)) delete pBuf; | |
287 | 372 | } |
288 | 373 | |
289 | 374 | |
290 | 375 | // =========================================================================================== |
376 | +// Reload a mesh file in response to VESSEL::MeshModified() call | |
291 | 377 | // |
378 | + | |
292 | 379 | void D3D9Mesh::ReLoadMeshFromHandle(MESHHANDLE hMesh) |
293 | 380 | { |
294 | - Release(); | |
295 | - Null(); | |
296 | - LoadMeshFromHandle(hMesh); | |
381 | + | |
382 | + // Relese buffers, Tex, Mtrl and Grp counts may have changed. | |
383 | + SAFE_DELETEA(Tex); | |
384 | + SAFE_DELETEA(Mtrl); | |
385 | + SAFE_DELETEA(pGrpTF); | |
386 | + SAFE_DELETEA(Grp); | |
387 | + | |
388 | + nGrp = oapiMeshGroupCount(hMesh); | |
389 | + | |
390 | + if (nGrp == 0) return; | |
391 | + | |
392 | + Grp = new GROUPREC[nGrp]; | |
393 | + memset2(Grp, 0, sizeof(GROUPREC) * nGrp); | |
394 | + | |
395 | + MaxFace = 0; // Incremented in SetGroupRec() | |
396 | + MaxVert = 0; | |
397 | + | |
398 | + for (DWORD i = 0; i<nGrp; i++) SetGroupRec(i, oapiMeshGroupEx(hMesh, i)); | |
399 | + | |
400 | + if (MaxVert == 0 || MaxFace == 0) { | |
401 | + if (pBuf) if (pBuf->IsLocalTo(this)) { | |
402 | + delete pBuf; pBuf = NULL; | |
403 | + } | |
404 | + return; | |
405 | + } | |
406 | + | |
407 | + // If this is an instance, Create a local vertex buffers... | |
408 | + if (pBuf->IsLocalTo(this) == false) pBuf = new MeshBuffer(MaxVert, MaxFace, this); | |
409 | + | |
410 | + // ----------------------------------------------------------------------- | |
411 | + nTex = oapiMeshTextureCount(hMesh) + 1; | |
412 | + Tex = new LPD3D9CLIENTSURFACE[nTex]; | |
413 | + Tex[0] = 0; // 'no texture' | |
414 | + for (DWORD i = 1; i<nTex; i++) Tex[i] = SURFACE(oapiGetTextureHandle(hMesh, i)); | |
415 | + // ----------------------------------------------------------------------- | |
416 | + nMtrl = oapiMeshMaterialCount(hMesh); | |
417 | + if (nMtrl) Mtrl = new D3D9MatExt[nMtrl]; | |
418 | + for (DWORD i = 0; i<nMtrl; i++) SetMaterial((const D3DMATERIAL9*)oapiMeshMaterial(hMesh, i), i, false); | |
419 | + // ----------------------------------------------------------------------- | |
420 | + | |
421 | + ProcessInherit(); | |
422 | + | |
423 | + for (DWORD i = 0; i<nGrp; i++) CopyVertices(&Grp[i], oapiMeshGroupEx(hMesh, i)); | |
424 | + | |
425 | + pGrpTF = new D3DXMATRIX[nGrp]; | |
426 | + | |
427 | + D3DXMatrixIdentity(&mTransform); | |
428 | + D3DXMatrixIdentity(&mTransformInv); | |
429 | + | |
430 | + UpdateBoundingBox(); | |
431 | + CheckMeshStatus(); | |
432 | + | |
433 | + pBuf->Map(pDev); | |
297 | 434 | } |
298 | 435 | |
299 | 436 |
@@ -302,14 +439,16 @@ | ||
302 | 439 | void D3D9Mesh::LoadMeshFromHandle(MESHHANDLE hMesh, D3DXVECTOR3 *reorig, float *scale) |
303 | 440 | { |
304 | 441 | nGrp = oapiMeshGroupCount(hMesh); |
442 | + | |
305 | 443 | if (nGrp == 0) return; |
306 | 444 | |
307 | 445 | Grp = new GROUPREC[nGrp]; memset2(Grp, 0, sizeof(GROUPREC) * nGrp); |
446 | + | |
308 | 447 | for (DWORD i = 0; i<nGrp; i++) SetGroupRec(i, oapiMeshGroupEx(hMesh, i)); |
448 | + | |
309 | 449 | if (MaxVert == 0 || MaxFace == 0) return; |
310 | 450 | |
311 | - HR(pDev->CreateVertexBuffer(MaxVert*sizeof(NMVERTEX), 0, 0, D3DPOOL_DEFAULT, &pVB, NULL)); | |
312 | - HR(pDev->CreateIndexBuffer(MaxFace*sizeof(WORD) * 3, 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &pIB, NULL)); | |
451 | + pBuf = new MeshBuffer(MaxVert, MaxFace, this); | |
313 | 452 | |
314 | 453 | // ----------------------------------------------------------------------- |
315 | 454 | nTex = oapiMeshTextureCount(hMesh) + 1; |
@@ -330,57 +469,24 @@ | ||
330 | 469 | |
331 | 470 | D3DXMatrixIdentity(&mTransform); |
332 | 471 | D3DXMatrixIdentity(&mTransformInv); |
333 | - MeshCatalog->Add(this); | |
334 | 472 | |
335 | 473 | UpdateBoundingBox(); |
336 | - UpdateGeometryBuffer(); | |
337 | 474 | CheckMeshStatus(); |
338 | 475 | } |
339 | 476 | |
340 | 477 | |
341 | 478 | // =========================================================================================== |
342 | 479 | // |
343 | -void D3D9Mesh::ConvertToDynamic() | |
344 | -{ | |
345 | - if (bDynamic) return; | |
346 | - bDynamic = true; | |
347 | - | |
348 | - LPDIRECT3DVERTEXBUFFER9 pVN = NULL; | |
349 | - LPDIRECT3DINDEXBUFFER9 pIN = NULL; | |
350 | - | |
351 | - HR(pDev->CreateVertexBuffer(MaxVert*sizeof(NMVERTEX), D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &pVN, NULL)); | |
352 | - HR(pDev->CreateIndexBuffer(MaxFace*sizeof(WORD) * 3, D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &pIN, NULL)); | |
353 | - LPVOID pSrc, pTgt; | |
354 | - | |
355 | - HR(pVB->Lock(0, 0, (LPVOID*)&pSrc, 0)); | |
356 | - HR(pVN->Lock(0, 0, (LPVOID*)&pTgt, 0)); | |
357 | - memcpy2(pTgt, pSrc, MaxVert*sizeof(NMVERTEX)); | |
358 | - HR(pVB->Unlock()); | |
359 | - HR(pVN->Unlock()); | |
360 | - HR(pIB->Lock(0, 0, (LPVOID*)&pSrc, 0)); | |
361 | - HR(pIN->Lock(0, 0, (LPVOID*)&pTgt, 0)); | |
362 | - memcpy2(pTgt, pSrc, MaxFace * 6); | |
363 | - HR(pIB->Unlock()); | |
364 | - HR(pIN->Unlock()); | |
365 | - SAFE_RELEASE(pVB); | |
366 | - SAFE_RELEASE(pIB); | |
367 | - pVB = pVN; | |
368 | - pIB = pIN; | |
369 | -} | |
370 | - | |
371 | -// =========================================================================================== | |
372 | -// | |
373 | 480 | void D3D9Mesh::SetName(const char *fname) |
374 | 481 | { |
375 | 482 | if (fname) strcpy_s(name,128,fname); |
376 | - if (!pVB) LogErr("No vertices in a mesh [%s]. Invalid Mesh",name); | |
377 | 483 | } |
378 | 484 | |
379 | 485 | // =========================================================================================== |
380 | 486 | // |
381 | 487 | bool D3D9Mesh::HasShadow() |
382 | 488 | { |
383 | - if (!pVB) return false; | |
489 | + if (!IsOK()) return false; | |
384 | 490 | for (DWORD g=0; g<nGrp; g++) { |
385 | 491 | if (Grp[g].UsrFlag & 3) continue; |
386 | 492 | if (Grp[g].IntFlag & 3) continue; |
@@ -395,7 +501,7 @@ | ||
395 | 501 | void D3D9Mesh::ProcessInherit() |
396 | 502 | { |
397 | 503 | _TRACE; |
398 | - if (!pVB) return; | |
504 | + if (!IsOK()) return; | |
399 | 505 | if (Grp[0].MtrlIdx == SPEC_INHERIT) Grp[0].MtrlIdx = SPEC_DEFAULT; |
400 | 506 | if (Grp[0].TexIdx == SPEC_INHERIT) Grp[0].TexIdx = SPEC_DEFAULT; |
401 | 507 | if (Grp[0].TexIdxEx[0] == SPEC_INHERIT) Grp[0].TexIdxEx[0] = SPEC_DEFAULT; |
@@ -421,79 +527,29 @@ | ||
421 | 527 | |
422 | 528 | // Do some safety checks |
423 | 529 | if (Grp[i].TexIdx>=nTex) { |
424 | - LogErr("Mesh(0x%X) has a texture index %u in group %u out of range. Constr=%u", this, Grp[i].TexIdx, i, Constr); | |
530 | + LogErr("Mesh(0x%X) has a texture index %u in group %u out of range.", this, Grp[i].TexIdx, i); | |
425 | 531 | Grp[i].TexIdx = 0; |
426 | 532 | bPopUp = true; |
427 | 533 | } |
428 | 534 | if (Grp[i].TexIdxEx[0]>=nTex) { |
429 | - LogErr("Mesh(0x%X) has a night texture index %u in group %u out of range. Constr=%u", this, Grp[i].TexIdxEx[0], i, Constr); | |
535 | + LogErr("Mesh(0x%X) has a night texture index %u in group %u out of range.", this, Grp[i].TexIdxEx[0], i); | |
430 | 536 | Grp[i].TexIdxEx[0] = 0; |
431 | 537 | bPopUp = true; |
432 | 538 | } |
433 | 539 | |
434 | 540 | if (Grp[i].MtrlIdx!=SPEC_DEFAULT) { |
435 | 541 | if (Grp[i].MtrlIdx>=nMtrl) { |
436 | - LogErr("Mesh(0x%X) has a material index %u in group %u out of range. Constr=%u", this, Grp[i].MtrlIdx, i, Constr); | |
542 | + LogErr("Mesh(0x%X) has a material index %u in group %u out of range.", this, Grp[i].MtrlIdx, i); | |
437 | 543 | Grp[i].MtrlIdx = SPEC_DEFAULT; |
438 | 544 | bPopUp = true; |
439 | 545 | } |
440 | 546 | } |
441 | 547 | } |
442 | - if (bPopUp) MessageBoxA(NULL, "Invalid Mesh Detected", "D3D9Client Error:",MB_OK); | |
443 | -} | |
444 | - | |
445 | - | |
446 | -// =========================================================================================== | |
447 | -// | |
448 | -void D3D9Mesh::UpdateGeometryBuffer(int grp) | |
449 | -{ | |
450 | - if (!pVB) return; | |
451 | - | |
452 | - if (!pGB) { | |
453 | - HR(pDev->CreateVertexBuffer(MaxVert * sizeof(D3DXVECTOR4), 0, 0, D3DPOOL_DEFAULT, &pGB, NULL)); | |
454 | - } | |
455 | - | |
456 | - if (!pGBSys) pGBSys = new D3DXVECTOR3[MaxVert]; | |
457 | - if (!pIBSys) pIBSys = new WORD[MaxFace * 3]; | |
458 | - | |
459 | - | |
460 | - WORD *pIdx = NULL; | |
461 | - HR(pIB->Lock(0, 0, (LPVOID*)&pIdx, 0)); | |
462 | - if (pIdx) { | |
463 | - memcpy2(pIBSys, pIdx, MaxFace * 3 * sizeof(WORD)); | |
464 | - HR(pIB->Unlock()); | |
548 | + | |
549 | + if (bPopUp) { | |
550 | + assert(false); | |
551 | + MessageBoxA(NULL, "Invalid Mesh Detected", "D3D9Client Error:", MB_OK); | |
465 | 552 | } |
466 | - | |
467 | - | |
468 | - NMVERTEX *pVSrc = NULL; | |
469 | - D3DXVECTOR4 *pVTgt = NULL; | |
470 | - | |
471 | - HR(pVB->Lock(0, 0, (LPVOID*)&pVSrc, 0)); | |
472 | - HR(pGB->Lock(0, 0, (LPVOID*)&pVTgt, 0)); | |
473 | - | |
474 | - if (!pVSrc || !pVTgt) { | |
475 | - LogErr("UpdateGeometryBuffer() Failed to lock a buffer"); | |
476 | - return; | |
477 | - } | |
478 | - | |
479 | - if (grp == -1) { | |
480 | - for (DWORD v = 0; v < MaxVert; v++) { | |
481 | - pVTgt[v] = D3DXVECTOR4(pVSrc[v].x, pVSrc[v].y, pVSrc[v].z, 0); | |
482 | - pGBSys[v] = D3DXVECTOR3(pVSrc[v].x, pVSrc[v].y, pVSrc[v].z); | |
483 | - } | |
484 | - } | |
485 | - else { | |
486 | - DWORD nV = Grp[grp].nVert; | |
487 | - DWORD vo = Grp[grp].VertOff; | |
488 | - for (DWORD v = 0; v < nV; v++) { | |
489 | - int x = vo + v; | |
490 | - pVTgt[x] = D3DXVECTOR4(pVSrc[x].x, pVSrc[x].y, pVSrc[x].z, 0); | |
491 | - pGBSys[x] = D3DXVECTOR3(pVSrc[x].x, pVSrc[x].y, pVSrc[x].z); | |
492 | - } | |
493 | - } | |
494 | - | |
495 | - HR(pVB->Unlock()); | |
496 | - HR(pGB->Unlock()); | |
497 | 553 | } |
498 | 554 | |
499 | 555 |
@@ -501,7 +557,7 @@ | ||
501 | 557 | // |
502 | 558 | D3DXVECTOR3 D3D9Mesh::GetGroupSize(DWORD idx) |
503 | 559 | { |
504 | - if (!pVB) return D3DXVECTOR3(0,0,0); | |
560 | + if (!IsOK()) return D3DXVECTOR3(0,0,0); | |
505 | 561 | if (idx>=nGrp) return D3DXVECTOR3(0,0,0); |
506 | 562 | if (Grp[idx].nVert<2) return D3DXVECTOR3(0,0,0); |
507 | 563 | return D3DXVECTOR3f4(Grp[idx].BBox.max - Grp[idx].BBox.min); |
@@ -513,7 +569,7 @@ | ||
513 | 569 | void D3D9Mesh::ResetTransformations() |
514 | 570 | { |
515 | 571 | _TRACE; |
516 | - if (!pVB) return; | |
572 | + if (!IsOK()) return; | |
517 | 573 | D3DXMatrixIdentity(&mTransform); |
518 | 574 | D3DXMatrixIdentity(&mTransformInv); |
519 | 575 | bGlobalTF = false; |
@@ -531,7 +587,7 @@ | ||
531 | 587 | // |
532 | 588 | void D3D9Mesh::UpdateTangentSpace(NMVERTEX *pVrt, WORD *pIdx, DWORD nVtx, DWORD nFace, bool bTextured) |
533 | 589 | { |
534 | - if (!pVB) return; | |
590 | + if (!IsOK()) return; | |
535 | 591 | |
536 | 592 | if (bTextured) { |
537 | 593 |
@@ -589,86 +645,28 @@ | ||
589 | 645 | } |
590 | 646 | } |
591 | 647 | |
592 | -/*void D3D9Mesh::UpdateTangentSpace(NMVERTEX *pVrt, WORD *pIdx, DWORD nVtx, DWORD nFace, bool bTextured) | |
593 | -{ | |
594 | - if (!pVB) return; | |
595 | - | |
596 | - if (bTextured) { | |
597 | - | |
598 | - D3DXVECTOR3 *ta = new D3DXVECTOR3[nVtx]; | |
599 | - | |
600 | - for (DWORD i = 0; i<nVtx; i++) ta[i] = D3DXVECTOR3(0, 0, 0); | |
601 | - | |
602 | - for (DWORD i = 0; i<nFace; i++) { | |
603 | - | |
604 | - DWORD i0 = pIdx[i * 3]; | |
605 | - DWORD i1 = pIdx[i * 3 + 1]; | |
606 | - DWORD i2 = pIdx[i * 3 + 2]; | |
607 | - | |
608 | - D3DXVECTOR3 r0 = D3DXVECTOR3(pVrt[i0].x, pVrt[i0].y, pVrt[i0].z); | |
609 | - D3DXVECTOR3 r1 = D3DXVECTOR3(pVrt[i1].x, pVrt[i1].y, pVrt[i1].z); | |
610 | - D3DXVECTOR3 r2 = D3DXVECTOR3(pVrt[i2].x, pVrt[i2].y, pVrt[i2].z); | |
611 | - D3DXVECTOR2 t0 = D3DXVECTOR2(pVrt[i0].u, pVrt[i0].v); | |
612 | - D3DXVECTOR2 t1 = D3DXVECTOR2(pVrt[i1].u, pVrt[i1].v); | |
613 | - D3DXVECTOR2 t2 = D3DXVECTOR2(pVrt[i2].u, pVrt[i2].v); | |
614 | - | |
615 | - float u0 = t1.x - t0.x; | |
616 | - float v0 = t1.y - t0.y; | |
617 | - float u1 = t2.x - t0.x; | |
618 | - float v1 = t2.y - t0.y; | |
619 | - | |
620 | - D3DXVECTOR3 k0 = r1 - r0; | |
621 | - D3DXVECTOR3 k1 = r2 - r0; | |
622 | - | |
623 | - float q = (u0*v1 - u1*v0); | |
624 | - if (q == 0) q = 1.0f; | |
625 | - else q = 1.0f / q; | |
626 | - | |
627 | - D3DXVECTOR3 t = ((k0*v1 - k1*v0) * q); | |
628 | - ta[i0] += t; ta[i1] += t; ta[i2] += t; | |
629 | - pVrt[i0].w = pVrt[i1].w = pVrt[i2].w = (q<0.0f ? 1.0f : -1.0f); | |
630 | - } | |
631 | - | |
632 | - for (DWORD i = 0; i<nVtx; i++) { | |
633 | - | |
634 | - D3DXVECTOR3 n = D3DXVECTOR3(pVrt[i].nx, pVrt[i].ny, pVrt[i].nz); | |
635 | - D3DXVec3Normalize(&n, &n); | |
636 | - D3DXVECTOR3 t = (ta[i] - n * D3DXVec3Dot(&ta[i], &n)); | |
637 | - D3DXVec3Normalize(&t, &t); | |
638 | - | |
639 | - pVrt[i].tx = t.x; | |
640 | - pVrt[i].ty = t.y; | |
641 | - pVrt[i].tz = t.z; | |
642 | - } | |
643 | - | |
644 | - delete[]ta; | |
645 | - } | |
646 | - else { | |
647 | - for (DWORD i = 0; i<nVtx; i++) { | |
648 | - D3DXVECTOR3 n = D3DXVECTOR3(pVrt[i].nx, pVrt[i].ny, pVrt[i].nz); | |
649 | - D3DXVECTOR3 t = Perpendicular(&n); | |
650 | - D3DXVec3Normalize(&t, &t); | |
651 | - pVrt[i].tx = t.x; | |
652 | - pVrt[i].ty = t.y; | |
653 | - pVrt[i].tz = t.z; | |
654 | - } | |
655 | - } | |
656 | -}*/ | |
657 | - | |
658 | 648 | |
659 | 649 | // =========================================================================================== |
660 | 650 | // |
661 | 651 | void D3D9Mesh::SetGroupRec(DWORD i, const MESHGROUPEX *mg) |
662 | 652 | { |
663 | 653 | if (i>=nGrp) return; |
654 | + | |
664 | 655 | memcpy2(Grp[i].TexIdxEx, mg->TexIdxEx, MAXTEX*sizeof(DWORD)); |
665 | 656 | memcpy2(Grp[i].TexMixEx, mg->TexMixEx, MAXTEX*sizeof(float)); |
657 | + | |
666 | 658 | Grp[i].TexIdx = mg->TexIdx; |
667 | 659 | Grp[i].MtrlIdx = mg->MtrlIdx; |
668 | - Grp[i].FaceOff = MaxFace; | |
660 | + Grp[i].IdexOff = MaxFace*3; | |
669 | 661 | Grp[i].VertOff = MaxVert; |
670 | 662 | Grp[i].nFace = mg->nIdx/3; |
671 | 663 | Grp[i].nVert = mg->nVtx; |
664 | + Grp[i].UsrFlag = mg->UsrFlag; | |
665 | + Grp[i].IntFlag = mg->Flags; | |
666 | + Grp[i].zBias = mg->zBias; | |
667 | + | |
668 | + D3DXMatrixIdentity(&Grp[i].Transform); | |
669 | + | |
672 | 670 | MaxFace += Grp[i].nFace; |
673 | 671 | MaxVert += Grp[i].nVert; |
674 | 672 | } |
@@ -678,20 +676,10 @@ | ||
678 | 676 | // |
679 | 677 | bool D3D9Mesh::CopyVertices(GROUPREC *grp, const MESHGROUPEX *mg, D3DXVECTOR3 *reorig, float *scale) |
680 | 678 | { |
681 | - if (!pVB) return false; | |
682 | - | |
683 | - grp->UsrFlag = mg->UsrFlag; | |
684 | - grp->IntFlag = mg->Flags; | |
685 | - grp->zBias = mg->zBias; | |
686 | - | |
687 | - D3DXMatrixIdentity(&grp->Transform); | |
688 | - | |
689 | - WORD *pIndex; | |
690 | - NMVERTEX *pVert; | |
691 | 679 | NTVERTEX *pNT = mg->Vtx; |
692 | - | |
693 | - HR(pIB->Lock(grp->FaceOff*6, grp->nFace*6, (LPVOID*)&pIndex, 0)); | |
694 | - HR(pVB->Lock(grp->VertOff*sizeof(NMVERTEX), grp->nVert*sizeof(NMVERTEX), (LPVOID*)&pVert, 0)); | |
680 | + NMVERTEX *pVert = pBuf->pVBSys + grp->VertOff; | |
681 | + D3DXVECTOR4 *pGeo = pBuf->pGBSys + grp->VertOff; | |
682 | + WORD *pIndex = pBuf->pIBSys + grp->IdexOff; | |
695 | 683 | |
696 | 684 | for (DWORD i=0;i<mg->nIdx;i++) pIndex[i] = mg->Idx[i]; |
697 | 685 |
@@ -715,6 +703,7 @@ | ||
715 | 703 | |
716 | 704 | pVert[i].u = pNT[i].tu; |
717 | 705 | pVert[i].v = pNT[i].tv; |
706 | + | |
718 | 707 | pVert[i].w = 1.0f; |
719 | 708 | pVert[i].tx = 1.0f; |
720 | 709 | pVert[i].ty = 0.0f; |
@@ -725,6 +714,8 @@ | ||
725 | 714 | pVert[i].y += reorig->y; |
726 | 715 | pVert[i].z += reorig->z; |
727 | 716 | } |
717 | + | |
718 | + pGeo[i] = D3DXVECTOR4(pVert[i].x, pVert[i].y, pVert[i].z, 0); | |
728 | 719 | } |
729 | 720 | |
730 | 721 | // Check vertex index errors (This is important) |
@@ -742,74 +733,17 @@ | ||
742 | 733 | if (mg->nVtx>0) BoundingBox(pVert, mg->nVtx, &grp->BBox); |
743 | 734 | else D9ZeroAABB(&grp->BBox); |
744 | 735 | |
745 | - HR(pIB->Unlock()); | |
746 | - HR(pVB->Unlock()); | |
747 | - | |
748 | 736 | return true; |
749 | 737 | } |
750 | 738 | |
751 | 739 | |
752 | 740 | // =========================================================================================== |
753 | -// | |
754 | -void D3D9Mesh::UpdateGroup(MESHHANDLE hMesh, DWORD idx) | |
755 | -{ | |
756 | - _TRACE; | |
757 | - if (!pVB) return; | |
758 | - if (hMesh) { | |
759 | - MESHGROUPEX *mg = oapiMeshGroupEx(hMesh, idx); | |
760 | - if (mg) { | |
761 | - assert(mg->nVtx == Grp[idx].nVert); | |
762 | - assert(mg->nIdx == Grp[idx].nFace*3); | |
763 | - CopyVertices(&Grp[idx], mg); | |
764 | - UpdateGeometryBuffer(); | |
765 | - } | |
766 | - } | |
767 | -} | |
768 | - | |
769 | - | |
770 | -// =========================================================================================== | |
771 | -// Mesh Update routine for AMSO | |
772 | -// | |
773 | -void D3D9Mesh::UpdateGroupEx(DWORD idx, const MESHGROUPEX *mg) | |
774 | -{ | |
775 | - _TRACE; | |
776 | - if (!pVB) return; | |
777 | - GROUPREC *grp = &Grp[idx]; | |
778 | - NMVERTEX *pVert = LockVertexBuffer(idx,0); | |
779 | - NTVERTEX *pNT = mg->Vtx; | |
780 | - | |
781 | - if (pVert) { | |
782 | - | |
783 | - for (DWORD i=0;i<mg->nVtx;i++) { | |
784 | - pVert[i].x = pNT[i].x; | |
785 | - pVert[i].y = pNT[i].y; | |
786 | - pVert[i].z = pNT[i].z; | |
787 | - } | |
788 | - | |
789 | - if (Config->UseNormalMap) { | |
790 | - WORD *idx=0; | |
791 | - if (pIB->Lock(grp->FaceOff*6, grp->nFace*6, (LPVOID*)&idx, 0)==S_OK) { | |
792 | - UpdateTangentSpace(pVert, idx, grp->nVert, grp->nFace, grp->TexIdx!=0); | |
793 | - pIB->Unlock(); | |
794 | - } | |
795 | - } | |
796 | - | |
797 | - if (mg->nVtx>0) BoundingBox(pVert, mg->nVtx, &grp->BBox); | |
798 | - else D9ZeroAABB(&grp->BBox); | |
799 | - | |
800 | - UnLockVertexBuffer(); | |
801 | - UpdateGeometryBuffer(); | |
802 | - } | |
803 | -} | |
804 | - | |
805 | - | |
806 | -// =========================================================================================== | |
807 | 741 | // This is required by Client implementation see clbkEditMeshGroup |
808 | 742 | // |
809 | 743 | int D3D9Mesh::EditGroup(DWORD grp, GROUPEDITSPEC *ges) |
810 | 744 | { |
811 | 745 | _TRACE; |
812 | - if (!pVB) return 1; | |
746 | + if (!IsOK()) return 1; | |
813 | 747 | if (grp >= nGrp) return 1; |
814 | 748 | |
815 | 749 | bBSRecompute = true; |
@@ -824,9 +758,20 @@ | ||
824 | 758 | |
825 | 759 | if (flag & GRPEDIT_VTX) { |
826 | 760 | |
827 | - if (!bDynamic) ConvertToDynamic(); | |
828 | - | |
829 | - NMVERTEX *vtx = LockVertexBuffer(grp,0); | |
761 | + if (pBuf->IsLocalTo(this) == false) | |
762 | + { | |
763 | + // Can't make modifications to a global template | |
764 | + // Create a local copy of the Mesh | |
765 | + // TODO: Create local copy of the group only | |
766 | + pBuf = new MeshBuffer(pBuf, this); | |
767 | + } | |
768 | + | |
769 | + pBuf->MustRemap(MAPMODE_CURRENT); | |
770 | + | |
771 | + D3DXVECTOR4 *pGeo = pBuf->pGBSys + g->VertOff; | |
772 | + NMVERTEX *vtx = pBuf->pVBSys + g->VertOff; | |
773 | + WORD *idx = pBuf->pIBSys + g->IdexOff; | |
774 | + | |
830 | 775 | DWORD i, vi; |
831 | 776 | if (vtx) { |
832 | 777 | for (i = 0; i < ges->nVtx; i++) { |
@@ -849,21 +794,17 @@ | ||
849 | 794 | else if (flag & GRPEDIT_VTXTEXADDU) vtx[vi].u += ges->Vtx[i].tu; |
850 | 795 | if (flag & GRPEDIT_VTXTEXV) vtx[vi].v = ges->Vtx[i].tv; |
851 | 796 | else if (flag & GRPEDIT_VTXTEXADDV) vtx[vi].v += ges->Vtx[i].tv; |
797 | + | |
798 | + if ((flag & GRPEDIT_VTXCRD)!=0 || (flag & GRPEDIT_VTXCRDADD)!=0) { | |
799 | + pGeo[vi] = D3DXVECTOR4(vtx[vi].x, vtx[vi].y, vtx[vi].z, 0); | |
800 | + } | |
852 | 801 | } |
853 | 802 | } |
854 | 803 | |
855 | - if (Config->UseNormalMap) { | |
856 | - WORD *idx=0; | |
857 | - if (pIB->Lock(g->FaceOff*6, g->nFace*6, (LPVOID*)&idx, D3DLOCK_READONLY)==S_OK) { | |
858 | - UpdateTangentSpace(vtx, idx, g->nVert, g->nFace, g->TexIdx!=0); | |
859 | - pIB->Unlock(); | |
860 | - } | |
861 | - } | |
804 | + if (Config->UseNormalMap) UpdateTangentSpace(vtx, idx, g->nVert, g->nFace, g->TexIdx!=0); | |
862 | 805 | |
863 | 806 | if (g->nVert>0) BoundingBox(vtx, g->nVert, &g->BBox); |
864 | 807 | else D9ZeroAABB(&g->BBox); |
865 | - | |
866 | - UnLockVertexBuffer(); | |
867 | 808 | } |
868 | 809 | } |
869 | 810 | return 0; |
@@ -890,7 +831,7 @@ | ||
890 | 831 | int ret = 0; |
891 | 832 | |
892 | 833 | if (grs->nVtx && grs->Vtx) { // vertex data requested |
893 | - NMVERTEX *vtx = LockVertexBuffer(grp, D3DLOCK_READONLY); | |
834 | + NMVERTEX *vtx = pBuf->pVBSys + Grp[grp].VertOff; | |
894 | 835 | if (vtx) { |
895 | 836 | if (grs->VtxPerm) { // random access data request |
896 | 837 | for (i = 0; i < grs->nVtx; i++) { |
@@ -906,13 +847,12 @@ | ||
906 | 847 | if (grs->nVtx > nv) grs->nVtx = nv; |
907 | 848 | for (i=0;i<grs->nVtx;i++) grs->Vtx[i] = Convert(vtx[i]); |
908 | 849 | } |
909 | - UnLockVertexBuffer(); | |
910 | 850 | } |
911 | 851 | else return 1; |
912 | 852 | } |
913 | 853 | |
914 | 854 | if (grs->nIdx && grs->Idx) { // index data requested |
915 | - WORD *idx = LockIndexBuffer(grp, D3DLOCK_READONLY); | |
855 | + WORD *idx = pBuf->pIBSys + Grp[grp].IdexOff; | |
916 | 856 | if (idx) { |
917 | 857 | if (grs->IdxPerm) { // random access data request |
918 | 858 | for (i = 0; i < grs->nIdx; i++) { |
@@ -928,7 +868,6 @@ | ||
928 | 868 | if (grs->nIdx > ni) grs->nIdx = ni; |
929 | 869 | for (i=0;i<grs->nIdx;i++) grs->Idx[i] = idx[i]; |
930 | 870 | } |
931 | - UnLockIndexBuffer(); | |
932 | 871 | } |
933 | 872 | else return 1; |
934 | 873 | } |
@@ -950,7 +889,7 @@ | ||
950 | 889 | bool D3D9Mesh::SetTexture(DWORD texidx, LPD3D9CLIENTSURFACE tex) |
951 | 890 | { |
952 | 891 | _TRACE; |
953 | - if (!pVB) return false; | |
892 | + if (!IsOK()) return false; | |
954 | 893 | if (texidx >= nTex) { |
955 | 894 | LogErr("D3D9Mesh::SetTexture(%u, 0x%X) index out of range",texidx,tex); |
956 | 895 | return false; |
@@ -965,7 +904,7 @@ | ||
965 | 904 | // |
966 | 905 | DWORD D3D9Mesh::GetMeshGroupMaterialIdx(DWORD idx) const |
967 | 906 | { |
968 | - if (!pVB) return 0; | |
907 | + if (!IsOK()) return 0; | |
969 | 908 | if (idx>=nGrp) return 0; |
970 | 909 | return Grp[idx].MtrlIdx; |
971 | 910 | } |
@@ -974,7 +913,7 @@ | ||
974 | 913 | // |
975 | 914 | DWORD D3D9Mesh::GetMeshGroupTextureIdx(DWORD idx) const |
976 | 915 | { |
977 | - if (!pVB) return 0; | |
916 | + if (!IsOK()) return 0; | |
978 | 917 | if (idx>=nGrp) return 0; |
979 | 918 | return Grp[idx].TexIdx; |
980 | 919 | } |
@@ -983,7 +922,7 @@ | ||
983 | 922 | // |
984 | 923 | bool D3D9Mesh::HasTexture(SURFHANDLE hSurf) |
985 | 924 | { |
986 | - if (!pVB) return false; | |
925 | + if (!IsOK()) return false; | |
987 | 926 | for (DWORD i=0;i<nTex;i++) if (Tex[i]==hSurf) return true; |
988 | 927 | return false; |
989 | 928 | } |
@@ -993,7 +932,7 @@ | ||
993 | 932 | void D3D9Mesh::SetTexMixture(DWORD ntex, float mix) |
994 | 933 | { |
995 | 934 | _TRACE; |
996 | - if (!pVB) return; | |
935 | + if (!IsOK()) return; | |
997 | 936 | ntex--; |
998 | 937 | for (DWORD g = 0; g < nGrp; g++) if (Grp[g].TexIdxEx[ntex] != SPEC_DEFAULT) Grp[g].TexMixEx[ntex] = mix; |
999 | 938 | } |
@@ -1002,75 +941,9 @@ | ||
1002 | 941 | // |
1003 | 942 | void D3D9Mesh::SetSunLight(const D3D9Sun *light) |
1004 | 943 | { |
1005 | - if (!pVB) return; | |
1006 | 944 | sunLight = light; |
1007 | 945 | } |
1008 | 946 | |
1009 | - | |
1010 | -// =========================================================================================== | |
1011 | -// | |
1012 | -NMVERTEX * D3D9Mesh::LockVertexBuffer(DWORD grp, DWORD flags) | |
1013 | -{ | |
1014 | - if (!pVB) return NULL; | |
1015 | - NMVERTEX *pVert; | |
1016 | - bBSRecompute = true; | |
1017 | - | |
1018 | - if (grp>=nGrp) { | |
1019 | - LogErr("D3D9Mesh(0x%X)::GetVertexBuffer(%u) index out of range",this,grp); | |
1020 | - return NULL; | |
1021 | - } | |
1022 | - | |
1023 | - double time = D3D9GetTime(); | |
1024 | - | |
1025 | - if (pVB->Lock(Grp[grp].VertOff*sizeof(NMVERTEX), Grp[grp].nVert*sizeof(NMVERTEX), (LPVOID*)&pVert, flags)==S_OK) { | |
1026 | - D3D9SetTime(D3D9Stats.Timer.LockWait, time); | |
1027 | - return pVert; | |
1028 | - } | |
1029 | - else { | |
1030 | - LogErr("D3D9Mesh(0x%X)::GetVertexBuffer(%u)",this,grp); | |
1031 | - return NULL; | |
1032 | - } | |
1033 | -} | |
1034 | - | |
1035 | -// =========================================================================================== | |
1036 | -// | |
1037 | -void D3D9Mesh::UnLockVertexBuffer() | |
1038 | -{ | |
1039 | - if (!pVB) return; | |
1040 | - HR(pVB->Unlock()); | |
1041 | -} | |
1042 | - | |
1043 | -// =========================================================================================== | |
1044 | -// | |
1045 | - | |
1046 | -WORD * D3D9Mesh::LockIndexBuffer(DWORD grp, DWORD flags) | |
1047 | -{ | |
1048 | - if (!pIB) return NULL; | |
1049 | - WORD *pIdx; | |
1050 | - bBSRecompute = true; | |
1051 | - | |
1052 | - if (grp>=nGrp) { | |
1053 | - LogErr("D3D9Mesh(0x%X)::LockIndexBuffer(%u) index out of range",this,grp); | |
1054 | - return NULL; | |
1055 | - } | |
1056 | - | |
1057 | - if (pIB->Lock(Grp[grp].FaceOff*6, Grp[grp].nFace*6, (LPVOID*)&pIdx, flags)==S_OK) { | |
1058 | - return pIdx; | |
1059 | - } | |
1060 | - else { | |
1061 | - LogErr("D3D9Mesh(0x%X)::LockIndexBuffer(%u)",this,grp); | |
1062 | - return NULL; | |
1063 | - } | |
1064 | -} | |
1065 | - | |
1066 | -// =========================================================================================== | |
1067 | -// | |
1068 | -void D3D9Mesh::UnLockIndexBuffer() | |
1069 | -{ | |
1070 | - if (!pIB) return; | |
1071 | - HR(pIB->Unlock()); | |
1072 | -} | |
1073 | - | |
1074 | 947 | // =========================================================================================== |
1075 | 948 | // |
1076 | 949 | DWORD D3D9Mesh::GetVertexCount(int grp) const |
@@ -1100,7 +973,7 @@ | ||
1100 | 973 | // |
1101 | 974 | const D3D9Mesh::GROUPREC *D3D9Mesh::GetGroup(DWORD idx) const |
1102 | 975 | { |
1103 | - if (!pVB) return NULL; | |
976 | + if (!IsOK()) return NULL; | |
1104 | 977 | if (idx<nGrp) return &Grp[idx]; |
1105 | 978 | return NULL; |
1106 | 979 | } |
@@ -1129,7 +1002,10 @@ | ||
1129 | 1002 | void D3D9Mesh::SetMaterial(const D3DMATERIAL9 *pMat, DWORD idx, bool bStat) |
1130 | 1003 | { |
1131 | 1004 | D3D9MatExt Mat; |
1132 | - CreateMatExt(pMat, &Mat); | |
1005 | + if (pMat == NULL) { | |
1006 | + LogErr("MeshMaterial is NULL, likely from oapiMeshMaterial() name=[%s], index=%d", name, idx); | |
1007 | + CreateDefaultMat(&Mat); | |
1008 | + } else CreateMatExt(pMat, &Mat); | |
1133 | 1009 | SetMaterial(&Mat, idx, bStat); |
1134 | 1010 | } |
1135 | 1011 |
@@ -1321,7 +1197,7 @@ | ||
1321 | 1197 | void D3D9Mesh::SetAmbientColor(D3DCOLOR c) |
1322 | 1198 | { |
1323 | 1199 | _TRACE; |
1324 | - if (!pVB) return; | |
1200 | + if (!IsOK()) return; | |
1325 | 1201 | cAmbient = c; |
1326 | 1202 | } |
1327 | 1203 |
@@ -1330,7 +1206,7 @@ | ||
1330 | 1206 | void D3D9Mesh::SetupFog(const LPD3DXMATRIX pW) |
1331 | 1207 | { |
1332 | 1208 | _TRACE; |
1333 | - if (!pVB) return; | |
1209 | + if (!IsOK()) return; | |
1334 | 1210 | FX->SetVector(eAttennuate, &D3DXVECTOR4(1,1,1,1)); |
1335 | 1211 | FX->SetVector(eInScatter, &D3DXVECTOR4(0,0,0,0)); |
1336 | 1212 | } |
@@ -1347,12 +1223,14 @@ | ||
1347 | 1223 | void D3D9Mesh::RenderGroup(const GROUPREC *grp) |
1348 | 1224 | { |
1349 | 1225 | _TRACE; |
1350 | - if (!pVB) return; | |
1226 | + if (!IsOK()) return; | |
1351 | 1227 | if (!grp) return; |
1228 | + pBuf->Map(pDev); | |
1229 | + | |
1352 | 1230 | pDev->SetVertexDeclaration(pMeshVertexDecl); |
1353 | - pDev->SetStreamSource(0, pVB, 0, sizeof(NMVERTEX)); | |
1354 | - pDev->SetIndices(pIB); | |
1355 | - pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, grp->VertOff, 0, grp->nVert, grp->FaceOff*3, grp->nFace); | |
1231 | + pDev->SetStreamSource(0, pBuf->pVB, 0, sizeof(NMVERTEX)); | |
1232 | + pDev->SetIndices(pBuf->pIB); | |
1233 | + pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, grp->VertOff, 0, grp->nVert, grp->IdexOff, grp->nFace); | |
1356 | 1234 | D3D9Stats.Mesh.Vertices += grp->nVert; |
1357 | 1235 | D3D9Stats.Mesh.MeshGrps++; |
1358 | 1236 | } |
@@ -1435,6 +1313,10 @@ | ||
1435 | 1313 | { |
1436 | 1314 | |
1437 | 1315 | _TRACE; |
1316 | + | |
1317 | + if (!IsOK()) return; | |
1318 | + | |
1319 | + pBuf->Map(pDev); | |
1438 | 1320 | |
1439 | 1321 | // Check material status |
1440 | 1322 | // |
@@ -1455,9 +1337,6 @@ | ||
1455 | 1337 | |
1456 | 1338 | const VCHUDSPEC *hudspec; |
1457 | 1339 | |
1458 | - if (!pVB) return; | |
1459 | - | |
1460 | - | |
1461 | 1340 | if (DebugControls::IsActive()) { |
1462 | 1341 | flags = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDEBUGFLAGS); |
1463 | 1342 | selmsh = *(DWORD*)gc->GetConfigParam(CFGPRM_GETSELECTEDMESH); |
@@ -1529,8 +1408,8 @@ | ||
1529 | 1408 | LPD3D9CLIENTSURFACE old_tex = NULL; |
1530 | 1409 | |
1531 | 1410 | pDev->SetVertexDeclaration(pMeshVertexDecl); |
1532 | - pDev->SetStreamSource(0, pVB, 0, sizeof(NMVERTEX)); | |
1533 | - pDev->SetIndices(pIB); | |
1411 | + pDev->SetStreamSource(0, pBuf->pVB, 0, sizeof(NMVERTEX)); | |
1412 | + pDev->SetIndices(pBuf->pIB); | |
1534 | 1413 | |
1535 | 1414 | if (flags&DBG_FLAGS_DUALSIDED) pDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); |
1536 | 1415 |
@@ -1904,11 +1783,11 @@ | ||
1904 | 1783 | if (Grp[g].bDualSided) { |
1905 | 1784 | pDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); |
1906 | 1785 | pDev->SetRenderState(D3DRS_ZWRITEENABLE, 0); |
1907 | - pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].FaceOff * 3, Grp[g].nFace); | |
1786 | + pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].IdexOff, Grp[g].nFace); | |
1908 | 1787 | pDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); |
1909 | 1788 | } |
1910 | 1789 | |
1911 | - pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].FaceOff*3, Grp[g].nFace); | |
1790 | + pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].IdexOff, Grp[g].nFace); | |
1912 | 1791 | |
1913 | 1792 | Grp[g].bRendered = true; |
1914 | 1793 |
@@ -1950,7 +1829,9 @@ | ||
1950 | 1829 | |
1951 | 1830 | const VCHUDSPEC *hudspec; |
1952 | 1831 | |
1953 | - if (!pVB) return; | |
1832 | + if (!IsOK()) return; | |
1833 | + | |
1834 | + pBuf->Map(pDev); | |
1954 | 1835 | |
1955 | 1836 | if (DebugControls::IsActive()) { |
1956 | 1837 | flags = *(DWORD*)gc->GetConfigParam(CFGPRM_GETDEBUGFLAGS); |
@@ -2022,8 +1903,8 @@ | ||
2022 | 1903 | LPDIRECT3DTEXTURE9 pEmis_old = NULL; |
2023 | 1904 | |
2024 | 1905 | pDev->SetVertexDeclaration(pMeshVertexDecl); |
2025 | - pDev->SetStreamSource(0, pVB, 0, sizeof(NMVERTEX)); | |
2026 | - pDev->SetIndices(pIB); | |
1906 | + pDev->SetStreamSource(0, pBuf->pVB, 0, sizeof(NMVERTEX)); | |
1907 | + pDev->SetIndices(pBuf->pIB); | |
2027 | 1908 | |
2028 | 1909 | if (flags&DBG_FLAGS_DUALSIDED) pDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); |
2029 | 1910 |
@@ -2239,11 +2120,11 @@ | ||
2239 | 2120 | if (Grp[g].bDualSided) { |
2240 | 2121 | pDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); |
2241 | 2122 | pDev->SetRenderState(D3DRS_ZWRITEENABLE, 0); |
2242 | - pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].FaceOff * 3, Grp[g].nFace); | |
2123 | + pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].IdexOff, Grp[g].nFace); | |
2243 | 2124 | pDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); |
2244 | 2125 | } |
2245 | 2126 | |
2246 | - pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].FaceOff * 3, Grp[g].nFace); | |
2127 | + pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].IdexOff, Grp[g].nFace); | |
2247 | 2128 | |
2248 | 2129 | Grp[g].bRendered = true; |
2249 | 2130 |
@@ -2320,7 +2201,7 @@ | ||
2320 | 2201 | // |
2321 | 2202 | void D3D9Mesh::RenderBaseTile(const LPD3DXMATRIX pW) |
2322 | 2203 | { |
2323 | - if (!pVB) return; | |
2204 | + if (!IsOK()) return; | |
2324 | 2205 | |
2325 | 2206 | Scene *scn = gc->GetScene(); |
2326 | 2207 |
@@ -2338,8 +2219,8 @@ | ||
2338 | 2219 | LPDIRECT3DTEXTURE9 pNorm = NULL; |
2339 | 2220 | |
2340 | 2221 | pDev->SetVertexDeclaration(pMeshVertexDecl); |
2341 | - pDev->SetStreamSource(0, pVB, 0, sizeof(NMVERTEX)); | |
2342 | - pDev->SetIndices(pIB); | |
2222 | + pDev->SetStreamSource(0, pBuf->pVB, 0, sizeof(NMVERTEX)); | |
2223 | + pDev->SetIndices(pBuf->pIB); | |
2343 | 2224 | |
2344 | 2225 | if (sunLight) FX->SetValue(eSun, sunLight, sizeof(D3D9Sun)); |
2345 | 2226 |
@@ -2431,7 +2312,7 @@ | ||
2431 | 2312 | |
2432 | 2313 | FX->CommitChanges(); |
2433 | 2314 | |
2434 | - pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].FaceOff*3, Grp[g].nFace); | |
2315 | + pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].IdexOff, Grp[g].nFace); | |
2435 | 2316 | |
2436 | 2317 | D3D9Stats.Mesh.Vertices += Grp[g].nVert; |
2437 | 2318 | D3D9Stats.Mesh.MeshGrps++; |
@@ -2446,7 +2327,7 @@ | ||
2446 | 2327 | // |
2447 | 2328 | void D3D9Mesh::RenderShadows(float alpha, const LPD3DXMATRIX pW, bool bShadowMap) |
2448 | 2329 | { |
2449 | - if (!pIB || !pGB) return; | |
2330 | + if (!IsOK()) return; | |
2450 | 2331 | |
2451 | 2332 | D3DXMATRIX GroupMatrix, mWorldMesh; UINT numPasses = 0; |
2452 | 2333 |
@@ -2456,8 +2337,8 @@ | ||
2456 | 2337 | D3D9Stats.Mesh.Meshes++; |
2457 | 2338 | |
2458 | 2339 | pDev->SetVertexDeclaration(pVector4Decl); |
2459 | - pDev->SetStreamSource(0, pGB, 0, sizeof(D3DXVECTOR4)); | |
2460 | - pDev->SetIndices(pIB); | |
2340 | + pDev->SetStreamSource(0, pBuf->pGB, 0, sizeof(D3DXVECTOR4)); | |
2341 | + pDev->SetIndices(pBuf->pIB); | |
2461 | 2342 | |
2462 | 2343 | //if (bShadowMap) pDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); |
2463 | 2344 |
@@ -2504,7 +2385,7 @@ | ||
2504 | 2385 | } |
2505 | 2386 | } |
2506 | 2387 | |
2507 | - pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].FaceOff * 3, Grp[g].nFace); | |
2388 | + pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].IdexOff, Grp[g].nFace); | |
2508 | 2389 | |
2509 | 2390 | D3D9Stats.Mesh.Vertices += Grp[g].nVert; |
2510 | 2391 | D3D9Stats.Mesh.MeshGrps++; |
@@ -2524,13 +2405,13 @@ | ||
2524 | 2405 | // |
2525 | 2406 | void D3D9Mesh::RenderShadowsEx(float alpha, const LPD3DXMATRIX pP, const LPD3DXMATRIX pW, const D3DXVECTOR4 *light, const D3DXVECTOR4 *param) |
2526 | 2407 | { |
2527 | - if (!pVB || !pGB) return; | |
2408 | + if (!IsOK()) return; | |
2528 | 2409 | |
2529 | 2410 | D3D9Stats.Mesh.Meshes++; |
2530 | 2411 | |
2531 | 2412 | pDev->SetVertexDeclaration(pVector4Decl); |
2532 | - pDev->SetStreamSource(0, pGB, 0, sizeof(D3DXVECTOR4)); | |
2533 | - pDev->SetIndices(pIB); | |
2413 | + pDev->SetStreamSource(0, pBuf->pGB, 0, sizeof(D3DXVECTOR4)); | |
2414 | + pDev->SetIndices(pBuf->pIB); | |
2534 | 2415 | |
2535 | 2416 | FX->SetTechnique(eShadowTech); |
2536 | 2417 | FX->SetMatrix(eW, pW); |
@@ -2548,7 +2429,7 @@ | ||
2548 | 2429 | if (Grp[g].UsrFlag & 0x3) continue; |
2549 | 2430 | if (Grp[g].IntFlag & 0x3) continue; |
2550 | 2431 | |
2551 | - pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].FaceOff * 3, Grp[g].nFace); | |
2432 | + pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, Grp[g].VertOff, 0, Grp[g].nVert, Grp[g].IdexOff, Grp[g].nFace); | |
2552 | 2433 | |
2553 | 2434 | D3D9Stats.Mesh.Vertices += Grp[g].nVert; |
2554 | 2435 | D3D9Stats.Mesh.MeshGrps++; |
@@ -2567,7 +2448,7 @@ | ||
2567 | 2448 | { |
2568 | 2449 | _TRACE; |
2569 | 2450 | |
2570 | - if (!pVB) return; | |
2451 | + if (!IsOK()) return; | |
2571 | 2452 | if (DebugControls::IsActive()==false) return; |
2572 | 2453 | |
2573 | 2454 | D3DXMATRIX q, qq; |
@@ -2663,27 +2544,6 @@ | ||
2663 | 2544 | |
2664 | 2545 | // =========================================================================================== |
2665 | 2546 | // |
2666 | -/*void D3D9Mesh::BoundingBox(const NMVERTEX *vtx, DWORD n, D9BBox *box) | |
2667 | -{ | |
2668 | - if (!pVB) return; | |
2669 | - box->min.x = box->max.x = vtx[0].x; | |
2670 | - box->min.y = box->max.y = vtx[0].y; | |
2671 | - box->min.z = box->max.z = vtx[0].z; | |
2672 | - | |
2673 | - for (DWORD i=1;i<n;i++) { | |
2674 | - if (vtx[i].x < box->min.x) box->min.x=vtx[i].x; | |
2675 | - else if (vtx[i].x > box->max.x) box->max.x=vtx[i].x; | |
2676 | - if (vtx[i].y < box->min.y) box->min.y=vtx[i].y; | |
2677 | - else if (vtx[i].y > box->max.y) box->max.y = vtx[i].y; | |
2678 | - if (vtx[i].z < box->min.z) box->min.z=vtx[i].z; | |
2679 | - else if (vtx[i].z > box->max.z) box->max.z=vtx[i].z; | |
2680 | - } | |
2681 | - | |
2682 | - box->min.w = box->max.w = 0.0f; | |
2683 | -}*/ | |
2684 | - | |
2685 | -// =========================================================================================== | |
2686 | -// | |
2687 | 2547 | |
2688 | 2548 | void D3D9Mesh::BoundingBox(const NMVERTEX *vtx, DWORD n, D9BBox *box) |
2689 | 2549 | { |
@@ -2702,7 +2562,7 @@ | ||
2702 | 2562 | // |
2703 | 2563 | void D3D9Mesh::TransformGroup(DWORD n, const D3DXMATRIX *m) |
2704 | 2564 | { |
2705 | - if (!pVB) return; | |
2565 | + if (!IsOK()) return; | |
2706 | 2566 | |
2707 | 2567 | bBSRecompute = true; |
2708 | 2568 |
@@ -2717,7 +2577,7 @@ | ||
2717 | 2577 | // |
2718 | 2578 | void D3D9Mesh::Transform(const D3DXMATRIX *m) |
2719 | 2579 | { |
2720 | - if (!pVB) return; | |
2580 | + if (!IsOK()) return; | |
2721 | 2581 | |
2722 | 2582 | bBSRecompute = true; |
2723 | 2583 | bBSRecomputeAll = true; |
@@ -2770,7 +2630,7 @@ | ||
2770 | 2630 | // |
2771 | 2631 | void D3D9Mesh::UpdateBoundingBox() |
2772 | 2632 | { |
2773 | - if (!pVB) return; | |
2633 | + if (!IsOK()) return; | |
2774 | 2634 | if (bBSRecompute==false) return; |
2775 | 2635 | |
2776 | 2636 | for (DWORD i=0;i<nGrp;i++) { |
@@ -2818,7 +2678,7 @@ | ||
2818 | 2678 | // |
2819 | 2679 | D9BBox * D3D9Mesh::GetAABB() |
2820 | 2680 | { |
2821 | - if (!pVB) return false; | |
2681 | + if (!IsOK()) return false; | |
2822 | 2682 | UpdateBoundingBox(); |
2823 | 2683 | return &BBox; |
2824 | 2684 | } |
@@ -2827,7 +2687,7 @@ | ||
2827 | 2687 | // |
2828 | 2688 | D3DXVECTOR3 D3D9Mesh::GetBoundingSpherePos() |
2829 | 2689 | { |
2830 | - if (!pVB) return D3DXVECTOR3(0,0,0); | |
2690 | + if (!IsOK()) return D3DXVECTOR3(0,0,0); | |
2831 | 2691 | UpdateBoundingBox(); |
2832 | 2692 | return D3DXVECTOR3f4(BBox.bs); |
2833 | 2693 | } |
@@ -2836,7 +2696,7 @@ | ||
2836 | 2696 | // |
2837 | 2697 | float D3D9Mesh::GetBoundingSphereRadius() |
2838 | 2698 | { |
2839 | - if (!pVB) return 0.0f; | |
2699 | + if (!IsOK()) return 0.0f; | |
2840 | 2700 | UpdateBoundingBox(); |
2841 | 2701 | return BBox.bs.w; |
2842 | 2702 | } |
@@ -2852,7 +2712,7 @@ | ||
2852 | 2712 | result.group = -1; |
2853 | 2713 | result.idx = -1; |
2854 | 2714 | |
2855 | - if (!pGBSys || !pIBSys) { | |
2715 | + if (!pBuf->pGBSys || !pBuf->pIBSys) { | |
2856 | 2716 | LogErr("D3D9Mesh::Pick() Failed: No Geometry Available"); |
2857 | 2717 | return result; |
2858 | 2718 | } |
@@ -2887,8 +2747,8 @@ | ||
2887 | 2747 | |
2888 | 2748 | D3DXVECTOR3 _a, _b, _c, cp; |
2889 | 2749 | |
2890 | - WORD *pIdc = &pIBSys[Grp[g].FaceOff*3]; | |
2891 | - D3DXVECTOR3 *pVrt = &pGBSys[Grp[g].VertOff]; | |
2750 | + WORD *pIdc = pBuf->pIBSys + Grp[g].IdexOff; | |
2751 | + D3DXVECTOR4 *pVrt = pBuf->pGBSys + Grp[g].VertOff; | |
2892 | 2752 | |
2893 | 2753 | D3DXMATRIX mWI; float det; |
2894 | 2754 | D3DXMatrixInverse(&mWI, &det, &mW); |
@@ -2904,9 +2764,9 @@ | ||
2904 | 2764 | WORD b = pIdc[i*3+1]; |
2905 | 2765 | WORD c = pIdc[i*3+2]; |
2906 | 2766 | |
2907 | - _a = pVrt[a]; | |
2908 | - _b = pVrt[b]; | |
2909 | - _c = pVrt[c]; | |
2767 | + _a = D3DXVECTOR3f4(pVrt[a]); | |
2768 | + _b = D3DXVECTOR3f4(pVrt[b]); | |
2769 | + _c = D3DXVECTOR3f4(pVrt[c]); | |
2910 | 2770 | |
2911 | 2771 | float u, v, dst; |
2912 | 2772 |
@@ -2945,16 +2805,16 @@ | ||
2945 | 2805 | |
2946 | 2806 | D3DXVECTOR3 cp; |
2947 | 2807 | |
2948 | - WORD *pIdc = &pIBSys[Grp[g].FaceOff * 3]; | |
2949 | - D3DXVECTOR3 *pVrt = &pGBSys[Grp[g].VertOff]; | |
2808 | + WORD *pIdc = &pBuf->pIBSys[Grp[g].IdexOff]; | |
2809 | + D3DXVECTOR4 *pVrt = &pBuf->pGBSys[Grp[g].VertOff]; | |
2950 | 2810 | |
2951 | 2811 | WORD a = pIdc[i * 3 + 0]; |
2952 | 2812 | WORD b = pIdc[i * 3 + 1]; |
2953 | 2813 | WORD c = pIdc[i * 3 + 2]; |
2954 | 2814 | |
2955 | - D3DXVECTOR3 _a = pVrt[a]; | |
2956 | - D3DXVECTOR3 _b = pVrt[b]; | |
2957 | - D3DXVECTOR3 _c = pVrt[c]; | |
2815 | + D3DXVECTOR3 _a = D3DXVECTOR3f4(pVrt[a]); | |
2816 | + D3DXVECTOR3 _b = D3DXVECTOR3f4(pVrt[b]); | |
2817 | + D3DXVECTOR3 _c = D3DXVECTOR3f4(pVrt[c]); | |
2958 | 2818 | |
2959 | 2819 | float u = result.u; |
2960 | 2820 | float v = result.v; |
@@ -2971,32 +2831,6 @@ | ||
2971 | 2831 | return result; |
2972 | 2832 | } |
2973 | 2833 | |
2974 | -// =========================================================================================== | |
2975 | -// | |
2976 | -void D3D9Mesh::DumpTextures() | |
2977 | -{ | |
2978 | - /* | |
2979 | - LogBlu("Mesh 0x%X has %u textures",this, nTex-1); | |
2980 | - if (Tex[0]!=NULL) LogErr("Texture in index 0"); | |
2981 | - for (DWORD i=1;i<nTex;i++) { | |
2982 | - if (Tex[i]) LogBlu("Texture %u: 0x%X (%s)", i, Tex[i], Tex[i]->GetName()); | |
2983 | - else LogBlu("Texture %u: NULL"); | |
2984 | - }*/ | |
2985 | -} | |
2986 | - | |
2987 | -// =========================================================================================== | |
2988 | -// | |
2989 | -void D3D9Mesh::DumpGroups() | |
2990 | -{ | |
2991 | - /* | |
2992 | - LogAlw("Mesh 0x%X has %u groups", this, nGrp); | |
2993 | - for (DWORD i=0;i<nGrp;i++) { | |
2994 | - LogAlw("Group(%u):",i); | |
2995 | - LogAlw("VertexCount = %u",Grp[i].nVert); | |
2996 | - LogAlw("FaceCount = %u",Grp[i].nFace); | |
2997 | - }*/ | |
2998 | -} | |
2999 | - | |
3000 | 2834 | |
3001 | 2835 | |
3002 | 2836 | // =========================================================================================== |
@@ -3027,7 +2861,7 @@ | ||
3027 | 2861 | void D3D9Mesh::RenderRings(const LPD3DXMATRIX pW, LPDIRECT3DTEXTURE9 pTex) |
3028 | 2862 | { |
3029 | 2863 | _TRACE; |
3030 | - if (!pVB) return; | |
2864 | + if (!IsOK()) return; | |
3031 | 2865 | if (!pTex) return; |
3032 | 2866 | |
3033 | 2867 | D3D9Stats.Mesh.Vertices += Grp[0].nVert; |
@@ -3051,7 +2885,7 @@ | ||
3051 | 2885 | void D3D9Mesh::RenderRings2(const LPD3DXMATRIX pW, LPDIRECT3DTEXTURE9 pTex, float irad, float orad) |
3052 | 2886 | { |
3053 | 2887 | _TRACE; |
3054 | - if (!pVB) return; | |
2888 | + if (!IsOK()) return; | |
3055 | 2889 | if (!pTex) return; |
3056 | 2890 | |
3057 | 2891 | D3D9Stats.Mesh.Vertices += Grp[0].nVert; |
@@ -3069,77 +2903,4 @@ | ||
3069 | 2903 | RenderGroup(0); |
3070 | 2904 | HR(FX->EndPass()); |
3071 | 2905 | HR(FX->End()); |
3072 | -} | |
3073 | - | |
3074 | - | |
3075 | - | |
3076 | - | |
3077 | - | |
3078 | -// =========================================================================================== | |
3079 | -// MESH EDITING SECTION | |
3080 | -// =========================================================================================== | |
3081 | -// | |
3082 | -DWORD D3D9Mesh::AddTexture(D3D9ClientSurface *pTex) | |
3083 | -{ | |
3084 | - SAFE_DELETEA(pTune); | |
3085 | - | |
3086 | - void *pBak = Tex; | |
3087 | - | |
3088 | - if (nTex==0) { | |
3089 | - nTex = 2; | |
3090 | - Tex = new LPD3D9CLIENTSURFACE[nTex]; | |
3091 | - Tex[0] = NULL; Tex[1] = pTex; | |
3092 | - return nTex-1; | |
3093 | - } else if (pBak) { | |
3094 | - Tex = new LPD3D9CLIENTSURFACE[nTex+1]; | |
3095 | - memcpy(Tex, pBak, sizeof(LPD3D9CLIENTSURFACE) * nTex); | |
3096 | - delete []pBak; | |
3097 | - Tex[nTex] = pTex; | |
3098 | - nTex++; | |
3099 | - return nTex-1; | |
3100 | - } | |
3101 | - return 0; | |
3102 | -} | |
3103 | - | |
3104 | - | |
3105 | -// =========================================================================================== | |
3106 | -// | |
3107 | -DWORD D3D9Mesh::AddMaterial(D3D9MatExt *pMat) | |
3108 | -{ | |
3109 | - void *pBak = Mtrl; | |
3110 | - Mtrl = new D3D9MatExt[nMtrl+1]; | |
3111 | - if (pBak) { | |
3112 | - memcpy(Mtrl, pBak, sizeof(D3D9MatExt)*nMtrl); | |
3113 | - delete []pBak; | |
3114 | - } | |
3115 | - memcpy(&Mtrl[nMtrl], pMat, sizeof(D3D9MatExt)); | |
3116 | - nMtrl++; | |
3117 | - return nMtrl-1; | |
3118 | -} | |
3119 | - | |
3120 | - | |
3121 | -// =========================================================================================== | |
3122 | -// | |
3123 | -void D3D9Mesh::SetMeshGroupTextureIdx(DWORD grp, DWORD tex_idx) | |
3124 | -{ | |
3125 | - Grp[grp].TexIdx = tex_idx; | |
3126 | -} | |
3127 | - | |
3128 | - | |
3129 | -// =========================================================================================== | |
3130 | -// | |
3131 | -void D3D9Mesh::SetMeshGroupMaterialIdx(DWORD grp, DWORD mtrl_idx) | |
3132 | -{ | |
3133 | - Grp[grp].MtrlIdx = mtrl_idx; | |
3134 | -} | |
3135 | - | |
3136 | - | |
3137 | -// =========================================================================================== | |
3138 | -// | |
3139 | -bool D3D9Mesh::Bake() | |
3140 | -{ | |
3141 | - UpdateBoundingBox(); | |
3142 | - UpdateGeometryBuffer(); | |
3143 | - CheckMeshStatus(); | |
3144 | - return true; | |
3145 | 2906 | } |
\ No newline at end of file |
@@ -3,7 +3,7 @@ | ||
3 | 3 | // Part of the ORBITER VISUALISATION PROJECT (OVP) |
4 | 4 | // Dual licensed under GPL v3 and LGPL v3 |
5 | 5 | // Copyright (C) 2006-2016 Martin Schweiger |
6 | -// 2012-2016 Jarmo Nikkanen | |
6 | +// 2012-2019 Jarmo Nikkanen | |
7 | 7 | // ============================================================== |
8 | 8 | |
9 | 9 | // ============================================================== |
@@ -49,12 +49,54 @@ | ||
49 | 49 | #define VCLASS_ULTRA 3 |
50 | 50 | #define VCLASS_SSU_CENTAUR 4 |
51 | 51 | |
52 | +#define MAPMODE_UNKNOWN 0 | |
53 | +#define MAPMODE_CURRENT 1 | |
54 | +#define MAPMODE_STATIC 2 | |
55 | +#define MAPMODE_DYNAMIC 3 | |
56 | + | |
57 | + | |
52 | 58 | struct _LightList { |
53 | 59 | int idx; |
54 | 60 | float illuminace; |
55 | 61 | }; |
56 | 62 | |
57 | 63 | |
64 | + | |
65 | + | |
66 | + | |
67 | +class MeshBuffer | |
68 | +{ | |
69 | +public: | |
70 | + | |
71 | + MeshBuffer(MeshBuffer *pSrc, const class D3D9Mesh *_pRoot); | |
72 | + MeshBuffer(DWORD nVtx, DWORD nIdx, const class D3D9Mesh *_pRoot); | |
73 | + ~MeshBuffer(); | |
74 | + | |
75 | + void Map(LPDIRECT3DDEVICE9 pDev); | |
76 | + bool IsLocalTo(const class D3D9Mesh *_pRoot) { return (_pRoot == pRoot); } | |
77 | + void MustRemap(DWORD mode); | |
78 | + | |
79 | + LPDIRECT3DVERTEXBUFFER9 pVB; | |
80 | + LPDIRECT3DVERTEXBUFFER9 pGB; | |
81 | + LPDIRECT3DINDEXBUFFER9 pIB; | |
82 | + | |
83 | + NMVERTEX *pVBSys; | |
84 | + D3DXVECTOR4 *pGBSys; | |
85 | + WORD *pIBSys; | |
86 | + | |
87 | + DWORD nVtx; | |
88 | + DWORD nIdx; | |
89 | + DWORD mapMode; | |
90 | + bool bMustRemap; | |
91 | + | |
92 | + const class D3D9Mesh *pRoot; | |
93 | +}; | |
94 | + | |
95 | + | |
96 | + | |
97 | + | |
98 | + | |
99 | + | |
58 | 100 | /** |
59 | 101 | * \brief Mesh object with D3D9-specific vertex buffer |
60 | 102 | * |
@@ -67,17 +109,20 @@ | ||
67 | 109 | |
68 | 110 | public: |
69 | 111 | |
70 | - bool bCanRenderFast; // Mesh doesn't contain any advanced features in any group | |
71 | - bool bIsReflective; // Mesh has a reflective material in one or more groups | |
72 | - bool bMtrlModidied; | |
112 | + bool bCanRenderFast; // Mesh doesn't contain any advanced features in any group | |
113 | + bool bIsReflective; // Mesh has a reflective material in one or more groups | |
114 | + bool bMtrlModidied; | |
115 | + bool bIsTemplate; | |
73 | 116 | |
74 | - D9BBox BBox; | |
75 | - | |
76 | - struct GROUPREC { // mesh group definition | |
117 | + D9BBox BBox; | |
118 | + MeshBuffer * pBuf; | |
119 | + | |
120 | +struct GROUPREC { // mesh group definition | |
121 | + | |
77 | 122 | DWORD VertOff; // Main mesh Vertex Offset |
78 | - DWORD FaceOff; // Main mesh Index Offset | |
123 | + DWORD IdexOff; // Main mesh Index Offset | |
79 | 124 | //------------------------------------------------ |
80 | - DWORD nFace; // Face count | |
125 | + DWORD nFace; // Face/Primitive count | |
81 | 126 | DWORD nVert; // Vertex count |
82 | 127 | //------------------------------------------------ |
83 | 128 | DWORD MtrlIdx; // material index |
@@ -93,38 +138,26 @@ | ||
93 | 138 | bool bDualSided; |
94 | 139 | bool bDeleted; // This entry is deleted by DelGroup() |
95 | 140 | bool bRendered; |
96 | - //bool bAdvanced; // This group reguires more advanced shader than default one | |
97 | 141 | D3DXMATRIX Transform; // Group specific transformation matrix |
98 | 142 | D9BBox BBox; |
99 | 143 | DWORD TexIdxEx[MAXTEX]; |
100 | 144 | float TexMixEx[MAXTEX]; |
101 | 145 | }; |
102 | 146 | |
103 | - explicit D3D9Mesh(const char *name); | |
104 | - D3D9Mesh(const D3D9Mesh &mesh) : D3D9Effect() { Copy(mesh); } | |
105 | - | |
106 | - /** | |
107 | - * \brief Create a mesh consisting of a single mesh group | |
108 | - * \param client graphics client | |
109 | - * \param grp vertex group definition | |
110 | - * \param deepcopy if true, group contents are copied; otherwise, group | |
111 | - * definition pointer is used directly | |
112 | - */ | |
147 | + | |
148 | + D3D9Mesh(const char *name); | |
113 | 149 | D3D9Mesh(DWORD nGrp, const MESHGROUPEX **hGroup, const SURFHANDLE *hSurf); |
114 | 150 | D3D9Mesh(const MESHGROUPEX *pGroup, const MATERIAL *pMat, D3D9ClientSurface *pTex); |
115 | 151 | D3D9Mesh(MESHHANDLE hMesh, bool asTemplate = false, D3DXVECTOR3 *reorig = NULL, float *scale = NULL); |
152 | + D3D9Mesh(MESHHANDLE hMesh, const D3D9Mesh &hTemp); | |
116 | 153 | ~D3D9Mesh(); |
117 | 154 | |
118 | - D3D9Mesh &operator =(const D3D9Mesh &mesh) { Copy(mesh); return *this; } | |
155 | + bool IsOK() const { return pBuf != NULL; } | |
119 | 156 | |
120 | 157 | void Release(); |
121 | 158 | |
122 | 159 | void LoadMeshFromHandle(MESHHANDLE hMesh, D3DXVECTOR3 *reorig = NULL, float *scale = NULL); |
123 | 160 | void ReLoadMeshFromHandle(MESHHANDLE hMesh); |
124 | - void UnLockVertexBuffer(); | |
125 | - void UnLockIndexBuffer(); | |
126 | - NMVERTEX * LockVertexBuffer(DWORD grp, DWORD flags); | |
127 | - WORD * LockIndexBuffer(DWORD grp, DWORD flags); | |
128 | 161 | |
129 | 162 | void SetName(const char *name); |
130 | 163 | const char * GetName() const { return name; } |
@@ -212,14 +245,11 @@ | ||
212 | 245 | void RenderAxisVector(LPD3DXMATRIX pW, const LPD3DXCOLOR pColor, float len); |
213 | 246 | |
214 | 247 | void CheckMeshStatus(); |
215 | - void ConvertToDynamic(); | |
216 | 248 | void ResetTransformations(); |
217 | 249 | void TransformGroup(DWORD n, const D3DXMATRIX *m); |
218 | 250 | void Transform(const D3DXMATRIX *m); |
219 | 251 | int GetGroup (DWORD grp, GROUPREQUESTSPEC *grs); |
220 | 252 | int EditGroup (DWORD grp, GROUPEDITSPEC *ges); |
221 | - void UpdateGroupEx(DWORD idx, const MESHGROUPEX *mg); | |
222 | - void UpdateGroup(MESHHANDLE hMesh, DWORD idx); | |
223 | 253 | |
224 | 254 | void SetSunLight(const D3D9Sun *pLight); |
225 | 255 |
@@ -232,8 +262,6 @@ | ||
232 | 262 | void SetupFog(const LPD3DXMATRIX pW); |
233 | 263 | void ResetRenderStatus(); |
234 | 264 | |
235 | - void DumpTextures(); | |
236 | - void DumpGroups(); | |
237 | 265 | |
238 | 266 | /** |
239 | 267 | * \brief Enable/disable material alpha value for transparency calculation. |
@@ -244,34 +272,19 @@ | ||
244 | 272 | * calculated as the product of material and texture alpha value. |
245 | 273 | */ |
246 | 274 | inline void EnableMatAlpha (bool enable) { bModulateMatAlpha = enable; } |
247 | - | |
248 | - DWORD AddTexture(D3D9ClientSurface *pTex); | |
249 | - DWORD AddMaterial(D3D9MatExt *pMat); | |
250 | - void SetMeshGroupTextureIdx(DWORD grp, DWORD tex_idx); | |
251 | - void SetMeshGroupMaterialIdx(DWORD grp, DWORD mtrl_idx); | |
252 | - bool Bake(); | |
253 | 275 | |
254 | 276 | private: |
255 | 277 | |
256 | - void Copy(const D3D9Mesh &mesh); | |
278 | + //void Copy(const D3D9Mesh &mesh); | |
257 | 279 | void UpdateTangentSpace(NMVERTEX *pVrt, WORD *pIdx, DWORD nVtx, DWORD nFace, bool bTextured); |
258 | 280 | void ProcessInherit(); |
259 | 281 | bool CopyVertices(GROUPREC *grp, const MESHGROUPEX *mg, D3DXVECTOR3 *reorig = NULL, float *scale = NULL); |
260 | 282 | void SetGroupRec(DWORD i, const MESHGROUPEX *mg); |
261 | - void UpdateGeometryBuffer(int grp=-1); | |
262 | 283 | void Null(); |
263 | 284 | |
264 | - LPDIRECT3DVERTEXBUFFER9 pVB; ///< (Local) Vertex buffer pointer | |
265 | - LPDIRECT3DVERTEXBUFFER9 pGB; | |
266 | - LPDIRECT3DINDEXBUFFER9 pIB; | |
267 | 285 | |
268 | - D3DXVECTOR3 *pGBSys; | |
269 | - WORD *pIBSys; | |
270 | - | |
271 | 286 | DWORD MaxVert; |
272 | 287 | DWORD MaxFace; |
273 | - DWORD Constr; | |
274 | - | |
275 | 288 | GROUPREC *Grp; // list of mesh groups |
276 | 289 | DWORD nGrp; // number of mesh groups |
277 | 290 | DWORD nMtrl; // number of mesh materials |
@@ -290,8 +303,6 @@ | ||
290 | 303 | _LightList LightList[MAX_SCENE_LIGHTS]; |
291 | 304 | LightStruct *Locals; |
292 | 305 | |
293 | - | |
294 | - bool bDynamic; // Mesh is using a dynamic vertex buffer for faster read-modify-write | |
295 | 306 | bool bBSRecompute; // Bounding sphere must be recomputed |
296 | 307 | bool bBSRecomputeAll; |
297 | 308 | bool bModulateMatAlpha; // mix material and texture alpha channels |
@@ -82,25 +82,4 @@ | ||
82 | 82 | for (i=0;i<nmlist;i++) if (mlist[i].hMesh==hMesh) return mlist[i].mesh; |
83 | 83 | // Should we store the mesh here ?? |
84 | 84 | return NULL; |
85 | -} | |
86 | - | |
87 | -void MeshManager::UpdateMesh (MESHHANDLE hMesh) | |
88 | -{ | |
89 | - int i; | |
90 | - for (i=0;i<nmlist;i++) if (mlist[i].hMesh==hMesh) { | |
91 | - if (mlist[i].mesh) { | |
92 | - DWORD ngrp = mlist[i].mesh->GetGroupCount(); | |
93 | - for (DWORD k=0;k<ngrp;k++) { | |
94 | - MESHGROUPEX *mg = oapiMeshGroupEx(hMesh, k); | |
95 | - if (mg) mlist[i].mesh->UpdateGroupEx(k, mg); | |
96 | - } | |
97 | - DWORD nMtrl = oapiMeshMaterialCount(hMesh); | |
98 | - for (DWORD k=0;k<nMtrl;k++) { | |
99 | - D3D9MatExt meshmat; | |
100 | - CreateMatExt((const D3DMATERIAL9 *)oapiMeshMaterial(hMesh, k), &meshmat); | |
101 | - mlist[i].mesh->SetMaterial(&meshmat, k); | |
102 | - } | |
103 | - } | |
104 | - break; | |
105 | - } | |
106 | 85 | } |
\ No newline at end of file |
@@ -25,7 +25,6 @@ | ||
25 | 25 | void DeleteAll(); |
26 | 26 | int StoreMesh (MESHHANDLE hMesh, const char *name); |
27 | 27 | const D3D9Mesh *GetMesh (MESHHANDLE hMesh); |
28 | - void UpdateMesh (MESHHANDLE hMesh); | |
29 | 28 | |
30 | 29 | private: |
31 | 30 | oapi::D3D9Client *gc; |
@@ -3,7 +3,7 @@ | ||
3 | 3 | // Part of the ORBITER VISUALISATION PROJECT (OVP) |
4 | 4 | // Dual licensed under GPL v3 and LGPL v3 |
5 | 5 | // Copyright (C) 2006-2016 Martin Schweiger |
6 | -// 2010-2016 Jarmo Nikkanen (D3D9Client modification) | |
6 | +// 2010-2019 Jarmo Nikkanen (D3D9Client modification) | |
7 | 7 | // ============================================================== |
8 | 8 | |
9 | 9 | #include <set> |
@@ -54,10 +54,9 @@ | ||
54 | 54 | pMatMgr = new MatMgr(this, scene->GetClient()); |
55 | 55 | for (int i = 0; i < ARRAYSIZE(pEnv); i++) pEnv[i] = NULL; |
56 | 56 | |
57 | - if (strcmp(vessel->GetClassNameA(), "AMSO") == 0) vClass = VCLASS_AMSO; | |
58 | - if (strcmp(vessel->GetClassNameA(), "XR2Ravenstar") == 0) vClass = VCLASS_XR2; | |
59 | - if (strcmp(vessel->GetClassNameA(), "SpaceShuttleUltra") == 0) vClass = VCLASS_ULTRA; | |
60 | - if (strcmp(vessel->GetClassNameA(), "SSU_CentaurGPrime") == 0) vClass = VCLASS_SSU_CENTAUR; | |
57 | + if (strncmp(vessel->GetClassNameA(), "XR2Ravenstar", 12) == 0) vClass = VCLASS_XR2; | |
58 | + if (strncmp(vessel->GetClassNameA(), "SpaceShuttleUltra", 17) == 0) vClass = VCLASS_ULTRA; | |
59 | + if (strncmp(vessel->GetClassNameA(), "SSU_CentaurGPrime", 17) == 0) vClass = VCLASS_SSU_CENTAUR; | |
61 | 60 | |
62 | 61 | bBSRecompute = true; |
63 | 62 | ExhaustLength = 0.0f; |
@@ -238,8 +237,8 @@ | ||
238 | 237 | bBSRecompute = true; |
239 | 238 | if (nmesh) DisposeMeshes(); |
240 | 239 | |
241 | - MESHHANDLE hMesh; | |
242 | - const D3D9Mesh *mesh; | |
240 | + MESHHANDLE hMesh = NULL; | |
241 | + const D3D9Mesh *mesh = NULL; | |
243 | 242 | VECTOR3 ofs; |
244 | 243 | UINT idx; |
245 | 244 |
@@ -255,20 +254,20 @@ | ||
255 | 254 | for (idx=0;idx<nmesh;idx++) { |
256 | 255 | |
257 | 256 | hMesh = vessel->GetMeshTemplate(idx); |
258 | - if (vClass==VCLASS_AMSO) mmgr->UpdateMesh(hMesh); | |
259 | 257 | mesh = mmgr->GetMesh(hMesh); |
260 | 258 | |
261 | - if (hMesh!=NULL && mesh!=NULL) { | |
259 | + if (hMesh && mesh) { | |
262 | 260 | // copy from preloaded template |
263 | - meshlist[idx].mesh = new D3D9Mesh(*mesh); | |
261 | + meshlist[idx].mesh = new D3D9Mesh(hMesh, *mesh); // Create new Instance from an existing mesh template | |
264 | 262 | meshlist[idx].mesh->SetClass(vClass); |
265 | 263 | } |
266 | 264 | else { |
267 | - // It's vital to use copy here for some reason | |
265 | + // It's vital to use "CopyMeshFromTemplate" here for some reason | |
266 | + // No global template exists for this mesh. Loaded with oapiLoadMesh() | |
268 | 267 | hMesh = vessel->CopyMeshFromTemplate(idx); |
269 | 268 | if (hMesh) { |
270 | 269 | // load on the fly and discard after copying |
271 | - meshlist[idx].mesh = new D3D9Mesh(hMesh, false); | |
270 | + meshlist[idx].mesh = new D3D9Mesh(hMesh); // Create new DX9 Mesh | |
272 | 271 | meshlist[idx].mesh->SetClass(vClass); |
273 | 272 | oapiDeleteMesh(hMesh); |
274 | 273 | } |
@@ -329,15 +328,13 @@ | ||
329 | 328 | // now add the new mesh |
330 | 329 | MeshManager *mmgr = gc->GetMeshMgr(); |
331 | 330 | MESHHANDLE hMesh = vessel->GetMeshTemplate(idx); |
332 | - if (vClass==VCLASS_AMSO) mmgr->UpdateMesh(hMesh); | |
333 | 331 | const D3D9Mesh *mesh = mmgr->GetMesh(hMesh); |
334 | 332 | |
335 | - | |
336 | 333 | if (hMesh && mesh) { |
337 | - meshlist[idx].mesh = new D3D9Mesh (*mesh); | |
334 | + meshlist[idx].mesh = new D3D9Mesh(hMesh, *mesh); // Create new Instance from an existing mesh template | |
338 | 335 | meshlist[idx].mesh->SetClass(vClass); |
339 | - } else if (hMesh = vessel->CopyMeshFromTemplate (idx)) { // It's vital to use a copy here for some reason | |
340 | - meshlist[idx].mesh = new D3D9Mesh (hMesh); | |
336 | + } else if (hMesh = vessel->CopyMeshFromTemplate (idx)) { | |
337 | + meshlist[idx].mesh = new D3D9Mesh(hMesh); // Create new DX9 Mesh | |
341 | 338 | meshlist[idx].mesh->SetClass(vClass); |
342 | 339 | oapiDeleteMesh (hMesh); |
343 | 340 | } else { |
@@ -365,6 +362,7 @@ | ||
365 | 362 | |
366 | 363 | |
367 | 364 | // ============================================================================================ |
365 | +// In response to VESSEL::MeshModified() | |
368 | 366 | // |
369 | 367 | void vVessel::ResetMesh(UINT idx) |
370 | 368 | { |
@@ -372,26 +370,27 @@ | ||
372 | 370 | |
373 | 371 | VECTOR3 ofs = _V(0, 0, 0); |
374 | 372 | |
375 | - if (idx < nmesh) { | |
373 | + if ((idx < nmesh) && meshlist[idx].mesh) { | |
376 | 374 | |
377 | 375 | MESHHANDLE hMesh = vessel->GetMeshTemplate(idx); |
378 | 376 | |
379 | 377 | if (hMesh) { |
380 | - | |
381 | 378 | meshlist[idx].mesh->ReLoadMeshFromHandle(hMesh); |
382 | - | |
383 | - pMatMgr->ApplyConfiguration(meshlist[idx].mesh); | |
379 | + meshlist[idx].mesh->ResetTransformations(); | |
380 | + } | |
381 | + else { | |
382 | + hMesh = vessel->CopyMeshFromTemplate(idx); | |
383 | + if (hMesh) { | |
384 | + meshlist[idx].mesh->ReLoadMeshFromHandle(hMesh); | |
385 | + meshlist[idx].mesh->ResetTransformations(); | |
386 | + oapiDeleteMesh(hMesh); | |
387 | + } | |
388 | + } | |
384 | 389 | |
385 | - meshlist[idx].vismode = vessel->GetMeshVisibilityMode(idx); | |
386 | - vessel->GetMeshOffset(idx, ofs); | |
387 | - | |
388 | - if (length(ofs)) { | |
389 | - if (!meshlist[idx].trans) meshlist[idx].trans = new D3DXMATRIX; | |
390 | - D3DMAT_Identity(meshlist[idx].trans); | |
391 | - D3DMAT_SetTranslation(meshlist[idx].trans, &ofs); | |
392 | - } | |
393 | - else { | |
394 | - SAFE_DELETE(meshlist[idx].trans); | |
390 | + for (UINT i = 0; i < nanim; ++i) { | |
391 | + UINT ncomp = anim[i].ncomp; | |
392 | + for (UINT k = 0; k < ncomp; ++k) { | |
393 | + if (anim[i].comp[k]->trans->mesh == idx) animstate[i] = anim[i].defstate; // reset to default animation state | |
395 | 394 | } |
396 | 395 | } |
397 | 396 | } |