1 /*
2 * Copyright 2011-2012 Arx Libertatis Team (see the AUTHORS file)
3 *
4 * This file is part of Arx Libertatis.
5 *
6 * Arx Libertatis is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Arx Libertatis is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Arx Libertatis. If not, see <http://www.gnu.org/licenses/>.
18 */
19 /* Based on:
20 ===========================================================================
21 ARX FATALIS GPL Source Code
22 Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
23
24 This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
25
26 Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
27 License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
28
29 Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
30 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code. If not, see
33 <http://www.gnu.org/licenses/>.
34
35 In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
36 additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
37 Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
38
39 If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
40 ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
41 ===========================================================================
42 */
43 // Code: Cyril Meynier
44 //
45 // Copyright (c) 1999-2000 ARKANE Studios SA. All rights reserved
46
47 #include "scene/Scene.h"
48
49 #include <cstdio>
50
51 #include "ai/Paths.h"
52
53 #include "animation/Animation.h"
54
55 #include "core/Application.h"
56 #include "core/GameTime.h"
57 #include "core/Core.h"
58
59 #include "game/EntityManager.h"
60 #include "game/Inventory.h"
61 #include "game/Player.h"
62 #include "game/Spells.h"
63
64 #include "gui/Interface.h"
65
66 #include "graphics/Draw.h"
67 #include "graphics/GraphicsModes.h"
68 #include "graphics/Math.h"
69 #include "graphics/VertexBuffer.h"
70 #include "graphics/data/TextureContainer.h"
71 #include "graphics/effects/DrawEffects.h"
72 #include "graphics/particle/ParticleEffects.h"
73 #include "graphics/texture/TextureStage.h"
74
75 #include "input/Input.h"
76
77 #include "io/log/Logger.h"
78
79 #include "scene/Light.h"
80 #include "scene/Interactive.h"
81
82 using std::vector;
83
84 //-----------------------------------------------------------------------------
85 #define MAX_OUT 4
86 #define VAL_THRESHOLD 100.f
87 #define PASSS 0.5f
88 #define PASS 50.f
89
90 //-----------------------------------------------------------------------------
91 extern long USE_LIGHT_OPTIM;
92 extern EERIE_3DOBJ * eyeballobj;
93 extern long NEED_TEST_TEXT;
94 extern long EXTERNALVIEW;
95 long LAST_PORTALS_COUNT=0;
96 //-----------------------------------------------------------------------------
97 extern TextureContainer *enviro;
98 extern long ZMAPMODE;
99 extern Color ulBKGColor;
100
101 EERIEPOLY * TransPol[MAX_TRANSPOL];
102
103 EERIE_PORTAL_DATA * portals = NULL;
104
105 static float WATEREFFECT = 0.f;
106
107 long TRANSPOLYSPOS=0;
108 long FRAME_COUNT=0;
109
110 long LAST_ROOM=-1;
111
112 CircularVertexBuffer<SMY_VERTEX3> * pDynamicVertexBuffer;
113
114 namespace {
115
116 struct DynamicVertexBuffer {
117
118 private:
119
120 SMY_VERTEX3 * vertices;
121 size_t start;
122
123 public:
124
125 size_t nbindices;
126 unsigned short * indices;
127 size_t offset;
128
DynamicVertexBuffer__anonb45ffd2a0111::DynamicVertexBuffer129 DynamicVertexBuffer() : vertices(NULL), nbindices(0), indices(NULL) { }
130
lock__anonb45ffd2a0111::DynamicVertexBuffer131 void lock() {
132
133 arx_assert(!vertices);
134
135 if(!indices) {
136 indices = new unsigned short[4 * pDynamicVertexBuffer->vb->capacity()];
137 start = 0;
138 }
139
140 BufferFlags flags = (pDynamicVertexBuffer->pos == 0) ? DiscardBuffer : NoOverwrite | DiscardRange;
141
142 vertices = pDynamicVertexBuffer->vb->lock(flags, pDynamicVertexBuffer->pos);
143 offset = 0;
144 }
145
append__anonb45ffd2a0111::DynamicVertexBuffer146 SMY_VERTEX3 * append(size_t nbvertices) {
147
148 arx_assert(vertices);
149
150 if(pDynamicVertexBuffer->pos + nbvertices > pDynamicVertexBuffer->vb->capacity()) {
151 return NULL;
152 }
153
154 SMY_VERTEX3 * pos = vertices + offset;
155
156 pDynamicVertexBuffer->pos += nbvertices, offset += nbvertices;
157
158 return pos;
159 }
160
unlock__anonb45ffd2a0111::DynamicVertexBuffer161 void unlock() {
162 arx_assert(vertices);
163 pDynamicVertexBuffer->vb->unlock(), vertices = NULL;
164 }
165
draw__anonb45ffd2a0111::DynamicVertexBuffer166 void draw(Renderer::Primitive primitive) {
167 arx_assert(!vertices);
168 pDynamicVertexBuffer->vb->drawIndexed(primitive, pDynamicVertexBuffer->pos - start, start, indices, nbindices);
169 }
170
done__anonb45ffd2a0111::DynamicVertexBuffer171 void done() {
172 arx_assert(!vertices);
173 start = pDynamicVertexBuffer->pos;
174 nbindices = 0;
175 }
176
reset__anonb45ffd2a0111::DynamicVertexBuffer177 void reset() {
178 arx_assert(!vertices);
179 start = pDynamicVertexBuffer->pos = 0;
180 nbindices = 0;
181 }
182
~DynamicVertexBuffer__anonb45ffd2a0111::DynamicVertexBuffer183 ~DynamicVertexBuffer() {
184 delete[] indices;
185 }
186
187 } dynamicVertices;
188
189 }
190
191 EERIE_FRUSTRUM_PLANE efpPlaneNear;
192
193 static vector<EERIEPOLY*> vPolyWater;
194 static vector<EERIEPOLY*> vPolyLava;
195
196 bool bOLD_CLIPP=false;
197
198 void PopAllTriangleListTransparency();
199
200 static PORTAL_ROOM_DRAW * RoomDraw = NULL;
201 static long NbRoomDraw = 0;
202 static long * RoomDrawList = NULL;
203 static long NbRoomDrawList = 0;
204 long TotalRoomDrawList=0;
205
206 //*************************************************************************************
207 //*************************************************************************************
ApplyWaterFXToVertex(Vec3f * odtv,TexturedVertex * dtv,float power)208 void ApplyWaterFXToVertex(Vec3f * odtv,TexturedVertex * dtv,float power)
209 {
210 power=power*0.05f;
211 dtv->uv.x+=EEsin((WATEREFFECT+odtv->x))*power;
212 dtv->uv.y+=EEcos((WATEREFFECT+odtv->z))*power;
213 }
214
ApplyLavaGlowToVertex(Vec3f * odtv,TexturedVertex * dtv,float power)215 static void ApplyLavaGlowToVertex(Vec3f * odtv,TexturedVertex * dtv, float power) {
216 float f;
217 long lr, lg, lb;
218 power = 1.f - (EEsin((WATEREFFECT+odtv->x+odtv->z)) * 0.05f) * power;
219 f = ((dtv->color >> 16) & 255) * power;
220 lr = clipByte(f);
221
222 f = ((dtv->color >> 8) & 255) * power;
223 lg = clipByte(f);
224
225 f = ((dtv->color) & 255) * power;
226 lb = clipByte(f);
227
228 dtv->color=0xFF000000L | (lr << 16) | (lg << 8) | lb;
229 }
230
ManageLavaWater(EERIEPOLY * ep,const long to,const unsigned long tim)231 void ManageLavaWater(EERIEPOLY * ep, const long to, const unsigned long tim)
232 {
233 if ((ep->type & POLY_WATER) || (ep->type & POLY_LAVA) )
234 {
235 for(long k = 0; k < to; k++) {
236 ep->tv[k].uv = ep->v[k].uv;
237 if(ep->type & POLY_LAVA) {
238 ApplyWaterFXToVertex(&ep->v[k].p, &ep->tv[k], 0.35f);
239 ApplyLavaGlowToVertex(&ep->v[k].p,&ep->tv[k],0.6f);
240 } else {
241 ApplyWaterFXToVertex(&ep->v[k].p,&ep->tv[k],0.35f);
242 }
243 }
244 }
245
246 if (ep->type & POLY_FALL)
247 {
248 if (ep->type & POLY_LAVA)
249 for (long k=0;k<to;k++)
250 {
251 ep->tv[k].uv.y-=(float)(tim)*( 1.0f / 12000 );
252 }
253 else
254 for (long k=0;k<to;k++)
255 {
256 ep->tv[k].uv.y-=(float)(tim)*( 1.0f / 1000 );
257 }
258 }
259 }
260
ManageWater_VertexBuffer(EERIEPOLY * ep,const long to,const unsigned long tim,SMY_VERTEX * _pVertex)261 void ManageWater_VertexBuffer(EERIEPOLY * ep, const long to, const unsigned long tim, SMY_VERTEX * _pVertex) {
262
263 for (long k=0;k<to;k++)
264 {
265 ep->tv[k].uv = ep->v[k].uv;
266
267 ApplyWaterFXToVertex(&ep->v[k].p,&ep->tv[k],0.35f);
268
269 if(ep->type&POLY_FALL)
270 {
271 ep->tv[k].uv.y-=(float)(tim)*( 1.0f / 1000 );
272 }
273
274 _pVertex[ep->uslInd[k]].uv = ep->tv[k].uv;
275 }
276 }
277
ManageLava_VertexBuffer(EERIEPOLY * ep,const long to,const unsigned long tim,SMY_VERTEX * _pVertex)278 void ManageLava_VertexBuffer(EERIEPOLY * ep, const long to, const unsigned long tim, SMY_VERTEX * _pVertex) {
279
280 for (long k=0;k<to;k++)
281 {
282 ep->tv[k].uv = ep->v[k].uv;
283
284 ApplyWaterFXToVertex(&ep->v[k].p, &ep->tv[k], 0.35f); //0.25f
285 ApplyLavaGlowToVertex(&ep->v[k].p, &ep->tv[k], 0.6f);
286
287 if(ep->type&POLY_FALL)
288 {
289 ep->tv[k].uv.y-=(float)(tim)*( 1.0f / 12000 );
290 }
291
292 _pVertex[ep->uslInd[k]].uv = ep->tv[k].uv;
293 }
294 }
295
296
297
298 extern EERIEMATRIX ProjectionMatrix;
specialEE_RTP2(TexturedVertex * in,TexturedVertex * out)299 void specialEE_RTP2(TexturedVertex * in, TexturedVertex * out) {
300
301 EERIE_TRANSFORM * et = (EERIE_TRANSFORM *)&ACTIVECAM->transform;
302 out->p = in->p - et->pos;
303
304 float temp = (out->p.z * et->ycos) - (out->p.x * et->ysin);
305 out->p.x = (out->p.z * et->ysin) + (out->p.x * et->ycos);
306 out->p.z = (out->p.y * et->xsin) + (temp * et->xcos);
307 out->p.y = (out->p.y * et->xcos) - (temp * et->xsin);
308
309 float fZTemp = 1.f / out->p.z;
310
311 out->p.z = fZTemp * ProjectionMatrix._33 + ProjectionMatrix._43;
312 out->p.x = out->p.x * ProjectionMatrix._11 * fZTemp + et->mod.x;
313 out->p.y = out->p.y * ProjectionMatrix._22 * fZTemp + et->mod.y;
314 out->rhw = fZTemp;
315 }
316
EERIERTPPoly2(EERIEPOLY * ep)317 long EERIERTPPoly2(EERIEPOLY *ep)
318 {
319 specialEE_RTP2(&ep->v[0],&ep->tv[0]);
320 specialEE_RTP2(&ep->v[1],&ep->tv[1]);
321 specialEE_RTP2(&ep->v[2],&ep->tv[2]);
322
323 if (ep->type & POLY_QUAD) specialEE_RTP2(&ep->v[3],&ep->tv[3]);
324 else ep->tv[3].p.z=1.f;
325
326 if ((ep->tv[0].p.z<=0.f) &&
327 (ep->tv[1].p.z<=0.f) &&
328 (ep->tv[2].p.z<=0.f) &&
329 (ep->tv[3].p.z<=0.f) ) return 0;
330
331 return 1;
332 }
333
334
335 bool IsSphereInFrustrum(float radius,Vec3f * point,EERIE_FRUSTRUM * frustrum);
FrustrumsClipSphere(EERIE_FRUSTRUM_DATA * frustrums,EERIE_SPHERE * sphere)336 bool FrustrumsClipSphere(EERIE_FRUSTRUM_DATA * frustrums,EERIE_SPHERE * sphere)
337 {
338 float dists=sphere->origin.x*efpPlaneNear.a + sphere->origin.y*efpPlaneNear.b + sphere->origin.z*efpPlaneNear.c + efpPlaneNear.d;
339
340 if (dists+sphere->radius>0)
341 {
342 for (long i=0;i<frustrums->nb_frustrums;i++)
343 {
344 if (IsSphereInFrustrum(sphere->radius, &sphere->origin, &frustrums->frustrums[i]))
345 return false;
346 }
347 }
348
349 return true;
350 }
351
VisibleSphere(float x,float y,float z,float radius)352 bool VisibleSphere(float x, float y, float z, float radius) {
353
354 Vec3f pos(x, y, z);
355 if(distSqr(pos, ACTIVECAM->pos) > square(ACTIVECAM->cdepth*0.5f + radius))
356 return false;
357
358 long room_num = ARX_PORTALS_GetRoomNumForPosition(&pos);
359
360 if (room_num>=0)
361 {
362 EERIE_SPHERE sphere;
363 sphere.origin = pos;
364 sphere.radius = radius;
365
366 EERIE_FRUSTRUM_DATA * frustrums=&RoomDraw[room_num].frustrum;
367
368 if (FrustrumsClipSphere(frustrums,&sphere))
369 return false;
370 }
371
372 return true;
373 }
374 bool IsInFrustrum(Vec3f * point,EERIE_FRUSTRUM * frustrum);
375
IsBBoxInFrustrum(EERIE_3D_BBOX * bbox,EERIE_FRUSTRUM * frustrum)376 bool IsBBoxInFrustrum(EERIE_3D_BBOX * bbox, EERIE_FRUSTRUM * frustrum) {
377
378 Vec3f point = bbox->min;
379 if(IsInFrustrum(&point, frustrum)) {
380 return true;
381 }
382
383 point = Vec3f(bbox->max.x, bbox->min.y, bbox->min.z);
384 if(IsInFrustrum(&point, frustrum)) {
385 return true;
386 }
387
388 point = Vec3f(bbox->max.x, bbox->max.y, bbox->min.z);
389 if(IsInFrustrum(&point, frustrum)) {
390 return true;
391 }
392
393 point = Vec3f(bbox->min.x, bbox->max.y, bbox->min.z);
394 if(IsInFrustrum(&point, frustrum)) {
395 return true;
396 }
397
398 point = Vec3f(bbox->min.x, bbox->min.y, bbox->max.z);
399 if(IsInFrustrum(&point, frustrum)) {
400 return true;
401 }
402
403 point = Vec3f(bbox->max.x, bbox->min.y, bbox->max.z);
404 if(IsInFrustrum(&point, frustrum)) {
405 return true;
406 }
407
408 point = bbox->max;
409 if(IsInFrustrum(&point, frustrum)) {
410 return true;
411 }
412
413 point = Vec3f(bbox->min.x, bbox->max.y, bbox->max.z);
414 if(IsInFrustrum(&point, frustrum)) {
415 return true;
416 }
417
418 return false;
419 }
420
FrustrumsClipBBox3D(EERIE_FRUSTRUM_DATA * frustrums,EERIE_3D_BBOX * bbox)421 bool FrustrumsClipBBox3D(EERIE_FRUSTRUM_DATA * frustrums,EERIE_3D_BBOX * bbox)
422 {
423 for (long i=0;i<frustrums->nb_frustrums;i++)
424 {
425 if (IsBBoxInFrustrum(bbox,&frustrums->frustrums[i]))
426 return false;
427 }
428
429 return false;
430 }
431
ARX_SCENE_PORTAL_Basic_ClipIO(Entity * io)432 bool ARX_SCENE_PORTAL_Basic_ClipIO(Entity * io) {
433
434 if(EDITMODE || io == entities.player() || (io->ioflags & IO_FORCEDRAW)) {
435 return false;
436 }
437
438 if (USE_PORTALS && portals)
439 {
440 Vec3f posi;
441 posi.x=io->pos.x;
442 posi.y=io->pos.y-20;
443 posi.z=io->pos.z;
444
445 if (io->room_flags & 1)
446 UpdateIORoom(io);
447
448 long room_num = io->room;
449
450 {
451 if (room_num==-1)
452 {
453 posi.y=io->pos.y-120;
454 room_num=ARX_PORTALS_GetRoomNumForPosition(&posi);
455 }
456
457 if ( (room_num>=0)
458 && (RoomDraw)
459 && (RoomDraw[room_num].count))
460 {
461
462 switch (USE_PORTALS)
463 {
464 case 2:
465 case 3:
466 case 4:
467 EERIE_SPHERE sphere;
468
469 if (io->ioflags & IO_ITEM)
470 {
471 sphere.origin.x=io->pos.x;
472 sphere.origin.y=io->pos.y-40.f;
473 sphere.origin.z=io->pos.z;
474
475 if (io->ioflags & IO_MOVABLE)
476 sphere.radius=160.f;
477 else sphere.radius = 75.f;
478 }
479 else if (io->ioflags & IO_FIX)
480 {
481 sphere.origin.x=io->pos.x;
482 sphere.origin.y=io->pos.y-60.f;
483 sphere.origin.z=io->pos.z;
484 sphere.radius=340.f;
485 }
486 else if (io->ioflags & IO_NPC)
487 {
488 sphere.origin.x=io->pos.x;
489 sphere.origin.y=io->pos.y-120.f;
490 sphere.origin.z=io->pos.z;
491 sphere.radius=120.f;
492 }
493
494 EERIE_FRUSTRUM_DATA * frustrums=&RoomDraw[room_num].frustrum;
495
496 if (FrustrumsClipSphere(frustrums,&sphere))
497 {
498 if (io)
499 {
500 io->bbox1.x=(short)-1;
501 io->bbox2.x=(short)-1;
502 io->bbox1.y=(short)-1;
503 io->bbox2.y=(short)-1;
504 }
505
506 return true;
507 }
508 }
509 }
510 else return false;
511 }
512 }
513
514 return false;
515 }
516
517 // USAGE/FUNCTION
518 // io can be NULL if io is valid io->bbox3D contains 3D world-bbox
519 // bboxmin & bboxmax ARE in fact 2D-screen BBOXes using only (x,y).
520 // RETURN:
521 // return true if IO cannot be seen, false if visible
522 // TODO:
523 // Implement all Portal Methods
524 // Return a reduced clipbox which can be used for polys clipping in the case of partial visibility
ARX_SCENE_PORTAL_ClipIO(Entity * io,Vec3f * position)525 bool ARX_SCENE_PORTAL_ClipIO(Entity * io, Vec3f * position) {
526
527 if (EDITMODE) return false;
528
529 if (io==entities.player()) return false;
530
531 if ((io) && (io->ioflags & IO_FORCEDRAW)) return false;
532
533 if (USE_PORTALS && portals)
534 {
535 Vec3f posi;
536 posi.x=position->x;
537 posi.y=position->y-60; //20
538 posi.z=position->z;
539 long room_num;
540
541 if (io)
542 {
543 if (io->room_flags & 1)
544 UpdateIORoom(io);
545
546 room_num=io->room;//
547 }
548 else
549 {
550 room_num=ARX_PORTALS_GetRoomNumForPosition(&posi);
551 }
552
553 if (room_num==-1)
554 {
555 posi.y=position->y-120;
556 room_num=ARX_PORTALS_GetRoomNumForPosition(&posi);
557 }
558
559 if ((room_num >= 0) && (RoomDraw))
560 {
561 if (RoomDraw[room_num].count==0)
562 {
563 if (io)
564 {
565 io->bbox1.x=(short)-1;
566 io->bbox2.x=(short)-1;
567 io->bbox1.y=(short)-1;
568 io->bbox2.y=(short)-1;
569 }
570
571 return true;
572 }
573
574 switch (USE_PORTALS)
575 {
576 case 1: // 2D portal
577 {
578 EERIE_2D_BBOX * bbox=&RoomDraw[room_num].bbox;
579
580 if ( bbox->min.x > BBOXMAX.x || BBOXMIN.x > bbox->max.x
581 || bbox->min.y > BBOXMAX.y || BBOXMIN.y > bbox->max.y)
582 {
583 if (io)
584 {
585 io->bbox1.x=(short)-1;
586 io->bbox2.x=(short)-1;
587 io->bbox1.y=(short)-1;
588 io->bbox2.y=(short)-1;
589 }
590
591 return true;
592 }
593 }
594 break;
595 case 2:
596 case 3:
597 case 4:
598
599 if(io) {
600
601 EERIE_SPHERE sphere;
602 sphere.origin = (io->bbox3D.min + io->bbox3D.max) * .5f;
603 sphere.radius = dist(sphere.origin, io->bbox3D.min) + 10.f;
604
605 EERIE_FRUSTRUM_DATA * frustrums=&RoomDraw[room_num].frustrum;
606
607 if (FrustrumsClipSphere(frustrums,&sphere))
608 {
609 if (io)
610 {
611 io->bbox1.x=(short)-1;
612 io->bbox2.x=(short)-1;
613 io->bbox1.y=(short)-1;
614 io->bbox2.y=(short)-1;
615 }
616
617 return true;
618 }
619
620 if (FrustrumsClipBBox3D(frustrums,&io->bbox3D))
621 {
622 if (io)
623 {
624 io->bbox1.x=(short)-1;
625 io->bbox2.x=(short)-1;
626 io->bbox1.y=(short)-1;
627 io->bbox2.y=(short)-1;
628 }
629
630 return true;
631 }
632 }
633
634 break;
635 }
636 }
637 }
638
639 return false;
640 }
641
ARX_PORTALS_GetRoomNumForPosition2(Vec3f * pos,long flag,float * height)642 long ARX_PORTALS_GetRoomNumForPosition2(Vec3f * pos,long flag,float * height)
643 {
644
645 EERIEPOLY * ep;
646
647 if (flag & 1)
648 {
649 ep=CheckInPolyPrecis(pos->x,pos->y-150.f,pos->z);
650
651 if (!ep)
652 ep=CheckInPolyPrecis(pos->x,pos->y-1.f,pos->z);
653 }
654 else
655 ep=CheckInPoly(pos->x,pos->y,pos->z);
656
657 if ((ep) && (ep->room>-1))
658 {
659 if (height) *height=ep->center.y;
660
661 return ep->room;
662 }
663
664 // Security... ?
665 ep=GetMinPoly(pos->x,pos->y,pos->z);
666
667 if ((ep) && (ep->room>-1))
668 {
669 if (height) *height=ep->center.y;
670
671 return ep->room;
672 }
673 else if (!(flag & 1))
674 {
675 ep=CheckInPolyPrecis(pos->x,pos->y,pos->z);
676
677 if ((ep) && (ep->room>-1))
678 {
679 if (height) *height=ep->center.y;
680
681 return ep->room;
682 }
683 }
684
685 if (flag & 2)
686 {
687 float off=20.f;
688 ep=CheckInPolyPrecis(pos->x-off,pos->y-off,pos->z);
689
690 if ((ep) && (ep->room>-1))
691 {
692 if (height) *height=ep->center.y;
693
694 return ep->room;
695 }
696
697 ep=CheckInPolyPrecis(pos->x-off,pos->y-20,pos->z-off);
698
699 if ((ep) && (ep->room>-1))
700 {
701 if (height) *height=ep->center.y;
702
703 return ep->room;
704 }
705
706 ep=CheckInPolyPrecis(pos->x-off,pos->y-20,pos->z+off);
707
708 if ((ep) && (ep->room>-1))
709 {
710 if (height) *height=ep->center.y;
711
712 return ep->room;
713 }
714
715 ep=CheckInPolyPrecis(pos->x+off,pos->y-20,pos->z);
716
717 if ((ep) && (ep->room>-1))
718 {
719 if (height) *height=ep->center.y;
720
721 return ep->room;
722 }
723
724 ep=CheckInPolyPrecis(pos->x+off,pos->y-20,pos->z+off);
725
726 if ((ep) && (ep->room>-1))
727 {
728 if (height) *height=ep->center.y;
729
730 return ep->room;
731 }
732
733 ep=CheckInPolyPrecis(pos->x+off,pos->y-20,pos->z-off);
734
735 if ((ep) && (ep->room>-1))
736 {
737 if (height) *height=ep->center.y;
738
739 return ep->room;
740 }
741
742 }
743
744 return -1;
745 }
ARX_PORTALS_GetRoomNumForCamera(float * height)746 long ARX_PORTALS_GetRoomNumForCamera(float * height)
747 {
748 EERIEPOLY * ep;
749 ep=CheckInPolyPrecis(ACTIVECAM->pos.x,ACTIVECAM->pos.y,ACTIVECAM->pos.z);
750
751 if ((ep) && (ep->room>-1))
752 {
753 if (height) *height=ep->center.y;
754
755 return ep->room;
756 }
757
758 ep=GetMinPoly(ACTIVECAM->pos.x,ACTIVECAM->pos.y,ACTIVECAM->pos.z);
759
760 if ((ep) && (ep->room>-1))
761 {
762 if (height) *height=ep->center.y;
763
764 return ep->room;
765 }
766
767 float dist=0.f;
768
769 while (dist<=20.f)
770 {
771 float vvv=radians(ACTIVECAM->angle.b);
772 ep=CheckInPolyPrecis( ACTIVECAM->pos.x+EEsin(vvv)*dist,
773 ACTIVECAM->pos.y,
774 ACTIVECAM->pos.z-EEcos(vvv)*dist);
775
776 if ((ep) && (ep->room>-1))
777 {
778 if (height) *height=ep->center.y;
779
780 return ep->room;
781 }
782
783 dist+=5.f;
784 }
785
786 return -1;
787 }
788 // flag==1 for player
ARX_PORTALS_GetRoomNumForPosition(Vec3f * pos,long flag)789 long ARX_PORTALS_GetRoomNumForPosition(Vec3f * pos,long flag)
790 {
791 long num;
792 float height;
793
794 if (flag & 1)
795 num=ARX_PORTALS_GetRoomNumForCamera(&height);
796 else
797 num=ARX_PORTALS_GetRoomNumForPosition2(pos,flag,&height);
798
799 if (num > -1)
800 {
801 long nearest=-1;
802 float nearest_dist=99999.f;
803
804 for (long n=0;n<portals->nb_rooms;n++)
805 {
806 for (long lll=0;lll<portals->room[n].nb_portals;lll++)
807 {
808 EERIE_PORTALS * po= &portals->portals[portals->room[n].portals[lll]];
809 EERIEPOLY * epp=&po->poly;
810
811 if (PointIn2DPolyXZ(epp, pos->x, pos->z))
812 {
813 float yy;
814
815 if (GetTruePolyY(epp,pos,&yy))
816 {
817 if (height>yy)
818 {
819 if ((yy>=pos->y) && (yy-pos->y<nearest_dist))
820 {
821 if (epp->norm.y>0)
822 nearest=po->room_2;
823 else
824 nearest=po->room_1;
825
826 nearest_dist=yy-pos->y;
827 }
828 }
829 }
830 }
831 }
832 }
833
834 if (nearest>-1)
835 num=nearest;
836 }
837
838 return num;
839 }
840
ARX_PORTALS_InitDrawnRooms()841 void ARX_PORTALS_InitDrawnRooms()
842 {
843 if (!portals) return;
844
845 EERIE_PORTALS *ep = &portals->portals[0];
846
847 for (long i=0;i<portals->nb_total;i++)
848 {
849 ep->useportal=0;
850 ep++;
851 }
852
853
854 if ((RoomDraw==NULL) || (NbRoomDraw<portals->nb_rooms+1))
855 {
856 RoomDraw=(PORTAL_ROOM_DRAW *)realloc(RoomDraw,sizeof(PORTAL_ROOM_DRAW)*(portals->nb_rooms+1));
857
858 if (RoomDraw)
859 {
860 NbRoomDraw=portals->nb_rooms+1;
861 }
862 }
863
864 if (RoomDraw)
865 {
866 for (long i=0;i<NbRoomDraw;i++)
867 {
868 RoomDraw[i].count=0;
869 RoomDraw[i].flags=0;
870 RoomDraw[i].frustrum.nb_frustrums=0;
871 }
872 }
873
874 vPolyWater.clear();
875 vPolyLava.clear();
876
877 if(pDynamicVertexBuffer) {
878 pDynamicVertexBuffer->vb->setData(NULL, 0, 0, DiscardBuffer);
879 dynamicVertices.reset();
880 }
881
882 }
BBoxClipPoly(EERIE_2D_BBOX * bbox,EERIEPOLY * ep)883 bool BBoxClipPoly(EERIE_2D_BBOX * bbox,EERIEPOLY * ep)
884 {
885 EERIE_2D_BBOX n_bbox;
886 long nbv;
887
888 if (ep->type & POLY_QUAD)
889 nbv=4;
890 else
891 nbv=3;
892
893 n_bbox.max.x=n_bbox.min.x=ep->tv[0].p.x;
894 n_bbox.max.y=n_bbox.min.y=ep->tv[0].p.y;
895
896 for (long i=1;i<nbv;i++)
897 {
898 n_bbox.min.x=min(n_bbox.min.x , ep->tv[i].p.x);
899 n_bbox.min.y=min(n_bbox.min.y , ep->tv[i].p.y);
900 n_bbox.max.x=max(n_bbox.max.x , ep->tv[i].p.x);
901 n_bbox.max.y=max(n_bbox.max.y , ep->tv[i].p.y);
902 }
903
904 if ( bbox->min.x > n_bbox.max.x || n_bbox.min.x > bbox->max.x
905 || bbox->min.y > n_bbox.max.y || n_bbox.min.y > bbox->max.y)
906 return true;
907
908 return false;
909
910 }
IsInFrustrum(Vec3f * point,EERIE_FRUSTRUM * frustrum)911 bool IsInFrustrum(Vec3f * point,EERIE_FRUSTRUM * frustrum)
912 {
913 if ( ((point->x*frustrum->plane[0].a + point->y*frustrum->plane[0].b + point->z*frustrum->plane[0].c + frustrum->plane[0].d)>0)
914 && ((point->x*frustrum->plane[1].a + point->y*frustrum->plane[1].b + point->z*frustrum->plane[1].c + frustrum->plane[1].d)>0)
915 && ((point->x*frustrum->plane[2].a + point->y*frustrum->plane[2].b + point->z*frustrum->plane[2].c + frustrum->plane[2].d)>0)
916 && ((point->x*frustrum->plane[3].a + point->y*frustrum->plane[3].b + point->z*frustrum->plane[3].c + frustrum->plane[3].d)>0) )
917 return true;
918
919 return false;
920 }
921
922
IsSphereInFrustrum(float radius,Vec3f * point,EERIE_FRUSTRUM * frustrum)923 bool IsSphereInFrustrum(float radius,Vec3f * point,EERIE_FRUSTRUM * frustrum)
924 {
925 float dists[4];
926 dists[0]=point->x*frustrum->plane[0].a + point->y*frustrum->plane[0].b + point->z*frustrum->plane[0].c + frustrum->plane[0].d;
927 dists[1]=point->x*frustrum->plane[1].a + point->y*frustrum->plane[1].b + point->z*frustrum->plane[1].c + frustrum->plane[1].d;
928 dists[2]=point->x*frustrum->plane[2].a + point->y*frustrum->plane[2].b + point->z*frustrum->plane[2].c + frustrum->plane[2].d;
929 dists[3]=point->x*frustrum->plane[3].a + point->y*frustrum->plane[3].b + point->z*frustrum->plane[3].c + frustrum->plane[3].d;
930
931 if ( (dists[0]+radius>0)
932 && (dists[1]+radius>0)
933 && (dists[2]+radius>0)
934 && (dists[3]+radius>0) )
935 return true;
936
937 return false;
938
939 }
940
FrustrumsClipPoly(EERIE_FRUSTRUM_DATA * frustrums,EERIEPOLY * ep)941 bool FrustrumsClipPoly(EERIE_FRUSTRUM_DATA * frustrums,EERIEPOLY * ep)
942 {
943 for (long i=0;i<frustrums->nb_frustrums;i++)
944 {
945 if (IsSphereInFrustrum(ep->v[0].rhw, &ep->center, &frustrums->frustrums[i]))
946 return false;
947 }
948
949 return true;
950 }
951
952
ARX_PORTALS_BlendBBox(long room_num,EERIE_2D_BBOX * bbox)953 void ARX_PORTALS_BlendBBox(long room_num,EERIE_2D_BBOX * bbox) {
954 if(RoomDraw[room_num].count == 0) {
955 RoomDraw[room_num].bbox.min = bbox->min;
956 RoomDraw[room_num].bbox.max = bbox->max;
957 } else {
958 RoomDraw[room_num].bbox.min.x = min(RoomDraw[room_num].bbox.min.x, bbox->min.x);
959 RoomDraw[room_num].bbox.min.y = min(RoomDraw[room_num].bbox.min.y, bbox->min.y);
960 RoomDraw[room_num].bbox.max.x = max(RoomDraw[room_num].bbox.max.x, bbox->max.x);
961 RoomDraw[room_num].bbox.max.y = max(RoomDraw[room_num].bbox.max.y, bbox->max.y);
962 }
963 }
964
Frustrum_Set(EERIE_FRUSTRUM * fr,long plane,float a,float b,float c,float d)965 void Frustrum_Set(EERIE_FRUSTRUM * fr,long plane,float a,float b,float c,float d)
966 {
967 fr->plane[plane].a=a;
968 fr->plane[plane].b=b;
969 fr->plane[plane].c=c;
970 fr->plane[plane].d=d;
971 }
972
CreatePlane(EERIE_FRUSTRUM * frustrum,long numplane,Vec3f * orgn,Vec3f * pt1,Vec3f * pt2)973 void CreatePlane(EERIE_FRUSTRUM * frustrum,long numplane,Vec3f * orgn,Vec3f * pt1,Vec3f * pt2)
974 {
975 float Ax, Ay, Az, Bx, By, Bz, epnlen;
976 Ax=pt1->x-orgn->x;
977 Ay=pt1->y-orgn->y;
978 Az=pt1->z-orgn->z;
979
980 Bx=pt2->x-orgn->x;
981 By=pt2->y-orgn->y;
982 Bz=pt2->z-orgn->z;
983
984 frustrum->plane[numplane].a=Ay*Bz-Az*By;
985 frustrum->plane[numplane].b=Az*Bx-Ax*Bz;
986 frustrum->plane[numplane].c=Ax*By-Ay*Bx;
987
988 epnlen = (float)sqrt( frustrum->plane[numplane].a * frustrum->plane[numplane].a
989 + frustrum->plane[numplane].b * frustrum->plane[numplane].b
990 + frustrum->plane[numplane].c * frustrum->plane[numplane].c );
991 epnlen=1.f/epnlen;
992 frustrum->plane[numplane].a*=epnlen;
993 frustrum->plane[numplane].b*=epnlen;
994 frustrum->plane[numplane].c*=epnlen;
995 frustrum->plane[numplane].d=-( orgn->x * frustrum->plane[numplane].a +
996 orgn->y * frustrum->plane[numplane].b +
997 orgn->z * frustrum->plane[numplane].c );
998
999
1000 }
1001 void CreateScreenFrustrum(EERIE_FRUSTRUM * frustrum);
CreateFrustrum(EERIE_FRUSTRUM * frustrum,EERIEPOLY * ep,long cull)1002 void CreateFrustrum(EERIE_FRUSTRUM * frustrum, EERIEPOLY * ep, long cull) {
1003
1004 long to = (ep->type & POLY_QUAD) ? 4 : 3;
1005
1006 if(cull) {
1007 CreatePlane(frustrum, 0, &ACTIVECAM->pos, &ep->v[0].p, &ep->v[1].p);
1008 CreatePlane(frustrum, 1, &ACTIVECAM->pos, &ep->v[3].p, &ep->v[2].p);
1009 CreatePlane(frustrum, 2, &ACTIVECAM->pos, &ep->v[1].p, &ep->v[3].p);
1010 CreatePlane(frustrum, 3, &ACTIVECAM->pos, &ep->v[2].p, &ep->v[0].p);
1011 } else {
1012 CreatePlane(frustrum, 0, &ACTIVECAM->pos, &ep->v[1].p, &ep->v[0].p);
1013 CreatePlane(frustrum, 1, &ACTIVECAM->pos, &ep->v[2].p, &ep->v[3].p);
1014 CreatePlane(frustrum, 2, &ACTIVECAM->pos, &ep->v[3].p, &ep->v[1].p);
1015 CreatePlane(frustrum, 3, &ACTIVECAM->pos, &ep->v[0].p, &ep->v[2].p);
1016 }
1017
1018 frustrum->nb = to;
1019 }
1020
CreateScreenFrustrum(EERIE_FRUSTRUM * frustrum)1021 void CreateScreenFrustrum(EERIE_FRUSTRUM * frustrum) {
1022
1023 Vec3f vEyePt(ACTIVECAM->pos.x, -ACTIVECAM->pos.y, ACTIVECAM->pos.z);
1024 Vec3f vTout(0.0f, 0.0f, 10000.0f);
1025
1026 Vec3f vTarget;
1027 vTarget.y = -(vTout.z * ACTIVECAM->Xsin);
1028 vTarget.z = -(vTout.z * ACTIVECAM->Xcos);
1029 vTarget.x = (vTarget.z * ACTIVECAM->Ysin);
1030 vTarget.z = -(vTarget.z * ACTIVECAM->Ycos);
1031 vTarget.x += ACTIVECAM->pos.x;
1032 vTarget.y -= ACTIVECAM->pos.y;
1033 vTarget.z += ACTIVECAM->pos.z;
1034
1035 Vec3f vUpVec(0.f, 1.f, 0.f);
1036
1037 // Set the app view matrix for normal viewing
1038 GRenderer->SetViewMatrix(vEyePt, vTarget, vUpVec);
1039
1040 EERIEMATRIX matProj;
1041 GRenderer->GetProjectionMatrix(matProj);
1042
1043 EERIEMATRIX matView;
1044 GRenderer->GetViewMatrix(matView);
1045
1046 EERIEMATRIX matres;
1047 MatrixMultiply(&matres, &matView, &matProj);
1048
1049 float a,b,c,d,n;
1050 a=matres._14-matres._11;
1051 b=matres._24-matres._21;
1052 c=matres._34-matres._31;
1053 d=matres._44-matres._41;
1054 b=-b;
1055 n = (float)(1.f /sqrt(a*a+b*b+c*c));
1056
1057 Frustrum_Set(frustrum,0,a*n,b*n,c*n,d*n);
1058 a=matres._14+matres._11;
1059 b=matres._24+matres._21;
1060 c=matres._34+matres._31;
1061 d=matres._44+matres._41;
1062 b=-b;
1063 n = (float)(1.f/sqrt(a*a+b*b+c*c));
1064
1065 Frustrum_Set(frustrum,1,a*n,b*n,c*n,d*n);
1066 a=matres._14-matres._12;
1067 b=matres._24-matres._22;
1068 c=matres._34-matres._32;
1069 d=matres._44-matres._42;
1070 b=-b;
1071 n = (float)(1.f/sqrt(a*a+b*b+c*c));
1072
1073 Frustrum_Set(frustrum,2,a*n,b*n,c*n,d*n);
1074 a=matres._14+matres._12;
1075 b=matres._24+matres._22;
1076 c=matres._34+matres._32;
1077 d=matres._44+matres._42;
1078 b=-b;
1079 n = (float)(1.f/sqrt(a*a+b*b+c*c));
1080
1081 Frustrum_Set(frustrum,3,a*n,b*n,c*n,d*n);
1082
1083 frustrum->nb=4;
1084
1085 a=matres._14+matres._13;
1086 b=matres._24+matres._23;
1087 c=matres._34+matres._33;
1088 d=matres._44+matres._43;
1089 b=-b;
1090 n = (float)(1.f/sqrt(a*a+b*b+c*c));
1091 efpPlaneNear.a=a*n;
1092 efpPlaneNear.b=b*n;
1093 efpPlaneNear.c=c*n;
1094 efpPlaneNear.d=d*n;
1095 }
1096
RoomDrawRelease()1097 void RoomDrawRelease() {
1098 free(RoomDrawList), RoomDrawList = NULL;
1099 free(RoomDraw), RoomDraw = NULL;
1100 }
1101
RoomDrawListAdd(long num)1102 void RoomDrawListAdd(long num) {
1103
1104 if(TotalRoomDrawList <= NbRoomDrawList) {
1105 RoomDrawList = (long *)realloc(RoomDrawList, sizeof(long) * (NbRoomDrawList + 1));
1106 TotalRoomDrawList=NbRoomDrawList+1;
1107 }
1108
1109 RoomDrawList[NbRoomDrawList]=num;
1110 NbRoomDrawList++;
1111 }
1112
RoomFrustrumAdd(long num,EERIE_FRUSTRUM * fr)1113 void RoomFrustrumAdd(long num,EERIE_FRUSTRUM * fr)
1114 {
1115 if (RoomDraw[num].frustrum.nb_frustrums<MAX_FRUSTRUMS-1)
1116 {
1117 memcpy(&RoomDraw[num].frustrum.frustrums
1118 [RoomDraw[num].frustrum.nb_frustrums],fr,sizeof(EERIE_FRUSTRUM));
1119 RoomDraw[num].frustrum.nb_frustrums++;
1120
1121 }
1122 }
1123 void ARX_PORTALS_RenderRoom(long room_num,EERIE_2D_BBOX * bbox,long prec,long tim);
ARX_PORTALS_RenderRooms(long prec,long tim)1124 void ARX_PORTALS_RenderRooms(long prec,long tim)
1125 {
1126 for (long i=0;i<NbRoomDrawList;i++)
1127 {
1128 ARX_PORTALS_RenderRoom(RoomDrawList[i],&RoomDraw[RoomDrawList[i]].bbox,prec,tim);
1129 }
1130
1131 NbRoomDrawList=0;
1132 }
1133 void ARX_PORTALS_Frustrum_RenderRoom(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim);
ARX_PORTALS_Frustrum_RenderRooms(long prec,long tim)1134 void ARX_PORTALS_Frustrum_RenderRooms(long prec,long tim)
1135 {
1136 for (long i=0;i<NbRoomDrawList;i++)
1137 {
1138 ARX_PORTALS_Frustrum_RenderRoom(RoomDrawList[i],&RoomDraw[RoomDrawList[i]].frustrum,prec,tim);
1139 }
1140
1141 NbRoomDrawList=0;
1142 }
1143
RenderWaterBatch()1144 static void RenderWaterBatch() {
1145
1146 if(!dynamicVertices.nbindices) {
1147 return;
1148 }
1149
1150 GRenderer->GetTextureStage(1)->SetColorOp(TextureStage::OpModulate4X, TextureStage::ArgTexture, TextureStage::ArgCurrent);
1151 GRenderer->GetTextureStage(1)->DisableAlpha();
1152
1153 GRenderer->GetTextureStage(2)->SetColorOp(TextureStage::OpModulate, TextureStage::ArgTexture, TextureStage::ArgCurrent);
1154 GRenderer->GetTextureStage(2)->DisableAlpha();
1155
1156 dynamicVertices.draw(Renderer::TriangleList);
1157
1158 GRenderer->GetTextureStage(1)->DisableColor();
1159 GRenderer->GetTextureStage(2)->DisableColor();
1160
1161 }
1162
RenderWater()1163 static void RenderWater() {
1164
1165 if(vPolyWater.empty()) {
1166 return;
1167 }
1168
1169 size_t iNbIndice = 0;
1170 int iNb = vPolyWater.size();
1171
1172 dynamicVertices.lock();
1173
1174 GRenderer->SetBlendFunc(Renderer::BlendDstColor, Renderer::BlendOne);
1175 GRenderer->SetTexture(0, enviro);
1176 GRenderer->SetTexture(2, enviro);
1177
1178 unsigned short * indices = dynamicVertices.indices;
1179
1180 while(iNb--) {
1181 EERIEPOLY * ep = vPolyWater[iNb];
1182
1183 unsigned short iNbVertex = (ep->type & POLY_QUAD) ? 4 : 3;
1184 SMY_VERTEX3 * pVertex = dynamicVertices.append(iNbVertex);
1185
1186 if(!pVertex) {
1187 dynamicVertices.unlock();
1188 RenderWaterBatch();
1189 dynamicVertices.reset();
1190 dynamicVertices.lock();
1191 iNbIndice = 0;
1192 indices = dynamicVertices.indices;
1193 pVertex = dynamicVertices.append(iNbVertex);
1194 }
1195
1196 pVertex->p.x = ep->v[0].p.x;
1197 pVertex->p.y = -ep->v[0].p.y;
1198 pVertex->p.z = ep->v[0].p.z;
1199 pVertex->color = 0xFF505050;
1200 float fTu = ep->v[0].p.x*(1.f/1000) + sin(ep->v[0].p.x*(1.f/200) + arxtime.get_frame_time()*(1.f/1000)) * (1.f/32);
1201 float fTv = ep->v[0].p.z*(1.f/1000) + cos(ep->v[0].p.z*(1.f/200) + arxtime.get_frame_time()*(1.f/1000)) * (1.f/32);
1202 if(ep->type & POLY_FALL) {
1203 fTv += arxtime.get_frame_time() * (1.f/4000);
1204 }
1205 pVertex->uv[0].x = fTu;
1206 pVertex->uv[0].y = fTv;
1207 fTu = (ep->v[0].p.x + 30.f)*(1.f/1000) + sin((ep->v[0].p.x + 30)*(1.f/200) + arxtime.get_frame_time()*(1.f/1000))*(1.f/28);
1208 fTv = (ep->v[0].p.z + 30.f)*(1.f/1000) - cos((ep->v[0].p.z + 30)*(1.f/200) + arxtime.get_frame_time()*(1.f/1000))*(1.f/28);
1209 if (ep->type & POLY_FALL) {
1210 fTv += arxtime.get_frame_time() * (1.f/4000);
1211 }
1212 pVertex->uv[1].x=fTu;
1213 pVertex->uv[1].y=fTv;
1214 fTu=(ep->v[0].p.x+60.f)*( 1.0f / 1000 )-EEsin((ep->v[0].p.x+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1215 fTv=(ep->v[0].p.z+60.f)*( 1.0f / 1000 )-EEcos((ep->v[0].p.z+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1216
1217 if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1218
1219 pVertex->uv[2].x=fTu;
1220 pVertex->uv[2].y=fTv;
1221
1222 pVertex++;
1223 pVertex->p.x=ep->v[1].p.x;
1224 pVertex->p.y=-ep->v[1].p.y;
1225 pVertex->p.z=ep->v[1].p.z;
1226 pVertex->color=0xFF505050;
1227 fTu=ep->v[1].p.x*( 1.0f / 1000 )+EEsin((ep->v[1].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1228 fTv=ep->v[1].p.z*( 1.0f / 1000 )+EEcos((ep->v[1].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1229
1230 if(ep->type&POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1231
1232 pVertex->uv[0].x=fTu;
1233 pVertex->uv[0].y=fTv;
1234 fTu=(ep->v[1].p.x+30.f)*( 1.0f / 1000 )+EEsin((ep->v[1].p.x+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1235 fTv=(ep->v[1].p.z+30.f)*( 1.0f / 1000 )-EEcos((ep->v[1].p.z+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1236
1237 if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1238
1239 pVertex->uv[1].x=fTu;
1240 pVertex->uv[1].y=fTv;
1241 fTu=(ep->v[1].p.x+60.f)*( 1.0f / 1000 )-EEsin((ep->v[1].p.x+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1242 fTv=(ep->v[1].p.z+60.f)*( 1.0f / 1000 )-EEcos((ep->v[1].p.z+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1243
1244 if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1245
1246 pVertex->uv[2].x=fTu;
1247 pVertex->uv[2].y=fTv;
1248 pVertex++;
1249 pVertex->p.x=ep->v[2].p.x;
1250 pVertex->p.y=-ep->v[2].p.y;
1251 pVertex->p.z=ep->v[2].p.z;
1252 pVertex->color=0xFF505050;
1253 fTu=ep->v[2].p.x*( 1.0f / 1000 )+EEsin((ep->v[2].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1254 fTv=ep->v[2].p.z*( 1.0f / 1000 )+EEcos((ep->v[2].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1255
1256 if(ep->type&POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1257
1258 pVertex->uv[0].x=fTu;
1259 pVertex->uv[0].y=fTv;
1260 fTu=(ep->v[2].p.x+30.f)*( 1.0f / 1000 )+EEsin((ep->v[2].p.x+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1261 fTv=(ep->v[2].p.z+30.f)*( 1.0f / 1000 )-EEcos((ep->v[2].p.z+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1262
1263 if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1264
1265 pVertex->uv[1].x=fTu;
1266 pVertex->uv[1].y=fTv;
1267 fTu=(ep->v[2].p.x+60.f)*( 1.0f / 1000 )-EEsin((ep->v[2].p.x+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1268 fTv=(ep->v[2].p.z+60.f)*( 1.0f / 1000 )-EEcos((ep->v[2].p.z+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1269
1270 if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1271
1272 pVertex->uv[2].x=fTu;
1273 pVertex->uv[2].y=fTv;
1274 pVertex++;
1275
1276 *indices++ = iNbIndice++;
1277 *indices++ = iNbIndice++;
1278 *indices++ = iNbIndice++;
1279 dynamicVertices.nbindices += 3;
1280
1281 if(iNbVertex == 4)
1282 {
1283 pVertex->p.x=ep->v[3].p.x;
1284 pVertex->p.y=-ep->v[3].p.y;
1285 pVertex->p.z=ep->v[3].p.z;
1286 pVertex->color=0xFF505050;
1287 fTu=ep->v[3].p.x*( 1.0f / 1000 )+EEsin((ep->v[3].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1288 fTv=ep->v[3].p.z*( 1.0f / 1000 )+EEcos((ep->v[3].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1289
1290 if(ep->type&POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1291
1292 pVertex->uv[0].x=fTu;
1293 pVertex->uv[0].y=fTv;
1294 fTu=(ep->v[3].p.x+30.f)*( 1.0f / 1000 )+EEsin((ep->v[3].p.x+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1295 fTv=(ep->v[3].p.z+30.f)*( 1.0f / 1000 )-EEcos((ep->v[3].p.z+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1296
1297 if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1298
1299 pVertex->uv[1].x=fTu;
1300 pVertex->uv[1].y=fTv;
1301 fTu=(ep->v[3].p.x+60.f)*( 1.0f / 1000 )-EEsin((ep->v[3].p.x+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1302 fTv=(ep->v[3].p.z+60.f)*( 1.0f / 1000 )-EEcos((ep->v[3].p.z+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1303
1304 if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1305
1306 pVertex->uv[2].x=fTu;
1307 pVertex->uv[2].y=fTv;
1308 pVertex++;
1309
1310 *indices++ = iNbIndice++;
1311 *indices++ = iNbIndice - 2;
1312 *indices++ = iNbIndice - 3;
1313 dynamicVertices.nbindices += 3;
1314 }
1315
1316 }
1317
1318 dynamicVertices.unlock();
1319 RenderWaterBatch();
1320 dynamicVertices.done();
1321
1322 vPolyWater.clear();
1323
1324 }
1325
RenderLavaBatch()1326 void RenderLavaBatch() {
1327
1328 GRenderer->SetBlendFunc(Renderer::BlendDstColor, Renderer::BlendOne);
1329 GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate2X, TextureStage::ArgTexture, TextureStage::ArgDiffuse);
1330
1331 if(!dynamicVertices.nbindices) {
1332 return;
1333 }
1334
1335 GRenderer->GetTextureStage(1)->SetColorOp(TextureStage::OpModulate4X, TextureStage::ArgTexture, TextureStage::ArgCurrent);
1336 GRenderer->GetTextureStage(1)->DisableAlpha();
1337
1338 GRenderer->GetTextureStage(2)->SetColorOp(TextureStage::OpModulate, TextureStage::ArgTexture, TextureStage::ArgCurrent);
1339 GRenderer->GetTextureStage(2)->DisableAlpha();
1340
1341 dynamicVertices.draw(Renderer::TriangleList);
1342
1343 GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
1344 GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate);
1345
1346 dynamicVertices.draw(Renderer::TriangleList);
1347
1348 GRenderer->GetTextureStage(1)->DisableColor();
1349 GRenderer->GetTextureStage(2)->DisableColor();
1350
1351 }
1352
RenderLava()1353 void RenderLava() {
1354
1355 if(vPolyLava.empty()) {
1356 return;
1357 }
1358
1359 size_t iNbIndice = 0;
1360 int iNb=vPolyLava.size();
1361
1362 dynamicVertices.lock();
1363
1364 GRenderer->SetBlendFunc(Renderer::BlendDstColor, Renderer::BlendOne);
1365 GRenderer->SetTexture(0, enviro);
1366 GRenderer->SetTexture(2, enviro);
1367
1368 unsigned short * indices = dynamicVertices.indices;
1369
1370 while(iNb--) {
1371 EERIEPOLY * ep = vPolyLava[iNb];
1372
1373 unsigned short iNbVertex = (ep->type & POLY_QUAD) ? 4 : 3;
1374 SMY_VERTEX3 * pVertex = dynamicVertices.append(iNbVertex);
1375
1376 if(!pVertex) {
1377 dynamicVertices.unlock();
1378 RenderLavaBatch();
1379 dynamicVertices.reset();
1380 dynamicVertices.lock();
1381 iNbIndice = 0;
1382 indices = dynamicVertices.indices;
1383 pVertex = dynamicVertices.append(iNbVertex);
1384 }
1385
1386 pVertex->p.x=ep->v[0].p.x;
1387 pVertex->p.y=-ep->v[0].p.y;
1388 pVertex->p.z=ep->v[0].p.z;
1389 pVertex->color=0xFF666666;
1390 float fTu=ep->v[0].p.x*( 1.0f / 1000 )+EEsin((ep->v[0].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1391 float fTv=ep->v[0].p.z*( 1.0f / 1000 )+EEcos((ep->v[0].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1392 pVertex->uv[0].x=fTu;
1393 pVertex->uv[0].y=fTv;
1394 fTu=ep->v[0].p.x*( 1.0f / 1000 )+EEsin((ep->v[0].p.x)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1395 fTv=ep->v[0].p.z*( 1.0f / 1000 )+EEcos((ep->v[0].p.z)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1396 pVertex->uv[1].x=fTu;
1397 pVertex->uv[1].y=fTv;
1398 fTu=ep->v[0].p.x*( 1.0f / 600 )+EEsin((ep->v[0].p.x)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1399 fTv=ep->v[0].p.z*( 1.0f / 600 )+EEcos((ep->v[0].p.z)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1400
1401 pVertex->uv[2].x=fTu;
1402 pVertex->uv[2].y=fTv;
1403 pVertex++;
1404 pVertex->p.x=ep->v[1].p.x;
1405 pVertex->p.y=-ep->v[1].p.y;
1406 pVertex->p.z=ep->v[1].p.z;
1407 pVertex->color=0xFF666666;
1408 fTu=ep->v[1].p.x*( 1.0f / 1000 )+EEsin((ep->v[1].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1409 fTv=ep->v[1].p.z*( 1.0f / 1000 )+EEcos((ep->v[1].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1410 pVertex->uv[0].x=fTu;
1411 pVertex->uv[0].y=fTv;
1412 fTu=ep->v[1].p.x*( 1.0f / 1000 )+EEsin((ep->v[1].p.x)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1413 fTv=ep->v[1].p.z*( 1.0f / 1000 )+EEcos((ep->v[1].p.z)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1414 pVertex->uv[1].x=fTu;
1415 pVertex->uv[1].y=fTv;
1416 fTu=ep->v[1].p.x*( 1.0f / 600 )+EEsin((ep->v[1].p.x)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1417 fTv=ep->v[1].p.z*( 1.0f / 600 )+EEcos((ep->v[1].p.z)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1418
1419 pVertex->uv[2].x=fTu;
1420 pVertex->uv[2].y=fTv;
1421 pVertex++;
1422 pVertex->p.x=ep->v[2].p.x;
1423 pVertex->p.y=-ep->v[2].p.y;
1424 pVertex->p.z=ep->v[2].p.z;
1425 pVertex->color=0xFF666666;
1426 fTu=ep->v[2].p.x*( 1.0f / 1000 )+EEsin((ep->v[2].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1427 fTv=ep->v[2].p.z*( 1.0f / 1000 )+EEcos((ep->v[2].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1428 pVertex->uv[0].x=fTu;
1429 pVertex->uv[0].y=fTv;
1430 fTu=ep->v[2].p.x*( 1.0f / 1000 )+EEsin((ep->v[2].p.x)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1431 fTv=ep->v[2].p.z*( 1.0f / 1000 )+EEcos((ep->v[2].p.z)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1432 pVertex->uv[1].x=fTu;
1433 pVertex->uv[1].y=fTv;
1434 fTu=ep->v[2].p.x*( 1.0f / 600 )+EEsin((ep->v[2].p.x)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1435 fTv=ep->v[2].p.z*( 1.0f / 600 )+EEcos((ep->v[2].p.z)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1436
1437 pVertex->uv[2].x=fTu;
1438 pVertex->uv[2].y=fTv;
1439 pVertex++;
1440
1441 *indices++ = iNbIndice++;
1442 *indices++ = iNbIndice++;
1443 *indices++ = iNbIndice++;
1444 dynamicVertices.nbindices += 3;
1445
1446 if(iNbVertex&4)
1447 {
1448 pVertex->p.x=ep->v[3].p.x;
1449 pVertex->p.y=-ep->v[3].p.y;
1450 pVertex->p.z=ep->v[3].p.z;
1451 pVertex->color=0xFF666666;
1452 fTu=ep->v[3].p.x*( 1.0f / 1000 )+EEsin((ep->v[3].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1453 fTv=ep->v[3].p.z*( 1.0f / 1000 )+EEcos((ep->v[3].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1454 pVertex->uv[0].x=fTu;
1455 pVertex->uv[0].y=fTv;
1456 fTu=ep->v[3].p.x*( 1.0f / 1000 )+EEsin((ep->v[3].p.x)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1457 fTv=ep->v[3].p.z*( 1.0f / 1000 )+EEcos((ep->v[3].p.z)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1458 pVertex->uv[1].x=fTu;
1459 pVertex->uv[1].y=fTv;
1460 fTu=ep->v[3].p.x*( 1.0f / 600 )+EEsin((ep->v[3].p.x)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1461 fTv=ep->v[3].p.z*( 1.0f / 600 )+EEcos((ep->v[3].p.z)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1462
1463 pVertex->uv[2].x=fTu;
1464 pVertex->uv[2].y=fTv;
1465 pVertex++;
1466
1467 *indices++ = iNbIndice++;
1468 *indices++ = iNbIndice - 2;
1469 *indices++ = iNbIndice - 3;
1470 dynamicVertices.nbindices += 3;
1471 }
1472
1473 }
1474
1475 dynamicVertices.unlock();
1476 RenderLavaBatch();
1477 dynamicVertices.done();
1478
1479 vPolyLava.clear();
1480
1481 }
1482
1483 void ARX_PORTALS_Frustrum_RenderRoom_TransparencyTSoftCull(long room_num);
ARX_PORTALS_Frustrum_RenderRooms_TransparencyT()1484 void ARX_PORTALS_Frustrum_RenderRooms_TransparencyT() {
1485
1486 GRenderer->SetFogColor(Color::none);
1487
1488 GRenderer->SetRenderState(Renderer::AlphaBlending, true);
1489 GRenderer->SetCulling(Renderer::CullNone);
1490 GRenderer->SetRenderState(Renderer::DepthWrite, false);
1491
1492 GRenderer->SetAlphaFunc(Renderer::CmpGreater, .5f);
1493
1494 for (long i=0;i<NbRoomDrawList;i++)
1495 {
1496 if(USE_PORTALS==4)
1497 {
1498 ARX_PORTALS_Frustrum_RenderRoom_TransparencyTSoftCull(RoomDrawList[i]);
1499 }
1500 else
1501 {
1502 LogWarning << "unimplemented";
1503 }
1504 }
1505
1506 GRenderer->SetAlphaFunc(Renderer::CmpNotEqual, 0.f);
1507
1508 NbRoomDrawList=0;
1509
1510
1511 SetZBias(8);
1512
1513 GRenderer->SetRenderState(Renderer::DepthWrite, false);
1514
1515 //render all fx!!
1516 GRenderer->SetCulling(Renderer::CullCW);
1517
1518 RenderWater();
1519 RenderLava();
1520
1521 SetZBias(0);
1522 GRenderer->SetFogColor(ulBKGColor);
1523 GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate);
1524 GRenderer->SetRenderState(Renderer::AlphaBlending, false);
1525 }
1526
1527 void ARX_PORTALS_Frustrum_RenderRoomTCullSoft(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim);
ARX_PORTALS_Frustrum_RenderRoomsTCullSoft(long prec,long tim)1528 void ARX_PORTALS_Frustrum_RenderRoomsTCullSoft(long prec,long tim)
1529 {
1530 GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
1531
1532 for (long i=0;i<NbRoomDrawList;i++)
1533 {
1534 ARX_PORTALS_Frustrum_RenderRoomTCullSoft(RoomDrawList[i],&RoomDraw[RoomDrawList[i]].frustrum,prec,tim);
1535 }
1536 }
ARX_PORTALS_RenderRoom(long room_num,EERIE_2D_BBOX * bbox,long prec,long tim)1537 void ARX_PORTALS_RenderRoom(long room_num,EERIE_2D_BBOX * bbox,long prec,long tim)
1538 {
1539
1540 if (RoomDraw[room_num].count)
1541 {
1542 EERIEDraw2DRect(bbox->min.x, bbox->min.y ,bbox->max.x, bbox->max.y, 0.0001f, Color::blue);
1543
1544 for (long lll=0;lll<portals->room[room_num].nb_polys;lll++)
1545 {
1546
1547 FAST_BKG_DATA * feg;
1548 feg=&ACTIVEBKG->fastdata[portals->room[room_num].epdata[lll].px][portals->room[room_num].epdata[lll].py];
1549
1550 if (!feg->treat)
1551 continue;
1552
1553 EERIEPOLY * ep=&feg->polydata[portals->room[room_num].epdata[lll].idx];
1554
1555 if (ep->type & (POLY_IGNORE | POLY_NODRAW))
1556 continue;
1557
1558 // GO for 3D Backface Culling
1559 if (ep->type & POLY_DOUBLESIDED)
1560 GRenderer->SetCulling(Renderer::CullNone);
1561 else
1562 {
1563 Vec3f nrm = ep->v[2].p - ACTIVECAM->pos;
1564 if ( ep->type & POLY_QUAD)
1565 {
1566 if ((dot(ep->norm , nrm) > 0.f) &&
1567 (dot(ep->norm2 , nrm) > 0.f) )
1568 continue;
1569 }
1570 else if (dot(ep->norm , nrm) > 0.f)
1571 continue;
1572
1573 GRenderer->SetCulling(Renderer::CullCW);
1574 }
1575
1576 if (!EERIERTPPoly(ep)) // RotTransProject Vertices
1577 continue;
1578
1579 if (BBoxClipPoly(bbox,ep))
1580 continue;
1581
1582 long to;
1583
1584 if ( ep->type & POLY_QUAD)
1585 {
1586 if (FRAME_COUNT<=0)
1587 ep->tv[3].color=ep->v[3].color;
1588
1589 to=4;
1590 }
1591 else to=3;
1592
1593 if (ep->type & POLY_TRANS)
1594 {
1595 ManageLavaWater(ep,to,tim);
1596 TransPol[TRANSPOLYSPOS++]=ep;
1597
1598 if (TRANSPOLYSPOS>=MAX_TRANSPOL) TRANSPOLYSPOS=MAX_TRANSPOL-1;
1599
1600 if (ViewMode)
1601 {
1602 if (ViewMode & VIEWMODE_WIRE)
1603 EERIEPOLY_DrawWired(ep);
1604
1605 if (ViewMode & VIEWMODE_NORMALS)
1606 EERIEPOLY_DrawNormals(ep);
1607 }
1608
1609 continue;
1610 }
1611
1612 if (!Project.improve) // Normal View...
1613 {
1614 if (ep->type & POLY_GLOW)
1615 ep->tv[0].color=ep->tv[1].color=ep->tv[2].color=ep->tv[3].color=0xFFFFFFFF;
1616 else
1617 {
1618 if (FRAME_COUNT<=0)
1619 {
1620 if (ModeLight & MODE_DYNAMICLIGHT) ApplyDynLight(ep);
1621 else
1622 {
1623 ep->tv[0].color=ep->v[0].color;
1624 ep->tv[1].color=ep->v[1].color;
1625 ep->tv[2].color=ep->v[2].color;
1626 }
1627 }
1628 }
1629
1630 ManageLavaWater(ep,to,tim);
1631
1632 Delayed_EERIEDRAWPRIM(ep);
1633
1634 if (ViewMode)
1635 {
1636 if (ViewMode & VIEWMODE_WIRE)
1637 EERIEPOLY_DrawWired(ep);
1638
1639 if (ViewMode & VIEWMODE_NORMALS)
1640 EERIEPOLY_DrawNormals(ep);
1641 }
1642 }
1643 else // Improve Vision Activated
1644 {
1645 if (FRAME_COUNT<=0)
1646 {
1647 if ( ModeLight & MODE_DYNAMICLIGHT ) ApplyDynLight(ep);
1648 else
1649 {
1650 ep->tv[0].color=ep->v[0].color;
1651 ep->tv[1].color=ep->v[1].color;
1652 ep->tv[2].color=ep->v[2].color;
1653 }
1654
1655
1656 for (long k=0;k<to;k++)
1657 {
1658 long lfr,lfb;
1659 float fr,fb;
1660 long lr=(ep->tv[k].color>>16) & 255;
1661 float ffr=(float)(lr);
1662
1663 float dd=(ep->tv[k].p.z*prec);
1664
1665 if (dd>1.f) dd=1.f;
1666
1667 if (dd<0.f) dd=0.f;
1668
1669 fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f;
1670 fr=((0.6f-dd)*6.f + (EEfabs(ep->nrml[k].z)+EEfabs(ep->nrml[k].y)))*0.125f;//(1.f-dd);
1671
1672 if (fr<0.f) fr=0.f;
1673 else fr=max(ffr,fr*255.f);
1674
1675 fb*=255.f;
1676 lfr = fr;
1677 lfb = fb;
1678 ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) );
1679 //GG component locked at 0x1E
1680 }
1681 }
1682
1683 Delayed_EERIEDRAWPRIM(ep);
1684 }
1685 }
1686 }
1687 }
ARX_PORTALS_Frustrum_RenderRoom(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim)1688 void ARX_PORTALS_Frustrum_RenderRoom(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim)
1689 {
1690
1691 if (RoomDraw[room_num].count)
1692 {
1693
1694 for (long lll=0;lll<portals->room[room_num].nb_polys;lll++)
1695 {
1696
1697 FAST_BKG_DATA * feg;
1698 feg=&ACTIVEBKG->fastdata[portals->room[room_num].epdata[lll].px][portals->room[room_num].epdata[lll].py];
1699
1700 if (!feg->treat)
1701 continue;
1702
1703 EERIEPOLY * ep=&feg->polydata[portals->room[room_num].epdata[lll].idx];
1704
1705 if (ep->type & (POLY_IGNORE | POLY_NODRAW))
1706 continue;
1707
1708 if (FrustrumsClipPoly(frustrums,ep))
1709 continue;
1710
1711 // GO for 3D Backface Culling
1712 if (ep->type & POLY_DOUBLESIDED)
1713 GRenderer->SetCulling(Renderer::CullNone);
1714 else
1715 {
1716 Vec3f nrm = ep->v[2].p - ACTIVECAM->pos;
1717 if ( ep->type & POLY_QUAD)
1718 {
1719 if ( (dot( ep->norm , nrm )>0.f) &&
1720 (dot( ep->norm2 , nrm )>0.f) )
1721 continue;
1722 }
1723 else if ( dot( ep->norm , nrm )>0.f)
1724 continue;
1725
1726 GRenderer->SetCulling(Renderer::CullCW);
1727 }
1728
1729 if (!EERIERTPPoly(ep)) // RotTransProject Vertices
1730 continue;
1731
1732 long to;
1733
1734 if ( ep->type & POLY_QUAD)
1735 {
1736 if (FRAME_COUNT<=0) ep->tv[3].color=ep->v[3].color;
1737
1738 to=4;
1739 }
1740 else to=3;
1741
1742 if (ep->type & POLY_TRANS)
1743 {
1744 ManageLavaWater(ep,to,tim);
1745 TransPol[TRANSPOLYSPOS++]=ep;
1746
1747 if (TRANSPOLYSPOS>=MAX_TRANSPOL) TRANSPOLYSPOS=MAX_TRANSPOL-1;
1748
1749 if (ViewMode)
1750 {
1751 if (ViewMode & VIEWMODE_WIRE)
1752 EERIEPOLY_DrawWired(ep);
1753
1754 if (ViewMode & VIEWMODE_NORMALS)
1755 EERIEPOLY_DrawNormals(ep);
1756 }
1757
1758 continue;
1759 }
1760
1761 if (!Project.improve) // Normal View...
1762 {
1763 if (ep->type & POLY_GLOW) ep->tv[0].color=ep->tv[1].color=ep->tv[2].color=ep->tv[3].color=0xFFFFFFFF;
1764 else
1765 {
1766 if (FRAME_COUNT<=0)
1767 {
1768 if (ModeLight & MODE_DYNAMICLIGHT) ApplyDynLight(ep);
1769 else
1770 {
1771 ep->tv[0].color=ep->v[0].color;
1772 ep->tv[1].color=ep->v[1].color;
1773 ep->tv[2].color=ep->v[2].color;
1774 }
1775 }
1776 }
1777
1778 ManageLavaWater(ep,to,tim);
1779
1780 Delayed_EERIEDRAWPRIM(ep);
1781
1782 if (ViewMode)
1783 {
1784 if (ViewMode & VIEWMODE_WIRE)
1785 EERIEPOLY_DrawWired(ep);
1786
1787 if (ViewMode & VIEWMODE_NORMALS)
1788 EERIEPOLY_DrawNormals(ep);
1789 }
1790 }
1791 else // Improve Vision Activated
1792 {
1793 if (FRAME_COUNT<=0)
1794 {
1795 if ( ModeLight & MODE_DYNAMICLIGHT ) ApplyDynLight(ep);
1796 else
1797 {
1798 ep->tv[0].color=ep->v[0].color;
1799 ep->tv[1].color=ep->v[1].color;
1800 ep->tv[2].color=ep->v[2].color;
1801 }
1802
1803
1804 for (long k=0;k<to;k++)
1805 {
1806 long lfr,lfb;
1807 float fr,fb;
1808 long lr=(ep->tv[k].color>>16) & 255;
1809 float ffr=(float)(lr);
1810
1811 float dd=(ep->tv[k].p.z*prec);
1812
1813 if (dd>1.f) dd=1.f;
1814
1815 if (dd<0.f) dd=0.f;
1816
1817 fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f;
1818 fr=((0.6f-dd)*6.f + (EEfabs(ep->nrml[k].z)+EEfabs(ep->nrml[k].y)))*0.125f;//(1.f-dd);
1819
1820 if (fr<0.f) fr=0.f;
1821 else fr=max(ffr,fr*255.f);
1822
1823 fb*=255.f;
1824 lfr = fr;
1825 lfb = fb;
1826 ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) );
1827 //GG component locked at 0x1E
1828 }
1829 }
1830
1831 Delayed_EERIEDRAWPRIM(ep);
1832 }
1833 }
1834 }
1835 }
1836
1837 void ApplyDynLight_VertexBuffer(EERIEPOLY *ep,SMY_VERTEX *_pVertex,unsigned short _usInd0,unsigned short _usInd1,unsigned short _usInd2,unsigned short _usInd3);
1838 void ApplyDynLight_VertexBuffer_2(EERIEPOLY *ep,short x,short y,SMY_VERTEX *_pVertex,unsigned short _usInd0,unsigned short _usInd1,unsigned short _usInd2,unsigned short _usInd3);
1839
1840 TILE_LIGHTS tilelights[MAX_BKGX][MAX_BKGZ];
1841
InitTileLights()1842 void InitTileLights()
1843 {
1844 for (long j=0;j<MAX_BKGZ;j++)
1845 for (long i=0;i<MAX_BKGZ;i++)
1846 {
1847 tilelights[i][j].el=NULL;
1848 tilelights[i][j].max=0;
1849 tilelights[i][j].num=0;
1850 }
1851 }
1852
ComputeTileLights(short x,short z)1853 void ComputeTileLights(short x,short z)
1854 {
1855 tilelights[x][z].num=0;
1856 float xx=((float)x+0.5f)*ACTIVEBKG->Xdiv;
1857 float zz=((float)z+0.5f)*ACTIVEBKG->Zdiv;
1858
1859 for (long i=0;i<TOTPDL;i++)
1860 {
1861 if(closerThan(Vec2f(xx, zz), Vec2f(PDL[i]->pos.x, PDL[i]->pos.z), PDL[i]->fallend + 60.f)) {
1862
1863 if (tilelights[x][z].num>=tilelights[x][z].max)
1864 {
1865 tilelights[x][z].max++;
1866 tilelights[x][z].el=(EERIE_LIGHT **)realloc(tilelights[x][z].el,sizeof(EERIE_LIGHT *)*(tilelights[x][z].max));
1867 }
1868
1869 tilelights[x][z].el[tilelights[x][z].num]=PDL[i];
1870 tilelights[x][z].num++;
1871 }
1872 }
1873 }
1874
ClearTileLights()1875 void ClearTileLights() {
1876 for(long j = 0; j < MAX_BKGZ; j++) for(long i = 0; i < MAX_BKGZ; i++) {
1877 tilelights[i][j].max = 0;
1878 tilelights[i][j].num = 0;
1879 free(tilelights[i][j].el), tilelights[i][j].el = NULL;
1880 }
1881 }
1882
ARX_PORTALS_Frustrum_RenderRoomTCullSoft(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim)1883 void ARX_PORTALS_Frustrum_RenderRoomTCullSoft(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim)
1884 {
1885
1886
1887 if(RoomDraw[room_num].count) {
1888
1889 if(!portals->room[room_num].pVertexBuffer) {
1890 // No need to spam this for every frame as there will already be an
1891 // earlier warning
1892 LogDebug("no vertex data for room " << room_num);
1893 return;
1894 }
1895
1896 SMY_VERTEX * pMyVertex = portals->room[room_num].pVertexBuffer->lock(NoOverwrite);
1897
1898 unsigned short *pIndices=portals->room[room_num].pussIndice;
1899
1900 FAST_BKG_DATA * feg;
1901 EERIEPOLY * ep;
1902 EP_DATA *pEPDATA = &portals->room[room_num].epdata[0];
1903
1904 for (long lll=0; lll<portals->room[room_num].nb_polys; lll++, pEPDATA++)
1905 {
1906
1907 feg = &ACTIVEBKG->fastdata[pEPDATA->px][pEPDATA->py];
1908
1909 if (!feg->treat)
1910 {
1911 long ix=max(0,pEPDATA->px-1);
1912 long ax=min(ACTIVEBKG->Xsize-1,pEPDATA->px+1);
1913 long iz=max(0,pEPDATA->py-1);
1914 long az=min(ACTIVEBKG->Zsize-1,pEPDATA->py+1);
1915
1916 (void)checked_range_cast<short>(iz);
1917 (void)checked_range_cast<short>(ix);
1918 (void)checked_range_cast<short>(az);
1919 (void)checked_range_cast<short>(ax);
1920
1921 for (long nz=iz;nz<=az;nz++)
1922 for (long nx=ix;nx<=ax;nx++)
1923
1924 {
1925 FAST_BKG_DATA * feg2 = &ACTIVEBKG->fastdata[nx][nz];
1926
1927 if (!feg2->treat)
1928 {
1929 feg2->treat=1;
1930
1931 if (USE_LIGHT_OPTIM)
1932 ComputeTileLights(static_cast<short>(nx), static_cast<short>(nz));
1933 }
1934 }
1935 }
1936
1937 ep=&feg->polydata[pEPDATA->idx];
1938
1939 if (!ep->tex)
1940 {
1941 continue;
1942 }
1943
1944 if (ep->type & (POLY_IGNORE | POLY_NODRAW| POLY_HIDE))
1945 {
1946 continue;
1947 }
1948
1949 if (FrustrumsClipPoly(frustrums,ep))
1950 {
1951 continue;
1952 }
1953
1954 //Clipp ZNear + Distance pour les ZMapps!!!
1955 float fDist=(ep->center.x*efpPlaneNear.a + ep->center.y*efpPlaneNear.b + ep->center.z*efpPlaneNear.c + efpPlaneNear.d);
1956
1957 if(ep->v[0].rhw<-fDist)
1958 {
1959 continue;
1960 }
1961
1962 fDist-=ep->v[0].rhw;
1963
1964 Vec3f nrm = ep->v[2].p - ACTIVECAM->pos;
1965 int to;
1966 if(ep->type&POLY_QUAD)
1967 {
1968 if( (!(ep->type&POLY_DOUBLESIDED))&&
1969 (dot( ep->norm , nrm )>0.f)&&
1970 (dot( ep->norm2 , nrm )>0.f) )
1971 {
1972 continue;
1973 }
1974
1975 to=4;
1976 }
1977 else
1978 {
1979 if( (!(ep->type&POLY_DOUBLESIDED))&&
1980 (dot( ep->norm , nrm )>0.f) )
1981 {
1982 continue;
1983 }
1984
1985 to=3;
1986 }
1987
1988 unsigned short *pIndicesCurr;
1989 unsigned long *pNumIndices;
1990
1991 if(ep->type&POLY_TRANS)
1992 {
1993 if(ep->transval>=2.f) //MULTIPLICATIVE
1994 {
1995 pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TMultiplicative+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative;
1996 pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative;
1997 }
1998 else
1999 {
2000 if(ep->transval>=1.f) //ADDITIVE
2001 {
2002 pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TAdditive+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TAdditive;
2003 pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TAdditive;
2004 }
2005 else
2006 {
2007 if(ep->transval>0.f) //NORMAL TRANS
2008 {
2009 pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TNormalTrans+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans;
2010 pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans;
2011 }
2012 else
2013 {
2014 //SUBTRACTIVE
2015 pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TSubstractive+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TSubstractive;
2016 pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TSubstractive;
2017 }
2018 }
2019 }
2020 }
2021 else
2022 {
2023 pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull+ep->tex->tMatRoom[room_num].uslNbIndiceCull;
2024 pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull;
2025
2026 if(ZMAPMODE)
2027 {
2028 if((fDist<200)&&(ep->tex->TextureRefinement))
2029 {
2030 ep->tex->TextureRefinement->vPolyZMap.push_back(ep);
2031 }
2032 }
2033 }
2034
2035 SMY_VERTEX *pMyVertexCurr;
2036
2037 *pIndicesCurr++=ep->uslInd[0];
2038 *pIndicesCurr++=ep->uslInd[1];
2039 *pIndicesCurr++=ep->uslInd[2];
2040
2041 if(to&4)
2042 {
2043 *pIndicesCurr++=ep->uslInd[3];
2044 *pIndicesCurr++=ep->uslInd[2];
2045 *pIndicesCurr++=ep->uslInd[1];
2046 *pNumIndices+=6;
2047 }
2048 else
2049 {
2050 *pNumIndices+=3;
2051 }
2052 pMyVertexCurr=&pMyVertex[ep->tex->tMatRoom[room_num].uslStartVertex];
2053
2054
2055 if (!Project.improve) // Normal View...
2056 {
2057 if(ep->type&POLY_GLOW)
2058 {
2059 pMyVertexCurr[ep->uslInd[0]].color=pMyVertexCurr[ep->uslInd[1]].color=pMyVertexCurr[ep->uslInd[2]].color=0xFFFFFFFF;
2060
2061 if(to&4)
2062 {
2063 pMyVertexCurr[ep->uslInd[3]].color=0xFFFFFFFF;
2064 }
2065 }
2066 else
2067 {
2068 if(ep->type&POLY_LAVA)
2069 {
2070 if((FRAME_COUNT<=0)&&(!(ep->type&POLY_TRANS)))
2071 {
2072 if(ModeLight & MODE_DYNAMICLIGHT)
2073 {
2074 ApplyDynLight(ep);
2075 }
2076 else
2077 {
2078 ep->tv[0].color=ep->v[0].color;
2079 ep->tv[1].color=ep->v[1].color;
2080 ep->tv[2].color=ep->v[2].color;
2081
2082 if(to&4)
2083 {
2084 ep->tv[3].color=ep->v[3].color;
2085 }
2086 }
2087 }
2088
2089 ManageLava_VertexBuffer(ep,to,tim,pMyVertexCurr);
2090
2091 vPolyLava.push_back(ep);
2092
2093 pMyVertexCurr[ep->uslInd[0]].color=ep->tv[0].color;
2094 pMyVertexCurr[ep->uslInd[1]].color=ep->tv[1].color;
2095 pMyVertexCurr[ep->uslInd[2]].color=ep->tv[2].color;
2096
2097 if(to&4)
2098 {
2099 pMyVertexCurr[ep->uslInd[3]].color=ep->tv[3].color;
2100 }
2101 }
2102 else
2103 {
2104 if((FRAME_COUNT<=0)&&(!(ep->type&POLY_TRANS)))
2105 {
2106 if(ModeLight & MODE_DYNAMICLIGHT)
2107 {
2108
2109 if (USE_LIGHT_OPTIM)
2110 ApplyDynLight_VertexBuffer_2( ep,pEPDATA->px,pEPDATA->py,
2111 pMyVertexCurr,
2112 ep->uslInd[0],
2113 ep->uslInd[1],
2114 ep->uslInd[2],
2115 ep->uslInd[3]);
2116
2117 else
2118 ApplyDynLight_VertexBuffer( ep,
2119 pMyVertexCurr,
2120 ep->uslInd[0],
2121 ep->uslInd[1],
2122 ep->uslInd[2],
2123 ep->uslInd[3]);
2124
2125 }
2126 else
2127 {
2128 pMyVertexCurr[ep->uslInd[0]].color=ep->v[0].color;
2129 pMyVertexCurr[ep->uslInd[1]].color=ep->v[1].color;
2130 pMyVertexCurr[ep->uslInd[2]].color=ep->v[2].color;
2131
2132 if(to&4)
2133 {
2134 pMyVertexCurr[ep->uslInd[3]].color=ep->v[3].color;
2135 }
2136 }
2137 }
2138
2139 if(ep->type&POLY_WATER)
2140 {
2141 ManageWater_VertexBuffer(ep,to,tim,pMyVertexCurr);
2142 vPolyWater.push_back(ep);
2143 }
2144 }
2145 }
2146
2147 if ((ViewMode & VIEWMODE_WIRE))
2148 {
2149 if (EERIERTPPoly(ep))
2150 EERIEPOLY_DrawWired(ep);
2151 }
2152
2153 }
2154 else // Improve Vision Activated
2155 {
2156 //!!!!!!!!! NOT OPTIMIZED T&L !!!!!!!!!!
2157 if ((FRAME_COUNT<=0)&&(!(ep->type&POLY_TRANS)))
2158 {
2159 if (!EERIERTPPoly(ep)) // RotTransProject Vertices
2160 {
2161 continue;
2162 }
2163
2164 if ( ModeLight & MODE_DYNAMICLIGHT ) ApplyDynLight(ep);
2165 else
2166 {
2167 ep->tv[0].color=ep->v[0].color;
2168 ep->tv[1].color=ep->v[1].color;
2169 ep->tv[2].color=ep->v[2].color;
2170
2171 if(to&4)
2172 {
2173 ep->tv[3].color=ep->v[3].color;
2174 }
2175 }
2176
2177 for (long k=0;k<to;k++)
2178 {
2179 long lfr,lfb;
2180 float fr,fb;
2181 long lr=(ep->tv[k].color>>16) & 255;
2182 float ffr=(float)(lr);
2183
2184 float dd=(ep->tv[k].rhw*prec);
2185
2186 if (dd>1.f) dd=1.f;
2187
2188 if (dd<0.f) dd=0.f;
2189
2190 fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f;
2191 fr = ((0.6f - dd) * 6.f + (EEfabs(ep->nrml[k].z) + EEfabs(ep->nrml[k].y))) * 0.125f;
2192
2193 if (fr<0.f) fr=0.f;
2194 else fr=max(ffr,fr*255.f);
2195
2196 fr=min(fr,255.f);
2197 fb*=255.f;
2198 fb=min(fb,255.f);
2199 lfr = fr;
2200 lfb = fb;
2201
2202 ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) );
2203
2204 }
2205
2206 pMyVertexCurr[ep->uslInd[0]].color=ep->tv[0].color;
2207 pMyVertexCurr[ep->uslInd[1]].color=ep->tv[1].color;
2208 pMyVertexCurr[ep->uslInd[2]].color=ep->tv[2].color;
2209
2210 if(to&4)
2211 {
2212 pMyVertexCurr[ep->uslInd[3]].color=ep->tv[3].color;
2213 }
2214 }
2215 }
2216 }
2217
2218 portals->room[room_num].pVertexBuffer->unlock();
2219
2220 //render opaque
2221 GRenderer->SetCulling(Renderer::CullNone);
2222 int iNbTex=portals->room[room_num].usNbTextures;
2223 TextureContainer **ppTexCurr=portals->room[room_num].ppTextureContainer;
2224
2225 while(iNbTex--)
2226 {
2227 TextureContainer *pTexCurr=*ppTexCurr;
2228
2229 if (ViewMode & VIEWMODE_FLAT)
2230 GRenderer->ResetTexture(0);
2231 else
2232 GRenderer->SetTexture(0, pTexCurr);
2233
2234 if(pTexCurr->userflags&POLY_METAL)
2235 {
2236 GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate2X);
2237 }
2238 else
2239 {
2240 GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate);
2241 }
2242
2243 if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull)
2244 {
2245 GRenderer->SetAlphaFunc(Renderer::CmpGreater, .5f);
2246 portals->room[room_num].pVertexBuffer->drawIndexed(Renderer::TriangleList, pTexCurr->tMatRoom[room_num].uslNbVertex, pTexCurr->tMatRoom[room_num].uslStartVertex,
2247 &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull],
2248 pTexCurr->tMatRoom[room_num].uslNbIndiceCull);
2249 GRenderer->SetAlphaFunc(Renderer::CmpNotEqual, 0.f);
2250
2251 EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull;
2252 pTexCurr->tMatRoom[room_num].uslNbIndiceCull=0;
2253 }
2254
2255 ppTexCurr++;
2256 }
2257
2258 //////////////////////////////
2259 //ZMapp
2260 GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate);
2261
2262 GRenderer->SetRenderState(Renderer::AlphaBlending, true);
2263 GRenderer->SetRenderState(Renderer::DepthWrite, false);
2264
2265 iNbTex=portals->room[room_num].usNbTextures;
2266 ppTexCurr=portals->room[room_num].ppTextureContainer;
2267
2268 while ( iNbTex-- ) //For each tex in portals->room[room_num]
2269 {
2270 TextureContainer * pTexCurr = *ppTexCurr;
2271
2272 if ( pTexCurr->TextureRefinement && pTexCurr->TextureRefinement->vPolyZMap.size() )
2273 {
2274 //---------------------------------------------------------------------------
2275 // INIT
2276
2277 GRenderer->SetTexture(0, pTexCurr->TextureRefinement);
2278
2279 dynamicVertices.lock();
2280 unsigned short * pussInd = dynamicVertices.indices;
2281 unsigned short iNbIndice = 0;
2282
2283 vector<EERIEPOLY *>::iterator it = pTexCurr->TextureRefinement->vPolyZMap.begin();
2284
2285
2286
2287 //---------------------------------------------------------------------------
2288 // LOOP
2289 for (; it != pTexCurr->TextureRefinement->vPolyZMap.end(); ++it)
2290 {
2291 EERIEPOLY * ep = *it;
2292
2293 unsigned short iNbVertex = (ep->type & POLY_QUAD) ? 4 : 3;
2294 SMY_VERTEX3 * pVertex = dynamicVertices.append(iNbVertex);
2295
2296 if(!pVertex) {
2297 dynamicVertices.unlock();
2298 if(dynamicVertices.nbindices) {
2299 dynamicVertices.draw(Renderer::TriangleList);
2300 }
2301 dynamicVertices.reset();
2302 dynamicVertices.lock();
2303 iNbIndice = 0;
2304 pussInd = dynamicVertices.indices;
2305 pVertex = dynamicVertices.append(iNbVertex);
2306 }
2307
2308 //-----------------------------------------------------------------------
2309 // PRECALCUL
2310 float tu[4];
2311 float tv[4];
2312 float _fTransp[4];
2313 unsigned short nu;
2314 long nrm=0;
2315
2316 if ( (EEfabs(ep->nrml[0].y)>=0.9f)
2317 || (EEfabs(ep->nrml[1].y)>=0.9f)
2318 || (EEfabs(ep->nrml[2].y)>=0.9f) )
2319 nrm=1;
2320
2321 for (nu=0;nu<iNbVertex;nu++)
2322 {
2323 if (nrm)
2324 {
2325 tu[nu]=(ep->v[nu].p.x*( 1.0f / 50 ));
2326 tv[nu]=(ep->v[nu].p.z*( 1.0f / 50 ));
2327 }
2328 else
2329 {
2330 tu[nu]=ep->v[nu].uv.x*4.f;
2331 tv[nu]=ep->v[nu].uv.y*4.f;
2332 }
2333
2334 float t = max(10.f, fdist(ACTIVECAM->pos, ep->v[nu].p) - 80.f);
2335
2336 _fTransp[nu] = (150.f - t) * 0.006666666f;
2337
2338 if (_fTransp[nu] < 0.f)
2339 _fTransp[nu] = 0.f;
2340 // t cannot be greater than 1.f (b should be negative for that)
2341 }
2342
2343 //-----------------------------------------------------------------------
2344 // FILL DATA
2345 for ( int idx = 0 ; idx < iNbVertex ; ++idx )
2346 {
2347 pVertex->p.x = ep->v[idx].p.x;
2348 pVertex->p.y = - ep->v[idx].p.y;
2349 pVertex->p.z = ep->v[idx].p.z;
2350 pVertex->color = Color::gray(_fTransp[idx]).toBGR();
2351 pVertex->uv[0].x = tu[idx];
2352 pVertex->uv[0].y = tv[idx];
2353 pVertex++;
2354
2355 *pussInd++ = iNbIndice++;
2356 dynamicVertices.nbindices++;
2357 }
2358
2359 if(iNbVertex&4) {
2360 *pussInd++=iNbIndice-2;
2361 *pussInd++=iNbIndice-3;
2362 dynamicVertices.nbindices += 2;
2363 }
2364
2365 }
2366
2367 //---------------------------------------------------------------------------
2368 // CLEAR CURRENT ZMAP
2369 pTexCurr->TextureRefinement->vPolyZMap.clear();
2370
2371 dynamicVertices.unlock();
2372 if(dynamicVertices.nbindices) {
2373 dynamicVertices.draw(Renderer::TriangleList);
2374 }
2375 dynamicVertices.done();
2376
2377 }
2378
2379 ppTexCurr++;
2380 } //END while ( iNbTex-- ) ----------------------------------------------------------
2381
2382 GRenderer->SetRenderState(Renderer::DepthWrite, true);
2383 GRenderer->SetRenderState(Renderer::AlphaBlending, false);
2384 }
2385 }
2386
2387 //-----------------------------------------------------------------------------
2388
ARX_PORTALS_Frustrum_RenderRoom_TransparencyTSoftCull(long room_num)2389 void ARX_PORTALS_Frustrum_RenderRoom_TransparencyTSoftCull(long room_num)
2390 {
2391 if (RoomDraw[room_num].count)
2392 {
2393 //render transparency
2394 int iNbTex=portals->room[room_num].usNbTextures;
2395 TextureContainer **ppTexCurr=portals->room[room_num].ppTextureContainer;
2396
2397 while(iNbTex--) {
2398
2399 TextureContainer * pTexCurr = *ppTexCurr;
2400 GRenderer->SetTexture(0, pTexCurr);
2401
2402 //NORMAL TRANS
2403 if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans)
2404 {
2405 SetZBias(2);
2406 GRenderer->SetBlendFunc(Renderer::BlendSrcColor, Renderer::BlendDstColor);
2407
2408 portals->room[room_num].pVertexBuffer->drawIndexed(Renderer::TriangleList, pTexCurr->tMatRoom[room_num].uslNbVertex, pTexCurr->tMatRoom[room_num].uslStartVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TNormalTrans], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans);
2409
2410 EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans;
2411 pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans=0;
2412 }
2413
2414 //MULTIPLICATIVE
2415 if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative)
2416 {
2417 SetZBias(2);
2418 GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
2419
2420 portals->room[room_num].pVertexBuffer->drawIndexed(Renderer::TriangleList, pTexCurr->tMatRoom[room_num].uslNbVertex, pTexCurr->tMatRoom[room_num].uslStartVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TMultiplicative], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative);
2421
2422 EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative;
2423 pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative=0;
2424 }
2425
2426 //ADDITIVE
2427 if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive)
2428 {
2429 SetZBias(2);
2430 GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
2431
2432 portals->room[room_num].pVertexBuffer->drawIndexed(Renderer::TriangleList, pTexCurr->tMatRoom[room_num].uslNbVertex, pTexCurr->tMatRoom[room_num].uslStartVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TAdditive], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive);
2433
2434 EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive;
2435 pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive=0;
2436 }
2437
2438 //SUBSTRACTIVE
2439 if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive)
2440 {
2441 SetZBias(8);
2442
2443 GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
2444
2445 portals->room[room_num].pVertexBuffer->drawIndexed(Renderer::TriangleList, pTexCurr->tMatRoom[room_num].uslNbVertex, pTexCurr->tMatRoom[room_num].uslStartVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TSubstractive], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive);
2446
2447 EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive;
2448 pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive=0;
2449 }
2450
2451 ppTexCurr++;
2452 }
2453 }
2454 }
2455
2456
ARX_PORTALS_ComputeRoom(long room_num,EERIE_2D_BBOX * bbox,long prec,long tim)2457 void ARX_PORTALS_ComputeRoom(long room_num,EERIE_2D_BBOX * bbox,long prec,long tim)
2458 {
2459 if (portals==NULL) return;
2460
2461 if (bbox->min.x>=DANAESIZX) return;
2462
2463 if (bbox->min.y>=DANAESIZY) return;
2464
2465 if (bbox->max.x<0) return;
2466
2467 if (bbox->max.y<0) return;
2468
2469 if (bbox->min.x>=bbox->max.x) return;
2470
2471 if (bbox->min.y>=bbox->max.y) return;
2472
2473 if (RoomDraw[room_num].count==0)
2474 RoomDrawListAdd(room_num);
2475
2476 ARX_PORTALS_BlendBBox(room_num,bbox);
2477 RoomDraw[room_num].count++;
2478
2479 // Now Checks For room Portals !!!
2480 for (long lll=0;lll<portals->room[room_num].nb_portals;lll++)
2481 {
2482 if (portals->portals[portals->room[room_num].portals[lll]].useportal) continue;
2483
2484 EERIE_PORTALS * po=&portals->portals[portals->room[room_num].portals[lll]];
2485 EERIEPOLY * epp=&po->poly;
2486
2487 float threshold = square(ACTIVECAM->cdepth - ACTIVECAM->cdepth * fZFogEnd);
2488 if((distSqr(ACTIVECAM->pos, epp->v[0].p) > threshold)
2489 && (distSqr(ACTIVECAM->pos, epp->v[2].p) > threshold)
2490 && (distSqr(ACTIVECAM->pos, epp->center) > threshold)) {
2491 portals->portals[portals->room[room_num].portals[lll]].useportal=2;
2492 continue;
2493 }
2494
2495 if (!EERIERTPPoly2(epp)) continue;
2496
2497
2498 int Cull=BackFaceCull2D(epp->tv);
2499
2500
2501 EERIE_2D_BBOX n_bbox;
2502 n_bbox.max.x=n_bbox.min.x=epp->tv[0].p.x;
2503 n_bbox.max.y=n_bbox.min.y=epp->tv[0].p.y;
2504 long to;
2505
2506 if (epp->type & POLY_QUAD)
2507 to=4;
2508 else
2509 to=3;
2510
2511 float minz=epp->tv[0].p.z;
2512 float maxz=epp->tv[0].p.z;
2513
2514 for (long nn=1;nn<to;nn++)
2515 {
2516 n_bbox.min.x=min(n_bbox.min.x , epp->tv[nn].p.x);
2517 n_bbox.min.y=min(n_bbox.min.y , epp->tv[nn].p.y);
2518 n_bbox.max.x=max(n_bbox.max.x , epp->tv[nn].p.x);
2519 n_bbox.max.y=max(n_bbox.max.y , epp->tv[nn].p.y);
2520 minz=min(minz,epp->tv[0].p.z);
2521 maxz=max(maxz,epp->tv[0].p.z);
2522 }
2523
2524 if (minz>0.5f) continue;
2525
2526 if ( bbox->min.x > n_bbox.max.x || n_bbox.min.x > bbox->max.x
2527 || bbox->min.y > n_bbox.max.y || n_bbox.min.y > bbox->max.y)
2528 continue;
2529
2530 if (Cull)
2531 EERIEPOLY_DrawWired(epp, Color::red);
2532 else
2533 EERIEPOLY_DrawWired(epp, Color::green);
2534
2535 n_bbox.min.x=max(n_bbox.min.x,bbox->min.x);
2536 n_bbox.min.y=max(n_bbox.min.y,bbox->min.y);
2537 n_bbox.max.x=min(n_bbox.max.x,bbox->max.x);
2538 n_bbox.max.y=min(n_bbox.max.y,bbox->max.y);
2539
2540 if (po->room_1==room_num)
2541 {
2542 if (!Cull)
2543 {
2544 portals->portals[portals->room[room_num].portals[lll]].useportal=1;
2545 ARX_PORTALS_ComputeRoom(po->room_2,&n_bbox,prec,tim);
2546 }
2547 }
2548 else if (po->room_2==room_num)
2549 {
2550 if (Cull)
2551 {
2552 portals->portals[portals->room[room_num].portals[lll]].useportal=1;
2553 ARX_PORTALS_ComputeRoom(po->room_1,&n_bbox,prec,tim);
2554 }
2555 }
2556 }
2557 }
2558
ARX_PORTALS_Frustrum_ComputeRoom(long room_num,EERIE_FRUSTRUM * frustrum,long prec,long tim)2559 long ARX_PORTALS_Frustrum_ComputeRoom(long room_num,EERIE_FRUSTRUM * frustrum,long prec,long tim)
2560 {
2561 long portals_count=0;
2562
2563 if (portals==NULL) return 0;
2564
2565 if (RoomDraw[room_num].count==0)
2566 {
2567 RoomDrawListAdd(room_num);
2568 }
2569
2570 RoomFrustrumAdd(room_num,frustrum);
2571 RoomDraw[room_num].count++;
2572
2573 float fClippZFar=ACTIVECAM->cdepth*(fZFogEnd*1.1f);
2574
2575 // Now Checks For room Portals !!!
2576 for (long lll=0;lll<portals->room[room_num].nb_portals;lll++)
2577 {
2578 if (portals->portals[portals->room[room_num].portals[lll]].useportal) continue;
2579
2580 EERIE_PORTALS * po=&portals->portals[portals->room[room_num].portals[lll]];
2581 EERIEPOLY * epp=&po->poly;
2582
2583 //clipp NEAR & FAR
2584 unsigned char ucVisibilityNear=0;
2585 unsigned char ucVisibilityFar=0;
2586 float fDist0=(efpPlaneNear.a*epp->v[0].p.x)+(efpPlaneNear.b*epp->v[0].p.y)+(efpPlaneNear.c*epp->v[0].p.z)+efpPlaneNear.d;
2587
2588 if(fDist0<0.f) ucVisibilityNear++;
2589 else
2590 {
2591 if(fDist0>fClippZFar) ucVisibilityFar++;
2592 }
2593
2594 fDist0=(efpPlaneNear.a*epp->v[1].p.x)+(efpPlaneNear.b*epp->v[1].p.y)+(efpPlaneNear.c*epp->v[1].p.z)+efpPlaneNear.d;
2595
2596 if(fDist0<0.f) ucVisibilityNear++;
2597 else
2598 {
2599 if(fDist0>fClippZFar) ucVisibilityFar++;
2600 }
2601
2602 fDist0=(efpPlaneNear.a*epp->v[2].p.x)+(efpPlaneNear.b*epp->v[2].p.y)+(efpPlaneNear.c*epp->v[2].p.z)+efpPlaneNear.d;
2603
2604 if(fDist0<0.f) ucVisibilityNear++;
2605 else
2606 {
2607 if(fDist0>fClippZFar) ucVisibilityFar++;
2608 }
2609
2610 fDist0=(efpPlaneNear.a*epp->v[3].p.x)+(efpPlaneNear.b*epp->v[3].p.y)+(efpPlaneNear.c*epp->v[3].p.z)+efpPlaneNear.d;
2611
2612 if(fDist0<0.f) ucVisibilityNear++;
2613 else
2614 {
2615 if(fDist0>fClippZFar) ucVisibilityFar++;
2616 }
2617
2618 if( (ucVisibilityFar&4)||(ucVisibilityNear&4) )
2619 {
2620 portals->portals[portals->room[room_num].portals[lll]].useportal=2;
2621 continue;
2622 }
2623
2624 Vec3f pos = epp->center - ACTIVECAM->pos;
2625 float fRes = dot(pos, epp->norm);
2626 long ret=1;
2627 if(IsSphereInFrustrum(epp->v[0].rhw, &epp->center, frustrum)) {
2628 ret=0;
2629 }
2630
2631 if (ret)
2632 {
2633 EERIERTPPoly2(epp);
2634
2635 if (NEED_TEST_TEXT)
2636 EERIEPOLY_DrawWired(epp, Color::magenta);
2637
2638 continue;
2639 }
2640
2641 portals_count++;
2642
2643 EERIERTPPoly2(epp);
2644
2645 int Cull;
2646
2647 if (fRes<0.f) Cull=0;
2648 else Cull=1;
2649
2650
2651 EERIE_FRUSTRUM fd;
2652 CreateFrustrum(&fd,epp,Cull);
2653
2654 if (NEED_TEST_TEXT)
2655 {
2656 if (Cull)
2657 EERIEPOLY_DrawWired(epp, Color::red);
2658 else
2659 EERIEPOLY_DrawWired(epp, Color::blue);
2660 }
2661
2662
2663 if (po->room_1==room_num)
2664 {
2665 if (!Cull)
2666 {
2667 portals->portals[portals->room[room_num].portals[lll]].useportal=1;
2668 ARX_PORTALS_Frustrum_ComputeRoom(po->room_2,&fd,prec,tim);
2669 }
2670 }
2671 else if (po->room_2==room_num)
2672 {
2673 if (Cull)
2674 {
2675 portals->portals[portals->room[room_num].portals[lll]].useportal=1;
2676 ARX_PORTALS_Frustrum_ComputeRoom(po->room_1,&fd,prec,tim);
2677 }
2678 }
2679 }
2680
2681 return portals_count;
2682 }
2683
Clip_Visible(const Vec3f * orgn,Vec3f * dest)2684 bool Clip_Visible(const Vec3f * orgn, Vec3f * dest) {
2685
2686 float dx, dy, dz, adx, ady, adz, ix, iz;
2687 float x0, z0;
2688 float forr, temp;
2689
2690 dx=(dest->x-orgn->x);
2691 adx=EEfabs(dx);
2692 dy=(dest->y-orgn->y);
2693 ady=EEfabs(dy);
2694 dz=(dest->z-orgn->z);
2695 adz=EEfabs(dz);
2696
2697 x0=orgn->x;
2698 z0=orgn->z;
2699
2700 if ( (adx>=ady) && (adx>=adz))
2701 {
2702 if (adx != dx)
2703 {
2704 ix = -1.f * PASS;
2705 }
2706 else
2707 {
2708 ix = 1.f * PASS;
2709 }
2710
2711 forr=adx;
2712 temp=1.f/(adx/PASS);
2713 iz=dz*temp;
2714 }
2715 else if ( (ady>=adx) && (ady>=adz))
2716 {
2717 forr=ady;
2718 temp=1.f/(ady/PASS);
2719 ix=dx*temp;
2720 iz=dz*temp;
2721 }
2722 else
2723 {
2724 if (adz != dz)
2725 {
2726 iz = -1.f * PASS;
2727 }
2728 else
2729 {
2730 iz = 1.f * PASS;
2731 }
2732
2733 forr=adz;
2734 temp=1.f/(adz/PASS);
2735 ix=dx*temp;
2736 }
2737
2738
2739 long curpixel;
2740 long tot;
2741 tot=0;
2742
2743 long x,y;
2744 FAST_BKG_DATA * LAST_eg=NULL;
2745 curpixel=2;
2746 x0+=ix*2;
2747 z0+=iz*2;
2748 forr-=PASS*2;
2749
2750 while (forr>PASSS)
2751 {
2752 FAST_BKG_DATA * feg;
2753 x = x0 * ACTIVEBKG->Xmul;
2754 y = z0 * ACTIVEBKG->Zmul;
2755 feg=&ACTIVEBKG->fastdata[x][y];
2756
2757 if (feg!=LAST_eg)
2758 {
2759
2760 LAST_eg=feg;
2761
2762 if (feg->nothing) tot += 2;
2763
2764 if (tot>MAX_OUT) return false;
2765 }
2766
2767 float v=(float)curpixel*( 1.0f / 5 );
2768
2769 if (v<1.f) v=1.f;
2770
2771 x0+=ix*v;
2772 z0+=iz*v;
2773 forr-=PASS*v;
2774 }
2775
2776 return true;//hard;
2777 }
2778
2779
2780
spGetTruePolyY(const EERIEPOLY * ep,const Vec3f * pos,float * ret)2781 bool spGetTruePolyY(const EERIEPOLY * ep, const Vec3f * pos, float * ret) {
2782
2783 Vec3f s21 = ep->v[1].p - ep->v[0].p;
2784 Vec3f s31 = ep->v[2].p - ep->v[0].p;
2785
2786 Vec3f n;
2787 n.y = (s21.z * s31.x) - (s21.x * s31.z);
2788 n.x = (s21.y * s31.z) - (s21.z * s31.y);
2789 n.z = (s21.x * s31.y) - (s21.y * s31.x);
2790
2791 float d = ep->v[0].p.x * n.x + ep->v[0].p.y * n.y + ep->v[0].p.z * n.z;
2792 *ret = (d - n.x * pos->x - n.z * pos->z) / n.y;
2793
2794 return true;
2795 }
2796
2797 extern long SPECIAL_DRAGINTER_RENDER;
2798 long MAX_FRAME_COUNT=0;
2799 //*************************************************************************************
2800 // Main Background Rendering Proc.
2801 // ie: Big Mess
2802 //*************************************************************************************
2803 ///////////////////////////////////////////////////////////
ARX_SCENE_Render(long flag)2804 void ARX_SCENE_Render(long flag) {
2805
2806 FRAME_COUNT++;
2807
2808 if (FRAME_COUNT>MAX_FRAME_COUNT) FRAME_COUNT=0;
2809
2810 if (EDITMODE) FRAME_COUNT=0;
2811
2812 if ((player.Interface & INTER_MAP ) && (!(player.Interface & INTER_COMBATMODE)))
2813 FRAME_COUNT=0;
2814
2815 static long x0=0;
2816 static long x1=0;
2817 static long z0=0;
2818 static long z1=0;
2819 long i;
2820 EERIEPOLY * ep;
2821 FAST_BKG_DATA * feg;
2822
2823 unsigned long tim = (unsigned long)(arxtime);
2824
2825 WATEREFFECT+=0.0005f*framedelay;
2826
2827 if (flag == 3)
2828 return;
2829
2830 float cval=(float)ACTIVECAM->clip3D+4;
2831 long lcval = cval;
2832
2833 //TODO(lubosz): no if / loop ?
2834
2835 {
2836
2837 PrepareActiveCamera();
2838 float xx=(float)(ACTIVECAM->pos.x*ACTIVEBKG->Xmul);
2839 float yy=(float)(ACTIVECAM->pos.z*ACTIVEBKG->Zmul);
2840
2841 ACTIVECAM->Xsnap = xx;
2842 ACTIVECAM->Zsnap = yy;
2843 ACTIVECAM->Xsnap = clamp(ACTIVECAM->Xsnap,0,ACTIVEBKG->Xsize-1);
2844 ACTIVECAM->Zsnap = clamp(ACTIVECAM->Zsnap,0,ACTIVEBKG->Zsize-1);
2845
2846 x0=ACTIVECAM->Xsnap-lcval;
2847 x1=ACTIVECAM->Xsnap+lcval;
2848 z0=ACTIVECAM->Zsnap-lcval;
2849 z1=ACTIVECAM->Zsnap+lcval;
2850 x0 = clamp(x0,0,ACTIVEBKG->Xsize-1);
2851 x1 = clamp(x1,0,ACTIVEBKG->Xsize-1);
2852 z0 = clamp(z0,0,ACTIVEBKG->Zsize-2);
2853 z1 = clamp(z1,0,ACTIVEBKG->Xsize-2);
2854
2855
2856 ACTIVEBKG->Backg[ACTIVECAM->Xsnap+ACTIVECAM->Zsnap * ACTIVEBKG->Xsize].treat = 1;
2857 float prec = 1.f / (ACTIVECAM->cdepth * ACTIVECAM->Zmul);
2858
2859
2860
2861 long lll;
2862
2863 // Temporary Hack...
2864 long LAST_FC=FRAME_COUNT;
2865 FRAME_COUNT=0;
2866
2867 if ((FRAME_COUNT<=0) && (ModeLight & MODE_DYNAMICLIGHT)) PrecalcDynamicLighting(x0,z0,x1,z1);
2868
2869 float temp0=radians(ACTIVECAM->angle.b);
2870 ACTIVECAM->norm.x=-(float)EEsin(temp0);
2871 ACTIVECAM->norm.y= (float)EEsin(radians(ACTIVECAM->angle.a));
2872 ACTIVECAM->norm.z= (float)EEcos(temp0);
2873
2874 fnormalize(ACTIVECAM->norm);
2875
2876 // Go for a growing-square-spirallike-render around the camera position
2877 // (To maximize Z-Buffer efficiency)
2878 temp0=0;
2879 Vec3f nrm;
2880
2881 long zsnap=ACTIVECAM->Zsnap;
2882 zsnap=min((int)zsnap,ACTIVEBKG->Zsize-1);
2883 zsnap=max((int)zsnap,1);
2884 long xsnap=ACTIVECAM->Xsnap;
2885 xsnap=min((int)xsnap,ACTIVEBKG->Xsize-1);
2886 xsnap=max((int)xsnap,1);
2887
2888
2889
2890 if (!USE_LIGHT_OPTIM)
2891 {
2892 for (long j=0;j<ACTIVEBKG->Zsize;j++)
2893 {
2894 feg=&ACTIVEBKG->fastdata[0][j];
2895
2896 for (i=0; i<ACTIVEBKG->Xsize; i++, feg++)
2897 {
2898 if (feg->treat)
2899 feg->treat=0;
2900 }
2901 }
2902 }
2903 else
2904 {
2905 for (long j=z0;j<=z1;j++)
2906 {
2907 for (i=x0; i<x1; i++)
2908 {
2909 feg=&ACTIVEBKG->fastdata[i][j];
2910 feg->treat=0;
2911 }
2912 }
2913
2914 for (long j=0;j<ACTIVEBKG->Zsize;j++)
2915 for (i=0; i<ACTIVEBKG->Xsize; i++)
2916 {
2917 if (tilelights[i][j].num)
2918 tilelights[i][j].num=0;
2919 }
2920 }
2921
2922
2923 if (USE_PORTALS && portals)
2924 {
2925 long room_num=ARX_PORTALS_GetRoomNumForPosition(&ACTIVECAM->pos,1);
2926 LAST_ROOM=room_num;
2927
2928 if (room_num>-1)
2929 {
2930 ARX_PORTALS_InitDrawnRooms();
2931
2932 long lprec = checked_range_cast<long>(prec);
2933
2934 switch (USE_PORTALS)
2935 {
2936 case 1: {
2937 EERIE_2D_BBOX bbox;
2938 bbox.min = Vec2f::ZERO;
2939 bbox.max = Vec2f(float(DANAESIZX), float(DANAESIZY));
2940 ARX_PORTALS_ComputeRoom(room_num, &bbox, lprec, tim);
2941 ARX_PORTALS_RenderRooms(lprec, tim);
2942 break;
2943 }
2944 case 2: {
2945 EERIE_FRUSTRUM frustrum;
2946 CreateScreenFrustrum(&frustrum);
2947 LAST_PORTALS_COUNT=ARX_PORTALS_Frustrum_ComputeRoom(room_num,&frustrum,lprec,tim);
2948 ARX_PORTALS_Frustrum_RenderRooms(lprec,tim);
2949 break;
2950 }
2951 case 3: {
2952 EERIE_FRUSTRUM frustrum;
2953 CreateScreenFrustrum(&frustrum);
2954 LAST_PORTALS_COUNT=ARX_PORTALS_Frustrum_ComputeRoom(room_num,&frustrum,lprec,tim);
2955 LogWarning << "unimplemented";
2956 break;
2957 }
2958 case 4: {
2959 EERIE_FRUSTRUM frustrum;
2960 CreateScreenFrustrum(&frustrum);
2961 LAST_PORTALS_COUNT=ARX_PORTALS_Frustrum_ComputeRoom(room_num,&frustrum,lprec,tim);
2962 ARX_PORTALS_Frustrum_RenderRoomsTCullSoft(lprec,tim);
2963 break;
2964 }
2965 }
2966
2967
2968 //ARX_SCENE_DilateBackground();
2969 }
2970 }
2971 else
2972 {
2973 for (long n=0;n<=lcval;n++)
2974 {
2975 temp0+=100.f;
2976
2977 for (long j=zsnap-n;j<=zsnap+n;j++)
2978 {
2979 for (i=xsnap-n;i<=xsnap+n;i++)
2980 {
2981 if ( (i!=xsnap-n) && (i!=xsnap+n) && (j!=zsnap-n) && (j!=zsnap+n) )
2982 {
2983 continue;
2984 }
2985
2986 if ( (i<0) || (j<0) || (i>=ACTIVEBKG->Xsize) || (j>=ACTIVEBKG->Zsize) ) continue;
2987
2988 if (i<x0) continue;
2989
2990 if (i>x1) continue;
2991
2992 feg = &ACTIVEBKG->fastdata[i][j];
2993
2994 if (!feg->treat) continue;
2995
2996 for ( lll=0;lll<feg->nbpoly;lll++)
2997 {
2998 //SPECIFIC INTEL COMPILER
2999 ep=&feg->polydata[lll];
3000
3001 if (ep->type & (POLY_IGNORE | POLY_NODRAW))
3002 continue;
3003
3004 if ((ep->min.y > feg->frustrum_maxy)
3005 || (ep->max.y < feg->frustrum_miny))
3006 continue;
3007
3008 // GO for 3D Backface Culling
3009 if (ep->type & POLY_DOUBLESIDED)
3010 GRenderer->SetCulling(Renderer::CullNone);
3011 else
3012 {
3013
3014 nrm = ep->v[2].p - ACTIVECAM->pos;
3015 if ( ep->type & POLY_QUAD)
3016 {
3017 if ( (dot( ep->norm , nrm )>0.f) &&
3018 (dot( ep->norm2 , nrm )>0.f) )
3019 continue;
3020 }
3021 else if ( dot( ep->norm , nrm )>0.f)
3022 continue;
3023
3024 GRenderer->SetCulling(Renderer::CullCW);
3025 }
3026
3027 if (!EERIERTPPoly(ep))
3028 continue;
3029
3030 long to;
3031 if ( ep->type & POLY_QUAD)
3032 {
3033 if (FRAME_COUNT<=0) ep->tv[3].color=ep->v[3].color;
3034
3035 to=4;
3036 }
3037 else to=3;
3038
3039 if (ep->type & POLY_TRANS)
3040 {
3041 ManageLavaWater(ep,to,tim);
3042 TransPol[TRANSPOLYSPOS++]=ep;
3043
3044 if (TRANSPOLYSPOS>=MAX_TRANSPOL) TRANSPOLYSPOS=MAX_TRANSPOL-1;
3045
3046 if (ViewMode)
3047 {
3048 if (ViewMode & VIEWMODE_WIRE)
3049 EERIEPOLY_DrawWired(ep);
3050
3051 if (ViewMode & VIEWMODE_NORMALS)
3052 EERIEPOLY_DrawNormals(ep);
3053 }
3054
3055 continue;
3056 }
3057
3058 if (!Project.improve) // Normal View...
3059 {
3060 if (ep->type & POLY_GLOW) ep->tv[0].color=ep->tv[1].color=ep->tv[2].color=ep->tv[3].color=0xFFFFFFFF;
3061 else
3062 {
3063 if (FRAME_COUNT<=0)
3064 {
3065 if (ModeLight & MODE_DYNAMICLIGHT) ApplyDynLight(ep);
3066 else
3067 {
3068 ep->tv[0].color=ep->v[0].color;
3069 ep->tv[1].color=ep->v[1].color;
3070 ep->tv[2].color=ep->v[2].color;
3071 }
3072
3073 }
3074 }
3075
3076 ManageLavaWater(ep,to,tim);
3077
3078 Delayed_EERIEDRAWPRIM(ep);
3079
3080 if (ViewMode)
3081 {
3082
3083 if (ViewMode & VIEWMODE_WIRE)
3084 EERIEPOLY_DrawWired(ep);
3085
3086 if (ViewMode & VIEWMODE_NORMALS)
3087 EERIEPOLY_DrawNormals(ep);
3088 }
3089 }
3090 else // Improve Vision Activated
3091 {
3092 if (FRAME_COUNT<=0)
3093 {
3094 if ( ModeLight & MODE_DYNAMICLIGHT ) ApplyDynLight(ep);
3095 else
3096 {
3097 ep->tv[0].color=ep->v[0].color;
3098 ep->tv[1].color=ep->v[1].color;
3099 ep->tv[2].color=ep->v[2].color;
3100 }
3101
3102
3103 for (long k=0;k<to;k++)
3104 {
3105 long lr=(ep->tv[k].color>>16) & 255;
3106 float ffr=(float)(lr);
3107
3108 float dd=(ep->tv[k].p.z*prec);
3109
3110 if (dd>1.f) dd=1.f;
3111
3112 if (dd<0.f) dd=0.f;
3113
3114 float fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f;
3115 float fr=((0.6f-dd)*6.f + (EEfabs(ep->nrml[k].z)+EEfabs(ep->nrml[k].y)))*0.125f;//(1.f-dd);
3116
3117 if (fr<0.f) fr=0.f;
3118 else fr=max(ffr,fr*255.f);
3119
3120 fb*=255.f;
3121 long lfb = fb;
3122 long lfr = fr;
3123 ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) );
3124 //GG component locked at 0x1E
3125 }
3126 }
3127
3128 Delayed_EERIEDRAWPRIM(ep);
3129 }
3130 }
3131 }
3132 }
3133 }
3134 }
3135
3136 if(GInput->isKeyPressedNowPressed(Keyboard::Key_J))
3137 bOLD_CLIPP=!bOLD_CLIPP;
3138
3139 if(!Project.improve) {
3140 ARXDRAW_DrawInterShadows();
3141 }
3142
3143 FRAME_COUNT=LAST_FC;
3144
3145 if(USE_PORTALS<3)
3146 Delayed_FlushAll();
3147
3148 ARX_THROWN_OBJECT_Manage(checked_range_cast<unsigned long>(FrameDiff));
3149
3150 RenderInter(0.f, 3200.f);
3151
3152
3153 if (DRAGINTER) // To render Dragged objs
3154 {
3155 SPECIAL_DRAGINTER_RENDER=1;
3156 ARX_INTERFACE_RenderCursor();
3157
3158 if(USE_PORTALS<3)
3159 Delayed_FlushAll();
3160
3161 SPECIAL_DRAGINTER_RENDER=0;
3162 }
3163
3164 PopAllTriangleList();
3165
3166 }
3167
3168 if (ACTIVECAM->type!=CAM_TOPVIEW)
3169 {
3170
3171 if ((eyeball.exist!=0) && eyeballobj)
3172 ARXDRAW_DrawEyeBall();
3173
3174
3175 GRenderer->SetRenderState(Renderer::DepthWrite, false);
3176
3177 if (BoomCount)
3178 ARXDRAW_DrawPolyBoom();
3179
3180 PopAllTriangleListTransparency();
3181
3182 if( (USE_PORTALS>2)&&
3183 (portals) )
3184 {
3185 ARX_PORTALS_Frustrum_RenderRooms_TransparencyT();
3186 }
3187 else
3188 {
3189 if (TRANSPOLYSPOS)
3190 ARXDRAW_DrawAllTransPolysPos();
3191 }
3192 }
3193
3194 if (HALOCUR>0)
3195 {
3196 GRenderer->ResetTexture(0);
3197 GRenderer->SetBlendFunc(Renderer::BlendSrcColor, Renderer::BlendOne);
3198 GRenderer->SetRenderState(Renderer::AlphaBlending, true);
3199 GRenderer->SetCulling(Renderer::CullNone);
3200 GRenderer->SetRenderState(Renderer::DepthWrite, false);
3201
3202 for (i=0;i<HALOCUR;i++)
3203 {
3204 //blue halo rendering (keyword : BLUE HALO RENDERING HIGHLIGHT AURA)
3205 TexturedVertex * vert=&LATERDRAWHALO[(i<<2)];
3206
3207 if (vert[2].color == 0)
3208 {
3209 GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
3210 vert[2].color =0xFF000000;
3211 EERIEDRAWPRIM(Renderer::TriangleFan, vert, 4);
3212 GRenderer->SetBlendFunc(Renderer::BlendSrcColor, Renderer::BlendOne);
3213 }
3214 else EERIEDRAWPRIM(Renderer::TriangleFan, vert, 4);
3215 }
3216
3217 HALOCUR = 0;
3218 GRenderer->SetRenderState(Renderer::AlphaBlending, false);
3219 }
3220
3221 GRenderer->SetCulling(Renderer::CullCCW);
3222 GRenderer->SetRenderState(Renderer::AlphaBlending, false);
3223 GRenderer->SetRenderState(Renderer::DepthWrite, true);
3224
3225 #ifdef BUILD_EDITOR
3226 if (EDITION==EDITION_LIGHTS)
3227 ARXDRAW_DrawAllLights(x0,z0,x1,z1);
3228 #endif
3229
3230 }
3231
3232