/* Used as RwIm3DPS2AllGetMeshHeaderMeshCache (function in debug) */ #define RwIm3DPS2AllGetMeshHeaderMeshCacheMacro(_stash, _ps2AllPipeData) \ MACRO_START \ { \ _rwIm3DPoolStash *_stch = (_stash); \ RxPS2AllPipeData *_p2apd = (_ps2AllPipeData); \ RpMesh *_msh; \ \ /* There'll be a static per callback that uses this (Mesh->material gets accessed */ \ /* in PS2All, due to Rabin's speculative texture upload stuff :o| ); not so bad */ \ /* (for the function version there'll only be one copy, yay). We set up the material's */ \ /* values once only, for efficiency. In order to enable alpha in Im3D vertices, we set */ \ /* material alpha to 254 */ \ static RpMaterial _mat = {(RwTexture *)NULL, /* No texture (use current renderstate) */ \ /* TODO[3]: FIND SOME BETTER LOGIC FOR SETTING skyVertexAlpha SO WE CAN REMOVE THIS */ \ {255, 255, 255, 254}, /* Opaque white (enable vertex alpha though) */ \ (RxPipeline *)NULL, /* Im3D pipes are groupPipe anyway */ \ {1.0f, 1.0f, 1.0f}, /* Surface properties the default */ \ (RwInt16)1, (RwInt16)0}; /* refCount 1, pad 0 */ \ /* Check our various static initialisations are valid: */ \ PS2ALLMACROASSERT(28 == sizeof(RpMaterial)); \ PS2ALLMACROASSERT(8 == sizeof(RwMeshCache)); \ PS2ALLMACROASSERT(16 == sizeof(RpMeshHeader)); \ \ _p2apd->meshCache = &_rwSkyIm3DMeshCache; \ _p2apd->meshHeader = &(_rwSkyIm3DMeshHeader[0]); \ \ /* Initialise the non-constant values of the static meshHeader/meshCache */ \ _p2apd->meshHeader->totalIndicesInMesh = _stch->numIndices; \ _p2apd->meshHeader->firstMeshOffset = 0; \ \ _p2apd->meshHeader->flags = 0; \ (void)RpMeshHeaderSetPrimType(_p2apd->meshHeader, _stch->primType); \ if (NULL == _stch->indices) \ { \ /* RwIm3DPS2AllInstance can now instance from unindexed meshes */ \ _p2apd->meshHeader->flags = (RxInstanceFlags) \ (_p2apd->meshHeader->flags | rpMESHHEADERUNINDEXED); \ } \ \ /* Roll-yer-own meshcache - ensure DMA chain gets built */ \ _p2apd->meshCache->meshes[0] = NULL; \ \ /* Set up the global mesh, with indices, numIndices and a pointer to the static material: */ \ _msh = (RpMesh *)(_p2apd->meshHeader + 1); \ _msh->material = &_mat; \ _msh->indices = _stch->indices; \ _msh->numIndices = _stch->numIndices; \ } \ MACRO_STOP /* Used as RwIm3DPS2AllGatherObjMetrics (function in debug) */ #if (defined(RWMETRICS)) #define RwIm3DPS2AllGatherObjMetricsMacro(_stash) \ MACRO_START \ { \ _rwIm3DPoolStash *_stch = (_stash); \ \ /* numVertices updated in PS2Im3DFastTransform */ \ \ /* We don't count lines/points */ \ if ((_stch->primType == rwPRIMTYPETRIFAN) || \ (_stch->primType == rwPRIMTYPETRISTRIP)) \ { \ RWSRCGLOBAL(metrics)->numTriangles += _stch->numIndices - 2; \ } \ else if (_stch->primType == rwPRIMTYPETRILIST) \ { \ RWSRCGLOBAL(metrics)->numTriangles += _stch->numIndices / 3; \ } \ } \ MACRO_STOP #else /* (defined(RWMETRICS)) */ #define RwIm3DPS2AllGatherObjMetricsMacro(_stash) /* No op */ #endif /* (defined(RWMETRICS)) */ #define RwIm3DPS2AllObjInstanceTestMacro(_ps2AllPipeData) \ MACRO_START \ { \ RxPS2AllPipeData *_p2apd = (_ps2AllPipeData); \ \ /* We always do a full reinstance for Im3D (I know... sorry :o/) */ \ _p2apd->objInstance = (RxInstanceFlags) \ ( rxINSTANCEFULLINSTANCE | rxINSTANCEALL ); \ REDEBUGPrintf(("im3d ps2AllPipeData->objInstance %x\n", (RwUInt32)_p2apd->objInstance)); \ } \ MACRO_STOP /* Used as RwIm3DPS2AllTransformSetup (function in debug) */ #define RwIm3DPS2AllTransformSetupMacro(_stash, _transform) \ MACRO_START \ { \ _rwIm3DPoolStash *_stch = (_stash); \ RwMatrix **_tnfm = (_transform); \ \ RwMatrix * const _mpLocalToWorld = (RwMatrix *)((_stch)->ltm); \ RwMatrix * const _viewMatrix = &(((RwCamera *)RWSRCGLOBAL(curCamera))->viewMatrix); \ \ PS2ALLMACROASSERT(RWMATRIXALIGNMENT(_mpLocalToWorld)); \ PS2ALLMACROASSERT(RWMATRIXALIGNMENT(_viewMatrix)); \ \ if (_mpLocalToWorld != NULL) \ { \ RwMatrixMultiply(*_tnfm, _mpLocalToWorld, _viewMatrix); \ } \ else \ { \ *_tnfm = _viewMatrix; \ } \ } \ MACRO_STOP /* Used as RwIm3DPS2AllFrustumTest (function in debug) */ #define RwIm3DPS2AllFrustumTestMacro(_stash, _inFrustum) \ MACRO_START \ { \ RwFrustumTestResult *_infm = (_inFrustum); \ \ *_infm = rwSPHEREBOUNDARY; \ if ((_stash)->flags & rwIM3D_NOCLIP) *_infm = rwSPHEREINSIDE; \ } \ MACRO_STOP /* Used as RwIm3DPS2AllResEntryAlloc (function in debug) */ #define RwIm3DPS2AllResEntryAllocMacro(_ps2AllPipeData, _repEntry, _size, _destroyCallBack) \ MACRO_START \ { \ RxPS2AllPipeData *_p2apd = (_ps2AllPipeData); \ RwResEntry **_rslt = (_repEntry); \ RwUInt32 _cyze = (_size); \ \ /* Im3D changes every frame (for now no caching), so don't use a resEntry (fake one), use */ \ /* the top of the DMA buffer (this will cause a buffer swap if there's no room), which */ \ /* will be 'freed' the next time the buffers swap. */ \ _rwDMAOpenVIFPkt(0, 128); \ *_rslt = (RwResEntry *)_rwDMADMAPktAllocHigh(sizeof(RwResEntry) + _cyze, FALSE); \ if (NULL == *_rslt) \ { \ RwDebugSendMessage(rwDEBUGERROR, "RwIm3DPS2AllResEntryAlloc", \ "Not enough memory could be allocated to draw an Im3D primitive of this size; either split the primitive or allocate more memory, using _rwDMAPreAlloc"); \ } \ /* OLD: result = RwMalloc(sizeof(RwResEntry) + size); */ \ \ /* We have to set up this space as if it were a resentry */ \ /* cos later pipe code assumes this is done... for now */ \ (*_rslt)->link.prev = (RwLLLink *)NULL; \ (*_rslt)->link.next = (RwLLLink *)NULL; \ (*_rslt)->owner = _p2apd->sourceObject; \ (*_rslt)->size = _cyze; \ (*_rslt)->ownerRef = (RwResEntry **)NULL; \ (*_rslt)->destroyNotify = (void (*)(RwResEntry *))_destroyCallBack; \ } \ MACRO_STOP /* Used as RwIm3DPS2AllGatherMeshMetrics (function in debug) */ #if (defined(RWMETRICS)) #define RwIm3DPS2AllGatherMeshMetricsMacro(_stash, _ps2AllPipeData) \ MACRO_START \ { \ _rwIm3DPoolStash *_stch = (_stash); \ RxPS2AllPipeData *_p2apd = (_ps2AllPipeData); \ \ /* We don't count lines */ \ if (!(_p2apd->transType & rxSKYTRANSTYPELINE)) \ { \ if (_p2apd->transType & rxSKYTRANSTYPELIST) \ { \ RWSRCGLOBAL(metrics)->numProcTriangles += _stch->numIndices / 3; \ } \ else \ { \ RWSRCGLOBAL(metrics)->numProcTriangles += _stch->numIndices - 2; \ } \ } \ } \ MACRO_STOP #else /* (defined(RWMETRICS)) */ #define RwIm3DPS2AllGatherMeshMetricsMacro(_stash, _ps2AllPipeData) /* No op */ #endif /* (defined(RWMETRICS)) */ extern RwMeshCache _rwSkyIm3DMeshCache; extern RpMeshHeader _rwSkyIm3DMeshHeader[]; #if (defined(__cplusplus)) extern "C" { #endif /* (defined(__cplusplus)) */ /* Default RW callbacks */ extern RwBool RwIm3DPS2AllObjectSetupCallBack( RxPS2AllPipeData *ps2AllPipeData, RwMatrix **transform); extern RwResEntry * RwIm3DPS2AllResEntryAllocCallBack( RxPS2AllPipeData *ps2AllPipeData, RwResEntry **repEntry, RwUInt32 size, RwResEntryDestroyNotify destroyCallBack); extern RwBool RwIm3DPS2AllInstanceCallBack( RxPS2AllPipeData *ps2AllPipeData, void **clusters, RwUInt32 numClusters); extern RwBool RwIm3DPS2AllBridgeCallBack( RxPS2AllPipeData *ps2AllPipeData); extern RwBool RwIm3DPS2AllPostMeshCallBack( RxPS2AllPipeData *ps2AllPipeData); /* Standard instance func for Im3D */ extern RwBool RwIm3DPS2AllInstance(RxPS2AllPipeData *ps2AllPipeData); /* Callback components, for use in user callbacks */ /* ObjectSetupCB */ extern void RwIm3DPS2AllGetMeshHeaderMeshCacheFunc( _rwIm3DPoolStash *stash, RxPS2AllPipeData *ps2AllPipeData); extern void RwIm3DPS2AllGatherObjMetricsFunc( _rwIm3DPoolStash *stash); extern void RwIm3DPS2AllObjInstanceTestFunc( RxPS2AllPipeData *ps2AllPipeData); extern void RwIm3DPS2AllTransformSetupFunc( _rwIm3DPoolStash *stash, RwMatrix **transform); extern void RwIm3DPS2AllFrustumTestFunc( _rwIm3DPoolStash *stash, RwFrustumTestResult *inFrustum); /* ResEntryAllocCB */ extern void RwIm3DPS2AllResEntryAllocFunc( RxPS2AllPipeData *ps2AllPipeData, RwResEntry **repEntry, RwUInt32 size, RwResEntryDestroyNotify destroyCallBack); /* PostMeshCB */ extern void RwIm3DPS2AllGatherMeshMetricsFunc( _rwIm3DPoolStash *stash, RxPS2AllPipeData *ps2AllPipeData); #if (defined(__cplusplus)) } #endif /* (defined(__cplusplus)) */ #if (defined(RWDEBUG)) #define RwIm3DPS2AllGetMeshHeaderMeshCache RwIm3DPS2AllGetMeshHeaderMeshCacheFunc #define RwIm3DPS2AllGatherObjMetrics RwIm3DPS2AllGatherObjMetricsFunc #define RwIm3DPS2AllObjInstanceTest RwIm3DPS2AllObjInstanceTestFunc #define RwIm3DPS2AllTransformSetup RwIm3DPS2AllTransformSetupFunc #define RwIm3DPS2AllFrustumTest RwIm3DPS2AllFrustumTestFunc #define RwIm3DPS2AllResEntryAlloc RwIm3DPS2AllResEntryAllocFunc #define RwIm3DPS2AllGatherMeshMetrics RwIm3DPS2AllGatherMeshMetricsFunc #else /* (defined(RWDEBUG)) */ #define RwIm3DPS2AllGetMeshHeaderMeshCache RwIm3DPS2AllGetMeshHeaderMeshCacheMacro #define RwIm3DPS2AllGatherObjMetrics RwIm3DPS2AllGatherObjMetricsMacro #define RwIm3DPS2AllObjInstanceTest RwIm3DPS2AllObjInstanceTestMacro #define RwIm3DPS2AllTransformSetup RwIm3DPS2AllTransformSetupMacro #define RwIm3DPS2AllFrustumTest RwIm3DPS2AllFrustumTestMacro #define RwIm3DPS2AllResEntryAlloc RwIm3DPS2AllResEntryAllocMacro #define RwIm3DPS2AllGatherMeshMetrics RwIm3DPS2AllGatherMeshMetricsMacro #endif /* (defined(RWDEBUG)) */