add fullscreen block overlay

This commit is contained in:
MihailRis 2024-10-31 18:22:55 +03:00
parent 9c3d4af907
commit b191f2ba9d
8 changed files with 74 additions and 19 deletions

View File

@ -1,5 +1,6 @@
{ {
"texture": "water", "texture": "water",
"overlay-texture": "water",
"draw-group": 3, "draw-group": 3,
"light-passing": true, "light-passing": true,
"sky-light-passing": false, "sky-light-passing": false,

View File

@ -326,6 +326,7 @@ void ContentLoader::loadBlock(
root.at("ui-layout").get(def.uiLayout); root.at("ui-layout").get(def.uiLayout);
root.at("inventory-size").get(def.inventorySize); root.at("inventory-size").get(def.inventorySize);
root.at("tick-interval").get(def.tickInterval); root.at("tick-interval").get(def.tickInterval);
root.at("overlay-texture").get(def.overlayTexture);
if (root.has("fields")) { if (root.has("fields")) {
def.dataStruct = std::make_unique<StructLayout>(); def.dataStruct = std::make_unique<StructLayout>();

View File

@ -58,11 +58,13 @@ Skybox::Skybox(uint size, Shader* shader)
Skybox::~Skybox() = default; Skybox::~Skybox() = default;
void Skybox::drawBackground(Camera* camera, Assets* assets, int width, int height) { void Skybox::drawBackground(
auto backShader = assets->get<Shader>("background"); const Camera& camera, const Assets& assets, int width, int height
) {
auto backShader = assets.get<Shader>("background");
backShader->use(); backShader->use();
backShader->uniformMatrix("u_view", camera->getView(false)); backShader->uniformMatrix("u_view", camera.getView(false));
backShader->uniform1f("u_zoom", camera->zoom*camera->getFov()/(M_PI*0.5f)); backShader->uniform1f("u_zoom", camera.zoom*camera.getFov()/(M_PI*0.5f));
backShader->uniform1f("u_ar", float(width)/float(height)); backShader->uniform1f("u_ar", float(width)/float(height));
backShader->uniform1i("u_cubemap", 1); backShader->uniform1i("u_cubemap", 1);
bind(); bind();
@ -93,8 +95,8 @@ void Skybox::drawStars(float angle, float opacity) {
void Skybox::draw( void Skybox::draw(
const DrawContext& pctx, const DrawContext& pctx,
Camera* camera, const Camera& camera,
Assets* assets, const Assets& assets,
float daytime, float daytime,
float fog) float fog)
{ {
@ -107,9 +109,9 @@ void Skybox::draw(
DrawContext ctx = pctx.sub(); DrawContext ctx = pctx.sub();
ctx.setBlendMode(BlendMode::addition); ctx.setBlendMode(BlendMode::addition);
auto p_shader = assets->get<Shader>("ui3d"); auto p_shader = assets.get<Shader>("ui3d");
p_shader->use(); p_shader->use();
p_shader->uniformMatrix("u_projview", camera->getProjView(false)); p_shader->uniformMatrix("u_projview", camera.getProjView(false));
p_shader->uniformMatrix("u_apply", glm::mat4(1.0f)); p_shader->uniformMatrix("u_apply", glm::mat4(1.0f));
batch3d->begin(); batch3d->begin();
@ -117,7 +119,7 @@ void Skybox::draw(
float opacity = glm::pow(1.0f-fog, 7.0f); float opacity = glm::pow(1.0f-fog, 7.0f);
for (auto& sprite : sprites) { for (auto& sprite : sprites) {
batch3d->texture(assets->get<Texture>(sprite.texture)); batch3d->texture(assets.get<Texture>(sprite.texture));
float sangle = daytime * float(M_PI)*2.0 + sprite.phase; float sangle = daytime * float(M_PI)*2.0 + sprite.phase;
float distance = sprite.distance; float distance = sprite.distance;

View File

@ -35,15 +35,17 @@ class Skybox {
std::vector<skysprite> sprites; std::vector<skysprite> sprites;
void drawStars(float angle, float opacity); void drawStars(float angle, float opacity);
void drawBackground(Camera* camera, Assets* assets, int width, int height); void drawBackground(
const Camera& camera, const Assets& assets, int width, int height
);
public: public:
Skybox(uint size, Shader* shader); Skybox(uint size, Shader* shader);
~Skybox(); ~Skybox();
void draw( void draw(
const DrawContext& pctx, const DrawContext& pctx,
Camera* camera, const Camera& camera,
Assets* assets, const Assets& assets,
float daytime, float daytime,
float fog float fog
); );

View File

@ -410,8 +410,8 @@ void WorldRenderer::draw(
skybox->refresh(pctx, worldInfo.daytime, 1.0f + worldInfo.fog * 2.0f, 4); skybox->refresh(pctx, worldInfo.daytime, 1.0f + worldInfo.fog * 2.0f, 4);
auto assets = engine->getAssets(); const auto& assets = *engine->getAssets();
auto linesShader = assets->get<Shader>("lines"); auto linesShader = assets.get<Shader>("lines");
// World render scope with diegetic HUD included // World render scope with diegetic HUD included
{ {
@ -421,7 +421,7 @@ void WorldRenderer::draw(
Window::clearDepth(); Window::clearDepth();
// Drawing background sky plane // Drawing background sky plane
skybox->draw(pctx, &camera, assets, worldInfo.daytime, worldInfo.fog); skybox->draw(pctx, camera, assets, worldInfo.daytime, worldInfo.fog);
// Actually world render with depth buffer on // Actually world render with depth buffer on
{ {
@ -432,23 +432,66 @@ void WorldRenderer::draw(
// Debug lines // Debug lines
if (hudVisible) { if (hudVisible) {
renderLines(camera, linesShader, ctx); renderLines(camera, linesShader, ctx);
renderHands(camera, *assets); renderHands(camera, assets);
} }
} }
if (hudVisible && player->debug) { if (hudVisible && player->debug) {
renderDebugLines(wctx, camera, linesShader); renderDebugLines(wctx, camera, linesShader);
} }
renderBlockOverlay(wctx, assets);
} }
// Rendering fullscreen quad with // Rendering fullscreen quad with
auto screenShader = assets->get<Shader>("screen"); auto screenShader = assets.get<Shader>("screen");
screenShader->use(); screenShader->use();
screenShader->uniform1f("u_timer", timer); screenShader->uniform1f("u_timer", timer);
screenShader->uniform1f("u_dayTime", worldInfo.daytime); screenShader->uniform1f("u_dayTime", worldInfo.daytime);
postProcessing->render(pctx, screenShader); postProcessing->render(pctx, screenShader);
} }
void WorldRenderer::renderBlockOverlay(const DrawContext& wctx, const Assets& assets) {
int x = std::floor(player->camera->position.x);
int y = std::floor(player->camera->position.y);
int z = std::floor(player->camera->position.z);
auto block = level->chunks->get(x, y, z);
if (block && block->id) {
const auto& def =
level->content->getIndices()->blocks.require(block->id);
if (def.overlayTexture.empty()) {
return;
}
DrawContext ctx = wctx.sub();
ctx.setDepthTest(false);
ctx.setCullFace(false);
auto& shader = assets.require<Shader>("ui3d");
auto& atlas = assets.require<Atlas>("blocks");
shader.use();
batch3d->begin();
shader.uniformMatrix("u_projview", glm::mat4(1.0f));
shader.uniformMatrix("u_apply", glm::mat4(1.0f));
auto light = level->chunks->getLight(x, y, z);
float s = Lightmap::extract(light, 3) / 15.0f;
glm::vec4 tint(
glm::min(1.0f, Lightmap::extract(light, 0) / 15.0f + s),
glm::min(1.0f, Lightmap::extract(light, 1) / 15.0f + s),
glm::min(1.0f, Lightmap::extract(light, 2) / 15.0f + s),
1.0f
);
batch3d->texture(atlas.getTexture());
batch3d->sprite(
glm::vec3(),
glm::vec3(0, 1, 0),
glm::vec3(1, 0, 0),
2,
2,
atlas.get(def.overlayTexture),
tint
);
batch3d->flush();
}
}
void WorldRenderer::drawBorders( void WorldRenderer::drawBorders(
int sx, int sy, int sz, int ex, int ey, int ez int sx, int sy, int sz, int ex, int ey, int ez
) { ) {

View File

@ -67,6 +67,8 @@ class WorldRenderer {
Shader* linesShader Shader* linesShader
); );
void renderBlockOverlay(const DrawContext& context, const Assets& assets);
void setupWorldShader( void setupWorldShader(
Shader* shader, Shader* shader,
const Camera& camera, const Camera& camera,

View File

@ -141,6 +141,7 @@ void Block::cloneTo(Block& dst) {
dst.uiLayout = uiLayout; dst.uiLayout = uiLayout;
dst.inventorySize = inventorySize; dst.inventorySize = inventorySize;
dst.tickInterval = tickInterval; dst.tickInterval = tickInterval;
dst.overlayTexture = overlayTexture;
} }
static std::set<std::string, std::less<>> RESERVED_BLOCK_FIELDS { static std::set<std::string, std::less<>> RESERVED_BLOCK_FIELDS {

View File

@ -185,6 +185,9 @@ public:
/// @brief Block will be used instead of this if generated on surface /// @brief Block will be used instead of this if generated on surface
std::string surfaceReplacement = name; std::string surfaceReplacement = name;
/// @brief Texture will be shown on screen if camera is inside of the block
std::string overlayTexture;
/// @brief Default block layout will be used by hud.open_block(...) /// @brief Default block layout will be used by hud.open_block(...)
std::string uiLayout = name; std::string uiLayout = name;