mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-13 15:01:49 +00:00
test environment (sky)
This commit is contained in:
parent
c4d5812b4f
commit
a7ad219261
14 changed files with 421 additions and 196 deletions
|
|
@ -9,6 +9,10 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#ifdef VC_ENABLE_REFLECTION
|
||||||
|
#include "util/EnumMetadata.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
template<class T> class Buffer;
|
template<class T> class Buffer;
|
||||||
}
|
}
|
||||||
|
|
@ -70,6 +74,14 @@ namespace dv {
|
||||||
return ptr != nullptr;
|
return ptr != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline value* operator->() noexcept {
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const value* operator->() const noexcept {
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
inline value& operator*() noexcept {
|
inline value& operator*() noexcept {
|
||||||
return *ptr;
|
return *ptr;
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +90,11 @@ namespace dv {
|
||||||
return *ptr;
|
return *ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VC_ENABLE_REFLECTION
|
||||||
|
template <typename T>
|
||||||
|
bool get(T& dst, const util::EnumMetadata<T>& mt) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool get(std::string& dst) const;
|
bool get(std::string& dst) const;
|
||||||
bool get(bool& dst) const;
|
bool get(bool& dst) const;
|
||||||
bool get(char& dst) const;
|
bool get(char& dst) const;
|
||||||
|
|
@ -552,6 +569,17 @@ namespace dv {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VC_ENABLE_REFLECTION
|
||||||
|
template <typename T>
|
||||||
|
inline bool optionalvalue::get(T& dst, const util::EnumMetadata<T>& mt) const {
|
||||||
|
if (ptr) {
|
||||||
|
return mt.getItem(ptr->asString(), dst);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
inline bool optionalvalue::get(std::string& dst) const {
|
inline bool optionalvalue::get(std::string& dst) const {
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
dst = ptr->asString();
|
dst = ptr->asString();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
Cubemap::Cubemap(uint width, uint height, ImageFormat imageFormat)
|
Cubemap::Cubemap(uint width, uint height, ImageFormat imageFormat)
|
||||||
: Texture(0, width, height)
|
: Texture(0U, width, height, imageFormat)
|
||||||
{
|
{
|
||||||
glGenTextures(1, &id);
|
glGenTextures(1, &id);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, id);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, id);
|
||||||
|
|
@ -14,7 +14,6 @@ Cubemap::Cubemap(uint width, uint height, ImageFormat imageFormat)
|
||||||
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
uint format = gl::to_glenum(imageFormat);
|
|
||||||
for (uint face = 0; face < 6; face++) {
|
for (uint face = 0; face < 6; face++) {
|
||||||
glTexImage2D(
|
glTexImage2D(
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
|
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
|
||||||
|
|
@ -37,3 +36,23 @@ void Cubemap::bind() const {
|
||||||
void Cubemap::unbind() const {
|
void Cubemap::unbind() const {
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cubemap::reload(const ubyte* data, uint width, uint height) {
|
||||||
|
this->width = width;
|
||||||
|
this->height = height;
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, id);
|
||||||
|
for (uint face = 0; face < 6; face++) {
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
|
||||||
|
0,
|
||||||
|
format,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
0,
|
||||||
|
format,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
|
data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,5 @@ public:
|
||||||
|
|
||||||
virtual void bind() const override;
|
virtual void bind() const override;
|
||||||
virtual void unbind() const override;
|
virtual void unbind() const override;
|
||||||
|
virtual void reload(const ubyte* data, uint w, uint h) override;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
#include "Framebuffer.hpp"
|
#include "Framebuffer.hpp"
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
#include "Texture.hpp"
|
#include "Texture.hpp"
|
||||||
#include "debug/Logger.hpp"
|
#include "debug/Logger.hpp"
|
||||||
|
|
||||||
static debug::Logger logger("gl-framebuffer");
|
static debug::Logger logger("gl-framebuffer");
|
||||||
|
|
||||||
Framebuffer::Framebuffer(uint fbo, uint depth, std::unique_ptr<Texture> texture)
|
Framebuffer::Framebuffer(uint fbo, uint depth, std::unique_ptr<Texture> texture)
|
||||||
: fbo(fbo), depth(depth), texture(std::move(texture))
|
: fbo(fbo), depth(depth), texture(std::move(texture)) {
|
||||||
{
|
|
||||||
if (this->texture) {
|
if (this->texture) {
|
||||||
width = this->texture->getWidth();
|
width = this->texture->getWidth();
|
||||||
height = this->texture->getHeight();
|
height = this->texture->getHeight();
|
||||||
|
|
@ -18,35 +18,55 @@ Framebuffer::Framebuffer(uint fbo, uint depth, std::unique_ptr<Texture> texture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<Texture> create_texture(int width, int height, int format) {
|
static std::unique_ptr<Texture> create_texture(
|
||||||
GLuint tex;
|
int width, int height, bool alpha
|
||||||
glGenTextures(1, &tex);
|
) {
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
GLenum glformat = alpha ? GL_RGBA : GL_RGB;
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
|
|
||||||
|
GLuint textureid;
|
||||||
|
glGenTextures(1, &textureid);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureid);
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
glformat,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
0,
|
||||||
|
glformat,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
|
glFramebufferTexture2D(
|
||||||
return std::make_unique<Texture>(tex, width, height);
|
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid, 0
|
||||||
|
);
|
||||||
|
return std::make_unique<Texture>(
|
||||||
|
textureid,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
alpha ? ImageFormat::RGBA8888 : ImageFormat::RGB888
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer::Framebuffer(uint width, uint height, bool alpha)
|
Framebuffer::Framebuffer(uint width, uint height, bool alpha)
|
||||||
: width(width), height(height)
|
: width(width), height(height) {
|
||||||
{
|
|
||||||
glGenFramebuffers(1, &fbo);
|
glGenFramebuffers(1, &fbo);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
|
|
||||||
format = alpha ? GL_RGBA : GL_RGB;
|
|
||||||
|
|
||||||
// Setup color attachment (texture)
|
// Setup color attachment (texture)
|
||||||
texture = create_texture(width, height, format);
|
texture = create_texture(width, height, alpha);
|
||||||
|
|
||||||
// Setup depth attachment
|
// Setup depth attachment
|
||||||
glGenRenderbuffers(1, &depth);
|
glGenRenderbuffers(1, &depth);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, depth);
|
glBindRenderbuffer(GL_RENDERBUFFER, depth);
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
|
glFramebufferRenderbuffer(
|
||||||
|
GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth
|
||||||
|
);
|
||||||
|
|
||||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
logger.error() << "framebuffer is not complete!";
|
logger.error() << "framebuffer is not complete!";
|
||||||
|
|
@ -60,6 +80,10 @@ Framebuffer::~Framebuffer() {
|
||||||
glDeleteRenderbuffers(1, &depth);
|
glDeleteRenderbuffers(1, &depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Framebuffer::setTexture(std::unique_ptr<Texture> texture) {
|
||||||
|
this->texture = std::move(texture);
|
||||||
|
}
|
||||||
|
|
||||||
void Framebuffer::bind() {
|
void Framebuffer::bind() {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +105,7 @@ void Framebuffer::resize(uint width, uint height) {
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
|
||||||
texture = create_texture(width, height, format);
|
texture->resize(width, height);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,5 +126,5 @@ uint Framebuffer::getHeight() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint Framebuffer::getFBO() const {
|
uint Framebuffer::getFBO() const {
|
||||||
return fbo;
|
return fbo;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,14 @@ class Framebuffer : public Bindable {
|
||||||
uint depth;
|
uint depth;
|
||||||
uint width;
|
uint width;
|
||||||
uint height;
|
uint height;
|
||||||
uint format;
|
|
||||||
std::shared_ptr<Texture> texture;
|
std::shared_ptr<Texture> texture;
|
||||||
public:
|
public:
|
||||||
Framebuffer(uint fbo, uint depth, std::unique_ptr<Texture> texture);
|
Framebuffer(uint fbo, uint depth, std::unique_ptr<Texture> texture);
|
||||||
Framebuffer(uint width, uint height, bool alpha=false);
|
Framebuffer(uint width, uint height, bool alpha=false);
|
||||||
~Framebuffer();
|
~Framebuffer();
|
||||||
|
|
||||||
|
void setTexture(std::unique_ptr<Texture> texture);
|
||||||
|
|
||||||
/// @brief Use framebuffer
|
/// @brief Use framebuffer
|
||||||
void bind() override;
|
void bind() override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
uint Texture::MAX_RESOLUTION = 1024; // Window.initialize overrides it
|
uint Texture::MAX_RESOLUTION = 1024; // Window.initialize overrides it
|
||||||
|
|
||||||
Texture::Texture(uint id, uint width, uint height)
|
Texture::Texture(uint id, uint width, uint height, ImageFormat imageFormat)
|
||||||
: id(id), width(width), height(height) {
|
: id(id), width(width), height(height), format(gl::to_glenum(imageFormat)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(const ubyte* data, uint width, uint height, ImageFormat imageFormat)
|
Texture::Texture(const ubyte* data, uint width, uint height, ImageFormat imageFormat)
|
||||||
|
|
@ -17,7 +17,7 @@ Texture::Texture(const ubyte* data, uint width, uint height, ImageFormat imageFo
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
GLenum format = gl::to_glenum(imageFormat);
|
format = gl::to_glenum(imageFormat);
|
||||||
glTexImage2D(
|
glTexImage2D(
|
||||||
GL_TEXTURE_2D, 0, format, width, height, 0,
|
GL_TEXTURE_2D, 0, format, width, height, 0,
|
||||||
format, GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(data)
|
format, GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(data)
|
||||||
|
|
@ -41,23 +41,27 @@ void Texture::unbind() const {
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Texture::resize(uint width, uint height) {
|
||||||
|
reload(nullptr, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
void Texture::reload(const ImageData& image) {
|
void Texture::reload(const ImageData& image) {
|
||||||
width = image.getWidth();
|
|
||||||
height = image.getHeight();
|
|
||||||
reload(image.getData(), width, height);
|
reload(image.getData(), width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::reload(const ubyte* data, uint width, uint height) {
|
void Texture::reload(const ubyte* data, uint width, uint height) {
|
||||||
|
this->width = width;
|
||||||
|
this->height = height;
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(data));
|
format, GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(data));
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::reloadPartial(const ImageData& image, uint x, uint y, uint w, uint h) {
|
void Texture::reloadPartial(const ImageData& image, uint x, uint y, uint w, uint h) {
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, image.getData());
|
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, GL_UNSIGNED_BYTE, image.getData());
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,19 +11,21 @@ protected:
|
||||||
uint id;
|
uint id;
|
||||||
uint width;
|
uint width;
|
||||||
uint height;
|
uint height;
|
||||||
|
uint format;
|
||||||
public:
|
public:
|
||||||
Texture(uint id, uint width, uint height);
|
Texture(uint id, uint width, uint height, ImageFormat imageFormat);
|
||||||
Texture(const ubyte* data, uint width, uint height, ImageFormat format);
|
Texture(const ubyte* data, uint width, uint height, ImageFormat format);
|
||||||
virtual ~Texture();
|
virtual ~Texture();
|
||||||
|
|
||||||
virtual void bind() const;
|
virtual void bind() const;
|
||||||
virtual void unbind() const;
|
virtual void unbind() const;
|
||||||
void reload(const ubyte* data, uint w, uint h);
|
virtual void reload(const ubyte* data, uint w, uint h);
|
||||||
void reloadPartial(const ImageData& image, uint x, uint y, uint w, uint h);
|
void reloadPartial(const ImageData& image, uint x, uint y, uint w, uint h);
|
||||||
|
|
||||||
void setNearestFilter();
|
void setNearestFilter();
|
||||||
|
|
||||||
void reload(const ImageData& image);
|
void reload(const ImageData& image);
|
||||||
|
virtual void resize(uint w, uint h);
|
||||||
|
|
||||||
void setMipMapping(bool flag, bool pixelated);
|
void setMipMapping(bool flag, bool pixelated);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,44 @@
|
||||||
#include "Skybox.hpp"
|
#include "Skybox.hpp"
|
||||||
#include "assets/Assets.hpp"
|
|
||||||
#include "graphics/core/Shader.hpp"
|
#include <GL/glew.h>
|
||||||
#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 <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
|
||||||
#include <GL/glew.h>
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
#include <glm/gtc/constants.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;
|
using namespace advanced_pipeline;
|
||||||
|
|
||||||
const int STARS_COUNT = 3000;
|
const int STARS_COUNT = 3000;
|
||||||
|
|
||||||
const int STARS_SEED = 632;
|
const int STARS_SEED = 632;
|
||||||
|
|
||||||
Skybox::Skybox(uint size, Shader& shader)
|
Skybox::Skybox(uint size, const Assets& assets)
|
||||||
: size(size),
|
: size(size),
|
||||||
shader(shader),
|
assets(assets),
|
||||||
batch3d(std::make_unique<Batch3D>(4096))
|
shader(assets.require<Shader>("skybox_gen")),
|
||||||
{
|
batch3d(std::make_unique<Batch3D>(4096)) {
|
||||||
auto cubemap = std::make_unique<Cubemap>(size, size, ImageFormat::RGB888);
|
|
||||||
|
|
||||||
uint fboid;
|
SkyboxVertex vertices[] {
|
||||||
glGenFramebuffers(1, &fboid);
|
|
||||||
fbo = std::make_unique<Framebuffer>(fboid, 0, std::move(cubemap));
|
|
||||||
|
|
||||||
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}},
|
{{-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);
|
mesh = std::make_unique<Mesh<SkyboxVertex>>(vertices, 6);
|
||||||
|
|
||||||
|
|
@ -52,7 +49,7 @@ Skybox::Skybox(uint size, Shader& shader)
|
||||||
false,
|
false,
|
||||||
glm::pi<float>() * 0.25f,
|
glm::pi<float>() * 0.25f,
|
||||||
});
|
});
|
||||||
|
|
||||||
sprites.push_back(SkySprite {
|
sprites.push_back(SkySprite {
|
||||||
"misc/moon_flare",
|
"misc/moon_flare",
|
||||||
glm::pi<float>() * 0.5f,
|
glm::pi<float>() * 0.5f,
|
||||||
|
|
@ -68,20 +65,20 @@ Skybox::Skybox(uint size, Shader& shader)
|
||||||
true,
|
true,
|
||||||
glm::pi<float>() * 0.25f,
|
glm::pi<float>() * 0.25f,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setMode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Skybox::~Skybox() = default;
|
Skybox::~Skybox() = default;
|
||||||
|
|
||||||
void Skybox::drawBackground(
|
void Skybox::drawBackground(const Camera& camera, int width, int height) {
|
||||||
const Camera& camera, const Assets& assets, int width, int height
|
|
||||||
) {
|
|
||||||
auto backShader = assets.get<Shader>("background");
|
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(
|
backShader->uniform1f(
|
||||||
"u_zoom", camera.zoom * camera.getFov() / glm::half_pi<float>()
|
"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);
|
backShader->uniform1i("u_skybox", 1);
|
||||||
bind();
|
bind();
|
||||||
mesh->draw();
|
mesh->draw();
|
||||||
|
|
@ -93,9 +90,7 @@ void Skybox::drawStars(float angle, float opacity) {
|
||||||
random.setSeed(STARS_SEED);
|
random.setSeed(STARS_SEED);
|
||||||
|
|
||||||
glm::mat4 rotation = glm::rotate(
|
glm::mat4 rotation = glm::rotate(
|
||||||
glm::mat4(1.0f),
|
glm::mat4(1.0f), -angle + glm::pi<float>() * 0.5f, glm::vec3(0, 0, -1)
|
||||||
-angle + glm::pi<float>() * 0.5f,
|
|
||||||
glm::vec3(0, 0, -1)
|
|
||||||
);
|
);
|
||||||
rotation = glm::rotate(rotation, sunAltitude, glm::vec3(1, 0, 0));
|
rotation = glm::rotate(rotation, sunAltitude, glm::vec3(1, 0, 0));
|
||||||
|
|
||||||
|
|
@ -108,41 +103,20 @@ void Skybox::drawStars(float angle, float opacity) {
|
||||||
glm::vec3 pos = glm::vec4(rx, ry, rz, 1) * rotation;
|
glm::vec3 pos = glm::vec4(rx, ry, rz, 1) * rotation;
|
||||||
|
|
||||||
float sopacity = random.randFloat();
|
float sopacity = random.randFloat();
|
||||||
if (pos.y < 0.0f)
|
if (pos.y < 0.0f) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
sopacity *= (0.2f + std::sqrt(std::cos(angle)) * 0.5f) - 0.05f;
|
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->point(pos * depth, tint);
|
||||||
}
|
}
|
||||||
batch3d->flushPoints();
|
batch3d->flushPoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skybox::draw(
|
void Skybox::drawSkySprites(
|
||||||
const DrawContext& pctx,
|
|
||||||
const Camera& camera,
|
|
||||||
const Assets& assets,
|
|
||||||
float daytime,
|
float daytime,
|
||||||
float fog)
|
float angle,
|
||||||
{
|
float opacity
|
||||||
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 depthScale = 2e3;
|
float depthScale = 2e3;
|
||||||
for (auto& sprite : sprites) {
|
for (auto& sprite : sprites) {
|
||||||
batch3d->texture(assets.get<Texture>(sprite.texture));
|
batch3d->texture(assets.get<Texture>(sprite.texture));
|
||||||
|
|
@ -159,39 +133,132 @@ void Skybox::draw(
|
||||||
glm::vec3 pos = glm::vec4(0, distance, 0, 1) * rotation;
|
glm::vec3 pos = glm::vec4(0, distance, 0, 1) * rotation;
|
||||||
glm::vec3 up = glm::vec4(depthScale, 0, 0, 1) * rotation;
|
glm::vec3 up = glm::vec4(depthScale, 0, 0, 1) * rotation;
|
||||||
glm::vec3 right = glm::vec4(0, 0, depthScale, 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) {
|
if (!sprite.emissive) {
|
||||||
tint *= 0.6f + std::cos(angle)*0.4;
|
tint *= 0.6f + std::cos(angle) * 0.4;
|
||||||
}
|
}
|
||||||
batch3d->sprite(pos, right,
|
batch3d->sprite(pos, right, up, 1, 1, UVRegion(), tint);
|
||||||
up, 1, 1, UVRegion(), tint);
|
|
||||||
}
|
}
|
||||||
batch3d->flush();
|
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();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
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 && !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) {
|
||||||
|
drawSkySprites(daytime, angle, opacity);
|
||||||
|
}
|
||||||
|
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()});
|
||||||
|
|
||||||
|
auto cubemap = dynamic_cast<Cubemap*>(fbo->getTexture());
|
||||||
|
assert(cubemap != nullptr);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
|
||||||
|
cubemap->bind();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
cubemap->unbind();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
frameid++;
|
frameid++;
|
||||||
float dayTime = t;
|
|
||||||
DrawContext ctx = pctx.sub();
|
DrawContext ctx = pctx.sub();
|
||||||
ctx.setDepthMask(false);
|
ctx.setDepthMask(false);
|
||||||
ctx.setDepthTest(false);
|
ctx.setDepthTest(false);
|
||||||
ctx.setFramebuffer(fbo.get());
|
ctx.setFramebuffer(fbo.get());
|
||||||
ctx.setViewport({size, size});
|
ctx.setViewport({fbo->getWidth(), fbo->getHeight()});
|
||||||
|
|
||||||
auto cubemap = dynamic_cast<Cubemap*>(fbo->getTexture());
|
auto cubemap = dynamic_cast<Cubemap*>(fbo->getTexture());
|
||||||
assert(cubemap != nullptr);
|
assert(cubemap != nullptr);
|
||||||
|
|
||||||
ready = true;
|
|
||||||
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
|
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
|
||||||
cubemap->bind();
|
cubemap->bind();
|
||||||
shader.use();
|
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));
|
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 sunAngle = glm::radians((dayTime - 0.25f) * 360.0f);
|
||||||
float x = -glm::cos(sunAngle + glm::pi<float>() * 0.5f) * glm::radians(sunAltitude);
|
float x = -glm::cos(sunAngle + glm::pi<float>() * 0.5f) *
|
||||||
|
glm::radians(sunAltitude);
|
||||||
float y = sunAngle - glm::pi<float>() * 0.5f;
|
float y = sunAngle - glm::pi<float>() * 0.5f;
|
||||||
float z = glm::radians(0.0f);
|
float z = glm::radians(0.0f);
|
||||||
rotation = glm::rotate(glm::mat4(1.0f), y, glm::vec3(0, 1, 0));
|
rotation = glm::rotate(glm::mat4(1.0f), y, glm::vec3(0, 1, 0));
|
||||||
|
|
@ -207,7 +274,9 @@ void Skybox::refresh(const DrawContext& pctx, float t, float mie, const glm::vec
|
||||||
shader.uniform3f("u_lightDir", lightDir);
|
shader.uniform3f("u_lightDir", lightDir);
|
||||||
shader.uniform1f("u_dayTime", dayTime);
|
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++) {
|
for (uint face = 0; face < 6; face++) {
|
||||||
refreshFace(face, cubemap);
|
refreshFace(face, cubemap);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#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 Shader;
|
||||||
class Assets;
|
class Assets;
|
||||||
class Camera;
|
class Camera;
|
||||||
|
|
@ -21,8 +25,7 @@ struct SkyboxVertex {
|
||||||
glm::vec2 position;
|
glm::vec2 position;
|
||||||
|
|
||||||
static constexpr VertexAttribute ATTRIBUTES[] {
|
static constexpr VertexAttribute ATTRIBUTES[] {
|
||||||
{VertexAttribute::Type::FLOAT, false, 2},
|
{VertexAttribute::Type::FLOAT, false, 2}, {{}, 0}};
|
||||||
{{}, 0}};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SkySprite {
|
struct SkySprite {
|
||||||
|
|
@ -34,10 +37,11 @@ struct SkySprite {
|
||||||
};
|
};
|
||||||
|
|
||||||
class Skybox {
|
class Skybox {
|
||||||
std::unique_ptr<Framebuffer> fbo;
|
SkyMode mode = SkyMode::SOLID;
|
||||||
uint size;
|
uint size;
|
||||||
|
std::unique_ptr<Framebuffer> fbo;
|
||||||
|
const Assets& assets;
|
||||||
Shader& shader;
|
Shader& shader;
|
||||||
bool ready = false;
|
|
||||||
FastRandom random;
|
FastRandom random;
|
||||||
glm::vec3 lightDir;
|
glm::vec3 lightDir;
|
||||||
|
|
||||||
|
|
@ -53,30 +57,36 @@ class Skybox {
|
||||||
glm::mat4 rotation;
|
glm::mat4 rotation;
|
||||||
|
|
||||||
void drawStars(float angle, float opacity);
|
void drawStars(float angle, float opacity);
|
||||||
void drawBackground(
|
void drawBackground(const Camera& camera, int width, int height);
|
||||||
const Camera& camera, const Assets& assets, int width, int height
|
void drawSkySprites(float daytime, float angle, float opacity);
|
||||||
);
|
|
||||||
void refreshFace(uint face, Cubemap* cubemap);
|
void refreshFace(uint face, Cubemap* cubemap);
|
||||||
public:
|
public:
|
||||||
Skybox(uint size, Shader& shader);
|
Skybox(uint size, const Assets& assets);
|
||||||
~Skybox();
|
~Skybox();
|
||||||
|
|
||||||
|
void setMode(SkyMode mode);
|
||||||
|
|
||||||
void draw(
|
void draw(
|
||||||
const DrawContext& pctx,
|
const Environment& environment,
|
||||||
const Camera& camera,
|
const DrawContext& pctx,
|
||||||
const Assets& assets,
|
const Camera& camera,
|
||||||
float daytime,
|
float daytime,
|
||||||
float fog
|
float fog
|
||||||
);
|
);
|
||||||
|
|
||||||
void refresh(const DrawContext& pctx, float t, float mie, const glm::vec3& tint, const glm::vec3& hightlight, uint quality);
|
void refresh(
|
||||||
|
const Environment& environment,
|
||||||
|
const DrawContext& pctx,
|
||||||
|
float t,
|
||||||
|
float mie,
|
||||||
|
const glm::vec3& tint,
|
||||||
|
const glm::vec3& hightlight,
|
||||||
|
uint quality
|
||||||
|
);
|
||||||
void bind() const;
|
void bind() const;
|
||||||
void unbind() const;
|
void unbind() const;
|
||||||
bool isReady() const {
|
|
||||||
return ready;
|
|
||||||
}
|
|
||||||
|
|
||||||
const glm::vec3 getLightDir() const {
|
const glm::vec3& getLightDir() const {
|
||||||
return lightDir;
|
return lightDir;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,45 @@
|
||||||
#include "WorldRenderer.hpp"
|
#include "WorldRenderer.hpp"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#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.hpp"
|
||||||
#include "assets/assets_util.hpp"
|
#include "assets/assets_util.hpp"
|
||||||
|
#include "coders/GLSLExtension.hpp"
|
||||||
#include "content/Content.hpp"
|
#include "content/Content.hpp"
|
||||||
#include "engine/Engine.hpp"
|
#include "engine/Engine.hpp"
|
||||||
#include "coders/GLSLExtension.hpp"
|
|
||||||
#include "frontend/LevelFrontend.hpp"
|
|
||||||
#include "frontend/ContentGfxCache.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/Texture.hpp"
|
||||||
#include "items/Inventory.hpp"
|
#include "items/Inventory.hpp"
|
||||||
#include "items/ItemDef.hpp"
|
#include "items/ItemDef.hpp"
|
||||||
#include "items/ItemStack.hpp"
|
#include "items/ItemStack.hpp"
|
||||||
|
|
@ -25,38 +58,6 @@
|
||||||
#include "world/Level.hpp"
|
#include "world/Level.hpp"
|
||||||
#include "world/LevelEvents.hpp"
|
#include "world/LevelEvents.hpp"
|
||||||
#include "world/World.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>
|
|
||||||
#include <glm/ext.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
using namespace advanced_pipeline;
|
using namespace advanced_pipeline;
|
||||||
|
|
||||||
|
|
@ -105,8 +106,7 @@ WorldRenderer::WorldRenderer(
|
||||||
[this](LevelEventType, Chunk* chunk) { chunksRenderer->unload(chunk); }
|
[this](LevelEventType, Chunk* chunk) { chunksRenderer->unload(chunk); }
|
||||||
);
|
);
|
||||||
skybox = std::make_unique<Skybox>(
|
skybox = std::make_unique<Skybox>(
|
||||||
settings.graphics.skyboxResolution.get(),
|
settings.graphics.skyboxResolution.get(), assets
|
||||||
assets.require<Shader>("skybox_gen")
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const auto& content = level.content;
|
const auto& content = level.content;
|
||||||
|
|
@ -179,6 +179,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(
|
void WorldRenderer::renderOpaque(
|
||||||
const DrawContext& ctx,
|
const DrawContext& ctx,
|
||||||
const Camera& camera,
|
const Camera& camera,
|
||||||
|
|
@ -187,14 +192,13 @@ void WorldRenderer::renderOpaque(
|
||||||
) {
|
) {
|
||||||
texts->render(ctx, camera, settings, hudVisible, false);
|
texts->render(ctx, camera, settings, hudVisible, false);
|
||||||
|
|
||||||
bool culling = engine.getSettings().graphics.frustumCulling.get();
|
float fogFactor = calcFogFactor();
|
||||||
float fogFactor =
|
|
||||||
15.0f / static_cast<float>(settings.chunks.loadDistance.get() - 2);
|
|
||||||
|
|
||||||
auto& entityShader = assets.require<Shader>("entity");
|
auto& entityShader = assets.require<Shader>("entity");
|
||||||
setupWorldShader(entityShader, camera, settings, fogFactor);
|
setupWorldShader(entityShader, camera, settings, fogFactor);
|
||||||
skybox->bind();
|
skybox->bind();
|
||||||
|
|
||||||
|
bool culling = engine.getSettings().graphics.frustumCulling.get();
|
||||||
if (culling) {
|
if (culling) {
|
||||||
frustumCulling->update(camera.getProjView());
|
frustumCulling->update(camera.getProjView());
|
||||||
}
|
}
|
||||||
|
|
@ -213,22 +217,24 @@ void WorldRenderer::renderOpaque(
|
||||||
|
|
||||||
auto& shader = assets.require<Shader>("main");
|
auto& shader = assets.require<Shader>("main");
|
||||||
auto& cloudsShader = assets.require<Shader>("clouds");
|
auto& cloudsShader = assets.require<Shader>("clouds");
|
||||||
auto& linesShader = assets.require<Shader>("lines");
|
|
||||||
|
|
||||||
setupWorldShader(shader, camera, settings, fogFactor);
|
setupWorldShader(shader, camera, settings, fogFactor);
|
||||||
|
|
||||||
chunksRenderer->drawChunks(camera, shader);
|
chunksRenderer->drawChunks(camera, shader);
|
||||||
blockWraps->draw(ctx);
|
blockWraps->draw(ctx);
|
||||||
|
|
||||||
int cloudsQuality = settings.graphics.cloudsQuality.get();
|
if (level.environment.sky.clouds) {
|
||||||
if (cloudsQuality > 0) {
|
int cloudsQuality = settings.graphics.cloudsQuality.get();
|
||||||
setupWorldShader(cloudsShader, camera, settings, fogFactor);
|
if (cloudsQuality > 0) {
|
||||||
cloudsRenderer->draw(
|
setupWorldShader(cloudsShader, camera, settings, fogFactor);
|
||||||
cloudsShader, weather, timer, fogFactor, camera, cloudsQuality
|
cloudsRenderer->draw(
|
||||||
);
|
cloudsShader, weather, timer, fogFactor, camera, cloudsQuality
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hudVisible) {
|
if (hudVisible) {
|
||||||
|
auto& linesShader = assets.require<Shader>("lines");
|
||||||
renderLines(camera, linesShader, ctx);
|
renderLines(camera, linesShader, ctx);
|
||||||
}
|
}
|
||||||
skybox->unbind();
|
skybox->unbind();
|
||||||
|
|
@ -286,21 +292,19 @@ void WorldRenderer::refreshSettings(Shader** shaders) {
|
||||||
|
|
||||||
int shadowsQuality = graphics.shadowsQuality.get() * gbufferPipeline;
|
int shadowsQuality = graphics.shadowsQuality.get() * gbufferPipeline;
|
||||||
shadowMapping->setQuality(shadowsQuality);
|
shadowMapping->setQuality(shadowsQuality);
|
||||||
|
|
||||||
CompileTimeShaderSettings currentSettings {
|
CompileTimeShaderSettings currentSettings {
|
||||||
gbufferPipeline,
|
gbufferPipeline,
|
||||||
shadowsQuality != 0,
|
shadowsQuality != 0,
|
||||||
graphics.ssao.get() && gbufferPipeline
|
graphics.ssao.get() && gbufferPipeline};
|
||||||
};
|
if (prevCTShaderSettings.advancedRender != currentSettings.advancedRender ||
|
||||||
if (
|
|
||||||
prevCTShaderSettings.advancedRender != currentSettings.advancedRender ||
|
|
||||||
prevCTShaderSettings.shadows != currentSettings.shadows ||
|
prevCTShaderSettings.shadows != currentSettings.shadows ||
|
||||||
prevCTShaderSettings.ssao != currentSettings.ssao
|
prevCTShaderSettings.ssao != currentSettings.ssao) {
|
||||||
) {
|
|
||||||
std::vector<std::string> defines;
|
std::vector<std::string> defines;
|
||||||
if (currentSettings.shadows) defines.emplace_back("ENABLE_SHADOWS");
|
if (currentSettings.shadows) defines.emplace_back("ENABLE_SHADOWS");
|
||||||
if (currentSettings.ssao) defines.emplace_back("ENABLE_SSAO");
|
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++) {
|
for (size_t i = 0; shaders[i]; i++) {
|
||||||
shaders[i]->recompile(defines);
|
shaders[i]->recompile(defines);
|
||||||
|
|
@ -332,7 +336,8 @@ void WorldRenderer::renderFrame(
|
||||||
auto& entityShader = assets.require<Shader>("entity");
|
auto& entityShader = assets.require<Shader>("entity");
|
||||||
auto& cloudsShader = assets.require<Shader>("clouds");
|
auto& cloudsShader = assets.require<Shader>("clouds");
|
||||||
auto& translucentShader = assets.require<Shader>("translucent");
|
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();
|
const auto& settings = engine.getSettings();
|
||||||
|
|
||||||
|
|
@ -342,19 +347,19 @@ void WorldRenderer::renderFrame(
|
||||||
&cloudsShader,
|
&cloudsShader,
|
||||||
&translucentShader,
|
&translucentShader,
|
||||||
&deferredShader,
|
&deferredShader,
|
||||||
nullptr
|
nullptr};
|
||||||
};
|
|
||||||
|
|
||||||
refreshSettings(affectedShaders);
|
refreshSettings(affectedShaders);
|
||||||
|
|
||||||
const auto& worldInfo = world->getInfo();
|
const auto& worldInfo = world->getInfo();
|
||||||
|
|
||||||
float clouds = weather.clouds();
|
float clouds = weather.clouds();
|
||||||
clouds = glm::max(worldInfo.fog, clouds);
|
clouds = glm::max(worldInfo.fog, clouds);
|
||||||
float mie = 1.0f + glm::max(worldInfo.fog, clouds * 0.5f) * 2.0f;
|
float mie = 1.0f + glm::max(worldInfo.fog, clouds * 0.5f) * 2.0f;
|
||||||
|
|
||||||
float random = rand() / static_cast<float>(RAND_MAX);
|
float random = rand() / static_cast<float>(RAND_MAX);
|
||||||
skybox->refresh(
|
skybox->refresh(
|
||||||
|
level.environment,
|
||||||
pctx,
|
pctx,
|
||||||
worldInfo.daytime,
|
worldInfo.daytime,
|
||||||
mie,
|
mie,
|
||||||
|
|
@ -385,8 +390,7 @@ void WorldRenderer::renderFrame(
|
||||||
texts->render(pctx, camera, settings, hudVisible, true);
|
texts->render(pctx, camera, settings, hudVisible, true);
|
||||||
}
|
}
|
||||||
skybox->bind();
|
skybox->bind();
|
||||||
float fogFactor =
|
float fogFactor = calcFogFactor();
|
||||||
15.0f / static_cast<float>(settings.chunks.loadDistance.get() - 2);
|
|
||||||
if (gbufferPipeline) {
|
if (gbufferPipeline) {
|
||||||
deferredShader.use();
|
deferredShader.use();
|
||||||
setupWorldShader(deferredShader, camera, settings, fogFactor);
|
setupWorldShader(deferredShader, camera, settings, fogFactor);
|
||||||
|
|
@ -403,7 +407,9 @@ void WorldRenderer::renderFrame(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Background sky plane
|
// 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");
|
auto& linesShader = assets.require<Shader>("lines");
|
||||||
linesShader.use();
|
linesShader.use();
|
||||||
|
|
@ -429,14 +435,17 @@ void WorldRenderer::renderFrame(
|
||||||
entityShader.use();
|
entityShader.use();
|
||||||
setupWorldShader(entityShader, camera, settings, fogFactor);
|
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) {
|
for (const auto& weather : weatherInstances) {
|
||||||
float maxIntensity = weather->fall.maxIntensity;
|
float maxIntensity = weather->fall.maxIntensity;
|
||||||
float zero = weather->fall.minOpacity;
|
float zero = weather->fall.minOpacity;
|
||||||
float one = weather->fall.maxOpacity;
|
float one = weather->fall.maxOpacity;
|
||||||
float t = (weather->intensity * (one - zero)) * maxIntensity + zero;
|
float t = (weather->intensity * (one - zero)) * maxIntensity + zero;
|
||||||
entityShader.uniform1i("u_alphaClip", weather->fall.opaque);
|
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()) {
|
if (weather->intensity > 1.e-3f && !weather->fall.texture.empty()) {
|
||||||
precipitation->render(camera, *weather);
|
precipitation->render(camera, *weather);
|
||||||
}
|
}
|
||||||
|
|
@ -446,7 +455,7 @@ void WorldRenderer::renderFrame(
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
postProcessing.render(pctx, assets, timer, camera);
|
postProcessing.render(pctx, assets, timer, camera);
|
||||||
|
|
||||||
if (player.currentCamera == player.fpCamera) {
|
if (player.currentCamera == player.fpCamera) {
|
||||||
DrawContext ctx = pctx.sub();
|
DrawContext ctx = pctx.sub();
|
||||||
ctx.setDepthTest(true);
|
ctx.setDepthTest(true);
|
||||||
|
|
@ -457,7 +466,7 @@ void WorldRenderer::renderFrame(
|
||||||
hudcam.far = 10.0f;
|
hudcam.far = 10.0f;
|
||||||
hudcam.setFov(0.9f);
|
hudcam.setFov(0.9f);
|
||||||
hudcam.position = {};
|
hudcam.position = {};
|
||||||
|
|
||||||
hands->render(camera);
|
hands->render(camera);
|
||||||
|
|
||||||
display::clearDepth();
|
display::clearDepth();
|
||||||
|
|
@ -486,13 +495,12 @@ void WorldRenderer::renderBlockOverlay(const DrawContext& wctx) {
|
||||||
if (def.overlayTexture.empty()) {
|
if (def.overlayTexture.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto textureRegion = util::get_texture_region(
|
auto textureRegion =
|
||||||
assets, def.overlayTexture, "blocks:notfound"
|
util::get_texture_region(assets, def.overlayTexture, "blocks:notfound");
|
||||||
);
|
|
||||||
DrawContext ctx = wctx.sub();
|
DrawContext ctx = wctx.sub();
|
||||||
ctx.setDepthTest(false);
|
ctx.setDepthTest(false);
|
||||||
ctx.setCullFace(false);
|
ctx.setCullFace(false);
|
||||||
|
|
||||||
auto& shader = assets.require<Shader>("ui3d");
|
auto& shader = assets.require<Shader>("ui3d");
|
||||||
shader.use();
|
shader.use();
|
||||||
batch3d->begin();
|
batch3d->begin();
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,8 @@ class WorldRenderer {
|
||||||
);
|
);
|
||||||
|
|
||||||
void refreshSettings(Shader** shaders);
|
void refreshSettings(Shader** shaders);
|
||||||
|
|
||||||
|
float calcFogFactor() const;
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<ParticlesRenderer> particles;
|
std::unique_ptr<ParticlesRenderer> particles;
|
||||||
std::unique_ptr<TextsRenderer> texts;
|
std::unique_ptr<TextsRenderer> texts;
|
||||||
|
|
|
||||||
25
src/world/Environment.cpp
Normal file
25
src/world/Environment.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#define VC_ENABLE_REFLECTION
|
||||||
|
#include "Environment.hpp"
|
||||||
|
|
||||||
|
#include "data/dv.hpp"
|
||||||
|
#include "data/dv_util.hpp"
|
||||||
|
|
||||||
|
dv::value Environment::serialize() const {
|
||||||
|
return dv::object({
|
||||||
|
{"sky", dv::object({
|
||||||
|
{"mode", SkyModeMeta.getNameString(sky.mode)},
|
||||||
|
{"stars", sky.stars},
|
||||||
|
{"clouds", sky.clouds},
|
||||||
|
{"sprites", sky.sprites},
|
||||||
|
})},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::deserialize(const dv::value& src) {
|
||||||
|
if (auto skyItem = src.at("sky")) {
|
||||||
|
skyItem->at("mode").get(sky.mode, SkyModeMeta);
|
||||||
|
skyItem->at("stars").get(sky.stars);
|
||||||
|
skyItem->at("clouds").get(sky.clouds);
|
||||||
|
skyItem->at("sprites").get(sky.sprites);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/world/Environment.hpp
Normal file
30
src/world/Environment.hpp
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "interfaces/Serializable.hpp"
|
||||||
|
#include "util/EnumMetadata.hpp"
|
||||||
|
|
||||||
|
enum class SkyMode {
|
||||||
|
NONE, SOLID, BOX
|
||||||
|
};
|
||||||
|
|
||||||
|
VC_ENUM_METADATA(SkyMode)
|
||||||
|
{"none", SkyMode::NONE},
|
||||||
|
{"solid", SkyMode::SOLID},
|
||||||
|
{"box", SkyMode::BOX},
|
||||||
|
VC_ENUM_END
|
||||||
|
|
||||||
|
class Environment : public Serializable {
|
||||||
|
public:
|
||||||
|
struct {
|
||||||
|
SkyMode mode = SkyMode::BOX;
|
||||||
|
bool stars = true;
|
||||||
|
bool clouds = true;
|
||||||
|
bool sprites = true;
|
||||||
|
} sky;
|
||||||
|
|
||||||
|
Environment() = default;
|
||||||
|
|
||||||
|
dv::value serialize() const override;
|
||||||
|
void deserialize(const dv::value& src) override;
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
|
#include "Environment.hpp"
|
||||||
|
|
||||||
class Content;
|
class Content;
|
||||||
class World;
|
class World;
|
||||||
|
|
@ -36,6 +37,7 @@ public:
|
||||||
std::unique_ptr<Players> players;
|
std::unique_ptr<Players> players;
|
||||||
std::unique_ptr<voxels::Pathfinding> pathfinding;
|
std::unique_ptr<voxels::Pathfinding> pathfinding;
|
||||||
std::vector<std::shared_ptr<Camera>> cameras; // move somewhere?
|
std::vector<std::shared_ptr<Camera>> cameras; // move somewhere?
|
||||||
|
Environment environment {};
|
||||||
|
|
||||||
Level(
|
Level(
|
||||||
std::unique_ptr<World> world,
|
std::unique_ptr<World> world,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue