0
\$\begingroup\$

I am currently using a SDL_Texture *texture as a chunk in my world that is being Perlin noised onto to make terrain.

Using a 2d array of these I tile the plane. But during dynamic generation of chunks I first free the textures that are not visible, then shift the texture around in the array (sometime the whole 2d array is shifted down or up) and then generate edit the texture where I have to render new chunks.

static void editTexture(SDL_Texture *texture, int32_t scrn_x,
                        int32_t scrn_y, time_t seed, float freq) {
    uint8_t r = 0, g = 0, b = 0;
    unsigned char *pixels;
    int32_t pitch = 0, offset = 0, grid_x = 0, grid_y = 0;
    uint32_t color = 0;

    SDL_LockTexture(texture, NULL, (void **)&pixels, &pitch);
    for (int y = 0; y < CHUNK_SIZE; y += TILE_SIZE) {
        for (int x = 0; x <  CHUNK_SIZE; x += TILE_SIZE) {
            grid_x = (scrn_x + x) / TILE_SIZE;
            grid_y = (scrn_y + y) / TILE_SIZE;
            FBM(freq, grid_x, grid_y, seed, &r, &g, &b);
            color = (255 << 24) | (r << 16) | (g << 8) | b;
            // This loop fills the entire tile size square with the calculated size of the tile.
            for (int i = 0; i < TILE_SIZE; i++) {
                for (int j = 0; j < TILE_SIZE; j++) {
                    i %= TILE_SIZE;
                    j %= TILE_SIZE;
                    offset = (y + i) * pitch + (x + j) * 4;
                    *(uint32_t*)&pixels[offset] = color;
                }
            }
        }
    }
    SDL_UnlockTexture(texture);
}

SDL_Texture ***initTerrainMap(SDL_Renderer *renderer, SDL_Rect *pOrigin_rect,
                              time_t seed) {
    SDL_Texture ***terrain_map = malloc(ROW_C * sizeof(SDL_Texture **));

    if (!terrain_map) {
        fprintf(stderr, "Failed to allocate mem for terrain map.\n");
        return NULL;
    }
    *pOrigin_rect = (SDL_Rect){.x = -CHUNK_SIZE, .y = -CHUNK_SIZE, .w = CHUNK_SIZE, .h = CHUNK_SIZE};
    for (int32_t y = -1; y < ROW_C - 1; y++) {
        terrain_map[y + 1] = malloc(COL_C * sizeof(SDL_Texture *));
        if (!terrain_map[y + 1]) {
            fprintf(stderr, "Failed to allocated memory for col in the terrain map init.\n");
            freeTerrainMap(terrain_map);
            return NULL;
        }
        for (int32_t x = -1; x < COL_C - 1; x++) {
            terrain_map[y + 1][x + 1] = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING,
                                                          CHUNK_SIZE, CHUNK_SIZE);
            if (!terrain_map[y + 1][x + 1]) { continue; } // Ignoring uncreated textures rather than failing.
            editTexture(terrain_map[y + 1][x + 1], x * CHUNK_SIZE, y * CHUNK_SIZE, seed, PERLIN_TERRAIN_FREQ);
        }
    }

    return terrain_map;
}

void updateTerrainMap(SDL_Texture ***terrain_map, SDL_Rect *pOrigin_rect,
                      time_t seed) {
    uint8_t update_flags = ifGenNewTextures(pOrigin_rect);

    if (!update_flags) { return; }
    if (HAS_FLAG(update_flags, UP)) {
        pOrigin_rect->y -= CHUNK_SIZE;
        for (int32_t i = 0; i < COL_C; i++) {
            if (terrain_map[ROW_C - 1][i]) { SDL_DestroyTexture(terrain_map[ROW_C - 1][i]); }
        }
        for (int32_t y = ROW_C - 2; y >= 0; y--) {
            for (int32_t x = 0; x < COL_C; x++) {
                printf("%d %d\n", y, x);
                terrain_map[y + 1][x] = terrain_map[y][x];
            }
        }
        //memmove(terrain_map[1], terrain_map[0], (ROW_C - 1) * sizeof(SDL_Texture **));
        for (int32_t i = 0; i < COL_C; i++) {
            if (terrain_map[0][i]) { editTexture(terrain_map[0][i], i * CHUNK_SIZE, pOrigin_rect->y,
                                                 seed, PERLIN_TERRAIN_FREQ); }
        }
    } else if (HAS_FLAG(update_flags, DOWN)) {
        // TODO
    }
    if (HAS_FLAG(update_flags, RIGHT)) {
        // TODO
    } else if (HAS_FLAG(update_flags, LEFT)) {
        // TODO
    }
}

In the editTexture function, the offset calculation goes out of bound for some reason when I start moving up.

Offset out of bounds: 828
INFO: Error: Offset out of bounds: 832
INFO: Error: Offset out of bounds: 836
INFO: Error: Offset out of bounds: 840
INFO: Error: Offset out of bounds: 844
INFO: Error: Offset out of bounds: 848
INFO: Error: Offset out of bounds: 852
INFO: Error: Offset out of bounds: 856
INFO: Error: Offset out of bounds: 860
INFO: Error: Offset out of bounds: 864
INFO: Error: Offset out of bounds: 868
INFO: Error: Offset out of bounds: 872
INFO: Error: Offset out of bounds: 876
INFO: Error: Offset out of bounds: 880
INFO: Error: Offset out of bounds: 884
INFO: Error: Offset out of bounds: 888
INFO: Error: Offset out of bounds: 892
INFO: Error: Offset out of bounds: 896
INFO: Error: Offset out of bounds: 900
INFO: Error: Offset out of bounds: 904
INFO: Error: Offset out of bounds: 908
INFO: Error: Offset out of bounds: 912
INFO: Error: Offset out of bounds: 916
INFO: Error: Offset out of bounds: 920
INFO: Error: Offset out of bounds: 924
INFO: Error: Offset out of bounds: 928
INFO: Error: Offset out of bounds: 932
INFO: Error: Offset out of bounds: 936
INFO: Error: Offset out of bounds: 940
INFO: Error: Offset out of bounds: 944
INFO: Error: Offset out of bounds: 948
INFO: Error: Offset out of bounds: 952
INFO: Error: Offset out of bounds: 956
INFO: Error: Offset out of bounds: 960
INFO: Error: Offset out of bounds: 964
INFO: Error: Offset out of bounds: 968
INFO: Error: Offset out of bounds: 972
INFO: Error: Offset out of bounds: 976
INFO: Error: Offset out of bounds: 980
INFO: Error: Offset out of bounds: 984
INFO: Error: Offset out of bounds: 988
INFO: Error: Offset out of bounds: 992
INFO: Error: Offset out of bounds: 996
INFO: Error: Offset out of bounds: 1000
INFO: Error: Offset out of bounds: 1004
INFO: Error: Offset out of bounds: 1008
INFO: Error: Offset out of bounds: 1012
INFO: Error: Offset out of bounds: 1016
INFO: Error: Offset out of bounds: 1020
INFO: Error: Offset out of bounds: 1024
INFO: Error: Offset out of bounds: 1028
INFO: Error: Offset out of bounds: 1032
INFO: Error: Offset out of bounds: 1036
INFO: Error: Offset out of bounds: 1040
INFO: Error: Offset out of bounds: 1044
INFO: Error: Offset out of bounds: 1048
INFO: Error: Offset out of bounds: 1052
INFO: Error: Offset out of bounds: 1056
INFO: Error: Offset out of bounds: 1060
INFO: Error: Offset out of bounds: 1064
INFO: Error: Offset out of bounds: 1068
INFO: Error: Offset out of bounds: 1072
INFO: Error: Offset out of bounds: 1076
INFO: Error: Offset out of bounds: 1080
INFO: Error: Offset out of bounds: 1084
INFO: Error: Offset out of bounds: 1088
INFO: Error: Offset out of bounds: 1092
INFO: Error: Offset out of bounds: 1096
INFO: Error: Offset out of bounds: 1100
INFO: Error: Offset out of bounds: 1104
INFO: Error: Offset out of bounds: 1108
INFO: Error: Offset out of bounds: 1112
INFO: Error: Offset out of bounds: 1116
INFO: Error: Offset out of bounds: 1120
INFO: Error: Offset out of bounds: 1124
INFO: Error: Offset out of bounds: 1128
INFO: Error: Offset out of bounds: 1132
INFO: Error: Offset out of bounds: 1136
INFO: Error: Offset out of bounds: 1140
INFO: Error: Offset out of bounds: 1144
INFO: Error: Offset out of bounds: 1148
INFO: Error: Offset out of bounds: 1152
INFO: Error: Offset out of bounds: 1156
INFO: Error: Offset out of bounds: 1160
INFO: Error: Offset out of bounds: 1164
INFO: Error: Offset out of bounds: 1168
INFO: Error: Offset out of bounds: 1172
INFO: Error: Offset out of bounds: 1176
INFO: Error: Offset out of bounds: 1180
INFO: Error: Offset out of bounds: 1184
INFO: Error: Offset out of bounds: 1188
INFO: Error: Offset out of bounds: 1192
INFO: Error: Offset out of bounds: 1196
INFO: Error: Offset out of bounds: 1200
INFO: Error: Offset out of bounds: 1204
INFO: Error: Offset out of bounds: 1208
INFO: Error: Offset out of bounds: 1212
INFO: Error: Offset out of bounds: 1216
INFO: Error: Offset out of bounds: 1220
INFO: Error: Offset out of bounds: 1224
INFO: Error: Offset out of bounds: 1228
INFO: Error: Offset out of bounds: 1232
INFO: Error: Offset out of bounds: 1236
INFO: Error: Offset out of bounds: 1240
INFO: Error: Offset out of bounds: 1244
INFO: Error: Offset out of bounds: 1248
INFO: Error: Offset out of bounds: 1252
INFO: Error: Offset out of bounds: 1256
INFO: Error: Offset out of bounds: 1260
INFO: Error: Offset out of bounds: 1264
INFO: Error: Offset out of bounds: 1268
INFO: Error: Offset out of bounds: 1272
INFO: Error: Offset out of bounds: 1276
INFO: Error: Offset out of bounds: 1280
INFO: Error: Offset out of bounds: 1284
INFO: Error: Offset out of bounds: 1288
INFO: Error: Offset out of bounds: 1292
INFO: Error: Offset out of bounds: 1296
INFO: Error: Offset out of bounds: 1300
INFO: Error: Offset out of bounds: 1304
INFO: Error: Offset out of bounds: 1308
INFO: Error: Offset out of bounds: 1312
INFO: Error: Offset out of bounds: 1316
INFO: Error: Offset out of bounds: 1320
INFO: Error: Offset out of bounds: 1324
INFO: Error: Offset out of bounds: 1328
INFO: Error: Offset out of bounds: 1332
INFO: Error: Offset out of bounds: 1336
INFO: Error: Offset out of bounds: 1340
INFO: Error: Offset out of bounds: 1344
INFO: Error: Offset out of bounds: 1348
INFO: Error: Offset out of bounds: 1352
INFO: Error: Offset out of bounds: 1356
INFO: Error: Offset out of bounds: 1360
INFO: Error: Offset out of bounds: 1364
INFO: Error: Offset out of bounds: 1368
INFO: Error: Offset out of bounds: 1372
INFO: Error: Offset out of bounds: 1376
INFO: Error: Offset out of bounds: 1380
INFO: Error: Offset out of bounds: 1384

This is the log for the error, The error starts from 0 then 4 then 8 all the way to 1996.

I used TILE_SIZE = 1, CHUNK_SIZE = 500 for this run.

Also, the creation, shifting of elements in array and editing them is an inefficient process as when editing texture while moving up the FPS drops to about 3.

Is there any way to improve this, i.e. some other method that would work better for my use case?

\$\endgroup\$
1
  • \$\begingroup\$ You might be interested in the "clipmap" strategy described here, which means you never need to shift existing tiles around in your array at all: gamedev.stackexchange.com/a/177398/39518 \$\endgroup\$ Commented Jan 29 at 14:11

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.