Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

User.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  User.c                                                                              */
00003 /*                                                                                      */
00004 /*  Author: John Pollard                                                                */
00005 /*  Description: User poly's                                                            */
00006 /*                                                                                      */
00007 /*  The contents of this file are subject to the Genesis3D Public License               */
00008 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00009 /*  compliance with the License. You may obtain a copy of the License at                */
00010 /*  http://www.genesis3d.com                                                            */
00011 /*                                                                                      */
00012 /*  Software distributed under the License is distributed on an "AS IS"                 */
00013 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00014 /*  the License for the specific language governing rights and limitations              */
00015 /*  under the License.                                                                  */
00016 /*                                                                                      */
00017 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00018 /*Genesis3D Version 1.1 released November 15, 1999                            */
00019 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
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;                                        // GLOBAL!!! in World.c
00041 
00042 //=====================================================================================
00043 //      Local static globals
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 //      Local Static Function Prototypes
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 //      User_EngineInit
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 //      User_EngineShutdown
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;         // Nothing to do...
00120 
00121         geRam_Free(Info);
00122 
00123         Engine->UserInfo = NULL;
00124 }
00125 
00126 //=====================================================================================
00127 //      User_WorldInit
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 //      User_WorldShutdown
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;         // Nothing to do...
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 //      User_RenderPolyList
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                         // Sorted polys (within this list) go in the SortedPoly list, and are sorted and drawn below
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                 // If it is not a sorted poly, render it now...
00224                 RenderUserPoly(gCamera, Poly);
00225         }
00226 
00227         if (!NumSortedPolys)            // nothing more to do, if no sorted polys
00228                 return GE_TRUE;
00229 
00230         // Now render all sorted polys
00231         // Sort the polys
00232         qsort(&SortedPolys, NumSortedPolys, sizeof(SortedPolys[0]), PolyComp);
00233 
00234         // Render them
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 //      User_DestroyPolyOnceList
00247 //=====================================================================================
00248 void User_DestroyPolyOnceList(geWorld *World, gePoly *List)
00249 {
00250         gePoly  *Poly, *Next;
00251 
00252         // Clear out all the AddPolyOnce polys...
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 //      User_DestroyPolyList
00265 //=====================================================================================
00266 void User_DestroyPolyList(geWorld *World, gePoly *List)
00267 {
00268         gePoly  *Poly, *Next;
00269 
00270         // Clear out all the AddPolyOnce polys...
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 //      User_SetCameraInfo
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         // Make the frustum go to World/Model space
00300         Frustum_TransformToWorldSpace(Fi, Camera, &gWorldSpaceFrustum);
00301 
00302         return GE_TRUE; 
00303 }
00304 
00305 //=====================================================================================
00306 //      User_DestroyOncePolys
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 //      RenderTexturedPoint
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;             // Restore the poly
00389                 Poly->Verts[0] = Save;
00390         }
00391         else
00392         {
00393                 //GFX_Plane             *Planes;
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                 // Xform the point 
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                 // Build the screen poly from the point
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                 // Now, clip it against the 2d camera viewport
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                 // Lastly, render it...
00534                 ScreenPnts[0].a = pVerts->a;
00535                 // Fixed bug where i fogot to set RGB's...
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) // skybox 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 //      RenderTexturedPoly
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 // skydome
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 // skydome
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                 // Swap them
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                 //geXForm3d_Transform(&Camera->XForm, pDest1, pDest2);
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) // skybox fog
00676                 RenderFlags |= DRV_RENDER_POLY_NO_FOG;
00677 
00678         // Render it...
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 //      RenderGouraudPoly
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                 //geXForm3d_Transform(&Camera->XForm, pDest1, pDest2);
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         // Render it...
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 //      User_EngineFillRect
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 // changed for RF
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 //      RenderUserPoly
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                         //geErrorLog_Add(GE_ERR_, NULL);
00867                         return GE_FALSE;
00868         }
00869         return GE_TRUE;
00870 }
00871 
00872 //=====================================================================================
00873 //      geWorld_LinkPolyToLeaf
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         // Take the first vert that is in a valid leaf
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))    // Try to find the first leaf NOT in 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         // Insert into the beginning of the list
00915         if (pLeafData->PolyList)
00916                 pLeafData->PolyList->Prev = Poly;
00917 
00918         Poly->Next = pLeafData->PolyList;
00919         Poly->Prev = NULL;                                      // This is TRUE cause the poly is always added to the front of the list
00920         pLeafData->PolyList = Poly;
00921 
00922         Poly->LeafData = pLeafData;             // Save the leaf data
00923 }
00924 
00925 //=====================================================================================
00926 //      geWorld_UnLinkPolyFromLeaf
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);              // Polys are allways in some kind of leaf, solid or not!!! (they just don't always render)
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         // Cut the poly from the leaf it was inserted into originally
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 //              **** Public GENESISAPI's ****
00963 //=====================================================================================
00964 
00965 //=====================================================================================
00966 //      geWorld_AddPoly
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;            // I could think of no other way!!!  Poly needs world in SetLVertex.  Should we require it as a parm???
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         // Link the poly to the leaf it is in
01014         geWorld_LinkPolyToLeaf(World, Poly);
01015 
01016         World->ActiveUserPolys++;
01017 
01018         return Poly;
01019 }
01020 
01021 //=====================================================================================
01022 //      geWorld_AddPolyOnce
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         // For AddPOlyOnce, do an AddPoly, then put it in the list to be removed at the end of the frame
01038         Poly = geWorld_AddPoly(World, Verts, NumVerts, Bitmap, Type, RenderFlags, Scale);
01039 
01040         if (!Poly)
01041                 return NULL;
01042 
01043         // Insert add poly once polys into the AddPolyOnceList so they can be removed at the end of the frame
01044         Poly->AddOnceNext = World->UserInfo->AddPolyOnceList;
01045         World->UserInfo->AddPolyOnceList = Poly;
01046 
01047         return Poly;
01048 }
01049 
01050 //=====================================================================================
01051 //      geWorld_RemovePoly
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         // Remove the poly from the leaf that it is in (it must be in one. or it would not have been added to the world)
01060         geWorld_UnLinkPolyFromLeaf(Poly);
01061 
01062         World->ActiveUserPolys--;
01063 
01064         geRam_Free(Poly);
01065 }
01066 
01067 //=====================================================================================
01068 //      gePoly_GetLVertex
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 //      gePoly_SetLVertex
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);         // A poly does not get created UNLESS it gets attaches to a leaf!!!
01099 
01100         geWorld_UnLinkPolyFromLeaf(Poly);                       // Detach the poly from it's current leaf
01101         geWorld_LinkPolyToLeaf(Poly->World, Poly);      // Re-attach to the new leaf (if any, check for cohearency!)
01102         
01103         return GE_TRUE;
01104 }

Generated on Tue Sep 30 12:36:35 2003 for GTestAndEngine by doxygen 1.3.2