mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-09 21:11:50 +00:00
Merge remote-tracking branch 'origin/main' into sdl-try-2
This commit is contained in:
commit
9dad26232a
264 changed files with 8609 additions and 2047 deletions
|
|
@ -38,6 +38,10 @@ bool Font::isPrintableChar(uint codepoint) const {
|
|||
}
|
||||
}
|
||||
|
||||
int FontMetrics::calcWidth(std::wstring_view text, size_t offset, size_t length) const {
|
||||
return std::min(text.length() - offset, length) * glyphInterval;
|
||||
}
|
||||
|
||||
int Font::calcWidth(std::wstring_view text, size_t length) const {
|
||||
return calcWidth(text, 0, length);
|
||||
}
|
||||
|
|
@ -57,6 +61,14 @@ static inline void draw_glyph(
|
|||
const FontStyle& style
|
||||
) {
|
||||
for (int i = 0; i <= style.bold; i++) {
|
||||
glm::vec4 color;
|
||||
|
||||
if (style.color == glm::vec4(1, 1, 1, 1)) {
|
||||
color = batch.getColor();
|
||||
} else {
|
||||
color = style.color;
|
||||
}
|
||||
|
||||
batch.sprite(
|
||||
pos.x + (offset.x + i / (right.x/glyphInterval/2.0f)) * right.x,
|
||||
pos.y + offset.y * right.y,
|
||||
|
|
@ -65,7 +77,7 @@ static inline void draw_glyph(
|
|||
-0.15f * style.italic,
|
||||
16,
|
||||
c,
|
||||
batch.getColor() * style.color
|
||||
color
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -81,6 +93,15 @@ static inline void draw_glyph(
|
|||
const FontStyle& style
|
||||
) {
|
||||
for (int i = 0; i <= style.bold; i++) {
|
||||
glm::vec4 color;
|
||||
|
||||
if (style.color == glm::vec4(1, 1, 1, 1)) {
|
||||
color = batch.getColor();
|
||||
} else {
|
||||
color = style.color;
|
||||
}
|
||||
|
||||
|
||||
batch.sprite(
|
||||
pos + right * (offset.x + i) + up * offset.y,
|
||||
up, right / glyphInterval,
|
||||
|
|
@ -88,7 +109,7 @@ static inline void draw_glyph(
|
|||
0.5f,
|
||||
16,
|
||||
c,
|
||||
batch.getColor() * style.color
|
||||
color
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "typedefs.hpp"
|
||||
#include "FontMetics.hpp"
|
||||
|
||||
class Texture;
|
||||
class Batch2D;
|
||||
|
|
@ -90,4 +92,8 @@ public:
|
|||
) const;
|
||||
|
||||
const Texture* getPage(int page) const;
|
||||
|
||||
FontMetrics getMetrics() const {
|
||||
return {lineHeight, yoffset, glyphInterval};
|
||||
}
|
||||
};
|
||||
|
|
|
|||
11
src/graphics/core/FontMetics.hpp
Normal file
11
src/graphics/core/FontMetics.hpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
struct FontMetrics {
|
||||
int lineHeight;
|
||||
int yoffset;
|
||||
int glyphInterval = 8;
|
||||
|
||||
int calcWidth(std::wstring_view text, size_t offset=0, size_t length=-1) const;
|
||||
};
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include "ImageData.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
|
|
@ -187,6 +188,41 @@ void ImageData::drawLine(int x1, int y1, int x2, int y2, const glm::ivec4& color
|
|||
}
|
||||
}
|
||||
|
||||
template<uint channels>
|
||||
static void draw_rect(ImageData& image, int dstX, int dstY, int width, int height, const glm::ivec4& color) {
|
||||
ubyte* data = image.getData();
|
||||
int imageWidth = image.getWidth();
|
||||
int imageHeight = image.getHeight();
|
||||
|
||||
int x1 = glm::min(glm::max(dstX, 0), imageWidth - 1);
|
||||
int y1 = glm::min(glm::max(dstY, 0), imageHeight - 1);
|
||||
|
||||
int x2 = glm::min(glm::max(dstX + width, 0), imageWidth - 1);
|
||||
int y2 = glm::min(glm::max(dstY + height, 0), imageHeight - 1);
|
||||
|
||||
for (int y = y1; y <= y2; y++) {
|
||||
for (int x = x1; x <= x2; x++) {
|
||||
int index = (y * imageWidth + x) * channels;
|
||||
for (int i = 0; i < channels; i++) {
|
||||
data[index + i] = color[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImageData::drawRect(int x, int y, int width, int height, const glm::ivec4& color) {
|
||||
switch (format) {
|
||||
case ImageFormat::rgb888:
|
||||
draw_rect<3>(*this, x, y, width, height, color);
|
||||
break;
|
||||
case ImageFormat::rgba8888:
|
||||
draw_rect<4>(*this, x, y, width, height, color);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageData::blitRGB_on_RGBA(const ImageData& image, int x, int y) {
|
||||
ubyte* source = image.getData();
|
||||
uint srcwidth = image.getWidth();
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ public:
|
|||
void flipY();
|
||||
|
||||
void drawLine(int x1, int y1, int x2, int y2, const glm::ivec4& color);
|
||||
void drawRect(int x, int y, int width, int height, const glm::ivec4& color);
|
||||
void blit(const ImageData& image, int x, int y);
|
||||
void extrude(int x, int y, int w, int h);
|
||||
void fixAlphaColor();
|
||||
|
|
|
|||
|
|
@ -128,15 +128,21 @@ glshader compile_shader(GLenum type, const GLchar* source, const std::string& fi
|
|||
}
|
||||
|
||||
static GLuint compile_program(
|
||||
const Shader::Source& vertexSource, const Shader::Source& fragmentSource
|
||||
const Shader::Source& vertexSource,
|
||||
const Shader::Source& fragmentSource,
|
||||
const std::vector<std::string>& defines
|
||||
) {
|
||||
auto& preprocessor = *Shader::preprocessor;
|
||||
|
||||
auto vertexCode = std::move(
|
||||
preprocessor.process(vertexSource.file, vertexSource.code).code
|
||||
preprocessor
|
||||
.process(vertexSource.file, vertexSource.code, false, defines)
|
||||
.code
|
||||
);
|
||||
auto fragmentCode = std::move(
|
||||
preprocessor.process(fragmentSource.file, fragmentSource.code).code
|
||||
preprocessor
|
||||
.process(fragmentSource.file, fragmentSource.code, false, defines)
|
||||
.code
|
||||
);
|
||||
|
||||
const GLchar* vCode = vertexCode.c_str();
|
||||
|
|
@ -166,8 +172,8 @@ static GLuint compile_program(
|
|||
return program;
|
||||
}
|
||||
|
||||
void Shader::recompile() {
|
||||
GLuint newProgram = compile_program(vertexSource, fragmentSource);
|
||||
void Shader::recompile(const std::vector<std::string>& defines) {
|
||||
GLuint newProgram = compile_program(vertexSource, fragmentSource, defines);
|
||||
glDeleteProgram(id);
|
||||
id = newProgram;
|
||||
uniformLocations.clear();
|
||||
|
|
@ -178,7 +184,7 @@ std::unique_ptr<Shader> Shader::create(
|
|||
Source&& vertexSource, Source&& fragmentSource
|
||||
) {
|
||||
return std::make_unique<Shader>(
|
||||
compile_program(vertexSource, fragmentSource),
|
||||
compile_program(vertexSource, fragmentSource, {}),
|
||||
std::move(vertexSource),
|
||||
std::move(fragmentSource)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
|
|
@ -50,7 +51,7 @@ public:
|
|||
void uniform4v(const std::string& name, int length, const float* v);
|
||||
|
||||
/// @brief Re-preprocess source code and re-compile shader program
|
||||
void recompile();
|
||||
void recompile(const std::vector<std::string>& defines);
|
||||
|
||||
/// @brief Create shader program using vertex and fragment shaders source.
|
||||
/// @return linked shader program containing vertex and fragment shaders
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
#include "ShadowMap.hpp"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
ShadowMap::ShadowMap(int resolution) : resolution(resolution) {
|
||||
glGenTextures(1, &depthMap);
|
||||
glBindTexture(GL_TEXTURE_2D, depthMap);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
|
||||
resolution, resolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
float border[4] {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR, border);
|
||||
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
ShadowMap::~ShadowMap() {
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
glDeleteTextures(1, &depthMap);
|
||||
}
|
||||
|
||||
void ShadowMap::bind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void ShadowMap::unbind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
uint ShadowMap::getDepthMap() const {
|
||||
return depthMap;
|
||||
}
|
||||
|
||||
int ShadowMap::getResolution() const {
|
||||
return resolution;
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "typedefs.hpp"
|
||||
|
||||
class ShadowMap {
|
||||
public:
|
||||
ShadowMap(int resolution);
|
||||
~ShadowMap();
|
||||
|
||||
void bind();
|
||||
void unbind();
|
||||
uint getDepthMap() const;
|
||||
int getResolution() const;
|
||||
private:
|
||||
uint fbo;
|
||||
uint depthMap;
|
||||
int resolution;
|
||||
};
|
||||
203
src/graphics/core/Shadows.cpp
Normal file
203
src/graphics/core/Shadows.cpp
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
#include "Shadows.hpp"
|
||||
|
||||
#include <GL/glew.h>
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/norm.hpp>
|
||||
|
||||
#include "assets/Assets.hpp"
|
||||
#include "graphics/core/DrawContext.hpp"
|
||||
#include "graphics/core/Shader.hpp"
|
||||
#include "graphics/core/commons.hpp"
|
||||
#include "world/Level.hpp"
|
||||
#include "world/Weather.hpp"
|
||||
#include "world/World.hpp"
|
||||
|
||||
using namespace advanced_pipeline;
|
||||
|
||||
inline constexpr int MIN_SHADOW_MAP_RES = 512;
|
||||
inline constexpr GLenum TEXTURE_MAIN = GL_TEXTURE0;
|
||||
|
||||
class ShadowMap {
|
||||
public:
|
||||
ShadowMap(int resolution) : resolution(resolution) {
|
||||
glGenTextures(1, &depthMap);
|
||||
glBindTexture(GL_TEXTURE_2D, depthMap);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
|
||||
resolution, resolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(
|
||||
GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE
|
||||
);
|
||||
float border[4] {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
|
||||
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0
|
||||
);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
~ShadowMap() {
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
glDeleteTextures(1, &depthMap);
|
||||
}
|
||||
|
||||
void bind(){
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void unbind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
uint getDepthMap() const {
|
||||
return depthMap;
|
||||
}
|
||||
int getResolution() const {
|
||||
return resolution;
|
||||
}
|
||||
private:
|
||||
uint fbo;
|
||||
uint depthMap;
|
||||
int resolution;
|
||||
};
|
||||
|
||||
Shadows::Shadows(const Level& level) : level(level) {}
|
||||
|
||||
Shadows::~Shadows() = default;
|
||||
|
||||
void Shadows::setQuality(int quality) {
|
||||
int resolution = MIN_SHADOW_MAP_RES << quality;
|
||||
if (quality > 0 && !shadows) {
|
||||
shadowMap = std::make_unique<ShadowMap>(resolution);
|
||||
wideShadowMap = std::make_unique<ShadowMap>(resolution);
|
||||
shadows = true;
|
||||
} else if (quality == 0 && shadows) {
|
||||
shadowMap.reset();
|
||||
wideShadowMap.reset();
|
||||
shadows = false;
|
||||
}
|
||||
if (shadows && shadowMap->getResolution() != resolution) {
|
||||
shadowMap = std::make_unique<ShadowMap>(resolution);
|
||||
wideShadowMap = std::make_unique<ShadowMap>(resolution);
|
||||
}
|
||||
this->quality = quality;
|
||||
}
|
||||
|
||||
void Shadows::setup(Shader& shader, const Weather& weather) {
|
||||
if (shadows) {
|
||||
const auto& worldInfo = level.getWorld()->getInfo();
|
||||
float cloudsIntensity = glm::max(worldInfo.fog, weather.clouds());
|
||||
float shadowsOpacity = 1.0f - cloudsIntensity;
|
||||
shadowsOpacity *= glm::sqrt(glm::abs(
|
||||
glm::mod((worldInfo.daytime + 0.5f) * 2.0f, 1.0f) * 2.0f - 1.0f
|
||||
));
|
||||
shader.uniform1i("u_screen", 0);
|
||||
shader.uniformMatrix("u_shadowsMatrix[0]", shadowCamera.getProjView());
|
||||
shader.uniformMatrix("u_shadowsMatrix[1]", wideShadowCamera.getProjView());
|
||||
shader.uniform3f("u_sunDir", shadowCamera.front);
|
||||
shader.uniform1i("u_shadowsRes", shadowMap->getResolution());
|
||||
shader.uniform1f("u_shadowsOpacity", shadowsOpacity); // TODO: make it configurable
|
||||
shader.uniform1f("u_shadowsSoftness", 1.0f + cloudsIntensity * 4); // TODO: make it configurable
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS0);
|
||||
shader.uniform1i("u_shadows[0]", TARGET_SHADOWS0);
|
||||
glBindTexture(GL_TEXTURE_2D, shadowMap->getDepthMap());
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS1);
|
||||
shader.uniform1i("u_shadows[1]", TARGET_SHADOWS1);
|
||||
glBindTexture(GL_TEXTURE_2D, wideShadowMap->getDepthMap());
|
||||
|
||||
glActiveTexture(TEXTURE_MAIN);
|
||||
}
|
||||
}
|
||||
|
||||
void Shadows::refresh(const Camera& camera, const DrawContext& pctx, std::function<void(Camera&)> renderShadowPass) {
|
||||
static int frameid = 0;
|
||||
if (shadows) {
|
||||
if (frameid % 2 == 0) {
|
||||
generateShadowsMap(camera, pctx, *shadowMap, shadowCamera, 1.0f, renderShadowPass);
|
||||
} else {
|
||||
generateShadowsMap(camera, pctx, *wideShadowMap, wideShadowCamera, 3.0f, renderShadowPass);
|
||||
}
|
||||
}
|
||||
frameid++;
|
||||
}
|
||||
|
||||
void Shadows::generateShadowsMap(
|
||||
const Camera& camera,
|
||||
const DrawContext& pctx,
|
||||
ShadowMap& shadowMap,
|
||||
Camera& shadowCamera,
|
||||
float scale,
|
||||
std::function<void(Camera&)> renderShadowPass
|
||||
) {
|
||||
auto world = level.getWorld();
|
||||
const auto& worldInfo = world->getInfo();
|
||||
|
||||
int resolution = shadowMap.getResolution();
|
||||
float shadowMapScale = 0.32f / (1 << glm::max(0, quality)) * scale;
|
||||
float shadowMapSize = resolution * shadowMapScale;
|
||||
|
||||
glm::vec3 basePos = glm::floor(camera.position / 4.0f) * 4.0f;
|
||||
glm::vec3 prevPos = shadowCamera.position;
|
||||
shadowCamera = Camera(
|
||||
glm::distance2(prevPos, basePos) > 25.0f ? basePos : prevPos,
|
||||
shadowMapSize
|
||||
);
|
||||
shadowCamera.near = 0.1f;
|
||||
shadowCamera.far = 1000.0f;
|
||||
shadowCamera.perspective = false;
|
||||
shadowCamera.setAspectRatio(1.0f);
|
||||
|
||||
float t = worldInfo.daytime - 0.25f;
|
||||
if (t < 0.0f) {
|
||||
t += 1.0f;
|
||||
}
|
||||
t = fmod(t, 0.5f);
|
||||
|
||||
float sunCycleStep = 1.0f / 500.0f;
|
||||
float sunAngle = glm::radians(
|
||||
90.0f -
|
||||
((static_cast<int>(t / sunCycleStep)) * sunCycleStep + 0.25f) * 360.0f
|
||||
);
|
||||
float sunAltitude = glm::pi<float>() * 0.25f;
|
||||
shadowCamera.rotate(
|
||||
-glm::cos(sunAngle + glm::pi<float>() * 0.5f) * sunAltitude,
|
||||
sunAngle - glm::pi<float>() * 0.5f,
|
||||
glm::radians(0.0f)
|
||||
);
|
||||
|
||||
shadowCamera.position -= shadowCamera.front * 500.0f;
|
||||
shadowCamera.position += shadowCamera.up * 0.0f;
|
||||
shadowCamera.position += camera.front * 0.0f;
|
||||
|
||||
auto view = shadowCamera.getView();
|
||||
|
||||
auto currentPos = shadowCamera.position;
|
||||
auto topRight = shadowCamera.right + shadowCamera.up;
|
||||
auto min = view * glm::vec4(currentPos - topRight * shadowMapSize * 0.5f, 1.0f);
|
||||
auto max = view * glm::vec4(currentPos + topRight * shadowMapSize * 0.5f, 1.0f);
|
||||
|
||||
shadowCamera.setProjection(glm::ortho(min.x, max.x, min.y, max.y, 0.1f, 1000.0f));
|
||||
|
||||
{
|
||||
auto sctx = pctx.sub();
|
||||
sctx.setDepthTest(true);
|
||||
sctx.setCullFace(true);
|
||||
sctx.setViewport({resolution, resolution});
|
||||
shadowMap.bind();
|
||||
if (renderShadowPass) {
|
||||
renderShadowPass(shadowCamera);
|
||||
}
|
||||
shadowMap.unbind();
|
||||
}
|
||||
}
|
||||
46
src/graphics/core/Shadows.hpp
Normal file
46
src/graphics/core/Shadows.hpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
#include "typedefs.hpp"
|
||||
#include "window/Camera.hpp"
|
||||
|
||||
class Shader;
|
||||
class Level;
|
||||
class Assets;
|
||||
struct Weather;
|
||||
class DrawContext;
|
||||
struct EngineSettings;
|
||||
class ShadowMap;
|
||||
|
||||
class Shadows {
|
||||
public:
|
||||
Shadows(const Level& level);
|
||||
~Shadows();
|
||||
|
||||
void setup(Shader& shader, const Weather& weather);
|
||||
void setQuality(int quality);
|
||||
void refresh(
|
||||
const Camera& camera,
|
||||
const DrawContext& pctx,
|
||||
std::function<void(Camera&)> renderShadowPass
|
||||
);
|
||||
private:
|
||||
const Level& level;
|
||||
bool shadows = false;
|
||||
Camera shadowCamera;
|
||||
Camera wideShadowCamera;
|
||||
std::unique_ptr<ShadowMap> shadowMap;
|
||||
std::unique_ptr<ShadowMap> wideShadowMap;
|
||||
int quality = 0;
|
||||
|
||||
void generateShadowsMap(
|
||||
const Camera& camera,
|
||||
const DrawContext& pctx,
|
||||
ShadowMap& shadowMap,
|
||||
Camera& shadowCamera,
|
||||
float scale,
|
||||
std::function<void(Camera&)> renderShadowPass
|
||||
);
|
||||
};
|
||||
|
|
@ -25,6 +25,9 @@ void TextureAnimator::update(float delta) {
|
|||
std::unordered_set<uint> changedTextures;
|
||||
|
||||
for (auto& elem : animations) {
|
||||
if (elem.frames.empty()) {
|
||||
continue;
|
||||
}
|
||||
elem.timer += delta;
|
||||
size_t frameNum = elem.currentFrame;
|
||||
Frame frame = elem.frames[elem.currentFrame];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue