Lazy load 1D atlases in LOWMEM builds

This commit is contained in:
UnknownShadow200 2024-06-17 20:39:03 +10:00
parent e32b5572a0
commit a8022a70b3
10 changed files with 85 additions and 31 deletions

View File

@ -156,7 +156,7 @@ void IsometricDrawer_Render(int count, int offset, int* state) {
if (state[i] == curIdx) continue;
/* Flush previous batch */
Gfx_BindTexture(Atlas1D.TexIds[curIdx]);
Atlas1D_Bind(curIdx);
Gfx_DrawVb_IndexedTris_Range(batchLen, batchBeg);
/* Reset for next batch */
@ -165,6 +165,6 @@ void IsometricDrawer_Render(int count, int offset, int* state) {
batchLen = 0;
}
Gfx_BindTexture(Atlas1D.TexIds[curIdx]);
Atlas1D_Bind(curIdx);
Gfx_DrawVb_IndexedTris_Range(batchLen, batchBeg);
}

View File

@ -195,10 +195,11 @@ void MapRenderer_RenderNormal(float delta) {
Gfx_SetAlphaTest(true);
Gfx_EnableMipmaps();
for (batch = 0; batch < MapRenderer_1DUsedCount; batch++) {
for (batch = 0; batch < MapRenderer_1DUsedCount; batch++)
{
if (normPartsCount[batch] <= 0) continue;
if (hasNormParts[batch] || checkNormParts[batch]) {
Gfx_BindTexture(Atlas1D.TexIds[batch]);
Atlas1D_Bind(batch);
RenderNormalBatch(batch);
checkNormParts[batch] = false;
}
@ -270,7 +271,8 @@ void MapRenderer_RenderTranslucent(float delta) {
Gfx_SetAlphaBlending(false);
Gfx_DepthOnlyRendering(true);
for (batch = 0; batch < MapRenderer_1DUsedCount; batch++) {
for (batch = 0; batch < MapRenderer_1DUsedCount; batch++)
{
if (tranPartsCount[batch] <= 0) continue;
if (hasTranParts[batch] || checkTranParts[batch]) {
RenderTranslucentBatch(batch);
@ -285,10 +287,12 @@ void MapRenderer_RenderTranslucent(float delta) {
Gfx_SetDepthWrite(false); /* already calculated depth values in depth pass */
Gfx_EnableMipmaps();
for (batch = 0; batch < MapRenderer_1DUsedCount; batch++) {
for (batch = 0; batch < MapRenderer_1DUsedCount; batch++)
{
if (tranPartsCount[batch] <= 0) continue;
if (!hasTranParts[batch]) continue;
Gfx_BindTexture(Atlas1D.TexIds[batch]);
Atlas1D_Bind(batch);
RenderTranslucentBatch(batch);
}
Gfx_DisableMipmaps();

View File

@ -3708,8 +3708,9 @@ static void TexIdsOverlay_BuildMesh(void* screen) {
static int TexIdsOverlay_RenderTerrain(struct TexIdsOverlay* s, int offset) {
int i, count = Atlas1D.TilesPerAtlas * 4;
for (i = 0; i < Atlas1D.Count; i++) {
Gfx_BindTexture(Atlas1D.TexIds[i]);
for (i = 0; i < Atlas1D.Count; i++)
{
Atlas1D_Bind(i);
Gfx_DrawVb_IndexedTris_Range(count, offset);
offset += count;

View File

@ -2190,11 +2190,12 @@ static void BlockModel_DrawParts(void) {
int lastTexIndex, i, offset = 0, count = 0;
lastTexIndex = bModel_texIndices[0];
for (i = 0; i < bModel_index; i++, count += 4) {
for (i = 0; i < bModel_index; i++, count += 4)
{
if (bModel_texIndices[i] == lastTexIndex) continue;
/* Different 1D flush texture, flush current vertices */
Gfx_BindTexture(Atlas1D.TexIds[lastTexIndex]);
Atlas1D_Bind(lastTexIndex);
Gfx_DrawVb_IndexedTris_Range(count, offset);
lastTexIndex = bModel_texIndices[i];
@ -2204,7 +2205,7 @@ static void BlockModel_DrawParts(void) {
/* Leftover vertices */
if (!count) return;
Gfx_BindTexture(Atlas1D.TexIds[lastTexIndex]);
Atlas1D_Bind(lastTexIndex);
Gfx_DrawVb_IndexedTris_Range(count, offset);
}

View File

@ -280,7 +280,8 @@ static void Terrain_Render(float t) {
data = (struct VertexTextured*)Gfx_LockDynamicVb(particles_VB,
VERTEX_FORMAT_TEXTURED, terrain_count * 4);
Terrain_Update1DCounts();
for (i = 0; i < terrain_count; i++) {
for (i = 0; i < terrain_count; i++)
{
index = Atlas1D_Index(terrain_particles[i].texLoc);
ptr = data + terrain_1DIndices[index];
@ -289,18 +290,20 @@ static void Terrain_Render(float t) {
}
Gfx_UnlockDynamicVb(particles_VB);
for (i = 0; i < Atlas1D.Count; i++) {
for (i = 0; i < Atlas1D.Count; i++)
{
int partCount = terrain_1DCount[i];
if (!partCount) continue;
Gfx_BindTexture(Atlas1D.TexIds[i]);
Atlas1D_Bind(i);
Gfx_DrawVb_IndexedTris_Range(partCount, offset);
offset += partCount;
}
}
static void Terrain_RemoveAt(int i) {
for (; i < terrain_count - 1; i++) {
for (; i < terrain_count - 1; i++)
{
terrain_particles[i] = terrain_particles[i + 1];
}
terrain_count--;
@ -308,7 +311,8 @@ static void Terrain_RemoveAt(int i) {
static void Terrain_Tick(float delta) {
int i;
for (i = 0; i < terrain_count; i++) {
for (i = 0; i < terrain_count; i++)
{
if (TerrainParticle_Tick(&terrain_particles[i], delta)) {
Terrain_RemoveAt(i); i--;
}

View File

@ -263,7 +263,7 @@ static cc_result File_Do(cc_file* file, const char* path, int mode) {
// Read/Write VMU for options.txt if no SD card, since that file is critical
cc_string raw = String_FromReadonly(path);
if (err && String_CaselessEqualsConst(raw, "/cd/options.txt")) {
if (err && String_CaselessEqualsConst(&raw, "/cd/options.txt")) {
return VMUFile_Do(file, mode);
}
return err;

View File

@ -63,6 +63,7 @@ void Platform_Log(const char* msg, int len) {
Mem_Copy(tmp, msg, len); tmp[len] = '\0';
_print("%s", tmp);
#define PS2_DEBUG
#ifdef PS2_DEBUG
volatile char* dst = (char*)0x1000F180;
@ -689,7 +690,7 @@ void Platform_Init(void) {
// Create root directory
cc_filepath* root = FILEPATH_RAW("mass:/ClassiCube");
int res = Diectory_Create(root);
int res = Directory_Create(root);
Platform_Log1("ROOT CREATE %i", &res);
}

View File

@ -1927,7 +1927,7 @@ static void LoadingScreen_Render(void* screen, float delta) {
offset = 0;
if (s->rows) {
loc = Block_Tex(BLOCK_DIRT, FACE_YMAX);
Gfx_BindTexture(Atlas1D.TexIds[Atlas1D_Index(loc)]);
Atlas1D_Bind(Atlas1D_Index(loc));
Gfx_DrawVb_IndexedTris(s->rows * 4);
offset = s->rows * 4;
}

View File

@ -79,29 +79,71 @@ TextureRec Atlas1D_TexRec(TextureLoc texLoc, int uCount, int* index) {
return rec;
}
static void Atlas1D_Load(int index, struct Bitmap* atlas1D) {
int tileSize = Atlas2D.TileSize;
int tilesPerAtlas = Atlas1D.TilesPerAtlas;
int y, tile = index * tilesPerAtlas;
int atlasX, atlasY;
for (y = 0; y < tilesPerAtlas; y++, tile++)
{
atlasX = Atlas2D_TileX(tile) * tileSize;
atlasY = Atlas2D_TileY(tile) * tileSize;
Bitmap_UNSAFE_CopyBlock(atlasX, atlasY, 0, y * tileSize,
&Atlas2D.Bmp, atlas1D, tileSize);
}
Gfx_RecreateTexture(&Atlas1D.TexIds[index], atlas1D, TEXTURE_FLAG_MANAGED | TEXTURE_FLAG_DYNAMIC, Gfx.Mipmaps);
}
/* TODO: always do this? */
#ifdef CC_BUILD_LOWMEM
static void Atlas1D_LoadBlock(int index) {
int tileSize = Atlas2D.TileSize;
int tilesPerAtlas = Atlas1D.TilesPerAtlas;
struct Bitmap atlas1D;
Platform_Log2("Lazy load atlas #%i (%i per bmp)", &index, &tilesPerAtlas);
Bitmap_Allocate(&atlas1D, tileSize, tilesPerAtlas * tileSize);
Atlas1D_Load(index, &atlas1D);
Mem_Free(atlas1D.scan0);
}
void Atlas1D_Bind(int index) {
if (index < Atlas1D.Count && !Atlas1D.TexIds[index])
Atlas1D_LoadBlock(index);
Gfx_BindTexture(Atlas1D.TexIds[index]);
}
static void Atlas_Convert2DTo1D(void) {
int tilesPerAtlas = Atlas1D.TilesPerAtlas;
int atlasesCount = Atlas1D.Count;
Platform_Log2("Terrain atlas: %i bmps, %i per bmp", &atlasesCount, &tilesPerAtlas);
}
#else
void Atlas1D_Bind(int index) {
Gfx_BindTexture(Atlas1D.TexIds[index]);
}
static void Atlas_Convert2DTo1D(void) {
int tileSize = Atlas2D.TileSize;
int tilesPerAtlas = Atlas1D.TilesPerAtlas;
int atlasesCount = Atlas1D.Count;
struct Bitmap atlas1D;
int atlasX, atlasY;
int tile = 0, i, y;
int tile = 0, i;
Platform_Log2("Loaded terrain atlas: %i bmps, %i per bmp", &atlasesCount, &tilesPerAtlas);
Bitmap_Allocate(&atlas1D, tileSize, tilesPerAtlas * tileSize);
for (i = 0; i < atlasesCount; i++) {
for (y = 0; y < tilesPerAtlas; y++, tile++) {
atlasX = Atlas2D_TileX(tile) * tileSize;
atlasY = Atlas2D_TileY(tile) * tileSize;
Bitmap_UNSAFE_CopyBlock(atlasX, atlasY, 0, y * tileSize,
&Atlas2D.Bmp, &atlas1D, tileSize);
}
Gfx_RecreateTexture(&Atlas1D.TexIds[i], &atlas1D, TEXTURE_FLAG_MANAGED | TEXTURE_FLAG_DYNAMIC, Gfx.Mipmaps);
for (i = 0; i < atlasesCount; i++)
{
Atlas1D_Load(i, &atlas1D);
}
Mem_Free(atlas1D.scan0);
}
#endif
static void Atlas_Update1D(void) {
int maxAtlasHeight, maxTilesPerAtlas, maxTiles;

View File

@ -73,6 +73,7 @@ cc_bool Atlas_TryChange(struct Bitmap* bmp);
/* That is, returns U1/U2/V1/V2 coords that make up the tile in a 1D atlas. */
/* index is set to the index of the 1D atlas that the tile is in. */
TextureRec Atlas1D_TexRec(TextureLoc texLoc, int uCount, int* index);
void Atlas1D_Bind(int index);
/* Whether the given URL is in list of accepted URLs. */
cc_bool TextureCache_HasAccepted(const cc_string* url);