engine/terrain/terrRender.h
2024-01-07 04:36:33 +00:00

343 lines
9.4 KiB
C++

//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#ifndef _TERRRENDER_H_
#define _TERRRENDER_H_
#ifndef _GTEXMANAGER_H_
#include "dgl/gTexManager.h"
#endif
#ifndef _COLOR_H_
#include "core/color.h"
#endif
#ifndef _WATERBLOCK_H_
#include "terrain/waterBlock.h"
#endif
struct EmitChunk;
struct AllocatedTexture {
U32 level;
S32 x, y;
F32 distance;
EmitChunk *list;
TextureHandle handle;
AllocatedTexture *next;
AllocatedTexture *previous;
AllocatedTexture *nextLink;
U32 mipLevel;
AllocatedTexture()
{
next = previous = NULL;
}
inline void unlink()
{
AssertFatal(next && previous, "Invalid unlink.");
next->previous = previous;
previous->next = next;
next = previous = NULL;
}
inline void linkAfter(AllocatedTexture *t)
{
AssertFatal(next == NULL && previous == NULL, "Cannot link a non-null next & prev");
next = t->next;
previous = t;
t->next->previous = this;
t->next = this;
}
};
struct Render2Point : public Point3F
{
F32 d;
// ColorI color;
};
struct EdgePoint : public Point3F
{
ColorI detailColor;
F32 haze;
F32 distance;
F32 fogRed;
F32 fogGreen;
};
struct ChunkCornerPoint : public EdgePoint
{
U32 pointIndex;
U32 xfIndex;
};
struct EdgeParent
{
ChunkCornerPoint *p1, *p2;
};
struct ChunkScanEdge : public EdgeParent
{
ChunkCornerPoint *mp;
EdgeParent *e1, *e2;
};
struct ChunkEdge : public EdgeParent
{
U32 xfIndex;
U32 pointIndex;
U32 pointCount;
EdgePoint pt[3];
EmitChunk *c1, *c2;
};
struct EmitChunk
{
ChunkEdge *edge[4];
S32 subDivLevel;
F32 growFactor;
S32 x, y;
S32 gridX, gridY;
U32 emptyFlags;
bool clip;
U32 lightMask;
EmitChunk *next;
bool renderDetails;
};
struct SquareStackNode2
{
U32 clipFlags;
U32 lightMask;
Point2I pos;
U32 level;
bool texAllocated;
};
struct SquareStackNode
{
U32 clipFlags;
U32 lightMask;
Point2I pos;
U32 level;
bool texAllocated;
EdgeParent *top, *right, *bottom, *left;
};
struct TerrLightInfo
{
Point3F pos; // world position
F32 radius; // radius of the light
F32 radiusSquared; // radius^2
F32 r, g, b;
F32 distSquared; // distance to camera
};
//struct ScanEdge
//{
// U16 p1, p2, mp;
// U16 firstSubEdge; // two sub edges for each edge, mp = InvalidPointIndex if none
//};
enum EmptyFlags {
SquareEmpty_0_0 = (1 << 0),
SquareEmpty_1_0 = (1 << 1),
SquareEmpty_2_0 = (1 << 2),
SquareEmpty_3_0 = (1 << 3),
SquareEmpty_0_1 = (1 << 4),
SquareEmpty_1_1 = (1 << 5),
SquareEmpty_2_1 = (1 << 6),
SquareEmpty_3_1 = (1 << 7),
SquareEmpty_0_2 = (1 << 8),
SquareEmpty_1_2 = (1 << 9),
SquareEmpty_2_2 = (1 << 10),
SquareEmpty_3_2 = (1 << 11),
SquareEmpty_0_3 = (1 << 12),
SquareEmpty_1_3 = (1 << 13),
SquareEmpty_2_3 = (1 << 14),
SquareEmpty_3_3 = (1 << 15),
CornerEmpty_0_0 = SquareEmpty_0_0 | SquareEmpty_1_0 | SquareEmpty_0_1 | SquareEmpty_1_1,
CornerEmpty_1_0 = SquareEmpty_2_0 | SquareEmpty_3_0 | SquareEmpty_2_1 | SquareEmpty_3_1,
CornerEmpty_0_1 = SquareEmpty_0_2 | SquareEmpty_1_2 | SquareEmpty_0_3 | SquareEmpty_1_3,
CornerEmpty_1_1 = SquareEmpty_2_2 | SquareEmpty_3_2 | SquareEmpty_2_3 | SquareEmpty_3_3,
};
struct RenderPoint : public Point3F
{
F32 dist;
F32 haze; // also used as grow factor
};
enum {
MaxClipPlanes = 8, // left, right, top, bottom - don't need far tho...
MaxTerrainMaterials = 256,
EdgeStackSize = 1024, // value for water/terrain edge stack size.
MaxWaves = 8,
MaxDetailLevel = 9,
MaxMipLevel = 8,
MaxTerrainLights = 64,
MaxVisibleLights = 31,
ClipPlaneMask = (1 << MaxClipPlanes) - 1,
FarSphereMask = 0x80000000,
FogPlaneBoxMask = 0x40000000,
VertexBufferSize = 65 * 65 + 1000,
AllocatedTextureCount = 16 + 64 + 256 + 1024 + 4096,
SmallMipLevel = 6
};
struct Color
{
S32 r, g, b;
F32 z;
};
class SceneState;
struct TerrainRender
{
static MatrixF mCameraToObject;
static AllocatedTexture mTextureFrameListHead;
static AllocatedTexture mTextureFrameListTail;
static AllocatedTexture mTextureFreeListHead;
static AllocatedTexture mTextureFreeListTail;
static AllocatedTexture mTextureFreeBigListHead;
static AllocatedTexture mTextureFreeBigListTail;
static U32 mTextureSlopSize;
static Vector<TextureHandle> mTextureFreeList;
static S32 mTextureMinSquareSize;
static SceneState *mSceneState;
static AllocatedTexture *mCurrentTexture;
static TerrainBlock *mCurrentBlock;
static S32 mSquareSize;
static F32 mScreenSize;
static U32 mFrameIndex;
static U32 mNumClipPlanes;
static AllocatedTexture *mTextureGrid[AllocatedTextureCount];
static AllocatedTexture **mTextureGridPtr[5];
static Point2F mBlockPos;
static Point2I mBlockOffset;
static Point2I mTerrainOffset;
static PlaneF mClipPlane[MaxClipPlanes];
static Point3F mCamPos;
static TextureHandle* mGrainyTexture;
static U32 mDynamicLightCount;
static bool mEnableTerrainDetails;
static bool mEnableTerrainDynLights;
static F32 mPixelError;
static TerrLightInfo mTerrainLights[MaxTerrainLights];
static F32 mScreenError;
static F32 mMinSquareSize;
static F32 mFarDistance;
static S32 mDynamicTextureCount;
static S32 mTextureSpaceUsed;
static S32 mLevelZeroCount;
static S32 mFullMipCount;
static S32 mStaticTextureCount;
static S32 mUnusedTextureCount;
static S32 mStaticTSU;
static S32 mSquareSeqAdd[256];
static U32 mNewGenTextureCount;
static F32 mInvFarDistance;
static F32 mInvHeightRange;
static U32 mMipCap;
static bool mRenderingCommander;
static ColorF mFogColor;
static bool mRenderOutline;
static U32 mMaterialCount;
static GBitmap* mBlendBitmap;
static void (*transformPoint)(U32 point, U32 p1, U32 p2);
static void init();
static void shutdown();
// static void allocReset();
// static void* alloc(U32 byteSize);
static void allocRenderEdges(U32 edgeCount, EdgeParent **dest, bool renderEdge);
static void subdivideChunkEdge(ChunkScanEdge *e, Point2I pos, bool chunkEdge);
static void processCurrentBlock2(SceneState* state, EdgeParent *topEdge, EdgeParent *rightEdge, EdgeParent *bottomEdge, EdgeParent *leftEdge);
static ChunkCornerPoint *allocInitialPoint(Point3F pos);
static ChunkCornerPoint *allocPoint(Point2I pos);
static void emitTerrChunk(SquareStackNode *n, F32 squareDistance, U32 lightMask, bool farClip, bool useDetails);
static void renderChunkOutline(EmitChunk *chunk);
static void renderChunkCommander(EmitChunk *chunk);
static void fixEdge(ChunkEdge *edge, S32 x, S32 y, S32 dx, S32 dy);
static void drawTriFan(U32 vCount, U32 *indexBuffer);
static U32 constructPoint(S32 x, S32 y);
static U32 interpPoint(U32 p1, U32 p2, S32 x, S32 y, F32 growFactor);
static void addEdge(ChunkEdge *edge);
static void clipStart(EdgePoint *pt, U32 index);
static void clipInsert(EdgePoint *pt, U32 index);
static void clipEnd();
static void clip(U32 triFanStart);
static F32 getScreenError() { return(mScreenError); }
static void setScreenError(F32 error) { mScreenError = error; }
static void flushCache();
static void transformTerrainPoint(U32 point, U32 p1, U32 p2);
static U8 getClipFlags(Point2F &pos, U8 clipMask);
static void allocTerrTexture(Point2I pos, U32 level, U32 mipLevel, bool vis, F32 distance);
static void freeTerrTexture(AllocatedTexture *texture);
static void buildBlendMap(AllocatedTexture *texture);
static U32 TestSquareLights(GridSquare *sq, S32 level, Point2I pos, U32 lightMask);
static S32 TestSquareVisibility(Point3F &min, Point3F &max, S32 clipMask, F32 expand);
static S32 allocEdges(S32 count);
static void clampEdge(S32 edge);
static void subdivideEdge(S32 edge, Point2I pos);
static F32 getSquareDistance(const Point3F& minPoint, const Point3F& maxPoint,
F32* zDiff);
static bool subdivideSquare(GridSquare *sq, S32 level, Point2I pos);
static void emitTerrSquare(SquareStackNode *n, U32 flags);
static void emitFullMipSquare(SquareStackNode *n, U32 flags);
static void emitNonzeroSquare(SquareStackNode *n, U32 flags, U32 mipLevel);
static void emitLevelZeroSquare(SquareStackNode *n, U32 flags, U32 material, U32 mipLevel);
static void buildTextureCoor();
static void renderCurrentBlock(S32 firstSquare, S32 lastSquare);
static void textureRecurse(SquareStackNode *n);
static void processCurrentBlock(S32 topEdge, S32 rightEdge, S32 bottomEdge, S32 leftEdge);
static void buildLightArray();
static void buildClippingPlanes(bool flipClipPlanes);
static void buildDetailTable();
static void renderXFCache();
static void renderBlock(TerrainBlock *, SceneState *state);
static void textureRecurse2(SquareStackNode2 *n);
static void tesselate0(SquareStackNode2 *n, U32 flags);
static void tesselate1(SquareStackNode2 *n);
static void tesselate2(SquareStackNode2 *n);
static void tesselate3(SquareStackNode2 *n);
static void farclip(SquareStackNode2 *n, U32 flags);
static void render2();
static void processBlockStack(SquareStackNode2 *stack, S32 curStackSize);
protected:
static void doesWaterBlockSubmergeCamera(SceneObject *sceneObj, S32 key);
};
#endif