00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <Assert.h>
00023 #include <Windows.h>
00024
00025 #include "User.h"
00026 #include "World.h"
00027 #include "Ram.h"
00028 #include "ErrorLog.h"
00029 #include "System.h"
00030 #include "Surface.h"
00031 #include "Genesis.h"
00032 #include "Camera.h"
00033 #include "Frustum.h"
00034 #include "Plane.h"
00035
00036 #include "DCommon.h"
00037
00038 #include "Bitmap._h"
00039
00040 extern int32 MirrorRecursion;
00041
00042
00043
00044
00045 static geEngine *gEngine;
00046 static geWorld *gWorld;
00047 static geCamera *gCamera;
00048 static GFX_Leaf *gGFXLeafs;
00049 static GFX_Model *gGFXModels;
00050 static World_BSP *gBSP;
00051 static Frustum_Info gWorldSpaceFrustum;
00052
00053 static gePoly *SortedPolys[USER_MAX_SORTED_POLYS];
00054
00055
00056
00057
00058 static geBoolean RenderTexturedPoint(DRV_Driver *RDriver, gePoly *Poly, Frustum_Info *FInfo, geCamera *Camera);
00059 static void RenderTexturedPoly(DRV_Driver *RDriver, gePoly *Poly, Frustum_Info *FInfo, geCamera *Camera);
00060 static void RenderGouraudPoly(DRV_Driver *RDriver, gePoly *Poly, Frustum_Info *FInfo, geCamera *Camera);
00061
00062 static geBoolean RenderUserPoly(geCamera *Camera, gePoly *Poly);
00063
00064 static void geWorld_LinkPolyToLeaf(const geWorld *World, gePoly *Poly);
00065 static void geWorld_UnLinkPolyFromLeaf(gePoly *Poly);
00066
00067 #ifdef _DEBUG
00068 geBoolean geWorld_PolyIsValid(gePoly *Poly)
00069 {
00070 if (!Poly)
00071 return GE_FALSE;
00072
00073 if (Poly->Self1 != Poly)
00074 return GE_FALSE;
00075
00076 if (Poly->Self2 != Poly)
00077 return GE_FALSE;
00078
00079 return GE_TRUE;
00080 }
00081 #endif
00082
00083
00084
00085
00086 geBoolean User_EngineInit(geEngine *Engine)
00087 {
00088 User_Info *Info;
00089
00090 assert(Engine->UserInfo == NULL);
00091
00092 Info = GE_RAM_ALLOCATE_STRUCT(User_Info);
00093
00094 if (!Info)
00095 {
00096 geErrorLog_Add(GE_ERR_OUT_OF_MEMORY, NULL);
00097 return GE_FALSE;;
00098 }
00099
00100 memset(Info, 0, sizeof(User_Info));
00101
00102 Engine->UserInfo = Info;
00103
00104 return GE_TRUE;
00105 }
00106
00107
00108
00109
00110 void User_EngineShutdown(geEngine *Engine)
00111 {
00112 User_Info *Info;
00113
00114 assert(Engine != NULL);
00115
00116 Info = Engine->UserInfo;
00117
00118 if (!Info)
00119 return;
00120
00121 geRam_Free(Info);
00122
00123 Engine->UserInfo = NULL;
00124 }
00125
00126
00127
00128
00129 geBoolean User_WorldInit(geWorld *World)
00130 {
00131 User_Info *Info;
00132
00133 assert(World != NULL);
00134
00135 Info = GE_RAM_ALLOCATE_STRUCT(User_Info);
00136
00137 assert(Info != NULL);
00138
00139 if (!Info)
00140 {
00141 geErrorLog_Add(GE_ERR_OUT_OF_MEMORY, NULL);
00142 return GE_FALSE;
00143 }
00144
00145 memset(Info, 0, sizeof(User_Info));
00146
00147 World->UserInfo = Info;
00148
00149 return GE_TRUE;
00150 }
00151
00152
00153
00154
00155 void User_WorldShutdown(geWorld *World)
00156 {
00157 User_Info *Info;
00158
00159 assert(World != NULL);
00160
00161 Info = World->UserInfo;
00162
00163 if (!Info)
00164 return;
00165
00166 geRam_Free(Info);
00167
00168 World->UserInfo = NULL;
00169 }
00170
00171
00172
00173
00174 static int PolyComp(const void *a, const void *b)
00175 {
00176 geFloat z1, z2;
00177
00178 z1 = (*(gePoly**)a)->ZOrder;
00179 z2 = (*(gePoly**)b)->ZOrder;
00180
00181 if ( z1 == z2)
00182 return 0;
00183
00184 if (z1 < z2)
00185 return -1;
00186
00187 return 1;
00188 }
00189
00190
00191
00192
00193 geBoolean User_RenderPolyList(gePoly *PolyList)
00194 {
00195 int32 i, NumSortedPolys;
00196 gePoly *Poly;
00197
00198 assert(PolyList);
00199
00200 NumSortedPolys = 0;
00201
00202 for (Poly = PolyList; Poly; Poly = Poly->Next)
00203 {
00204 assert(geWorld_PolyIsValid(Poly));
00205
00206 if ((Poly->RenderFlags & GE_RENDER_DEPTH_SORT_BF) && NumSortedPolys < USER_MAX_SORTED_POLYS)
00207 {
00208
00209 geVec3d Src;
00210 geVec3d Dest;
00211
00212 Src.X = Poly->Verts->X;
00213 Src.Y = Poly->Verts->Y;
00214 Src.Z = Poly->Verts->Z;
00215
00216 geCamera_Transform(gCamera, &Src, &Dest);
00217 Poly->ZOrder = Dest.Z;
00218
00219 SortedPolys[NumSortedPolys++] = Poly;
00220 continue;
00221 }
00222
00223
00224 RenderUserPoly(gCamera, Poly);
00225 }
00226
00227 if (!NumSortedPolys)
00228 return GE_TRUE;
00229
00230
00231
00232 qsort(&SortedPolys, NumSortedPolys, sizeof(SortedPolys[0]), PolyComp);
00233
00234
00235 for (i=0; i< NumSortedPolys; i++)
00236 {
00237 Poly = SortedPolys[i];
00238
00239 RenderUserPoly(gCamera, Poly);
00240 }
00241
00242 return GE_TRUE;
00243 }
00244
00245
00246
00247
00248 void User_DestroyPolyOnceList(geWorld *World, gePoly *List)
00249 {
00250 gePoly *Poly, *Next;
00251
00252
00253 for (Poly = List; Poly; Poly = Next)
00254 {
00255 Next = Poly->AddOnceNext;
00256
00257 assert(geWorld_PolyIsValid(Poly));
00258
00259 geWorld_RemovePoly(World, Poly);
00260 }
00261 }
00262
00263
00264
00265
00266 void User_DestroyPolyList(geWorld *World, gePoly *List)
00267 {
00268 gePoly *Poly, *Next;
00269
00270
00271 for (Poly = List; Poly; Poly = Next)
00272 {
00273 Next = Poly->Next;
00274
00275 assert(geWorld_PolyIsValid(Poly));
00276
00277 geWorld_RemovePoly(World, Poly);
00278 }
00279 }
00280
00281
00282
00283
00284 geBoolean User_SetCameraInfo(geEngine *Engine, geWorld *World, geCamera *Camera, Frustum_Info *Fi)
00285 {
00286 assert(Engine != NULL);
00287 assert(World != NULL);
00288 assert(World->UserInfo != NULL);
00289 assert(Camera != NULL);
00290 assert(Fi != NULL);
00291
00292 gWorld = World;
00293 gEngine = Engine;
00294 gCamera = Camera;
00295 gBSP = World->CurrentBSP;
00296 gGFXLeafs = World->CurrentBSP->BSPData.GFXLeafs;
00297 gGFXModels = World->CurrentBSP->BSPData.GFXModels;
00298
00299
00300 Frustum_TransformToWorldSpace(Fi, Camera, &gWorldSpaceFrustum);
00301
00302 return GE_TRUE;
00303 }
00304
00305
00306
00307
00308 geBoolean User_DestroyOncePolys(geWorld *World)
00309 {
00310 if (World->UserInfo->AddPolyOnceList)
00311 {
00312 User_DestroyPolyOnceList(World, World->UserInfo->AddPolyOnceList);
00313 World->UserInfo->AddPolyOnceList = NULL;
00314 }
00315
00316 return GE_TRUE;
00317 }
00318
00319
00320
00321
00322 static geBoolean RenderTexturedPoint(DRV_Driver *RDriver, gePoly *Poly, Frustum_Info *FInfo, geCamera *Camera)
00323 {
00324 assert(geWorld_PolyIsValid(Poly));
00325
00326 if (MirrorRecursion > 0)
00327 {
00328 GE_LVertex *pVerts, Save;
00329 geVec3d Up, Left, Start;
00330 geFloat Scale, XScale, YScale;
00331 const geXForm3d *MXForm;
00332
00333 pVerts = Poly->Verts;
00334
00335 Poly->NumVerts = 4;
00336
00337 Start.X = pVerts[0].X;
00338 Start.Y = pVerts[0].Y;
00339 Start.Z = pVerts[0].Z;
00340
00341 Save = pVerts[1] = pVerts[2] = pVerts[3] = pVerts[0];
00342
00343 MXForm = geCamera_GetWorldSpaceXForm(Camera);
00344
00345 geXForm3d_GetLeft(MXForm, &Left);
00346 geXForm3d_GetUp(MXForm, &Up);
00347
00348 Scale = Poly->Scale * 0.5f;
00349
00350 XScale = (geFloat)geBitmap_Width(Poly->Bitmap) * Scale;
00351 YScale = (geFloat)geBitmap_Height(Poly->Bitmap) * Scale;
00352
00353 geVec3d_Scale(&Left, XScale, &Left);
00354 geVec3d_Scale(&Up, YScale, &Up);
00355
00356 pVerts->X = Start.X - Left.X + Up.X;
00357 pVerts->Y = Start.Y - Left.Y + Up.Y;
00358 pVerts->Z = Start.Z - Left.Z + Up.Z;
00359 pVerts->u = 0.0f;
00360 pVerts->v = 0.0f;
00361
00362 pVerts++;
00363
00364 pVerts->X = Start.X + Left.X + Up.X;
00365 pVerts->Y = Start.Y + Left.Y + Up.Y;
00366 pVerts->Z = Start.Z + Left.Z + Up.Z;
00367 pVerts->u = 1.0f;
00368 pVerts->v = 0.0f;
00369
00370 pVerts++;
00371
00372 pVerts->X = Start.X + Left.X - Up.X;
00373 pVerts->Y = Start.Y + Left.Y - Up.Y;
00374 pVerts->Z = Start.Z + Left.Z - Up.Z;
00375 pVerts->u = 1.0f;
00376 pVerts->v = 1.0f;
00377
00378 pVerts++;
00379
00380 pVerts->X = Start.X - Left.X - Up.X;
00381 pVerts->Y = Start.Y - Left.Y - Up.Y;
00382 pVerts->Z = Start.Z - Left.Z - Up.Z;
00383 pVerts->u = 1.0f;
00384 pVerts->v = 0.0f;
00385
00386 RenderTexturedPoly(RDriver, Poly, FInfo, Camera);
00387
00388 Poly->NumVerts = 1;
00389 Poly->Verts[0] = Save;
00390 }
00391 else
00392 {
00393
00394 geVec3d Src, Dest;
00395 GE_LVertex *pVerts;
00396 DRV_TLVertex ScreenPnts[4];
00397 geBitmap *Bitmap;
00398 geFloat Sx, Sy, z, UVAdd, Width, Height;
00399 geFloat Left, Right, Top, Bottom;
00400 geFloat Scale;
00401 uint32 RenderFlags;
00402 int32 i;
00403
00404 assert(Poly != NULL);
00405 assert(Camera != NULL);
00406
00407 pVerts = &Poly->Verts[0];
00408
00409
00410 Src.X = pVerts->X;
00411 Src.Y = pVerts->Y;
00412 Src.Z = pVerts->Z;
00413
00414 geCamera_Transform(Camera,&Src,&Dest);
00415
00416 geCamera_Project(Camera, &Dest, &Src);
00417
00418 for (i=0; i<4; i++)
00419 {
00420 ScreenPnts[i].x = Src.X;
00421 ScreenPnts[i].y = Src.Y;
00422 ScreenPnts[i].z = Src.Z;
00423 ScreenPnts[i].r = pVerts->r;
00424 ScreenPnts[i].g = pVerts->g;
00425 ScreenPnts[i].b = pVerts->b;
00426 ScreenPnts[i].a = pVerts->a;
00427 }
00428
00429 z = -Dest.Z;
00430
00431 if (z < 1)
00432 return GE_TRUE;
00433
00434 {
00435 geRect Rect;
00436 geCamera_GetClippingRect(Camera,&Rect);
00437
00438 Left = (geFloat)Rect.Left;
00439 Right = (geFloat)Rect.Right+1.0f;
00440 Top = (geFloat)Rect.Top;
00441 Bottom = (geFloat)Rect.Bottom+1.0f;
00442 }
00443
00444 Scale = ((geCamera_GetScale(Camera) / z) * Poly->Scale);
00445
00446 Bitmap = Poly->Bitmap;
00447 Width = (geFloat)geBitmap_Width(Bitmap) * Scale;
00448 Height = (geFloat)geBitmap_Height(Bitmap) * Scale;
00449
00450 Sx = Width * 0.5f;
00451 Sy = Height * 0.5f;
00452
00453
00454 ScreenPnts[0].x -= Sx;
00455 ScreenPnts[0].y -= Sy;
00456
00457 ScreenPnts[1].x += Sx;
00458 ScreenPnts[1].y -= Sy;
00459
00460 ScreenPnts[2].x += Sx;
00461 ScreenPnts[2].y += Sy;
00462
00463 ScreenPnts[3].x -= Sx;
00464 ScreenPnts[3].y += Sy;
00465
00466 ScreenPnts[0].u = 0.0f + pVerts->u;
00467 ScreenPnts[0].v = 0.0f + pVerts->v;
00468 ScreenPnts[1].u = 1.0f + pVerts->u;
00469 ScreenPnts[1].v = 0.0f + pVerts->v;
00470 ScreenPnts[2].u = 1.0f + pVerts->u;
00471 ScreenPnts[2].v = 1.0f + pVerts->v;
00472 ScreenPnts[3].u = 0.0f + pVerts->u;
00473 ScreenPnts[3].v = 1.0f + pVerts->v;
00474
00475
00476 if (ScreenPnts[0].x < Left)
00477 {
00478 if (ScreenPnts[1].x <= Left)
00479 return GE_TRUE;
00480
00481 UVAdd = (Left-ScreenPnts[0].x) / Width;
00482 Width -= Left-ScreenPnts[0].x;
00483
00484 ScreenPnts[0].u += UVAdd;
00485 ScreenPnts[3].u += UVAdd;
00486
00487 ScreenPnts[0].x = Left;
00488 ScreenPnts[3].x = Left;
00489 }
00490 if (ScreenPnts[0].y < Top)
00491 {
00492 if (ScreenPnts[2].y <= Top)
00493 return GE_TRUE;
00494
00495 UVAdd = (Top-ScreenPnts[0].y) / Height;
00496 Height -= (Top-ScreenPnts[0].y);
00497
00498 ScreenPnts[0].v += UVAdd;
00499 ScreenPnts[1].v += UVAdd;
00500
00501 ScreenPnts[0].y = Top;
00502 ScreenPnts[1].y = Top;
00503 }
00504 if (ScreenPnts[1].x >= Right)
00505 {
00506 if (ScreenPnts[0].x >= Right)
00507 return GE_TRUE;
00508
00509 UVAdd = (ScreenPnts[1].x-Right) / Width;
00510 Width -= (ScreenPnts[1].x-Right);
00511
00512 ScreenPnts[1].u -= UVAdd;
00513 ScreenPnts[2].u -= UVAdd;
00514
00515 ScreenPnts[1].x = Right-1;
00516 ScreenPnts[2].x = Right-1;
00517 }
00518 if (ScreenPnts[2].y >= Bottom)
00519 {
00520 if (ScreenPnts[0].y >= Bottom)
00521 return GE_TRUE;
00522
00523 UVAdd = (ScreenPnts[2].y-Bottom) / Height;
00524 Height -= (ScreenPnts[2].x-Bottom);
00525
00526 ScreenPnts[2].v -= UVAdd;
00527 ScreenPnts[3].v -= UVAdd;
00528
00529 ScreenPnts[2].y = Bottom-1;
00530 ScreenPnts[3].y = Bottom-1;
00531 }
00532
00533
00534 ScreenPnts[0].a = pVerts->a;
00535
00536 ScreenPnts[0].r = pVerts->r;
00537 ScreenPnts[0].g = pVerts->g;
00538 ScreenPnts[0].b = pVerts->b;
00539
00540 if (Poly->RenderFlags & GE_RENDER_DO_NOT_OCCLUDE_OTHERS)
00541 RenderFlags = DRV_RENDER_NO_ZWRITE;
00542 else
00543 RenderFlags = 0;
00544
00545 if (Poly->RenderFlags & GE_RENDER_DO_NOT_OCCLUDE_SELF)
00546 RenderFlags |= DRV_RENDER_NO_ZMASK;
00547
00548 if (pVerts->a != 255.0f)
00549 RenderFlags |= DRV_RENDER_ALPHA;
00550
00551 if (Poly->RenderFlags & GE_RENDER_DEPTH_SORT_BF)
00552 RenderFlags |= DRV_RENDER_FLUSH;
00553
00554 if (Poly->RenderFlags & GE_RENDER_CLAMP_UV)
00555 RenderFlags |= DRV_RENDER_CLAMP_UV;
00556
00557 if (Poly->RenderFlags & GE_RENDER_NO_FOG)
00558 RenderFlags |= DRV_RENDER_POLY_NO_FOG;
00559
00560 assert(geWorld_HasBitmap(gWorld, Bitmap));
00561 assert(geBitmap_GetTHandle(Bitmap));
00562
00563 RDriver->RenderMiscTexturePoly((DRV_TLVertex*)ScreenPnts, 4, geBitmap_GetTHandle(Bitmap), RenderFlags);
00564 }
00565
00566 return GE_TRUE;
00567 }
00568
00569
00570
00571
00572 static void RenderTexturedPoly(DRV_Driver *RDriver, gePoly *Poly, Frustum_Info *FInfo, geCamera *Camera)
00573 {
00574 geVec3d Dest1[30], Dest2[30], *pDest1, *pDest2, *pDest3, *pTempDest;
00575 GE_LVertex *pLVert;
00576 Surf_TexVert Tex1[30], Tex2[30];
00577 Surf_TexVert *pTex1, *pTex2, *pTempTex;
00578 DRV_TLVertex Clipped1[90];
00579 int32 Length1, Length2;
00580 geBitmap *pBitmap;
00581 GFX_Plane *pFPlanes;
00582 int32 i, p;
00583 uint32 RenderFlags;
00584
00585 int32 plan;
00586
00587 assert(geWorld_PolyIsValid(Poly));
00588
00589 pFPlanes = FInfo->Planes;
00590
00591 pDest1 = Dest1;
00592 pTex1 = Tex1;
00593 pLVert = Poly->Verts;
00594
00595 for (i=0; i< Poly->NumVerts; i++)
00596 {
00597 pDest1->X = pLVert->X;
00598 pDest1->Y = pLVert->Y;
00599 pDest1->Z = pLVert->Z;
00600
00601 pTex1->u = pLVert->u;
00602 pTex1->v = pLVert->v;
00603 pTex1->r = pLVert->r;
00604 pTex1->g = pLVert->g;
00605 pTex1->b = pLVert->b;
00606
00607 pDest1++;
00608 pLVert++;
00609 pTex1++;
00610 }
00611
00612 pDest1 = Dest1;
00613 pDest2 = Dest2;
00614 pTex1 = Tex1;
00615 pTex2 = Tex2;
00616 Length1 = Poly->NumVerts;
00617
00618
00619 plan = FInfo->NumPlanes;
00620 if (((Poly->RenderFlags & GE_RENDER_NO_CLIP)==GE_RENDER_NO_CLIP) && plan==5)
00621 plan -= 1;
00622
00623 for (p=0; p< plan; p++, pFPlanes++)
00624 {
00625 if (!Frustum_ClipToPlaneUVRGB(pFPlanes, pDest1, pDest2, pTex1, pTex2, Length1, &Length2))
00626 return;
00627
00628
00629 pTempDest = pDest1;
00630 pDest1 = pDest2;
00631 pDest2 = pTempDest;
00632
00633 pTempTex = pTex1;
00634 pTex1 = pTex2;
00635 pTex2 = pTempTex;
00636
00637 Length1 = Length2;
00638 }
00639
00640 if (Length1 < 3)
00641 return;
00642
00643 pDest3 = pDest2;
00644 for (i=0; i< Length1; i++)
00645 {
00646
00647 geCamera_Transform(Camera,pDest1,pDest2);
00648 pDest1++;
00649 pDest2++;
00650 }
00651
00652 Frustum_ProjectRGB(pDest3, pTex1, Clipped1, Length1, Camera);
00653
00654 pBitmap = Poly->Bitmap;
00655
00656 Clipped1[0].a = Poly->Verts[0].a;
00657
00658 if (Poly->RenderFlags & GE_RENDER_DO_NOT_OCCLUDE_OTHERS)
00659 RenderFlags = DRV_RENDER_NO_ZWRITE;
00660 else
00661 RenderFlags = 0;
00662
00663 if (Poly->RenderFlags & GE_RENDER_DO_NOT_OCCLUDE_SELF)
00664 RenderFlags |= DRV_RENDER_NO_ZMASK;
00665
00666 if (Clipped1[0].a != 255.0f)
00667 RenderFlags |= DRV_RENDER_ALPHA;
00668
00669 if (Poly->RenderFlags & GE_RENDER_DEPTH_SORT_BF)
00670 RenderFlags |= DRV_RENDER_FLUSH;
00671
00672 if (Poly->RenderFlags & GE_RENDER_CLAMP_UV)
00673 RenderFlags |= DRV_RENDER_CLAMP_UV;
00674
00675 if (Poly->RenderFlags & GE_RENDER_NO_FOG)
00676 RenderFlags |= DRV_RENDER_POLY_NO_FOG;
00677
00678
00679 assert(geWorld_HasBitmap(gWorld, pBitmap));
00680 assert(geBitmap_GetTHandle(pBitmap));
00681
00682 RDriver->RenderMiscTexturePoly(Clipped1, Length1, geBitmap_GetTHandle(pBitmap), RenderFlags);
00683
00684 }
00685
00686
00687
00688
00689 static void RenderGouraudPoly(DRV_Driver *RDriver, gePoly *Poly, Frustum_Info *FInfo, geCamera *Camera)
00690 {
00691 geVec3d Verts[30], *pVert;
00692 GE_LVertex *pLVert;
00693 geVec3d Dest1[30], Dest2[30], *pDest1, *pDest2, *pDest3;
00694 Surf_TexVert Tex1[30], Tex2[30];
00695 Surf_TexVert *pTex1, *pTex2;
00696 DRV_TLVertex Clipped1[90];
00697 int32 Length1, Length2;
00698 GFX_Plane *pFPlanes;
00699 int32 i, p;
00700
00701 assert(geWorld_PolyIsValid(Poly));
00702
00703 pFPlanes = FInfo->Planes;
00704
00705 pVert = Verts;
00706 pLVert = Poly->Verts;
00707 pTex1 = Tex1;
00708
00709 for (i=0; i< Poly->NumVerts; i++)
00710 {
00711 pVert->X = pLVert->X;
00712 pVert->Y = pLVert->Y;
00713 pVert->Z = pLVert->Z;
00714
00715 pTex1->r = pLVert->r;
00716 pTex1->g = pLVert->g;
00717 pTex1->b = pLVert->b;
00718
00719 pVert++;
00720 pLVert++;
00721 pTex1++;
00722 }
00723
00724 pDest1 = Verts;
00725 pDest2 = Dest2;
00726 pTex1 = Tex1;
00727 pTex2 = Tex2;
00728 Length1 = Poly->NumVerts;
00729
00730 for (p=0; p< 4; p++)
00731 {
00732 if (!Frustum_ClipToPlaneRGB(&pFPlanes[p], pDest1, pDest2, pTex1, pTex2, Length1, &Length2))
00733 return;
00734
00735 if (pDest1 == Dest2)
00736 {
00737 pDest1 = Dest1;
00738 pDest2 = Dest2;
00739 pTex1 = Tex1;
00740 pTex2 = Tex2;
00741 }
00742 else
00743 {
00744 pDest1 = Dest2;
00745 pDest2 = Dest1;
00746 pTex1 = Tex2;
00747 pTex2 = Tex1;
00748 }
00749 Length1 = Length2;
00750 }
00751
00752 if (Length1 < 3)
00753 return;
00754
00755 pDest3 = pDest2;
00756 for (i=0; i< Length1; i++)
00757 {
00758
00759 geCamera_Transform(Camera,pDest1,pDest2);
00760 pDest1++;
00761 pDest2++;
00762 }
00763
00764 Frustum_ProjectRGB(pDest3, pTex1, Clipped1, Length1, Camera);
00765
00766 Clipped1[0].a = Poly->Verts[0].a;
00767
00768
00769 if (Clipped1[0].a != 255.0f)
00770 RDriver->RenderGouraudPoly(Clipped1, Length1, DRV_RENDER_ALPHA);
00771 else
00772 RDriver->RenderGouraudPoly(Clipped1, Length1, 0);
00773
00774 }
00775
00776
00777
00778
00779 void User_EngineFillRect(geEngine *Engine, const GE_Rect *Rect, const GE_RGBA *Color)
00780 {
00781 DRV_TLVertex DrvVertex[4];
00782 DRV_Driver * RDriver;
00783
00784 RDriver = Engine->DriverInfo.RDriver;
00785
00786 assert(RDriver != NULL);
00787
00788 #define NEARZ 1.0f
00789 DrvVertex[0].x = (geFloat)Rect->Left;
00790 DrvVertex[0].y = (geFloat)Rect->Top;
00791 DrvVertex[0].z = NEARZ;
00792 DrvVertex[0].u =
00793 DrvVertex[0].v = 0.0f;
00794 DrvVertex[0].r = Color->r;
00795 DrvVertex[0].g = Color->g;
00796 DrvVertex[0].b = Color->b;
00797 DrvVertex[0].a = Color->a;
00798
00799 DrvVertex[1].x = (geFloat)Rect->Right;
00800 DrvVertex[1].y = (geFloat)Rect->Top;
00801 DrvVertex[1].z = NEARZ;
00802 DrvVertex[1].u =
00803 DrvVertex[1].v = 0.0f;
00804 DrvVertex[1].r = Color->r;
00805 DrvVertex[1].g = Color->g;
00806 DrvVertex[1].b = Color->b;
00807 DrvVertex[1].a = Color->a;
00808
00809 DrvVertex[2].x = (geFloat)Rect->Right;
00810 DrvVertex[2].y = (geFloat)Rect->Bottom;
00811 DrvVertex[2].z = NEARZ;
00812 DrvVertex[2].u =
00813 DrvVertex[2].v = 0.0f;
00814 DrvVertex[2].r = Color->r;
00815 DrvVertex[2].g = Color->g;
00816 DrvVertex[2].b = Color->b;
00817 DrvVertex[2].a = Color->a;
00818
00819 DrvVertex[3].x = (geFloat)Rect->Left;
00820 DrvVertex[3].y = (geFloat)Rect->Bottom;
00821 DrvVertex[3].z = NEARZ;
00822 DrvVertex[3].u =
00823 DrvVertex[3].v = 0.0f;
00824 DrvVertex[3].r = Color->r;
00825 DrvVertex[3].g = Color->g;
00826 DrvVertex[3].b = Color->b;
00827 DrvVertex[3].a = Color->a;
00828
00829 if (Color->a != 255.0f)
00830 RDriver->RenderGouraudPoly(DrvVertex, 4, DRV_RENDER_FLUSH);
00831 else
00832 RDriver->RenderGouraudPoly(DrvVertex, 4, DRV_RENDER_ALPHA | DRV_RENDER_FLUSH);
00833 }
00834
00835
00836
00837
00838 static geBoolean RenderUserPoly(geCamera *Camera, gePoly *Poly)
00839 {
00840 DRV_Driver *RDriver;
00841
00842 assert(Camera);
00843 assert(geWorld_PolyIsValid(Poly));
00844
00845 RDriver = gEngine->DriverInfo.RDriver;
00846
00847 gWorld->DebugInfo.NumUserPolys++;
00848
00849 assert(RDriver != NULL);
00850
00851 switch(Poly->Type)
00852 {
00853 case GE_TEXTURED_POLY:
00854 RenderTexturedPoly(RDriver, Poly, &gWorldSpaceFrustum, Camera);
00855 break;
00856
00857 case GE_GOURAUD_POLY:
00858 RenderGouraudPoly(RDriver, Poly, &gWorldSpaceFrustum, Camera);
00859 break;
00860
00861 case GE_TEXTURED_POINT:
00862 RenderTexturedPoint(RDriver, Poly, &gWorldSpaceFrustum, Camera);
00863 break;
00864
00865 default:
00866
00867 return GE_FALSE;
00868 }
00869 return GE_TRUE;
00870 }
00871
00872
00873
00874
00875 void geWorld_LinkPolyToLeaf(const geWorld *World, gePoly *Poly)
00876 {
00877 #if SEARCH_ALL_VERTS_FOR_LEAF
00878 int32 i;
00879 #endif
00880 geWorld_Leaf *pLeafData;
00881 int32 Leaf;
00882 GE_LVertex *Verts;
00883
00884 assert(World);
00885 assert(Poly);
00886 assert(geWorld_PolyIsValid(Poly));
00887 assert(Poly->LeafData == NULL);
00888
00889 Verts = Poly->Verts;
00890
00891 #if SEARCH_ALL_VERTS_FOR_LEAF
00892
00893 for (i=0; i<Poly->NumVerts; i++, Verts++)
00894 #endif
00895 {
00896 geVec3d Src;
00897
00898 Src.X = Verts->X;
00899 Src.Y = Verts->Y;
00900 Src.Z = Verts->Z;
00901
00902 Leaf = Plane_FindLeaf(World, gGFXModels[0].RootNode[0], &Src);
00903
00904 #if SEARCH_ALL_VERTS_FOR_LEAF
00905 if (!(gGFXLeafs[Leaf].Contents & GE_CONTENTS_SOLID))
00906 break;
00907 #endif
00908 }
00909
00910 assert(Leaf >=0 && Leaf < World->CurrentBSP->BSPData.NumGFXLeafs);
00911
00912 pLeafData = &World->CurrentBSP->LeafData[Leaf];
00913
00914
00915 if (pLeafData->PolyList)
00916 pLeafData->PolyList->Prev = Poly;
00917
00918 Poly->Next = pLeafData->PolyList;
00919 Poly->Prev = NULL;
00920 pLeafData->PolyList = Poly;
00921
00922 Poly->LeafData = pLeafData;
00923 }
00924
00925
00926
00927
00928 void geWorld_UnLinkPolyFromLeaf(gePoly *Poly)
00929 {
00930 geWorld_Leaf *pLeafData;
00931
00932 assert(Poly);
00933 assert(geWorld_PolyIsValid(Poly));
00934
00935 pLeafData = Poly->LeafData;
00936 assert(pLeafData);
00937
00938 if (Poly->Prev)
00939 {
00940 assert(Poly->Prev->Next == Poly);
00941 Poly->Prev->Next = Poly->Next;
00942 }
00943 if (Poly->Next)
00944 {
00945 assert(Poly->Next->Prev == Poly);
00946 Poly->Next->Prev = Poly->Prev;
00947 }
00948
00949
00950 if (Poly == pLeafData->PolyList)
00951 {
00952 assert(Poly->Prev == NULL);
00953 pLeafData->PolyList = Poly->Next;
00954 }
00955
00956 Poly->LeafData = NULL;
00957 Poly->Next = NULL;
00958 Poly->Prev = NULL;
00959 }
00960
00961
00962
00963
00964
00965
00966
00967
00968 GENESISAPI gePoly *geWorld_AddPoly( geWorld *World,
00969 GE_LVertex *Verts,
00970 int32 NumVerts,
00971 geBitmap *Bitmap,
00972 gePoly_Type Type,
00973 uint32 RenderFlags,
00974 geFloat Scale)
00975 {
00976 gePoly *Poly;
00977
00978 assert(World != NULL);
00979 assert(World->UserInfo != NULL);
00980
00981 assert(Bitmap != NULL || Type == GE_GOURAUD_POLY);
00982 assert(Verts != NULL);
00983 assert(NumVerts <= MAX_USER_VERTS);
00984
00985 Poly = GE_RAM_ALLOCATE_STRUCT(gePoly);
00986
00987 if (!Poly)
00988 return NULL;
00989
00990 if ( World->CurrentBSP )
00991 gGFXModels = World->CurrentBSP->BSPData.GFXModels;
00992 else
00993 gGFXModels = NULL;
00994
00995 #ifdef _DEBUG
00996 Poly->Self1 = Poly;
00997 Poly->Self2 = Poly;
00998 #endif
00999
01000 Poly->NumVerts = NumVerts;
01001 Poly->Bitmap = Bitmap;
01002 Poly->Type = Type;
01003 Poly->RenderFlags = RenderFlags;
01004 Poly->Scale = Scale;
01005 Poly->World = World;
01006 Poly->AddOnceNext = NULL;
01007 Poly->Next = NULL;
01008 Poly->Prev = NULL;
01009 Poly->LeafData = NULL;
01010
01011 memcpy(Poly->Verts, Verts, sizeof(GE_LVertex)*NumVerts);
01012
01013
01014 geWorld_LinkPolyToLeaf(World, Poly);
01015
01016 World->ActiveUserPolys++;
01017
01018 return Poly;
01019 }
01020
01021
01022
01023
01024 GENESISAPI gePoly *geWorld_AddPolyOnce( geWorld *World,
01025 GE_LVertex *Verts,
01026 int32 NumVerts,
01027 geBitmap *Bitmap,
01028 gePoly_Type Type,
01029 uint32 RenderFlags,
01030 geFloat Scale)
01031 {
01032 gePoly *Poly;
01033
01034 assert(World != NULL);
01035 assert(World->UserInfo != NULL);
01036
01037
01038 Poly = geWorld_AddPoly(World, Verts, NumVerts, Bitmap, Type, RenderFlags, Scale);
01039
01040 if (!Poly)
01041 return NULL;
01042
01043
01044 Poly->AddOnceNext = World->UserInfo->AddPolyOnceList;
01045 World->UserInfo->AddPolyOnceList = Poly;
01046
01047 return Poly;
01048 }
01049
01050
01051
01052
01053 GENESISAPI void geWorld_RemovePoly(geWorld *World, gePoly *Poly)
01054 {
01055 assert(World != NULL);
01056 assert(Poly != NULL);
01057 assert(geWorld_PolyIsValid(Poly));
01058
01059
01060 geWorld_UnLinkPolyFromLeaf(Poly);
01061
01062 World->ActiveUserPolys--;
01063
01064 geRam_Free(Poly);
01065 }
01066
01067
01068
01069
01070 GENESISAPI geBoolean gePoly_GetLVertex(gePoly *Poly, int32 Index, GE_LVertex *LVert)
01071 {
01072 assert (Poly != NULL);
01073 assert(LVert != NULL);
01074 assert(geWorld_PolyIsValid(Poly));
01075
01076 assert(Index >= 0);
01077 assert(Index < Poly->NumVerts);
01078
01079 *LVert= Poly->Verts[Index];
01080
01081 return GE_TRUE;
01082 }
01083
01084
01085
01086
01087 GENESISAPI geBoolean gePoly_SetLVertex(gePoly *Poly, int32 Index, const GE_LVertex *LVert)
01088 {
01089 assert (Poly != NULL);
01090 assert(LVert != NULL);
01091 assert(geWorld_PolyIsValid(Poly));
01092
01093 assert(Index >= 0);
01094 assert(Index < Poly->NumVerts);
01095
01096 Poly->Verts[Index] = *LVert;
01097
01098 assert(Poly->LeafData);
01099
01100 geWorld_UnLinkPolyFromLeaf(Poly);
01101 geWorld_LinkPolyToLeaf(Poly->World, Poly);
01102
01103 return GE_TRUE;
01104 }