mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-06 11:31:49 +00:00
Merge branch 'MihailRis:main' into main
This commit is contained in:
commit
7536ac2736
130 changed files with 2932 additions and 1028 deletions
|
|
@ -538,7 +538,6 @@ void BlocksRenderer::render(
|
|||
break;
|
||||
}
|
||||
case BlockModelType::CUSTOM: {
|
||||
if (!denseRender)
|
||||
blockCustomModel(
|
||||
{x, y, z},
|
||||
def,
|
||||
|
|
|
|||
|
|
@ -34,4 +34,7 @@ void HandsRenderer::render(const Camera& camera) {
|
|||
glm::vec3(),
|
||||
glm::vec3(1.0f)
|
||||
);
|
||||
|
||||
modelBatch.render();
|
||||
modelBatch.setLightsOffset(glm::vec3());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,91 +1,64 @@
|
|||
#include "Skybox.hpp"
|
||||
#include "assets/Assets.hpp"
|
||||
#include "graphics/core/Shader.hpp"
|
||||
#include "graphics/core/Mesh.hpp"
|
||||
#include "graphics/core/Batch3D.hpp"
|
||||
#include "graphics/core/Texture.hpp"
|
||||
#include "graphics/core/Cubemap.hpp"
|
||||
#include "graphics/core/Framebuffer.hpp"
|
||||
#include "graphics/core/DrawContext.hpp"
|
||||
#include "window/Window.hpp"
|
||||
#include "window/Camera.hpp"
|
||||
#include "maths/UVRegion.hpp"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <GL/glew.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/constants.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <limits>
|
||||
|
||||
#include "assets/Assets.hpp"
|
||||
#include "graphics/core/Batch3D.hpp"
|
||||
#include "graphics/core/Cubemap.hpp"
|
||||
#include "graphics/core/DrawContext.hpp"
|
||||
#include "graphics/core/Framebuffer.hpp"
|
||||
#include "graphics/core/Mesh.hpp"
|
||||
#include "graphics/core/Shader.hpp"
|
||||
#include "graphics/core/Texture.hpp"
|
||||
#include "maths/UVRegion.hpp"
|
||||
#include "window/Camera.hpp"
|
||||
#include "window/Window.hpp"
|
||||
|
||||
using namespace advanced_pipeline;
|
||||
|
||||
const int STARS_COUNT = 3000;
|
||||
const int STARS_SEED = 632;
|
||||
|
||||
Skybox::Skybox(uint size, Shader& shader)
|
||||
: size(size),
|
||||
shader(shader),
|
||||
batch3d(std::make_unique<Batch3D>(4096))
|
||||
{
|
||||
auto cubemap = std::make_unique<Cubemap>(size, size, ImageFormat::RGB888);
|
||||
Skybox::Skybox(uint size, const Assets& assets)
|
||||
: size(size),
|
||||
assets(assets),
|
||||
shader(assets.require<Shader>("skybox_gen")),
|
||||
batch3d(std::make_unique<Batch3D>(4096)) {
|
||||
|
||||
uint fboid;
|
||||
glGenFramebuffers(1, &fboid);
|
||||
fbo = std::make_unique<Framebuffer>(fboid, 0, std::move(cubemap));
|
||||
|
||||
SkyboxVertex vertices[]{
|
||||
SkyboxVertex vertices[] {
|
||||
{{-1.0f, -1.0f}},
|
||||
{{-1.0f, 1.0f}},
|
||||
{{1.0f, 1.0f}},
|
||||
{{-1.0f, -1.0f}},
|
||||
{{1.0f, 1.0f}},
|
||||
{{1.0f, -1.0f}}
|
||||
};
|
||||
{{1.0f, -1.0f}}};
|
||||
|
||||
mesh = std::make_unique<Mesh<SkyboxVertex>>(vertices, 6);
|
||||
|
||||
sprites.push_back(SkySprite {
|
||||
"misc/moon",
|
||||
glm::pi<float>() * 0.5f,
|
||||
4.0f,
|
||||
false,
|
||||
glm::pi<float>() * 0.25f,
|
||||
});
|
||||
|
||||
sprites.push_back(SkySprite {
|
||||
"misc/moon_flare",
|
||||
glm::pi<float>() * 0.5f,
|
||||
0.5f,
|
||||
false,
|
||||
glm::pi<float>() * 0.25f,
|
||||
});
|
||||
|
||||
sprites.push_back(SkySprite {
|
||||
"misc/sun",
|
||||
glm::pi<float>() * 1.5f,
|
||||
4.0f,
|
||||
true,
|
||||
glm::pi<float>() * 0.25f,
|
||||
});
|
||||
setMode(mode);
|
||||
}
|
||||
|
||||
Skybox::~Skybox() = default;
|
||||
|
||||
void Skybox::drawBackground(
|
||||
const Camera& camera, const Assets& assets, int width, int height
|
||||
) {
|
||||
void Skybox::drawBackground(const Camera& camera, int width, int height) {
|
||||
auto backShader = assets.get<Shader>("background");
|
||||
backShader->use();
|
||||
backShader->uniformMatrix("u_view", camera.getView(false));
|
||||
backShader->uniform1f(
|
||||
"u_zoom", camera.zoom * camera.getFov() / glm::half_pi<float>()
|
||||
);
|
||||
backShader->uniform1f("u_ar", float(width)/float(height));
|
||||
backShader->uniform1f("u_ar", float(width) / float(height));
|
||||
backShader->uniform1i("u_skybox", 1);
|
||||
bind();
|
||||
|
||||
auto texture = fbo->getTexture();
|
||||
texture->bind();
|
||||
mesh->draw();
|
||||
unbind();
|
||||
texture->unbind();
|
||||
}
|
||||
|
||||
void Skybox::drawStars(float angle, float opacity) {
|
||||
|
|
@ -93,9 +66,7 @@ void Skybox::drawStars(float angle, float opacity) {
|
|||
random.setSeed(STARS_SEED);
|
||||
|
||||
glm::mat4 rotation = glm::rotate(
|
||||
glm::mat4(1.0f),
|
||||
-angle + glm::pi<float>() * 0.5f,
|
||||
glm::vec3(0, 0, -1)
|
||||
glm::mat4(1.0f), -angle + glm::pi<float>() * 0.5f, glm::vec3(0, 0, -1)
|
||||
);
|
||||
rotation = glm::rotate(rotation, sunAltitude, glm::vec3(1, 0, 0));
|
||||
|
||||
|
|
@ -108,41 +79,21 @@ void Skybox::drawStars(float angle, float opacity) {
|
|||
glm::vec3 pos = glm::vec4(rx, ry, rz, 1) * rotation;
|
||||
|
||||
float sopacity = random.randFloat();
|
||||
if (pos.y < 0.0f)
|
||||
continue;
|
||||
if (pos.y < 0.0f) continue;
|
||||
|
||||
sopacity *= (0.2f + std::sqrt(std::cos(angle)) * 0.5f) - 0.05f;
|
||||
glm::vec4 tint (1,1,1, sopacity * opacity);
|
||||
glm::vec4 tint(1, 1, 1, sopacity * opacity);
|
||||
batch3d->point(pos * depth, tint);
|
||||
}
|
||||
batch3d->flushPoints();
|
||||
}
|
||||
|
||||
void Skybox::draw(
|
||||
const DrawContext& pctx,
|
||||
const Camera& camera,
|
||||
const Assets& assets,
|
||||
void Skybox::drawSkySprites(
|
||||
float daytime,
|
||||
float fog)
|
||||
{
|
||||
const glm::uvec2& viewport = pctx.getViewport();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
drawBackground(camera, assets, viewport.x, viewport.y);
|
||||
|
||||
DrawContext ctx = pctx.sub();
|
||||
ctx.setBlendMode(BlendMode::addition);
|
||||
|
||||
auto shader = assets.get<Shader>("ui3d");
|
||||
shader->use();
|
||||
shader->uniformMatrix("u_projview", camera.getProjView(false));
|
||||
shader->uniformMatrix("u_apply", glm::mat4(1.0f));
|
||||
batch3d->begin();
|
||||
|
||||
float angle = daytime * glm::pi<float>() * 2.0f;
|
||||
float opacity = glm::pow(1.0f - fog, 7.0f);
|
||||
|
||||
float angle,
|
||||
float opacity,
|
||||
const std::vector<SkySprite>& sprites
|
||||
) {
|
||||
float depthScale = 2e3;
|
||||
for (auto& sprite : sprites) {
|
||||
batch3d->texture(assets.get<Texture>(sprite.texture));
|
||||
|
|
@ -159,39 +110,124 @@ void Skybox::draw(
|
|||
glm::vec3 pos = glm::vec4(0, distance, 0, 1) * rotation;
|
||||
glm::vec3 up = glm::vec4(depthScale, 0, 0, 1) * rotation;
|
||||
glm::vec3 right = glm::vec4(0, 0, depthScale, 1) * rotation;
|
||||
glm::vec4 tint (1,1,1, opacity);
|
||||
glm::vec4 tint(1, 1, 1, opacity);
|
||||
if (!sprite.emissive) {
|
||||
tint *= 0.6f + std::cos(angle)*0.4;
|
||||
tint *= 0.6f + std::cos(angle) * 0.4;
|
||||
}
|
||||
batch3d->sprite(pos, right,
|
||||
up, 1, 1, UVRegion(), tint);
|
||||
batch3d->sprite(pos, right, up, 1, 1, UVRegion(), tint);
|
||||
}
|
||||
batch3d->flush();
|
||||
drawStars(angle, opacity);
|
||||
}
|
||||
|
||||
void Skybox::refresh(const DrawContext& pctx, float t, float mie, const glm::vec3& tint, const glm::vec3& hightlight, uint quality) {
|
||||
void Skybox::draw(
|
||||
const Environment& environment,
|
||||
const DrawContext& pctx,
|
||||
const Camera& camera,
|
||||
float daytime,
|
||||
float fog
|
||||
) {
|
||||
const glm::uvec2& viewport = pctx.getViewport();
|
||||
drawBackground(camera, viewport.x, viewport.y);
|
||||
|
||||
float angle = daytime * glm::pi<float>() * 2.0f;
|
||||
float opacity = glm::pow(1.0f - fog, 7.0f);
|
||||
|
||||
DrawContext ctx = pctx.sub();
|
||||
ctx.setBlendMode(BlendMode::addition);
|
||||
|
||||
if (environment.sky.sprites.empty() && !environment.sky.stars) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto shader = assets.get<Shader>("ui3d");
|
||||
shader->use();
|
||||
shader->uniformMatrix("u_projview", camera.getProjView(false));
|
||||
shader->uniformMatrix("u_apply", glm::mat4(1.0f));
|
||||
batch3d->begin();
|
||||
|
||||
if (!environment.sky.sprites.empty()) {
|
||||
drawSkySprites(daytime, angle, opacity, environment.sky.sprites);
|
||||
}
|
||||
if (environment.sky.stars) {
|
||||
drawStars(angle, opacity);
|
||||
}
|
||||
}
|
||||
|
||||
void Skybox::setMode(SkyMode mode) {
|
||||
if (this->mode == mode && fbo) {
|
||||
return;
|
||||
}
|
||||
this->mode = mode;
|
||||
|
||||
uint size = mode == SkyMode::BOX ? this->size : 1U;
|
||||
prevT = std::numeric_limits<float>().min();
|
||||
|
||||
uint fboid;
|
||||
glGenFramebuffers(1, &fboid);
|
||||
fbo = std::make_unique<Framebuffer>(
|
||||
fboid,
|
||||
false,
|
||||
std::make_unique<Cubemap>(size, size, ImageFormat::RGB888)
|
||||
);
|
||||
}
|
||||
|
||||
void Skybox::refresh(
|
||||
const Environment& environment,
|
||||
const DrawContext& pctx,
|
||||
float dayTime,
|
||||
float mie,
|
||||
const glm::vec3& tint,
|
||||
const glm::vec3& hightlight,
|
||||
uint quality
|
||||
) {
|
||||
setMode(environment.sky.mode);
|
||||
|
||||
if (mode == SkyMode::NONE) {
|
||||
return;
|
||||
} else if (mode == SkyMode::SOLID) {
|
||||
DrawContext ctx = pctx.sub();
|
||||
ctx.setDepthMask(false);
|
||||
ctx.setDepthTest(false);
|
||||
ctx.setFramebuffer(fbo.get());
|
||||
ctx.setViewport({fbo->getWidth(), fbo->getHeight()});
|
||||
ctx.useTexture(advanced_pipeline::TARGET_SKYBOX, fbo->getTexture());
|
||||
ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr);
|
||||
|
||||
auto cubemap = dynamic_cast<Cubemap*>(fbo->getTexture());
|
||||
assert(cubemap != nullptr);
|
||||
|
||||
for (int face = 0; face < 6; face++) {
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
|
||||
cubemap->getId(),
|
||||
0
|
||||
);
|
||||
glClearColor(tint.r, tint.g, tint.b, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
frameid++;
|
||||
float dayTime = t;
|
||||
DrawContext ctx = pctx.sub();
|
||||
ctx.setDepthMask(false);
|
||||
ctx.setDepthTest(false);
|
||||
ctx.setFramebuffer(fbo.get());
|
||||
ctx.setViewport({size, size});
|
||||
ctx.setViewport({fbo->getWidth(), fbo->getHeight()});
|
||||
ctx.useTexture(advanced_pipeline::TARGET_SKYBOX, fbo->getTexture());
|
||||
ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr);
|
||||
|
||||
auto cubemap = dynamic_cast<Cubemap*>(fbo->getTexture());
|
||||
assert(cubemap != nullptr);
|
||||
|
||||
ready = true;
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
|
||||
cubemap->bind();
|
||||
shader.use();
|
||||
t *= glm::two_pi<float>();
|
||||
|
||||
float t = dayTime * glm::two_pi<float>();
|
||||
lightDir = glm::normalize(glm::vec3(sin(t), -cos(t), 0.0f));
|
||||
|
||||
float sunAngle = glm::radians((t / glm::two_pi<float>() - 0.25f) * 360.0f);
|
||||
float x = -glm::cos(sunAngle + glm::pi<float>() * 0.5f) * glm::radians(sunAltitude);
|
||||
float sunAngle = glm::radians((dayTime - 0.25f) * 360.0f);
|
||||
float x = -glm::cos(sunAngle + glm::pi<float>() * 0.5f) *
|
||||
glm::radians(sunAltitude);
|
||||
float y = sunAngle - glm::pi<float>() * 0.5f;
|
||||
float z = glm::radians(0.0f);
|
||||
rotation = glm::rotate(glm::mat4(1.0f), y, glm::vec3(0, 1, 0));
|
||||
|
|
@ -199,6 +235,7 @@ void Skybox::refresh(const DrawContext& pctx, float t, float mie, const glm::vec
|
|||
rotation = glm::rotate(rotation, z, glm::vec3(0, 0, 1));
|
||||
lightDir = glm::vec3(rotation * glm::vec4(0, 0, -1, 1));
|
||||
|
||||
shader.use();
|
||||
shader.uniform1i("u_quality", quality);
|
||||
shader.uniform1f("u_mie", mie);
|
||||
shader.uniform3f("u_tint", tint);
|
||||
|
|
@ -207,23 +244,22 @@ void Skybox::refresh(const DrawContext& pctx, float t, float mie, const glm::vec
|
|||
shader.uniform3f("u_lightDir", lightDir);
|
||||
shader.uniform1f("u_dayTime", dayTime);
|
||||
|
||||
if (glm::abs(mie-prevMie) + glm::abs(t-prevT) + glm::abs(prevHighlight.r - hightlight.r) >= 0.01) {
|
||||
if (glm::abs(mie - prevMie) + glm::abs(t - prevT) +
|
||||
glm::abs(prevHighlight.r - hightlight.r) >=
|
||||
0.01) {
|
||||
for (uint face = 0; face < 6; face++) {
|
||||
refreshFace(face, cubemap);
|
||||
refreshFace(face, *cubemap);
|
||||
}
|
||||
} else {
|
||||
uint face = frameid % 6;
|
||||
refreshFace(face, cubemap);
|
||||
refreshFace(face, *cubemap);
|
||||
}
|
||||
prevMie = mie;
|
||||
prevT = t;
|
||||
prevHighlight = hightlight;
|
||||
|
||||
cubemap->unbind();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
void Skybox::refreshFace(uint face, Cubemap* cubemap) {
|
||||
void Skybox::refreshFace(uint face, Cubemap& cubemap) {
|
||||
const glm::vec3 xaxs[] = {
|
||||
{0.0f, 0.0f, -1.0f},
|
||||
{0.0f, 0.0f, 1.0f},
|
||||
|
|
@ -256,7 +292,7 @@ void Skybox::refreshFace(uint face, Cubemap* cubemap) {
|
|||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
|
||||
cubemap->getId(),
|
||||
cubemap.getId(),
|
||||
0
|
||||
);
|
||||
shader.uniform3f("u_xaxis", xaxs[face]);
|
||||
|
|
@ -265,14 +301,6 @@ void Skybox::refreshFace(uint face, Cubemap* cubemap) {
|
|||
mesh->draw();
|
||||
}
|
||||
|
||||
void Skybox::bind() const {
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
|
||||
fbo->getTexture()->bind();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
void Skybox::unbind() const {
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
|
||||
fbo->getTexture()->unbind();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
const Cubemap* Skybox::getCubemap() const {
|
||||
return dynamic_cast<const Cubemap*>(fbo->getTexture());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <glm/glm.hpp>
|
||||
#include "typedefs.hpp"
|
||||
#include "maths/fastmaths.hpp"
|
||||
#include "graphics/core/MeshData.hpp"
|
||||
|
||||
template<typename VertexStructure> class Mesh;
|
||||
#include "graphics/core/MeshData.hpp"
|
||||
#include "maths/fastmaths.hpp"
|
||||
#include "typedefs.hpp"
|
||||
#include "world/Environment.hpp"
|
||||
|
||||
template <typename VertexStructure>
|
||||
class Mesh;
|
||||
class Shader;
|
||||
class Assets;
|
||||
class Camera;
|
||||
|
|
@ -21,29 +24,20 @@ struct SkyboxVertex {
|
|||
glm::vec2 position;
|
||||
|
||||
static constexpr VertexAttribute ATTRIBUTES[] {
|
||||
{VertexAttribute::Type::FLOAT, false, 2},
|
||||
{{}, 0}};
|
||||
};
|
||||
|
||||
struct SkySprite {
|
||||
std::string texture;
|
||||
float phase;
|
||||
float distance;
|
||||
bool emissive;
|
||||
float altitude;
|
||||
{VertexAttribute::Type::FLOAT, false, 2}, {{}, 0}};
|
||||
};
|
||||
|
||||
class Skybox {
|
||||
std::unique_ptr<Framebuffer> fbo;
|
||||
SkyMode mode = SkyMode::SOLID;
|
||||
uint size;
|
||||
std::unique_ptr<Framebuffer> fbo;
|
||||
const Assets& assets;
|
||||
Shader& shader;
|
||||
bool ready = false;
|
||||
FastRandom random;
|
||||
glm::vec3 lightDir;
|
||||
|
||||
std::unique_ptr<Mesh<SkyboxVertex>> mesh;
|
||||
std::unique_ptr<Batch3D> batch3d;
|
||||
std::vector<SkySprite> sprites;
|
||||
int frameid = 0;
|
||||
|
||||
float prevMie = -1.0f;
|
||||
|
|
@ -53,30 +47,41 @@ class Skybox {
|
|||
glm::mat4 rotation;
|
||||
|
||||
void drawStars(float angle, float opacity);
|
||||
void drawBackground(
|
||||
const Camera& camera, const Assets& assets, int width, int height
|
||||
void drawBackground(const Camera& camera, int width, int height);
|
||||
void drawSkySprites(
|
||||
float daytime,
|
||||
float angle,
|
||||
float opacity,
|
||||
const std::vector<SkySprite>& sprites
|
||||
);
|
||||
void refreshFace(uint face, Cubemap* cubemap);
|
||||
void refreshFace(uint face, Cubemap& cubemap);
|
||||
public:
|
||||
Skybox(uint size, Shader& shader);
|
||||
Skybox(uint size, const Assets& assets);
|
||||
~Skybox();
|
||||
|
||||
void setMode(SkyMode mode);
|
||||
|
||||
void draw(
|
||||
const DrawContext& pctx,
|
||||
const Camera& camera,
|
||||
const Assets& assets,
|
||||
const Environment& environment,
|
||||
const DrawContext& pctx,
|
||||
const Camera& camera,
|
||||
float daytime,
|
||||
float fog
|
||||
);
|
||||
|
||||
void refresh(const DrawContext& pctx, float t, float mie, const glm::vec3& tint, const glm::vec3& hightlight, uint quality);
|
||||
void bind() const;
|
||||
void unbind() const;
|
||||
bool isReady() const {
|
||||
return ready;
|
||||
}
|
||||
void refresh(
|
||||
const Environment& environment,
|
||||
const DrawContext& pctx,
|
||||
float t,
|
||||
float mie,
|
||||
const glm::vec3& tint,
|
||||
const glm::vec3& hightlight,
|
||||
uint quality
|
||||
);
|
||||
|
||||
const glm::vec3 getLightDir() const {
|
||||
const Cubemap* getCubemap() const;
|
||||
|
||||
const glm::vec3& getLightDir() const {
|
||||
return lightDir;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -58,7 +58,10 @@ void TextsRenderer::renderNote(
|
|||
}
|
||||
opacity = preset.xrayOpacity;
|
||||
}
|
||||
auto& font = assets.require<Font>(FONT_DEFAULT);
|
||||
|
||||
auto specifiedFont = assets.get<Font>(preset.font);
|
||||
auto& font =
|
||||
specifiedFont ? *specifiedFont : assets.require<Font>(FONT_DEFAULT);
|
||||
|
||||
glm::vec3 xvec = note.getAxisX();
|
||||
glm::vec3 yvec = note.getAxisY();
|
||||
|
|
@ -76,7 +79,10 @@ void TextsRenderer::renderNote(
|
|||
yvec = camera.up;
|
||||
}
|
||||
float scale =
|
||||
(1.0f - preset.perspective) * glm::pow(glm::distance(camera.position, pos), 1.0f-preset.perspective);
|
||||
(1.0f - preset.perspective) *
|
||||
glm::pow(
|
||||
glm::distance(camera.position, pos), 1.0f - preset.perspective
|
||||
);
|
||||
xvec *= 1.0f + scale;
|
||||
yvec *= 1.0f + scale;
|
||||
}
|
||||
|
|
@ -118,6 +124,7 @@ void TextsRenderer::renderNote(
|
|||
}
|
||||
auto color = preset.color;
|
||||
batch.setColor(glm::vec4(color.r, color.g, color.b, color.a * opacity));
|
||||
|
||||
font.draw(
|
||||
batch,
|
||||
text,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,39 @@
|
|||
#include "WorldRenderer.hpp"
|
||||
|
||||
#include "BlockWrapsRenderer.hpp"
|
||||
#include "ChunksRenderer.hpp"
|
||||
#include "CloudsRenderer.hpp"
|
||||
#include "DebugLinesRenderer.hpp"
|
||||
#include "Emitter.hpp"
|
||||
#include "HandsRenderer.hpp"
|
||||
#include "ModelBatch.hpp"
|
||||
#include "NamedSkeletons.hpp"
|
||||
#include "ParticlesRenderer.hpp"
|
||||
#include "PrecipitationRenderer.hpp"
|
||||
#include "Skybox.hpp"
|
||||
#include "TextNote.hpp"
|
||||
#include "TextsRenderer.hpp"
|
||||
#include "assets/Assets.hpp"
|
||||
#include "assets/assets_util.hpp"
|
||||
#include "coders/GLSLExtension.hpp"
|
||||
#include "content/Content.hpp"
|
||||
#include "engine/Engine.hpp"
|
||||
#include "coders/GLSLExtension.hpp"
|
||||
#include "frontend/LevelFrontend.hpp"
|
||||
#include "frontend/ContentGfxCache.hpp"
|
||||
#include "frontend/LevelFrontend.hpp"
|
||||
#include "graphics/commons/Model.hpp"
|
||||
#include "graphics/core/Atlas.hpp"
|
||||
#include "graphics/core/Batch3D.hpp"
|
||||
#include "graphics/core/DrawContext.hpp"
|
||||
#include "graphics/core/Font.hpp"
|
||||
#include "graphics/core/Framebuffer.hpp"
|
||||
#include "graphics/core/GBuffer.hpp"
|
||||
#include "graphics/core/LineBatch.hpp"
|
||||
#include "graphics/core/Mesh.hpp"
|
||||
#include "graphics/core/PostProcessing.hpp"
|
||||
#include "graphics/core/Shader.hpp"
|
||||
#include "graphics/core/Shadows.hpp"
|
||||
#include "graphics/core/Cubemap.hpp"
|
||||
#include "graphics/core/Texture.hpp"
|
||||
#include "items/Inventory.hpp"
|
||||
#include "items/ItemDef.hpp"
|
||||
#include "items/ItemStack.hpp"
|
||||
|
|
@ -25,32 +52,6 @@
|
|||
#include "world/Level.hpp"
|
||||
#include "world/LevelEvents.hpp"
|
||||
#include "world/World.hpp"
|
||||
#include "graphics/commons/Model.hpp"
|
||||
#include "graphics/core/Atlas.hpp"
|
||||
#include "graphics/core/Batch3D.hpp"
|
||||
#include "graphics/core/DrawContext.hpp"
|
||||
#include "graphics/core/LineBatch.hpp"
|
||||
#include "graphics/core/Mesh.hpp"
|
||||
#include "graphics/core/PostProcessing.hpp"
|
||||
#include "graphics/core/Framebuffer.hpp"
|
||||
#include "graphics/core/Shader.hpp"
|
||||
#include "graphics/core/Texture.hpp"
|
||||
#include "graphics/core/Font.hpp"
|
||||
#include "graphics/core/Shadows.hpp"
|
||||
#include "graphics/core/GBuffer.hpp"
|
||||
#include "BlockWrapsRenderer.hpp"
|
||||
#include "ParticlesRenderer.hpp"
|
||||
#include "PrecipitationRenderer.hpp"
|
||||
#include "HandsRenderer.hpp"
|
||||
#include "NamedSkeletons.hpp"
|
||||
#include "TextsRenderer.hpp"
|
||||
#include "ChunksRenderer.hpp"
|
||||
#include "DebugLinesRenderer.hpp"
|
||||
#include "ModelBatch.hpp"
|
||||
#include "Skybox.hpp"
|
||||
#include "Emitter.hpp"
|
||||
#include "TextNote.hpp"
|
||||
#include "CloudsRenderer.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
|
|
@ -58,8 +59,6 @@
|
|||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <memory>
|
||||
|
||||
using namespace advanced_pipeline;
|
||||
|
||||
inline constexpr size_t BATCH3D_CAPACITY = 4096;
|
||||
inline constexpr size_t MODEL_BATCH_CAPACITY = 20'000;
|
||||
|
||||
|
|
@ -105,8 +104,7 @@ WorldRenderer::WorldRenderer(
|
|||
[this](LevelEventType, Chunk* chunk) { chunksRenderer->unload(chunk); }
|
||||
);
|
||||
skybox = std::make_unique<Skybox>(
|
||||
settings.graphics.skyboxResolution.get(),
|
||||
assets.require<Shader>("skybox_gen")
|
||||
settings.graphics.skyboxResolution.get(), assets
|
||||
);
|
||||
|
||||
const auto& content = level.content;
|
||||
|
|
@ -160,7 +158,7 @@ void WorldRenderer::setupWorldShader(
|
|||
shader.uniform1i("u_debugNormals", false);
|
||||
shader.uniform1f("u_dayTime", level.getWorld()->getInfo().daytime);
|
||||
shader.uniform2f("u_lightDir", skybox->getLightDir());
|
||||
shader.uniform1i("u_skybox", TARGET_SKYBOX);
|
||||
shader.uniform1i("u_skybox", advanced_pipeline::TARGET_SKYBOX);
|
||||
|
||||
auto indices = level.content.getIndices();
|
||||
// Light emission when an emissive item is chosen
|
||||
|
|
@ -179,6 +177,11 @@ void WorldRenderer::setupWorldShader(
|
|||
}
|
||||
}
|
||||
|
||||
float WorldRenderer::calcFogFactor() const {
|
||||
const auto& settings = engine.getSettings();
|
||||
return 15.0f / static_cast<float>(settings.chunks.loadDistance.get() - 2);
|
||||
}
|
||||
|
||||
void WorldRenderer::renderOpaque(
|
||||
const DrawContext& ctx,
|
||||
const Camera& camera,
|
||||
|
|
@ -187,14 +190,12 @@ void WorldRenderer::renderOpaque(
|
|||
) {
|
||||
texts->render(ctx, camera, settings, hudVisible, false);
|
||||
|
||||
bool culling = engine.getSettings().graphics.frustumCulling.get();
|
||||
float fogFactor =
|
||||
15.0f / static_cast<float>(settings.chunks.loadDistance.get() - 2);
|
||||
float fogFactor = calcFogFactor();
|
||||
|
||||
auto& entityShader = assets.require<Shader>("entity");
|
||||
setupWorldShader(entityShader, camera, settings, fogFactor);
|
||||
skybox->bind();
|
||||
|
||||
bool culling = engine.getSettings().graphics.frustumCulling.get();
|
||||
if (culling) {
|
||||
frustumCulling->update(camera.getProjView());
|
||||
}
|
||||
|
|
@ -213,25 +214,26 @@ void WorldRenderer::renderOpaque(
|
|||
|
||||
auto& shader = assets.require<Shader>("main");
|
||||
auto& cloudsShader = assets.require<Shader>("clouds");
|
||||
auto& linesShader = assets.require<Shader>("lines");
|
||||
|
||||
setupWorldShader(shader, camera, settings, fogFactor);
|
||||
|
||||
chunksRenderer->drawChunks(camera, shader);
|
||||
blockWraps->draw(ctx);
|
||||
|
||||
int cloudsQuality = settings.graphics.cloudsQuality.get();
|
||||
if (cloudsQuality > 0) {
|
||||
setupWorldShader(cloudsShader, camera, settings, fogFactor);
|
||||
cloudsRenderer->draw(
|
||||
cloudsShader, weather, timer, fogFactor, camera, cloudsQuality
|
||||
);
|
||||
if (level.environment.sky.clouds) {
|
||||
int cloudsQuality = settings.graphics.cloudsQuality.get();
|
||||
if (cloudsQuality > 0) {
|
||||
setupWorldShader(cloudsShader, camera, settings, fogFactor);
|
||||
cloudsRenderer->draw(
|
||||
cloudsShader, weather, timer, fogFactor, camera, cloudsQuality
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (hudVisible) {
|
||||
auto& linesShader = assets.require<Shader>("lines");
|
||||
renderLines(camera, linesShader, ctx);
|
||||
}
|
||||
skybox->unbind();
|
||||
}
|
||||
|
||||
void WorldRenderer::renderBlockSelection() {
|
||||
|
|
@ -287,21 +289,19 @@ void WorldRenderer::refreshSettings(Shader** shaders) {
|
|||
|
||||
int shadowsQuality = graphics.shadowsQuality.get() * gbufferPipeline;
|
||||
shadowMapping->setQuality(shadowsQuality);
|
||||
|
||||
|
||||
CompileTimeShaderSettings currentSettings {
|
||||
gbufferPipeline,
|
||||
shadowsQuality != 0,
|
||||
graphics.ssao.get() && gbufferPipeline
|
||||
};
|
||||
if (
|
||||
prevCTShaderSettings.advancedRender != currentSettings.advancedRender ||
|
||||
graphics.ssao.get() && gbufferPipeline};
|
||||
if (prevCTShaderSettings.advancedRender != currentSettings.advancedRender ||
|
||||
prevCTShaderSettings.shadows != currentSettings.shadows ||
|
||||
prevCTShaderSettings.ssao != currentSettings.ssao
|
||||
) {
|
||||
prevCTShaderSettings.ssao != currentSettings.ssao) {
|
||||
std::vector<std::string> defines;
|
||||
if (currentSettings.shadows) defines.emplace_back("ENABLE_SHADOWS");
|
||||
if (currentSettings.ssao) defines.emplace_back("ENABLE_SSAO");
|
||||
if (currentSettings.advancedRender) defines.emplace_back("ADVANCED_RENDER");
|
||||
if (currentSettings.advancedRender)
|
||||
defines.emplace_back("ADVANCED_RENDER");
|
||||
|
||||
for (size_t i = 0; shaders[i]; i++) {
|
||||
shaders[i]->recompile(defines);
|
||||
|
|
@ -333,7 +333,8 @@ void WorldRenderer::renderFrame(
|
|||
auto& entityShader = assets.require<Shader>("entity");
|
||||
auto& cloudsShader = assets.require<Shader>("clouds");
|
||||
auto& translucentShader = assets.require<Shader>("translucent");
|
||||
auto& deferredShader = assets.require<PostEffect>("deferred_lighting").getShader();
|
||||
auto& deferredShader =
|
||||
assets.require<PostEffect>("deferred_lighting").getShader();
|
||||
|
||||
const auto& settings = engine.getSettings();
|
||||
|
||||
|
|
@ -343,19 +344,19 @@ void WorldRenderer::renderFrame(
|
|||
&cloudsShader,
|
||||
&translucentShader,
|
||||
&deferredShader,
|
||||
nullptr
|
||||
};
|
||||
nullptr};
|
||||
|
||||
refreshSettings(affectedShaders);
|
||||
|
||||
const auto& worldInfo = world->getInfo();
|
||||
|
||||
|
||||
float clouds = weather.clouds();
|
||||
clouds = glm::max(worldInfo.fog, clouds);
|
||||
float mie = 1.0f + glm::max(worldInfo.fog, clouds * 0.5f) * 2.0f;
|
||||
|
||||
float random = rand() / static_cast<float>(RAND_MAX);
|
||||
skybox->refresh(
|
||||
level.environment,
|
||||
pctx,
|
||||
worldInfo.daytime,
|
||||
mie,
|
||||
|
|
@ -374,20 +375,19 @@ void WorldRenderer::renderFrame(
|
|||
{
|
||||
DrawContext wctx = pctx.sub();
|
||||
postProcessing.use(wctx, gbufferPipeline);
|
||||
|
||||
display::clearDepth();
|
||||
|
||||
/* Main opaque pass (GBuffer pass) */ {
|
||||
DrawContext ctx = wctx.sub();
|
||||
ctx.setDepthTest(true);
|
||||
ctx.setCullFace(true);
|
||||
ctx.useTexture(advanced_pipeline::TARGET_SKYBOX, skybox->getCubemap());
|
||||
ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr);
|
||||
renderOpaque(ctx, camera, settings, hudVisible);
|
||||
}
|
||||
texts->render(pctx, camera, settings, hudVisible, true);
|
||||
}
|
||||
skybox->bind();
|
||||
float fogFactor =
|
||||
15.0f / static_cast<float>(settings.chunks.loadDistance.get() - 2);
|
||||
float fogFactor = calcFogFactor();
|
||||
if (gbufferPipeline) {
|
||||
deferredShader.use();
|
||||
setupWorldShader(deferredShader, camera, settings, fogFactor);
|
||||
|
|
@ -396,6 +396,7 @@ void WorldRenderer::renderFrame(
|
|||
{
|
||||
DrawContext ctx = pctx.sub();
|
||||
ctx.setDepthTest(true);
|
||||
ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr);
|
||||
|
||||
if (gbufferPipeline) {
|
||||
postProcessing.bindDepthBuffer();
|
||||
|
|
@ -404,7 +405,9 @@ void WorldRenderer::renderFrame(
|
|||
}
|
||||
|
||||
// Background sky plane
|
||||
skybox->draw(ctx, camera, assets, worldInfo.daytime, clouds);
|
||||
skybox->draw(
|
||||
level.environment, ctx, camera, worldInfo.daytime, clouds
|
||||
);
|
||||
|
||||
auto& linesShader = assets.require<Shader>("lines");
|
||||
linesShader.use();
|
||||
|
|
@ -416,10 +419,12 @@ void WorldRenderer::renderFrame(
|
|||
linesShader.uniformMatrix("u_projview", projView);
|
||||
lineBatch->flush();
|
||||
|
||||
skybox->bind();
|
||||
DrawContext wctx = ctx.sub();
|
||||
wctx.useTexture(advanced_pipeline::TARGET_SKYBOX, skybox->getCubemap());
|
||||
wctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr);
|
||||
// Translucent blocks
|
||||
{
|
||||
auto sctx = ctx.sub();
|
||||
auto sctx = wctx.sub();
|
||||
sctx.setCullFace(true);
|
||||
translucentShader.use();
|
||||
setupWorldShader(translucentShader, camera, settings, fogFactor);
|
||||
|
|
@ -430,44 +435,41 @@ void WorldRenderer::renderFrame(
|
|||
entityShader.use();
|
||||
setupWorldShader(entityShader, camera, settings, fogFactor);
|
||||
|
||||
std::array<const WeatherPreset*, 2> weatherInstances {&weather.a, &weather.b};
|
||||
std::array<const WeatherPreset*, 2> weatherInstances {
|
||||
&weather.a, &weather.b};
|
||||
for (const auto& weather : weatherInstances) {
|
||||
float maxIntensity = weather->fall.maxIntensity;
|
||||
float zero = weather->fall.minOpacity;
|
||||
float one = weather->fall.maxOpacity;
|
||||
float t = (weather->intensity * (one - zero)) * maxIntensity + zero;
|
||||
entityShader.uniform1i("u_alphaClip", weather->fall.opaque);
|
||||
entityShader.uniform1f("u_opacity", weather->fall.opaque ? t * t : t);
|
||||
entityShader.uniform1f(
|
||||
"u_opacity", weather->fall.opaque ? t * t : t
|
||||
);
|
||||
if (weather->intensity > 1.e-3f && !weather->fall.texture.empty()) {
|
||||
precipitation->render(camera, *weather);
|
||||
}
|
||||
}
|
||||
skybox->unbind();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
postProcessing.render(pctx, assets, timer, camera);
|
||||
|
||||
|
||||
if (player.currentCamera == player.fpCamera) {
|
||||
DrawContext ctx = pctx.sub();
|
||||
ctx.setDepthTest(true);
|
||||
ctx.setCullFace(true);
|
||||
ctx.useTexture(advanced_pipeline::TARGET_SKYBOX, skybox->getCubemap());
|
||||
ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr);
|
||||
display::clearDepth();
|
||||
|
||||
// prepare modified HUD camera
|
||||
Camera hudcam = camera;
|
||||
hudcam.far = 10.0f;
|
||||
hudcam.setFov(0.9f);
|
||||
hudcam.position = {};
|
||||
|
||||
hands->render(camera);
|
||||
|
||||
display::clearDepth();
|
||||
setupWorldShader(entityShader, hudcam, engine.getSettings(), 0.0f);
|
||||
|
||||
skybox->bind();
|
||||
modelBatch->render();
|
||||
modelBatch->setLightsOffset(glm::vec3());
|
||||
skybox->unbind();
|
||||
hands->render(camera);
|
||||
}
|
||||
renderBlockOverlay(pctx);
|
||||
|
||||
|
|
@ -487,13 +489,12 @@ void WorldRenderer::renderBlockOverlay(const DrawContext& wctx) {
|
|||
if (def.overlayTexture.empty()) {
|
||||
return;
|
||||
}
|
||||
auto textureRegion = util::get_texture_region(
|
||||
assets, def.overlayTexture, "blocks:notfound"
|
||||
);
|
||||
auto textureRegion =
|
||||
util::get_texture_region(assets, def.overlayTexture, "blocks:notfound");
|
||||
DrawContext ctx = wctx.sub();
|
||||
ctx.setDepthTest(false);
|
||||
ctx.setCullFace(false);
|
||||
|
||||
|
||||
auto& shader = assets.require<Shader>("ui3d");
|
||||
shader.use();
|
||||
batch3d->begin();
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ class WorldRenderer {
|
|||
);
|
||||
|
||||
void refreshSettings(Shader** shaders);
|
||||
|
||||
float calcFogFactor() const;
|
||||
public:
|
||||
std::unique_ptr<ParticlesRenderer> particles;
|
||||
std::unique_ptr<TextsRenderer> texts;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue