diff --git a/src/miami/renderer/ShadowCamera.cpp b/src/miami/renderer/ShadowCamera.cpp index f69c234f..d59ab842 100644 --- a/src/miami/renderer/ShadowCamera.cpp +++ b/src/miami/renderer/ShadowCamera.cpp @@ -271,13 +271,13 @@ CShadowCamera::InvertRaster() RwIm2DVertexSetIntRGBA (&vx[1], 255, 255, 255, 255); RwIm2DVertexSetScreenX (&vx[2], crw); - RwIm2DVertexSetScreenY (&vx[2], 0.0f); + RwIm2DVertexSetScreenY (&vx[2], crh); RwIm2DVertexSetScreenZ (&vx[2], RwIm2DGetNearScreenZ()); RwIm2DVertexSetRecipCameraZ(&vx[2], recipZ); RwIm2DVertexSetIntRGBA (&vx[2], 255, 255, 255, 255); RwIm2DVertexSetScreenX (&vx[3], crw); - RwIm2DVertexSetScreenY (&vx[3], crh); + RwIm2DVertexSetScreenY (&vx[3], 0.0f); RwIm2DVertexSetScreenZ (&vx[3], RwIm2DGetNearScreenZ()); RwIm2DVertexSetRecipCameraZ(&vx[3], recipZ); RwIm2DVertexSetIntRGBA (&vx[3], 255, 255, 255, 255); @@ -289,7 +289,7 @@ CShadowCamera::InvertRaster() RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDINVDESTCOLOR); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO); - RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4); + RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, vx, 4); RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA); diff --git a/src/miami/rw/RwHelper.cpp b/src/miami/rw/RwHelper.cpp index d5d0885d..3a797311 100644 --- a/src/miami/rw/RwHelper.cpp +++ b/src/miami/rw/RwHelper.cpp @@ -384,23 +384,23 @@ RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwRe RwIm2DVertexSetU(&vx[1], uvOffset, recipCamZ); RwIm2DVertexSetV(&vx[1], 1.0f + uvOffset, recipCamZ); - RwIm2DVertexSetScreenX(&vx[2], x2); - RwIm2DVertexSetScreenY(&vx[2], y1); + RwIm2DVertexSetScreenX(&vx[2], x2); + RwIm2DVertexSetScreenY(&vx[2], y2); RwIm2DVertexSetScreenZ(&vx[2], z); RwIm2DVertexSetIntRGBA(&vx[2], 255, 255, 255, 255); RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ); RwIm2DVertexSetU(&vx[2], 1.0f + uvOffset, recipCamZ); - RwIm2DVertexSetV(&vx[2], uvOffset, recipCamZ); - + RwIm2DVertexSetV(&vx[2], 1.0f + uvOffset, recipCamZ); + RwIm2DVertexSetScreenX(&vx[3], x2); - RwIm2DVertexSetScreenY(&vx[3], y2); + RwIm2DVertexSetScreenY(&vx[3], y1); RwIm2DVertexSetScreenZ(&vx[3], z); RwIm2DVertexSetIntRGBA(&vx[3], 255, 255, 255, 255); RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ); RwIm2DVertexSetU(&vx[3], 1.0f + uvOffset, recipCamZ); - RwIm2DVertexSetV(&vx[3], 1.0f + uvOffset, recipCamZ); + RwIm2DVertexSetV(&vx[3], uvOffset, recipCamZ); - RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4); + RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, vx, 4); return TRUE; } diff --git a/vendor/librw/src/dc/rwdc.cpp b/vendor/librw/src/dc/rwdc.cpp index 8114204a..3f2ed63c 100644 --- a/vendor/librw/src/dc/rwdc.cpp +++ b/vendor/librw/src/dc/rwdc.cpp @@ -674,7 +674,7 @@ struct atomic_context_t { bool global_needsNoClip; bool skinMatrix0Identity; - matrix_t worldView, mtx; + matrix_t mtx; UniformObject uniform; }; /* END Ligting Structs and Defines */ @@ -934,6 +934,14 @@ struct chunked_vector { curr->header.used = 0; curr->header.free = chunk::item_count; } + // Free all chunks except first_chunk. + chunk* curr = first_chunk.header.next; + while (curr) { + chunk* next = curr->header.next; + free(curr); + curr = next; + } + first_chunk.header.next = nullptr; // Optionally, reset last pointer to first for reuse. last = first; } @@ -1656,55 +1664,60 @@ pvr_ptr_t pvrTexturePointer(Raster *r) { void im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32_t numVertices) { auto *verts = reinterpret_cast(vertices); + pvr_poly_cxt_t cxt; + + if (current_raster) [[likely]] { + pvr_poly_cxt_txr(&cxt, + PVR_LIST_TR_POLY, + pvrFormatForRaster(current_raster), + current_raster->width, + current_raster->height, + pvrTexturePointer(current_raster), + PVR_FILTER_BILINEAR); + pvrTexAddress(&cxt, addressingU, addressingV); + } else { + pvr_poly_cxt_col(&cxt, PVR_LIST_TR_POLY); + } + + if (blendEnabled) [[likely]] { + cxt.blend.src = srcBlend; + cxt.blend.dst = dstBlend; + } else { + // non blended sprites are also submitted in TR lists + // so we need to reset the blend mode + cxt.blend.src = PVR_BLEND_ONE; + cxt.blend.dst = PVR_BLEND_ZERO; + } + + cxt.gen.culling = cullModePvr; + cxt.depth.comparison = zFunction; + cxt.depth.write = zWrite; + + cxt.gen.fog_type = fogFuncPvr; + + pvr_poly_hdr_t hdr; + pvr_poly_compile(&hdr, &cxt); + + assert(primType == PRIMTYPETRILIST || primType == PRIMTYPETRIFAN); + auto renderCB = - [=, - current_raster = dc::current_raster, - blend_enabled = dc::blendEnabled, - src_blend = dc::srcBlend, - dst_blend = dc::dstBlend, - z_function = dc::zFunction, - z_write = dc::zWrite, - cull_mode_pvr = dc::cullModePvr, - addressingU = dc::addressingU, - addressingV = dc::addressingV, - fog_func_pvr = dc::fogFuncPvr] + [ + primType, + numVertices, + cmd = hdr.cmd, + mode1 = hdr.mode1, + mode2 = hdr.mode2, + mode3 = hdr.mode3 + ] (const Im2DVertex* vtx) __attribute__((always_inline)) { auto pvrHeaderSubmit = [=]() __attribute__((always_inline)) { - pvr_poly_cxt_t cxt; - - if (current_raster) [[likely]] { - pvr_poly_cxt_txr(&cxt, - PVR_LIST_TR_POLY, - pvrFormatForRaster(current_raster), - current_raster->width, - current_raster->height, - pvrTexturePointer(current_raster), - PVR_FILTER_BILINEAR); - pvrTexAddress(&cxt, addressingU, addressingV); - } else { - pvr_poly_cxt_col(&cxt, PVR_LIST_TR_POLY); - } - - if (blend_enabled) [[likely]] { - cxt.blend.src = src_blend; - cxt.blend.dst = dst_blend; - } else { - // non blended sprites are also submitted in TR lists - // so we need to reset the blend mode - cxt.blend.src = PVR_BLEND_ONE; - cxt.blend.dst = PVR_BLEND_ZERO; - } - - cxt.gen.culling = cull_mode_pvr; - cxt.depth.comparison = z_function; - cxt.depth.write = z_write; - - cxt.gen.fog_type = fog_func_pvr; - auto* hdr = reinterpret_cast(pvr_dr_target(drState)); - pvr_poly_compile(hdr, &cxt); + hdr->cmd = cmd; + hdr->mode1 = mode1; + hdr->mode2 = mode2; + hdr->mode3 = mode3; pvr_dr_commit(hdr); }; @@ -1760,26 +1773,133 @@ void im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32_t numVert } }; - std::vector vertData(verts, verts + numVertices); - blendCallbacks.emplace_back([=, data = std::move(vertData)]() { - renderCB(&data[0]); + Im2DVertex* vertData = (Im2DVertex*)malloc(numVertices * sizeof(Im2DVertex)); + assert(vertData); + memcpy(vertData, verts, numVertices * sizeof(Im2DVertex)); + blendCallbacks.emplace_back([renderCB, vertData]() { + renderCB(vertData); + free(vertData); }); } void im2DRenderIndexedPrimitive(PrimitiveType primType, void *vertices, int32 numVertices, void *indices, int32 numIndices) { auto idx = (unsigned short*)indices; - auto vtx = (Im2DVertex*)vertices; + auto verts = (Im2DVertex*)vertices; - std::vector vertData(numIndices); + pvr_poly_cxt_t cxt; - for (int32 i = 0; i < numIndices; i++) { - vertData[i] = vtx[idx[i]]; + if (current_raster) [[likely]] { + pvr_poly_cxt_txr(&cxt, + PVR_LIST_TR_POLY, + pvrFormatForRaster(current_raster), + current_raster->width, + current_raster->height, + pvrTexturePointer(current_raster), + PVR_FILTER_BILINEAR); + pvrTexAddress(&cxt, addressingU, addressingV); + } else { + pvr_poly_cxt_col(&cxt, PVR_LIST_TR_POLY); } - im2DRenderPrimitive(primType, &vertData[0], vertData.size()); + if (blendEnabled) [[likely]] { + cxt.blend.src = srcBlend; + cxt.blend.dst = dstBlend; + } else { + // non blended sprites are also submitted in TR lists + // so we need to reset the blend mode + cxt.blend.src = PVR_BLEND_ONE; + cxt.blend.dst = PVR_BLEND_ZERO; + } + + cxt.gen.culling = cullModePvr; + cxt.depth.comparison = zFunction; + cxt.depth.write = zWrite; + + cxt.gen.fog_type = fogFuncPvr; + + pvr_poly_hdr_t hdr; + pvr_poly_compile(&hdr, &cxt); + + assert(primType == PRIMTYPETRILIST); + + auto renderCB = + [ + primType, + numIndices, + cmd = hdr.cmd, + mode1 = hdr.mode1, + mode2 = hdr.mode2, + mode3 = hdr.mode3 + ] + (const Im2DVertex* vtx, const uint16_t* idx) __attribute__((always_inline)) + { + + auto pvrHeaderSubmit = [=]() __attribute__((always_inline)) { + auto* hdr = reinterpret_cast(pvr_dr_target(drState)); + hdr->cmd = cmd; + hdr->mode1 = mode1; + hdr->mode2 = mode2; + hdr->mode3 = mode3; + pvr_dr_commit(hdr); + }; + + auto pvrVertexSubmit = [](const Im2DVertex >aVert, unsigned flags) + __attribute__((always_inline)) + { + auto *pvrVert = pvr_dr_target(drState); + pvrVert->flags = flags; + pvrVert->x = gtaVert.x * VIDEO_MODE_SCALE_X; + pvrVert->y = gtaVert.y; + pvrVert->z = MATH_Fast_Invert(gtaVert.w); // this is perfect for almost every case... + pvrVert->u = gtaVert.u; + pvrVert->v = gtaVert.v; + pvrVert->argb = (gtaVert.a << 24) | + (gtaVert.r << 16) | + (gtaVert.g << 8) | + (gtaVert.b << 0); + pvr_dr_commit(pvrVert); + }; + + switch(primType) { + case PRIMTYPETRILIST: + pvrHeaderSubmit(); + dcache_pref_block(vtx); + for(int i = 0; i < numIndices; i += 3) [[likely]] { + dcache_pref_block(&vtx[idx[i + 1]]); + pvrVertexSubmit(vtx[idx[i + 0]], PVR_CMD_VERTEX); + dcache_pref_block(&vtx[idx[i + 2]]); + pvrVertexSubmit(vtx[idx[i + 1]], PVR_CMD_VERTEX); + dcache_pref_block(&vtx[idx[i + 3]]); + pvrVertexSubmit(vtx[idx[i + 2]], PVR_CMD_VERTEX_EOL); + } + break; + default: + UNIMPL_LOGV("primType: %d, vertices: %p, numVertices: %d", primType, vertices, numVertices); + } + }; + + Im2DVertex* vertData = (Im2DVertex*)malloc(numVertices * sizeof(Im2DVertex)); + assert(vertData); + memcpy(vertData, verts, numVertices * sizeof(Im2DVertex)); + uint16_t* idxData = (uint16_t*)malloc(numIndices * sizeof(uint16_t)); + assert(idxData); + memcpy(idxData, idx, numIndices * sizeof(uint16_t)); + blendCallbacks.emplace_back([renderCB, vertData, idxData]() { + renderCB(vertData, idxData); + free(vertData); + free(idxData); + }); + + // std::vector vertData(numIndices); + + // for (int32 i = 0; i < numIndices; i++) { + // vertData[i] = vtx[idx[i]]; + // } + + // im2DRenderPrimitive(primType, &vertData[0], vertData.size()); } -static std::vector im3dVertices; +static Im3DVertex* im3dVertices; void im3DTransform(void *vertices, int32 numVertices, Matrix *worldMat, uint32 flags) { // UNIMPL_LOGV("start %d", numVertices); if(worldMat == nil){ @@ -1797,7 +1917,12 @@ void im3DTransform(void *vertices, int32 numVertices, Matrix *worldMat, uint32 f rw::RawMatrix::mult(&mtx, &proj, (RawMatrix*)&DCE_MAT_SCREENVIEW); // mat_load(&DCE_MAT_SCREENVIEW); // ~11 cycles. mat_load(( matrix_t*)&mtx.right); // Number of cycles: ~32. - im3dVertices.resize(numVertices); + if (im3dVertices) { + free(im3dVertices); + } + + im3dVertices = (Im3DVertex*)malloc(numVertices * sizeof(Im3DVertex)); + assert(im3dVertices); auto vtx = (Im3DVertex*)vertices; @@ -1825,49 +1950,56 @@ void im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32_t numIndices) { + if (primType == PRIMTYPELINELIST || primType == PRIMTYPEPOLYLINE) { + return; + } + pvr_poly_cxt_t cxt; + + if (current_raster) [[likely]] { + pvr_poly_cxt_txr(&cxt, + blendEnabled? PVR_LIST_TR_POLY : PVR_LIST_OP_POLY, + pvrFormatForRaster(current_raster), + current_raster->width, + current_raster->height, + pvrTexturePointer(current_raster), + PVR_FILTER_BILINEAR); + pvrTexAddress(&cxt, addressingU, addressingV); + } else pvr_poly_cxt_col(&cxt, blendEnabled? PVR_LIST_TR_POLY : PVR_LIST_OP_POLY); + + if (blendEnabled) [[likely]] { + cxt.blend.src = srcBlend; + cxt.blend.dst = dstBlend; + } + + cxt.gen.culling = cullModePvr; + cxt.depth.comparison = zFunction; + cxt.depth.write = zWrite; + + + cxt.gen.fog_type = fogFuncPvr; + + pvr_poly_hdr_t hdr; + pvr_poly_compile(&hdr, &cxt); + + assert(primType == PRIMTYPETRILIST); + auto renderCB = - [=, - current_raster = dc::current_raster, - cull_mode_pvr = dc::cullModePvr, - src_blend = dc::srcBlend, - dst_blend = dc::dstBlend, - blend_enabled = dc::blendEnabled, - z_function = dc::zFunction, - z_write = dc::zWrite, - addressingU = dc::addressingU, - addressingV = dc::addressingV, - fog_func_pvr = dc::fogFuncPvr] + [ + numIndices, + cmd = hdr.cmd, + mode1 = hdr.mode1, + mode2 = hdr.mode2, + mode3 = hdr.mode3 + ] (const void* indices, const Im3DVertex *im3dVertices) __attribute__((always_inline)) { auto pvrHeaderSubmit = [=]() __attribute__((always_inline)) { - pvr_poly_cxt_t cxt; - - if (current_raster) [[likely]] { - pvr_poly_cxt_txr(&cxt, - blendEnabled? PVR_LIST_TR_POLY : PVR_LIST_OP_POLY, - pvrFormatForRaster(current_raster), - current_raster->width, - current_raster->height, - pvrTexturePointer(current_raster), - PVR_FILTER_BILINEAR); - pvrTexAddress(&cxt, addressingU, addressingV); - } else pvr_poly_cxt_col(&cxt, blendEnabled? PVR_LIST_TR_POLY : PVR_LIST_OP_POLY); - - if (blend_enabled) [[likely]] { - cxt.blend.src = src_blend; - cxt.blend.dst = dst_blend; - } - - cxt.gen.culling = cull_mode_pvr; - cxt.depth.comparison = z_function; - cxt.depth.write = z_write; - - - cxt.gen.fog_type = fog_func_pvr; - auto* hdr = reinterpret_cast(pvr_dr_target(drState)); - pvr_poly_compile(hdr, &cxt); + hdr->cmd = cmd; + hdr->mode1 = mode1; + hdr->mode2 = mode2; + hdr->mode3 = mode3; pvr_dr_commit(hdr); }; @@ -1916,98 +2048,99 @@ void im3DRenderIndexedPrimitive(PrimitiveType primType, DCE_RenderSubmitVertex(&pvrVert, flags); }; - if(primType == PRIMTYPETRILIST) [[likely]] { - const auto *idx = reinterpret_cast(indices); - - pvrHeaderSubmit(); + const auto *idx = reinterpret_cast(indices); + + pvrHeaderSubmit(); - dcache_pref_block(idx); - for (int32_t i = 0; i < numIndices; i += 3) [[likely]]{ - uint16_t idx0 = idx[i + 0]; - auto vtx0 = im3dVertices[idx0]; - uint16_t idx1 = idx[i + 1]; - auto vtx1 = im3dVertices[idx1]; - uint16_t idx2 = idx[i + 2]; - auto vtx2 = im3dVertices[idx2]; + dcache_pref_block(idx); + for (int32_t i = 0; i < numIndices; i += 3) [[likely]]{ + uint16_t idx0 = idx[i + 0]; + auto vtx0 = im3dVertices[idx0]; + uint16_t idx1 = idx[i + 1]; + auto vtx1 = im3dVertices[idx1]; + uint16_t idx2 = idx[i + 2]; + auto vtx2 = im3dVertices[idx2]; - uint32_t vismask = 0; - if(vtx0.position.z > 1.0f) vismask |= 0b100; - vismask >>= 1; - if(vtx1.position.z > 1.0f) vismask |= 0b100; - vismask >>= 1; - if(vtx2.position.z > 1.0f) vismask |= 0b100; + uint32_t vismask = 0; + if(vtx0.position.z > 1.0f) vismask |= 0b100; + vismask >>= 1; + if(vtx1.position.z > 1.0f) vismask |= 0b100; + vismask >>= 1; + if(vtx2.position.z > 1.0f) vismask |= 0b100; - if (vismask == 0) continue; + if (vismask == 0) continue; - if (vismask == 7) { + if (vismask == 7) { + VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX); + VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX); + VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX_EOL); + } + + switch (vismask) { + case 1: // 0 visible, 1 and 2 hidden + VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx0, vtx2, PVR_CMD_VERTEX_EOL); + break; + case 2: // 0 hidden, 1 visible, 2 hidden + pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX); + VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX_EOL); + break; + case 3: // 0 and 1 visible, 2 hidden VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX); VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX_EOL); + VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx0, vtx2, PVR_CMD_VERTEX_EOL); + break; + case 4: // 0 and 1 hidden, 2 visible + VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx2, vtx0, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx2, vtx1, PVR_CMD_VERTEX_EOL); + break; + case 5: // 0 visible, 1 hidden, 2 visible + VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX); VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX_EOL); - } - - switch (vismask) { - case 1: // 0 visible, 1 and 2 hidden - VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx0, vtx2, PVR_CMD_VERTEX_EOL); - break; - case 2: // 0 hidden, 1 visible, 2 hidden - pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX); - VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX_EOL); - break; - case 3: // 0 and 1 visible, 2 hidden - VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX); - VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX_EOL); - VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx0, vtx2, PVR_CMD_VERTEX_EOL); - break; - case 4: // 0 and 1 hidden, 2 visible - VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx2, vtx0, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx2, vtx1, PVR_CMD_VERTEX_EOL); - break; - case 5: // 0 visible, 1 hidden, 2 visible - VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX); - VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX_EOL); - VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx2, vtx1, PVR_CMD_VERTEX_EOL); - break; - case 6: // 0 hidden, 1 and 2 visible - VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX); - VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX_EOL); - VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX); - pvrVertexSubmit_interp(vtx2, vtx0, PVR_CMD_VERTEX_EOL); - break; - default: - break; - } + VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx2, vtx1, PVR_CMD_VERTEX_EOL); + break; + case 6: // 0 hidden, 1 and 2 visible + VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX); + VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX_EOL); + VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX); + pvrVertexSubmit_interp(vtx2, vtx0, PVR_CMD_VERTEX_EOL); + break; + default: + break; } - } - else UNIMPL_LOGV("primType: %d", primType); + } }; + assert(im3dVertices); + auto vtxData = im3dVertices; + im3dVertices = nullptr; + + auto *idxData = (uint16_t*)malloc(numIndices * sizeof(uint16_t)); + assert(idxData); + memcpy(idxData, indices, numIndices * sizeof(uint16_t)); + if (blendEnabled) { - auto *idx = reinterpret_cast(indices); - std::vector indexBuffer(idx, idx + numIndices); - blendCallbacks.emplace_back([=, - data = std::move(indexBuffer), - vtxData = im3dVertices](){ - renderCB(&data[0], &vtxData[0]); + blendCallbacks.emplace_back([renderCB, idxData = idxData, vtxData = vtxData](){ + renderCB(idxData, vtxData); + free(idxData); + free(vtxData); }); } else { - auto *idx = reinterpret_cast(indices); - std::vector indexBuffer(idx, idx + numIndices); - opCallbacks.emplace_back([=, - data = std::move(indexBuffer), - vtxData = im3dVertices](){ - renderCB(&data[0], &vtxData[0]); + opCallbacks.emplace_back([renderCB, idxData = idxData, vtxData = vtxData](){ + renderCB(idxData, vtxData); + free(idxData); + free(vtxData); }); } @@ -2015,7 +2148,10 @@ void im3DRenderIndexedPrimitive(PrimitiveType primType, void im3DEnd(void) { // UNIMPL_LOG(); - im3dVertices.resize(0); + if (im3dVertices) { + free(im3dVertices); + } + im3dVertices = nullptr; } template @@ -3765,12 +3901,9 @@ void defaultRenderCB(ObjPipeline *pipe, Atomic *atomic) { rw::convMatrix(&world, atomic->getFrame()->getLTM()); - mat_load((matrix_t*)&cam->devView); - mat_apply((matrix_t*)&world); - mat_store((matrix_t*)&atomicContexts.back().worldView); - mat_load((matrix_t*)&cam->devProjScreen); - mat_apply((matrix_t*)&atomicContexts.back().worldView); + mat_apply((matrix_t*)&cam->devView); + mat_apply((matrix_t*)&world); mat_store((matrix_t*)&atomicContexts.back().mtx); int16_t contextId = atomicContexts.size() - 1; @@ -3907,7 +4040,6 @@ void defaultRenderCB(ObjPipeline *pipe, Atomic *atomic) { const auto& global_needsNoClip = acp->global_needsNoClip; const auto& uniformObject = acp->uniform; const auto& mtx = acp->mtx; - const auto& worldView = acp->worldView; const auto& atomic = acp->atomic; const auto& cam = acp->cam; const auto meshContext = &meshContexts[acp->meshContextOffset + n];