1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** $Id: d3d_poly.cpp 4349 2010-12-17 15:07:11Z dj_jl $
11 //**
12 //** Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //** This program is free software; you can redistribute it and/or
15 //** modify it under the terms of the GNU General Public License
16 //** as published by the Free Software Foundation; either version 2
17 //** of the License, or (at your option) any later version.
18 //**
19 //** This program is distributed in the hope that it will be useful,
20 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 //** GNU General Public License for more details.
23 //**
24 //**************************************************************************
25
26 // HEADER FILES ------------------------------------------------------------
27
28 #include "d3d_local.h"
29
30 // MACROS ------------------------------------------------------------------
31
32 // TYPES -------------------------------------------------------------------
33
34 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
35
36 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
37
38 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
39
40 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
41
42 // PUBLIC DATA DEFINITIONS -------------------------------------------------
43
44 // PRIVATE DATA DEFINITIONS ------------------------------------------------
45
46 static byte ptex[8][8] =
47 {
48 { 0, 0, 0, 0, 0, 0, 0, 0 },
49 { 0, 0, 0, 0, 0, 0, 0, 0 },
50 { 0, 0, 0, 1, 1, 0, 0, 0 },
51 { 0, 0, 1, 1, 1, 1, 0, 0 },
52 { 0, 0, 1, 1, 1, 1, 0, 0 },
53 { 0, 0, 0, 1, 1, 0, 0, 0 },
54 { 0, 0, 0, 0, 0, 0, 0, 0 },
55 { 0, 0, 0, 0, 0, 0, 0, 0 },
56 };
57
58 // CODE --------------------------------------------------------------------
59
60 //==========================================================================
61 //
62 // MatrixMultiply
63 //
64 //==========================================================================
65
MatrixMultiply(MyD3DMatrix & out,const MyD3DMatrix & a,const MyD3DMatrix & b)66 void MatrixMultiply(MyD3DMatrix &out, const MyD3DMatrix& a, const MyD3DMatrix& b)
67 {
68 MyD3DMatrix ret;
69 for (int i = 0; i < 4; i++)
70 {
71 for (int j = 0; j < 4; j++)
72 {
73 ret(i, j) = 0.0f;
74 for (int k = 0; k < 4; k++)
75 {
76 ret(i, j) += a(i, k) * b(k, j);
77 }
78 }
79 }
80 out = ret;
81 }
82
83 //==========================================================================
84 //
85 // VDirect3DDrawer::WorldDrawing
86 //
87 //==========================================================================
88
WorldDrawing()89 void VDirect3DDrawer::WorldDrawing()
90 {
91 guard(VDirect3DDrawer::WorldDrawing);
92 MyD3DVertex out[256];
93 int lb, i;
94 surfcache_t *cache;
95 float s, t, lights, lightt;
96 surface_t *surf;
97 texinfo_t *tex;
98 vuint32 light;
99
100 // First draw horizons.
101 if (RendLev->HorizonPortalsHead)
102 {
103 for (surf = RendLev->HorizonPortalsHead; surf; surf = surf->DrawNext)
104 {
105 DoHorizonPolygon(surf);
106 }
107 }
108
109 // For sky areas we just write to the depth buffer to prevent drawing
110 // polygons behind the sky.
111 if (RendLev->SkyPortalsHead)
112 {
113 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
114 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
115 for (surf = RendLev->SkyPortalsHead; surf; surf = surf->DrawNext)
116 {
117 for (i = 0; i < surf->count; i++)
118 {
119 out[i] = MyD3DVertex(surf->verts[i], 0, 0, 0);
120 }
121 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, surf->count - 2, out, sizeof(MyD3DVertex));
122 }
123 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0f);
124 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
125 }
126
127 // Draw surfaces.
128 if (RendLev->SimpleSurfsHead)
129 {
130 for (surf = RendLev->SimpleSurfsHead; surf; surf = surf->DrawNext)
131 {
132 texinfo_t *tex = surf->texinfo;
133 SetTexture(tex->Tex, tex->ColourMap);
134
135 if (surf->lightmap != NULL ||
136 surf->dlightframe == r_dlightframecount)
137 {
138 light = 0xffffffff;
139 }
140 else
141 {
142 int lev = surf->Light >> 24;
143 int lR = ((surf->Light >> 16) & 255) * lev / 255;
144 int lG = ((surf->Light >> 8) & 255) * lev / 255;
145 int lB = (surf->Light & 255) * lev / 255;
146 light = 0xff000000 | (lR << 16) | (lG << 8) | lB;
147 }
148 SetFade(surf->Fade);
149
150 for (i = 0; i < surf->count; i++)
151 {
152 out[i] = MyD3DVertex(surf->verts[i], light,
153 (DotProduct(surf->verts[i], tex->saxis) + tex->soffs) * tex_iw,
154 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
155 }
156
157 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, surf->count - 2, out, sizeof(MyD3DVertex));
158 }
159 }
160
161 if (HaveMultiTexture)
162 {
163 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
164 RenderDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
165 RenderDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
166 RenderDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
167 RenderDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
168 RenderDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
169 RenderDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
170
171 for (lb = 0; lb < NUM_BLOCK_SURFS; lb++)
172 {
173 if (!RendLev->light_chain[lb])
174 {
175 continue;
176 }
177
178 if (!light_surf[lb])
179 {
180 light_surf[lb] = CreateSurface(BLOCK_WIDTH, BLOCK_HEIGHT, 16, false);
181 RendLev->block_changed[lb] = true;
182 }
183 if (RendLev->block_changed[lb])
184 {
185 RendLev->block_changed[lb] = false;
186 UploadTextureImage(light_surf[lb], 0, BLOCK_WIDTH, BLOCK_HEIGHT, RendLev->light_block[lb]);
187 }
188
189 RenderDevice->SetTexture(1, light_surf[lb]);
190
191 for (cache = RendLev->light_chain[lb]; cache; cache = cache->chain)
192 {
193 surf = cache->surf;
194 tex = surf->texinfo;
195 SetTexture(tex->Tex, tex->ColourMap);
196 SetFade(surf->Fade);
197 for (i = 0; i < surf->count; i++)
198 {
199 s = DotProduct(surf->verts[i], tex->saxis) + tex->soffs;
200 t = DotProduct(surf->verts[i], tex->taxis) + tex->toffs;
201 lights = (s - surf->texturemins[0]) / 16 + cache->s + 0.5;
202 lightt = (t - surf->texturemins[1]) / 16 + cache->t + 0.5;
203 out[i] = MyD3DVertex(surf->verts[i], 0xffffffff,
204 s * tex_iw, t * tex_ih,
205 lights / BLOCK_WIDTH, lightt / BLOCK_HEIGHT);
206 }
207 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, surf->count - 2, out, sizeof(MyD3DVertex));
208 }
209 }
210
211 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
212 RenderDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
213 }
214 else
215 {
216 RenderDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
217 RenderDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
218 RenderDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
219 RenderDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
220 RenderDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
221 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
222 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); // don't bother writing Z
223
224 for (lb = 0; lb < NUM_BLOCK_SURFS; lb++)
225 {
226 if (!RendLev->light_chain[lb])
227 {
228 continue;
229 }
230
231 if (!light_surf[lb])
232 {
233 light_surf[lb] = CreateSurface(BLOCK_WIDTH, BLOCK_HEIGHT, 16, false);
234 RendLev->block_changed[lb] = true;
235 }
236 if (RendLev->block_changed[lb])
237 {
238 RendLev->block_changed[lb] = false;
239 UploadTextureImage(light_surf[lb], 0, BLOCK_WIDTH, BLOCK_HEIGHT, RendLev->light_block[lb]);
240 }
241
242 RenderDevice->SetTexture(0, light_surf[lb]);
243
244 for (cache = RendLev->light_chain[lb]; cache; cache = cache->chain)
245 {
246 surf = cache->surf;
247 tex = surf->texinfo;
248 SetFade(surf->Fade);
249 for (i = 0; i < surf->count; i++)
250 {
251 s = DotProduct(surf->verts[i], tex->saxis) + tex->soffs;
252 t = DotProduct(surf->verts[i], tex->taxis) + tex->toffs;
253 lights = (s - surf->texturemins[0]) / 16 + cache->s + 0.5;
254 lightt = (t - surf->texturemins[1]) / 16 + cache->t + 0.5;
255 out[i] = MyD3DVertex(surf->verts[i], 0xffffffff,
256 lights / BLOCK_WIDTH, lightt / BLOCK_HEIGHT);
257 }
258 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, surf->count - 2, out, sizeof(MyD3DVertex));
259 }
260 }
261
262 RenderDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, magfilter);
263 RenderDevice->SetSamplerState(0, D3DSAMP_MINFILTER, minfilter);
264 RenderDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, mipfilter);
265 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
266 RenderDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
267 RenderDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
268 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); // back to normal Z buffering
269 }
270
271 //
272 // Add specular hightlights
273 //
274 if (specular_highlights)
275 {
276 RenderDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
277 RenderDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
278 RenderDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
279 RenderDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
280 RenderDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
281 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
282 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); // don't bother writing Z
283 SetFade(0);
284
285 for (lb = 0; lb < NUM_BLOCK_SURFS; lb++)
286 {
287 if (!RendLev->add_chain[lb])
288 {
289 continue;
290 }
291
292 if (!add_surf[lb])
293 {
294 add_surf[lb] = CreateSurface(BLOCK_WIDTH, BLOCK_HEIGHT, 16, false);
295 RendLev->add_changed[lb] = true;
296 }
297 if (RendLev->add_changed[lb])
298 {
299 RendLev->add_changed[lb] = false;
300 UploadTextureImage(add_surf[lb], 0, BLOCK_WIDTH, BLOCK_HEIGHT, RendLev->add_block[lb]);
301 }
302
303 RenderDevice->SetTexture(0, add_surf[lb]);
304
305 for (cache = RendLev->add_chain[lb]; cache; cache = cache->addchain)
306 {
307 surf = cache->surf;
308 tex = surf->texinfo;
309 for (i = 0; i < surf->count; i++)
310 {
311 s = DotProduct(surf->verts[i], tex->saxis) + tex->soffs;
312 t = DotProduct(surf->verts[i], tex->taxis) + tex->toffs;
313 lights = (s - surf->texturemins[0]) / 16 + cache->s + 0.5;
314 lightt = (t - surf->texturemins[1]) / 16 + cache->t + 0.5;
315 out[i] = MyD3DVertex(surf->verts[i], 0xffffffff,
316 lights / BLOCK_WIDTH, lightt / BLOCK_HEIGHT);
317 }
318 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, surf->count - 2, out, sizeof(MyD3DVertex));
319 }
320 }
321
322 RenderDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, magfilter);
323 RenderDevice->SetSamplerState(0, D3DSAMP_MINFILTER, minfilter);
324 RenderDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, mipfilter);
325 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
326 RenderDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
327 RenderDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
328 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); // back to normal Z buffering
329 }
330 unguard;
331 }
332
333 //==========================================================================
334 //
335 // VDirect3DDrawer::DoHorizonPolygon
336 //
337 //==========================================================================
338
DoHorizonPolygon(surface_t * Surf)339 void VDirect3DDrawer::DoHorizonPolygon(surface_t* Surf)
340 {
341 guard(VDirect3DDrawer::DoHorizonPolygon);
342 float Dist = 4096.0;
343 TVec v[4];
344 if (Surf->HorizonPlane->normal.z > 0.0)
345 {
346 v[0] = Surf->verts[0];
347 v[3] = Surf->verts[3];
348 TVec HDir = -Surf->plane->normal;
349
350 TVec Dir1 = Normalise(vieworg - Surf->verts[1]);
351 TVec Dir2 = Normalise(vieworg - Surf->verts[2]);
352 float Mul1 = 1.0 / DotProduct(HDir, Dir1);
353 v[1] = Surf->verts[1] + Dir1 * Mul1 * Dist;
354 float Mul2 = 1.0 / DotProduct(HDir, Dir2);
355 v[2] = Surf->verts[2] + Dir2 * Mul2 * Dist;
356 if (v[1].z < v[0].z)
357 {
358 v[1] = Surf->verts[1] + Dir1 * Mul1 * Dist * (Surf->verts[1].z -
359 Surf->verts[0].z) / (Surf->verts[1].z - v[1].z);
360 v[2] = Surf->verts[2] + Dir2 * Mul2 * Dist * (Surf->verts[2].z -
361 Surf->verts[3].z) / (Surf->verts[2].z - v[2].z);
362 }
363 }
364 else
365 {
366 v[1] = Surf->verts[1];
367 v[2] = Surf->verts[2];
368 TVec HDir = -Surf->plane->normal;
369
370 TVec Dir1 = Normalise(vieworg - Surf->verts[0]);
371 TVec Dir2 = Normalise(vieworg - Surf->verts[3]);
372 float Mul1 = 1.0 / DotProduct(HDir, Dir1);
373 v[0] = Surf->verts[0] + Dir1 * Mul1 * Dist;
374 float Mul2 = 1.0 / DotProduct(HDir, Dir2);
375 v[3] = Surf->verts[3] + Dir2 * Mul2 * Dist;
376 if (v[1].z < v[0].z)
377 {
378 v[0] = Surf->verts[0] + Dir1 * Mul1 * Dist * (Surf->verts[1].z -
379 Surf->verts[0].z) / (v[0].z - Surf->verts[0].z);
380 v[3] = Surf->verts[3] + Dir2 * Mul2 * Dist * (Surf->verts[2].z -
381 Surf->verts[3].z) / (v[3].z - Surf->verts[3].z);
382 }
383 }
384
385 texinfo_t* Tex = Surf->texinfo;
386 SetTexture(Tex->Tex, Tex->ColourMap);
387
388 int lev = Surf->Light >> 24;
389 int lR = ((Surf->Light >> 16) & 255) * lev / 255;
390 int lG = ((Surf->Light >> 8) & 255) * lev / 255;
391 int lB = (Surf->Light & 255) * lev / 255;
392 vuint32 light = 0xff000000 | (lR << 16) | (lG << 8) | lB;
393 SetFade(Surf->Fade);
394
395 // Draw it
396 MyD3DVertex out[4];
397 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
398 for (int i = 0; i < 4; i++)
399 {
400 out[i] = MyD3DVertex(v[i], light,
401 (DotProduct(v[i], Tex->saxis) + Tex->soffs) * tex_iw,
402 (DotProduct(v[i], Tex->taxis) + Tex->toffs) * tex_ih);
403 }
404 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, out, sizeof(MyD3DVertex));
405 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
406
407 // Write to the depth buffer.
408 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
409 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
410 for (int i = 0; i < Surf->count; i++)
411 {
412 out[i] = MyD3DVertex(Surf->verts[i], 0, 0, 0);
413 }
414 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, out, sizeof(MyD3DVertex));
415 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0f);
416 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
417 unguard;
418 }
419
420 //==========================================================================
421 //
422 // VDirect3DDrawer::DrawSkyPolygon
423 //
424 //==========================================================================
425
DrawSkyPolygon(surface_t * surf,bool bIsSkyBox,VTexture * Texture1,float offs1,VTexture * Texture2,float offs2,int CMap)426 void VDirect3DDrawer::DrawSkyPolygon(surface_t* surf, bool bIsSkyBox,
427 VTexture* Texture1, float offs1, VTexture* Texture2, float offs2,
428 int CMap)
429 {
430 guard(VDirect3DDrawer::DrawSkyPolygon);
431 MyD3DVertex out[256];
432 int i;
433 int sidx[4];
434
435 SetFade(surf->Fade);
436 sidx[0] = 0;
437 sidx[1] = 1;
438 sidx[2] = 2;
439 sidx[3] = 3;
440 if (!bIsSkyBox)
441 {
442 if (surf->verts[1].z > 0)
443 {
444 sidx[1] = 0;
445 sidx[2] = 3;
446 }
447 else
448 {
449 sidx[0] = 1;
450 sidx[3] = 2;
451 }
452 }
453 texinfo_t *tex = surf->texinfo;
454 if (HaveMultiTexture && Texture2->Type != TEXTYPE_Null)
455 {
456 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
457 RenderDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
458 RenderDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
459 RenderDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
460 RenderDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
461
462 SetTexture(Texture1, CMap);
463 TexStage = 1;
464 SetTexture(Texture2, CMap);
465 TexStage = 0;
466 for (i = 0; i < surf->count; i++)
467 {
468 out[i] = MyD3DVertex(surf->verts[i] + vieworg, 0xff000000 | (int(r_sky_bright_factor * 255) << 16) & 0x00ff0000 |
469 (int(r_sky_bright_factor * 255) << 8) & 0x0000ff00 | int(r_sky_bright_factor * 255) & 0x000000ff,
470 (DotProduct(surf->verts[sidx[i]], tex->saxis) + tex->soffs - offs1) * tex_iw,
471 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih,
472 (DotProduct(surf->verts[sidx[i]], tex->saxis) + tex->soffs - offs2) * tex_iw,
473 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
474 }
475 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, surf->count - 2, out, sizeof(MyD3DVertex));
476
477 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
478 RenderDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
479 }
480 else
481 {
482 SetTexture(Texture1, CMap);
483 for (i = 0; i < surf->count; i++)
484 {
485 out[i] = MyD3DVertex(surf->verts[i] + vieworg, 0xff000000 | (int(r_sky_bright_factor * 255) << 16) & 0x00ff0000 |
486 (int(r_sky_bright_factor * 255) << 8) & 0x0000ff00 | int(r_sky_bright_factor * 255) & 0x000000ff,
487 (DotProduct(surf->verts[sidx[i]], tex->saxis) + tex->soffs - offs1) * tex_iw,
488 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
489 }
490 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, surf->count - 2, out, sizeof(MyD3DVertex));
491
492 if (Texture2->Type != TEXTYPE_Null)
493 {
494 SetTexture(Texture2, CMap);
495 for (i = 0; i < surf->count; i++)
496 {
497 out[i] = MyD3DVertex(surf->verts[i] + vieworg, 0xff000000 | (int(r_sky_bright_factor * 255) << 16) & 0x00ff0000 |
498 (int(r_sky_bright_factor * 255) << 8) & 0x0000ff00 | int(r_sky_bright_factor * 255) & 0x000000ff,
499 (DotProduct(surf->verts[sidx[i]], tex->saxis) + tex->soffs - offs2) * tex_iw,
500 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
501 }
502 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
503 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, surf->count - 2, out, sizeof(MyD3DVertex));
504 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
505 }
506 }
507 unguard;
508 }
509
510 //==========================================================================
511 //
512 // VDirect3DDrawer::DrawMaskedPolygon
513 //
514 //==========================================================================
515
DrawMaskedPolygon(surface_t * surf,float Alpha,bool Additive)516 void VDirect3DDrawer::DrawMaskedPolygon(surface_t* surf, float Alpha,
517 bool Additive)
518 {
519 guard(VDirect3DDrawer::DrawMaskedPolygon);
520 MyD3DVertex out[256];
521 int l;
522
523 texinfo_t* tex = surf->texinfo;
524 SetTexture(tex->Tex, tex->ColourMap);
525
526 if (surf->lightmap != NULL ||
527 surf->dlightframe == r_dlightframecount)
528 {
529 RendLev->BuildLightMap(surf, 0);
530 int w = (surf->extents[0] >> 4) + 1;
531 int h = (surf->extents[1] >> 4) + 1;
532 int size = w * h;
533 int r = 0;
534 int g = 0;
535 int b = 0;
536 for (int i = 0; i < size; i++)
537 {
538 r += 255 * 256 - blocklightsr[i];
539 g += 255 * 256 - blocklightsg[i];
540 b += 255 * 256 - blocklightsb[i];
541 }
542 r = r / (size * 256);
543 g = g / (size * 256);
544 b = b / (size * 256);
545 int alpha = (int)(Alpha * 255);
546 l = (alpha << 24) | (r << 16) | (g << 8) | b;
547 }
548 else
549 {
550 int lev = surf->Light >> 24;
551 int lR = ((surf->Light >> 16) & 255) * lev / 255;
552 int lG = ((surf->Light >> 8) & 255) * lev / 255;
553 int lB = (surf->Light & 255) * lev / 255;
554 int alpha = (int)(Alpha * 255);
555 l = (alpha << 24) | (lR << 16) | (lG << 8) | lB;
556 }
557 SetFade(surf->Fade);
558
559 for (int i = 0; i < surf->count; i++)
560 {
561 out[i] = MyD3DVertex(surf->verts[i], l,
562 (DotProduct(surf->verts[i], tex->saxis) + tex->soffs) * tex_iw,
563 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
564 }
565
566 RenderDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
567 if (blend_sprites || Additive || Alpha < 1.0)
568 {
569 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
570 RenderDevice->SetRenderState(D3DRS_ALPHAREF, 0);
571 }
572 if (Additive)
573 {
574 RenderDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
575 }
576
577 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, surf->count - 2, out, sizeof(MyD3DVertex));
578
579 RenderDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
580 if (blend_sprites || Additive || Alpha < 1.0)
581 {
582 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
583 RenderDevice->SetRenderState(D3DRS_ALPHAREF, 170);
584 }
585 if (Additive)
586 {
587 RenderDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
588 }
589 unguard;
590 }
591
592 //==========================================================================
593 //
594 // VDirect3DDrawer::DrawSpritePolygon
595 //
596 //==========================================================================
597
DrawSpritePolygon(TVec * cv,VTexture * Tex,float Alpha,bool Additive,VTextureTranslation * Translation,int CMap,vuint32 light,vuint32 Fade,const TVec &,float,const TVec & saxis,const TVec & taxis,const TVec & texorg)598 void VDirect3DDrawer::DrawSpritePolygon(TVec *cv, VTexture* Tex, float Alpha,
599 bool Additive, VTextureTranslation* Translation, int CMap, vuint32 light,
600 vuint32 Fade, const TVec&, float, const TVec& saxis, const TVec& taxis,
601 const TVec& texorg)
602 {
603 guard(VDirect3DDrawer::DrawSpritePolygon);
604 MyD3DVertex out[4];
605
606 SetSpriteLump(Tex, Translation, CMap);
607
608 int l = ((int)(Alpha * 255) << 24) | (light & 0x00ffffff);
609 for (int i = 0; i < 4; i++)
610 {
611 TVec texpt = cv[i] - texorg;
612 out[i] = MyD3DVertex(cv[i], l,
613 DotProduct(texpt, saxis) * tex_iw,
614 DotProduct(texpt, taxis) * tex_ih);
615 }
616 SetFade(Fade);
617
618 if (blend_sprites || Additive || Alpha < 1.0)
619 {
620 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
621 RenderDevice->SetRenderState(D3DRS_ALPHAREF, 0);
622 }
623 if (Additive)
624 {
625 RenderDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
626 }
627 RenderDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
628
629 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, out, sizeof(MyD3DVertex));
630
631 if (blend_sprites || Additive || Alpha < 1.0)
632 {
633 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
634 RenderDevice->SetRenderState(D3DRS_ALPHAREF, 170);
635 }
636 if (Additive)
637 {
638 RenderDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
639 }
640 RenderDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
641 unguard;
642 }
643
644 //==========================================================================
645 //
646 // VDirect3DDrawer::DrawAliasModel
647 //
648 //==========================================================================
649
DrawAliasModel(const TVec & origin,const TAVec & angles,const TVec & Offset,const TVec & Scale,VMeshModel * Mdl,int frame,int nextframe,VTexture * Skin,VTextureTranslation * Trans,int CMap,vuint32 light,vuint32 Fade,float Alpha,bool Additive,bool is_view_model,float Inter,bool Interpolate)650 void VDirect3DDrawer::DrawAliasModel(const TVec &origin, const TAVec &angles,
651 const TVec& Offset, const TVec& Scale, VMeshModel* Mdl, int frame,
652 int nextframe, VTexture* Skin, VTextureTranslation* Trans, int CMap,
653 vuint32 light, vuint32 Fade, float Alpha, bool Additive,
654 bool is_view_model, float Inter, bool Interpolate)
655 {
656 guard(VDirect3DDrawer::DrawAliasModel);
657 mframe_t *pframedesc;
658 mframe_t *pnextframedesc;
659 float l;
660 int index;
661 trivertx_t *verts;
662 trivertx_t *verts2;
663 int *order;
664 int count;
665 float shadelightr;
666 float shadelightg;
667 float shadelightb;
668 float *shadedots;
669 MyD3DVertex out[256];//FIXME
670 D3DPRIMITIVETYPE primtype;
671 int i;
672 MyD3DMatrix matWorld;
673 MyD3DMatrix matTmp;
674 TVec alias_forward;
675 TVec alias_right;
676 TVec alias_up;
677 vuint32 alpha;
678
679 if (is_view_model)
680 {
681 // hack the depth range to prevent view model from poking into walls
682 viewData.MaxZ = 0.3;
683 RenderDevice->SetViewport(&viewData);
684 }
685
686 //
687 // get lighting information
688 //
689 shadelightr = ((light >> 16) & 0xff) / 512.0;
690 shadelightg = ((light >> 8) & 0xff) / 512.0;
691 shadelightb = (light & 0xff) / 512.0;
692 shadedots = r_avertexnormal_dots[((int)(angles.yaw * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
693 light &= 0x00ffffff;
694 alpha = int(Alpha * 255) << 24;
695
696 //
697 // draw all the triangles
698 //
699 mmdl_t* pmdl = Mdl->Data;
700 pframedesc = (mframe_t*)((byte *)pmdl + pmdl->ofsframes + frame * pmdl->framesize);
701 pnextframedesc = (mframe_t*)((byte *)pmdl + pmdl->ofsframes + nextframe * pmdl->framesize);
702
703 AngleVectors(angles, alias_forward, alias_right, alias_up);
704
705 matWorld = IdentityMatrix;
706 for (i = 0; i < 3; i++)
707 {
708 matWorld(0, i) = alias_forward[i];
709 matWorld(1, i) = -alias_right[i];
710 matWorld(2, i) = alias_up[i];
711 }
712 matWorld(3, 0) = origin.x;
713 matWorld(3, 1) = origin.y;
714 matWorld(3, 2) = origin.z;
715
716 matTmp = IdentityMatrix;
717 matTmp(0, 0) = Scale.x;
718 matTmp(1, 1) = Scale.y;
719 matTmp(2, 2) = Scale.z;
720 matTmp(3, 0) = Offset.x * Scale.x;
721 matTmp(3, 1) = Offset.y * Scale.y;
722 matTmp(3, 2) = Offset.z * Scale.z;
723 matWorld = matTmp * matWorld;
724
725 TVec scale;
726 TVec scale_origin;
727 if (Interpolate)
728 {
729 scale[0] = pframedesc->scale[0] + Inter * (pnextframedesc->scale[0] - pframedesc->scale[0]);
730 scale[1] = pframedesc->scale[1] + Inter * (pnextframedesc->scale[1] - pframedesc->scale[1]);
731 scale[2] = pframedesc->scale[2] + Inter * (pnextframedesc->scale[2] - pframedesc->scale[2]);
732 scale_origin[0] = ((1 - Inter) * pframedesc->scale_origin[0] + Inter * pnextframedesc->scale_origin[0]);
733 scale_origin[1] = ((1 - Inter) * pframedesc->scale_origin[1] + Inter * pnextframedesc->scale_origin[1]);
734 scale_origin[2] = ((1 - Inter) * pframedesc->scale_origin[2] + Inter * pnextframedesc->scale_origin[2]);
735 }
736 else
737 {
738 scale[0] = pframedesc->scale[0];
739 scale[1] = pframedesc->scale[1];
740 scale[2] = pframedesc->scale[2];
741 scale_origin[0] = pframedesc->scale_origin[0];
742 scale_origin[1] = pframedesc->scale_origin[1];
743 scale_origin[2] = pframedesc->scale_origin[2];
744 }
745
746 matTmp = IdentityMatrix;
747 matTmp(0, 0) = scale[0];
748 matTmp(1, 1) = scale[1];
749 matTmp(2, 2) = scale[2];
750 matTmp(3, 0) = scale_origin[0];
751 matTmp(3, 1) = scale_origin[1];
752 matTmp(3, 2) = scale_origin[2];
753 matWorld = matTmp * matWorld;
754
755 RenderDevice->SetTransform(D3DTS_WORLD, &matWorld);
756
757 SetPic(Skin, Trans, CMap);
758
759 RenderDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
760 RenderDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
761 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
762 if (Additive)
763 {
764 RenderDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
765 }
766 RenderDevice->SetRenderState(D3DRS_ALPHAREF, 0);
767
768 SetFade(Fade);
769
770 verts = (trivertx_t *)(pframedesc + 1);
771 order = (int *)((byte *)pmdl + pmdl->ofscmds);
772 if (Interpolate)
773 {
774 verts2 = (trivertx_t *)(pnextframedesc + 1);
775 }
776
777 while (*order)
778 {
779 // get the vertex count and primitive type
780 count = *order++;
781 if (count < 0)
782 {
783 count = -count;
784 primtype = D3DPT_TRIANGLEFAN;
785 }
786 else
787 {
788 primtype = D3DPT_TRIANGLESTRIP;
789 }
790
791 if (count > 256)
792 {
793 Sys_Error("Too many command verts");
794 }
795
796 for (i = 0; i < count; i++)
797 {
798 // texture coordinates come from the draw list
799 out[i].texs = ((float *)order)[0];
800 out[i].text = ((float *)order)[1];
801 order += 2;
802
803 // normals and vertexes come from the frame list
804 index = *order++;
805 if (model_lighting)
806 {
807 l = shadedots[verts[index].lightnormalindex];
808 out[i].colour = alpha |
809 (((int)(l * shadelightr * 0xff) << 16) & 0x00ff0000) |
810 (((int)(l * shadelightg * 0xff) << 8) & 0x0000ff00) |
811 (((int)(l * shadelightb * 0xff) ) & 0x000000ff);
812 }
813 else
814 {
815 out[i].colour = alpha | light;
816 }
817 if (Interpolate)
818 {
819 out[i].x = ((1 - Inter) * verts[index].v[0] + (Inter) * verts2[index].v[0]);
820 out[i].y = ((1 - Inter) * verts[index].v[1] + (Inter) * verts2[index].v[1]);
821 out[i].z = ((1 - Inter) * verts[index].v[2] + (Inter) * verts2[index].v[2]);
822 }
823 else
824 {
825 out[i].x = verts[index].v[0];
826 out[i].y = verts[index].v[1];
827 out[i].z = verts[index].v[2];
828 }
829 }
830
831 RenderDevice->DrawPrimitiveUP(primtype, count - 2, out, sizeof(MyD3DVertex));
832 }
833
834 RenderDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
835 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
836 if (Additive)
837 {
838 RenderDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
839 }
840 RenderDevice->SetRenderState(D3DRS_ALPHAREF, 170);
841 RenderDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
842
843 RenderDevice->SetTransform(D3DTS_WORLD, &IdentityMatrix);
844 if (is_view_model)
845 {
846 viewData.MaxZ = 1.0;
847 RenderDevice->SetViewport(&viewData);
848 }
849 unguard;
850 }
851
852 //==========================================================================
853 //
854 // VDirect3DDrawer::StartParticles
855 //
856 //==========================================================================
857
StartParticles()858 void VDirect3DDrawer::StartParticles()
859 {
860 guard(VDirect3DDrawer::StartParticles);
861 if (!particle_texture)
862 {
863 rgba_t pbuf[8][8];
864
865 for (int j = 0; j < 8; j++)
866 {
867 for (int i = 0; i < 8; i++)
868 {
869 pbuf[j][i].r = 255;
870 pbuf[j][i].g = 255;
871 pbuf[j][i].b = 255;
872 pbuf[j][i].a = byte(ptex[j][i] * 255);
873 }
874 }
875 particle_texture = CreateSurface(8, 8, 16, false);
876 UploadTextureImage(particle_texture, 0, 8, 8, &pbuf[0][0]);
877 }
878 RenderDevice->SetTexture(0, particle_texture);
879 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
880 RenderDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
881 RenderDevice->SetRenderState(D3DRS_ALPHAREF, 0);
882 unguard;
883 }
884
885 //==========================================================================
886 //
887 // VDirect3DDrawer::DrawParticle
888 //
889 //==========================================================================
890
DrawParticle(particle_t * p)891 void VDirect3DDrawer::DrawParticle(particle_t *p)
892 {
893 guard(VDirect3DDrawer::DrawParticle);
894 MyD3DVertex out[4];
895 out[0] = MyD3DVertex(p->org - viewright * p->Size + viewup * p->Size, p->colour, 0, 0);
896 out[1] = MyD3DVertex(p->org + viewright * p->Size + viewup * p->Size, p->colour, 1, 0);
897 out[2] = MyD3DVertex(p->org + viewright * p->Size - viewup * p->Size, p->colour, 1, 1);
898 out[3] = MyD3DVertex(p->org - viewright * p->Size - viewup * p->Size, p->colour, 0, 1);
899 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, out, sizeof(MyD3DVertex));
900 unguard;
901 }
902
903 //==========================================================================
904 //
905 // VDirect3DDrawer::EndParticles
906 //
907 //==========================================================================
908
EndParticles()909 void VDirect3DDrawer::EndParticles()
910 {
911 guard(VDirect3DDrawer::EndParticles);
912 RenderDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
913 RenderDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
914 RenderDevice->SetRenderState(D3DRS_ALPHAREF, 170);
915 unguard;
916 }
917
918 //==========================================================================
919 //
920 // VDirect3DDrawer::StartPortal
921 //
922 //==========================================================================
923
StartPortal(VPortal * Portal,bool UseStencil)924 bool VDirect3DDrawer::StartPortal(VPortal* Portal, bool UseStencil)
925 {
926 guard(VDirect3DDrawer::StartPortal);
927 if (UseStencil)
928 {
929 // Disable drawing
930 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
931 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
932 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
933
934 // Set up stencil test.
935 if (!RendLev->PortalDepth)
936 {
937 RenderDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
938 }
939 RenderDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
940 RenderDevice->SetRenderState(D3DRS_STENCILREF, RendLev->PortalDepth);
941 RenderDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR);
942
943 // Mark the portal area.
944 DrawPortalArea(Portal);
945
946 // Set up stencil test for portal
947 RenderDevice->SetRenderState(D3DRS_STENCILREF, RendLev->PortalDepth + 1);
948 RenderDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
949
950 if (Portal->NeedsDepthBuffer())
951 {
952 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
953 // Clear depth buffer
954 viewData.MinZ = 1.0;
955 RenderDevice->SetViewport(&viewData);
956 RenderDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
957 DrawPortalArea(Portal);
958 RenderDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
959 viewData.MinZ = 0.0;
960 RenderDevice->SetViewport(&viewData);
961 }
962 else
963 {
964 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
965 RenderDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
966 }
967
968 // Enable drawing.
969 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0f);
970 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
971
972 RendLev->PortalDepth++;
973 }
974 else
975 {
976 if (!Portal->NeedsDepthBuffer())
977 {
978 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
979 RenderDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
980 }
981 }
982 return true;
983 unguard;
984 }
985
986 //==========================================================================
987 //
988 // VDirect3DDrawer::DrawPortalArea
989 //
990 //==========================================================================
991
DrawPortalArea(VPortal * Portal)992 void VDirect3DDrawer::DrawPortalArea(VPortal* Portal)
993 {
994 guard(VDirect3DDrawer::DrawPortalArea);
995 MyD3DVertex out[256];
996 for (int i = 0; i < Portal->Surfs.Num(); i++)
997 {
998 const surface_t* Surf = Portal->Surfs[i];
999 for (int i = 0; i < Surf->count; i++)
1000 {
1001 out[i] = MyD3DVertex(Surf->verts[i], 0, 0, 0);
1002 }
1003 RenderDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, Surf->count - 2,
1004 out, sizeof(MyD3DVertex));
1005 }
1006 unguard;
1007 }
1008
1009 //==========================================================================
1010 //
1011 // VDirect3DDrawer::EndPortal
1012 //
1013 //==========================================================================
1014
EndPortal(VPortal * Portal,bool UseStencil)1015 void VDirect3DDrawer::EndPortal(VPortal* Portal, bool UseStencil)
1016 {
1017 guard(VDirect3DDrawer::EndPortal);
1018 if (UseStencil)
1019 {
1020 if (Portal->NeedsDepthBuffer())
1021 {
1022 // Clear depth buffer
1023 viewData.MinZ = 1.0;
1024 RenderDevice->SetViewport(&viewData);
1025 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
1026 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
1027 RenderDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
1028 DrawPortalArea(Portal);
1029 RenderDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1030 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0f);
1031 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
1032 viewData.MinZ = 0.0;
1033 RenderDevice->SetViewport(&viewData);
1034 }
1035 else
1036 {
1037 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
1038 RenderDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
1039 }
1040
1041 RenderDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR);
1042
1043 // Draw proper z-buffer for the portal area.
1044 RenderDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
1045 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
1046 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
1047 DrawPortalArea(Portal);
1048 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0f);
1049 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
1050 RenderDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1051
1052 RenderDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
1053
1054 RendLev->PortalDepth--;
1055 RenderDevice->SetRenderState(D3DRS_STENCILREF, RendLev->PortalDepth);
1056 if (!RendLev->PortalDepth)
1057 {
1058 RenderDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
1059 }
1060 }
1061 else
1062 {
1063 if (Portal->NeedsDepthBuffer())
1064 {
1065 // Clear depth buffer
1066 RenderDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0);
1067 }
1068 else
1069 {
1070 RenderDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
1071 RenderDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
1072 }
1073
1074 // Draw proper z-buffer for the portal area.
1075 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
1076 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
1077 DrawPortalArea(Portal);
1078 RenderDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0f);
1079 RenderDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
1080 }
1081 unguard;
1082 }
1083