I need assistance with strategies for optimizing my rendering code.
Based mostly on perf, it takes an amazing period of time to run, more often than not is spent on the sunshine rendering and never as a lot, however nonetheless fairly a big portion is spent on liquids.
I actually have no idea what to do. The sunshine viewport is 2 occasions smaller than the dimensions of the window and something much less appears to be like uneven. As might be seen within the code, I do not use chunks and simply replace every part within the display screen boundaries. I eliminated some pointless code within the instance.
// Render capabilities
void Map::renderLight(const Camera2D &digital camera, Texture2D &texture, float x, float y, const Vector2 &dimension, const Shade &shade) const {
drawTexture(texture, {(((x + 0.5f - digital camera.goal.x) * digital camera.zoom) + digital camera.offset.x) / 2.0f, (((y + 0.5f - digital camera.goal.y) * digital camera.zoom) + digital camera.offset.y) / 2.0f}, dimension, 0, shade);
}
void Map::render(const std::vector<DroppedItem> &droppedItems, const Participant &participant, float accumulator, const Rectangle &cameraBounds, const Camera2D &digital camera) const {
// Render background partitions
for (int y = cameraBounds.y; y <= cameraBounds.peak; ++y) {
for (int x = cameraBounds.x; x <= cameraBounds.width; ++x) {
const Block &wall = partitions[y][x];
if ((wall.sort & BlockType::empty) || !(blocks[y][x].sort & BlockType::clear)) {
proceed;
}
int oldX = x;
whereas (x <= cameraBounds.width && partitions[y][x].id == wall.id && (blocks[y][x].sort & BlockType::clear)) {
x += 1;
}
drawTextureBlock(*wall.texture, {(float)oldX, (float)y, float(x - oldX), 1}, wallTint);
x -= 1;
}
}
// Render blocks
for (int y = cameraBounds.y; y <= cameraBounds.peak; ++y) {
for (int x = cameraBounds.x; x <= cameraBounds.width; ++x) {
const Block &block = blocks[y][x];
if (block.sort & BlockType::empty) {
proceed;
}
// Render torches
else if (block.sort & BlockType::torch) {
constexpr static float torchLightOffsetsY[] = {-1.0f, -1.0f * (5.0f / 8.0f), -0.75f, -0.75f, -1.0f * (5.0f / 8.0f)};
float textureSize = block.texture->peak / 2.0f;
DrawTexturePro(*block.texture, {textureSize * block.value2, 0, textureSize, textureSize}, {(float)x, (float)y, 1, 1}, {0, 0}, 0, WHITE);
DrawTexturePro(*block.texture, {textureSize * block.worth, textureSize, textureSize, textureSize}, {(float)x, (float)y + torchLightOffsetsY[block.value2], 1, 1}, {0, 0}, 0, WHITE);
proceed;
}
// Render common blocks
int oldX = x;
whereas (x <= cameraBounds.width && blocks[y][x].id == block.id) {
x += 1;
}
drawTextureBlock(*block.texture, {(float)oldX, (float)y, float(x - oldX), 1});
x -= 1;
}
}
// Render fluids
Shader &waterShader = getShader("water");
float time = GetTime();
SetShaderValue(waterShader, timeShaderLocation, &time, SHADER_UNIFORM_FLOAT);
// Render fluids
BeginShaderMode(waterShader);
for (int y = cameraBounds.y; y <= cameraBounds.peak; ++y) {
for (int x = cameraBounds.x; x <= cameraBounds.width; ++x) {
if (!isLiquid(x, y)) {
proceed;
}
float peak = (float)getLiquidHeight(x, y) / (float)maxLiquidLayers;
Shade liquidFlags;
liquidFlags.r = (is(x, y - 1, BlockType::strong) && !is(x, y - 1, BlockType::platform) ? 255 : 0);
liquidFlags.g = (!isLiquidAtAll(x, y + 1) || !isLiquidOfType(x, y + 1, liquidTypes[y][x]) ? 255 : 0);
drawFluidBlock(getLiquidTexture(x, y), {(float)x, (float)y + (1 - peak), 1, peak}, Fade(liquidFlags, peak));
}
}
EndShaderMode();
// Render lights
BeginTextureMode(lightmap);
ClearBackground(BLACK);
BeginBlendMode(BLEND_ADDITIVE);
int lightBoundsMinX = std::max<int>(0, cameraBounds.x - 8);
int lightBoundsMinY = std::max<int>(0, cameraBounds.y - 8);
int lightBoundsMaxX = std::min<int>(sizeX - 1, cameraBounds.width + 8);
int lightBoundsMaxY = std::min<int>(sizeY - 1, cameraBounds.peak + 8);
Shade airLightColor = getLightBasedOnTime();
Shade waterLightColor = Fade(airLightColor, 0.1f);
// const perform hack
static float counter = 0.0f;
counter += GetFrameTime();
float sizeOffset = std::sin(counter * 1.5f) * digital camera.zoom * 0.4f;
float positionOffset = std::cos(counter * 0.8f) * digital camera.zoom * 0.0075f;
Vector2 lightSize = {3.5f * digital camera.zoom, 3.5f * digital camera.zoom};
Vector2 lightLargeSize = {lightSize.x + lightSize.x, lightSize.y + lightSize.y};
Vector2 lightHugeSize = {lightLargeSize.x + lightSize.x, lightLargeSize.y + lightSize.y};
Vector2 liquidSize = {lightSize.x + sizeOffset, lightSize.y + sizeOffset};
Texture2D &lightHugeTexture = getTexture("lightsource_6x");
Texture2D &lightLargeTexture = getTexture("lightsource_4x");
Texture2D &lightTexture = getTexture("lightsource_2x");
for (int y = lightBoundsMinY; y <= lightBoundsMaxY; ++y) {
for (int x = lightBoundsMinX; x <= lightBoundsMaxX; ++x) {
BlockType sort = blocks[y][x].sort;
if (!(sort & BlockType::lightsource) && !(sort & BlockType::clear)) {
proceed;
}
// Direct gentle sources, ones who don't require the wall behind to be clear
if (isLiquidAtAll(x, y) && isLiquidOfType(x, y, LiquidType::lava)) {
if (isLiquid(x, y)) {
renderLight(digital camera, lightTexture, x + positionOffset, y + positionOffset, liquidSize, {255, 125, 0, 255});
}
proceed;
} else if (sort & BlockType::torch) {
renderLight(digital camera, lightHugeTexture, x + positionOffset, y + positionOffset, lightHugeSize, {255, 200, 160, 255}); // Gentle orange
} else if (sort & BlockType::lightsource) {
renderLight(digital camera, lightLargeTexture, x, y, lightLargeSize, {255, 255, 0, 255});
}
if (!(partitions[y][x].sort & BlockType::clear)) {
proceed;
}
// Oblique gentle sources, these require to background to be empty
if (isLiquid(x, y)) {
renderLight(digital camera, lightTexture, x, y, lightSize, waterLightColor);
} else {
renderLight(digital camera, lightTexture, x, y, lightSize, airLightColor);
}
}
}
EndBlendMode();
EndTextureMode();
BeginBlendMode(BLEND_MULTIPLIED);
DrawTexturePro(lightmap.texture, {0, 0, (float)lightmap.texture.width, -(float)lightmap.texture.peak}, {0, 0, (float)GetScreenWidth(), (float)GetScreenHeight()}, {0, 0}, 0, WHITE);
EndBlendMode();
BeginMode2D(digital camera); // EndTextureMode disables it for some purpose
}
First, partitions and blocks get rendered. Comparable blocks are grouped on the X axis. After that liquids are rendered, a distinct container is used for them in order that merely will get iterated. The water shader makes use of the draw shade as two attributes – is prime block strong and is backside block strong. Lastly, I render the lights, once more iterating by the map. I render them to a viewport two occasions smaller than the display screen dimension in additive mix mode and at last draw the viewport in multiplicative mix mode.



