This commit is contained in:
Astazium 2026-10-03 16:24:04 +05:00 • committed by GitHub
commit 2f884caddf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 212 additions and 279 deletions

View file

@ -42,7 +42,7 @@ target_link_options(VoxelEngine PRIVATE $<$<CXX_COMPILER_ID:GNU>:-no-pie>)
add_custom_command( add_custom_command(
TARGET VoxelEngine TARGET VoxelEngine
POST_BUILD POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/res $<TARGET_FILE_DIR:VoxelEngine>/res) ${CMAKE_CURRENT_SOURCE_DIR}/res $<TARGET_FILE_DIR:VoxelEngine>/res)
if(VOXELENGINE_BUILD_TESTS) if(VOXELENGINE_BUILD_TESTS)

View file

@ -138,5 +138,5 @@ VCA файл состоит из набора директив, порядок
>[!WARNING] >[!WARNING]
> Использование незадокументированных функций может иметь иметь любые незадокументированные последствия. > Использование незадокументированных функций может иметь любые незадокументированные последствия.

View file

@ -14,6 +14,13 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
find_package(OpenAL CONFIG REQUIRED) find_package(OpenAL CONFIG REQUIRED)
else() else()
find_package(OpenAL REQUIRED) find_package(OpenAL REQUIRED)
if(NOT TARGET OpenAL::OpenAL)
add_library(OpenAL::OpenAL UNKNOWN IMPORTED)
set_target_properties(OpenAL::OpenAL PROPERTIES
IMPORTED_LOCATION "${OPENAL_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${OPENAL_INCLUDE_DIR}"
)
endif()
endif() endif()
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
find_package(PNG REQUIRED) find_package(PNG REQUIRED)

View file

@ -10,53 +10,69 @@ class ObjParser : BasicParser<char> {
std::vector<glm::vec2> uvs {{0, 0}}; std::vector<glm::vec2> uvs {{0, 0}};
std::vector<glm::vec3> normals {{0, 1, 0}}; std::vector<glm::vec3> normals {{0, 1, 0}};
// TODO: refactor Vertex parseFaceVertex() {
void parseFace(Mesh& mesh) { auto parseIndex = [&]() -> uint {
std::vector<Vertex> vertices; if (!hasNext() || !is_digit(peekInLine())) {
while (hasNext()) { return 0;
auto c = peekInLine(); }
if (c == '\n') { return parseSimpleInt(10);
break; };
} else if (hasNext()) {
uint indices[3] {};
uint i = 0;
do {
char next = peekInLine();
if (is_digit(next)) {
indices[i] = parseSimpleInt(10);
if (hasNext() && peekInLine() == '/') {
pos++;
}
} else if (next == '/') {
pos++;
} else {
break;
}
} while (hasNext() && peekInLine() != '\n' && ++i < 3);
vertices.push_back(Vertex { uint coord = parseIndex();
coords[indices[0]], uvs[indices[1]], normals[indices[2]]}); uint uv = 0;
uint normal = 0;
if (hasNext() && peekInLine() == '/') {
pos++;
uv = parseIndex();
if (hasNext() && peekInLine() == '/') {
pos++;
normal = parseIndex();
} }
} }
if (hasNext() && peekInLine() != '\n') {
skipLine(); return Vertex {
} coords[coord],
uvs[uv],
normals[normal]
};
}
void triangulate(const std::vector<Vertex>& vertices, std::vector<Vertex>& output) {
if (vertices.size() >= 3) { if (vertices.size() >= 3) {
for (size_t j = 0; j < vertices.size() - 2; j++) { for (size_t j = 0; j < vertices.size() - 2; j++) {
mesh.vertices.push_back(vertices[0]); output.push_back(vertices[0]);
for (size_t i = 1; i < 3; i++) { for (size_t i = 1; i < 3; i++) {
mesh.vertices.push_back(vertices[i + j]); output.push_back(vertices[i + j]);
} }
} }
} }
} }
public:
ObjParser(const std::string_view file, const std::string_view src) void parseFace(Mesh& mesh) {
: BasicParser(file, src) { std::vector<Vertex> vertices;
while (hasNext() && peekInLine() != '\n') {
vertices.push_back(parseFaceVertex());
}
triangulate(vertices, mesh.vertices);
} }
std::unique_ptr<Model> parse() { glm::vec3 parseVec3() {
// first iteration - collecting vertex data float x = parseNumber().asNumber();
float y = parseNumber().asNumber();
float z = parseNumber().asNumber();
return glm::vec3 {x, y, z};
}
glm::vec2 parseVec2() {
float x = parseNumber().asNumber();
float y = parseNumber().asNumber();
return glm::vec2 {x, y};
}
void collectVertexData() {
while (hasNext()) { while (hasNext()) {
if (peek() == '#') { if (peek() == '#') {
skipLine(); skipLine();
@ -64,27 +80,18 @@ public:
} }
auto cmd = parseName(); auto cmd = parseName();
if (cmd == "v") { if (cmd == "v") {
float x = parseNumber().asNumber(); coords.emplace_back(parseVec3());
float y = parseNumber().asNumber();
float z = parseNumber().asNumber();
coords.emplace_back(x, y, z);
} else if (cmd == "vt") { } else if (cmd == "vt") {
float u = parseNumber().asNumber(); uvs.emplace_back(parseVec2());
float v = parseNumber().asNumber();
uvs.emplace_back(u, v);
} else if (cmd == "vn") { } else if (cmd == "vn") {
float x = parseNumber().asNumber(); normals.emplace_back(parseVec3());
float y = parseNumber().asNumber();
float z = parseNumber().asNumber();
normals.emplace_back(x, y, z);
} else { } else {
skipLine(); skipLine();
} }
} }
// second iteration - building meshes }
reset();
auto model = std::make_unique<Model>(); void buildMeshes(Model& model) {
std::string texture; std::string texture;
while (hasNext()) { while (hasNext()) {
if (peek() != '#' && parseName() == "usemtl") { if (peek() != '#' && parseName() == "usemtl") {
@ -95,7 +102,7 @@ public:
skipLine(); skipLine();
} }
do { do {
Mesh* mesh = &model->addMesh(texture); Mesh* mesh = &model.addMesh(texture);
while (hasNext()) { while (hasNext()) {
if (peek() == '#') { if (peek() == '#') {
skipLine(); skipLine();
@ -105,7 +112,7 @@ public:
if (cmd == "usemtl") { if (cmd == "usemtl") {
skipWhitespace(); skipWhitespace();
texture = readUntilEOL(); texture = readUntilEOL();
mesh = &model->addMesh(texture); mesh = &model.addMesh(texture);
break; break;
} else if (cmd == "f") { } else if (cmd == "f") {
parseFace(*mesh); parseFace(*mesh);
@ -113,6 +120,19 @@ public:
skipLine(); skipLine();
} }
} while (hasNext()); } while (hasNext());
}
public:
ObjParser(const std::string_view file, const std::string_view src)
: BasicParser(file, src) {
}
std::unique_ptr<Model> parse() {
// first iteration - collecting vertex data
collectVertexData();
// second iteration - building meshes
reset();
auto model = std::make_unique<Model>();
buildMeshes(*model);
model->clean(); model->clean();
return model; return model;
} }

View file

@ -8,143 +8,62 @@ using namespace advanced_pipeline;
static debug::Logger logger("gl-gbuffer"); static debug::Logger logger("gl-gbuffer");
// TODO: REFACTOR void GBuffer::createBuffer(Buffer& buffer) {
if (buffer.buffer == 0) {
void GBuffer::createColorBuffer() { if (&buffer == &depthBuffer)
if (colorBuffer == 0) glGenRenderbuffers(1, &depthBuffer.buffer);
glGenTextures(1, &colorBuffer); else
glBindTexture(GL_TEXTURE_2D, colorBuffer); glGenTextures(1, &buffer.buffer);
glTexImage2D( }
GL_TEXTURE_2D, if (&buffer == &depthBuffer){
0, glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer.buffer);
GL_RGB, glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
width, glFramebufferRenderbuffer(
height, GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer.buffer
0, );
GL_RGB, } else {
GL_UNSIGNED_BYTE, glBindTexture(GL_TEXTURE_2D, buffer.buffer);
nullptr glTexImage2D(
); GL_TEXTURE_2D,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 0,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); buffer.internalformat,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); width,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); height,
glFramebufferTexture2D( 0,
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBuffer, 0 buffer.format,
); buffer.type,
nullptr
);
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_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (&buffer != &ssaoBuffer)
{
glFramebufferTexture2D(
GL_FRAMEBUFFER, buffer.attachment, GL_TEXTURE_2D, buffer.buffer, 0
);
}
}
} }
void GBuffer::createPositionsBuffer() { GBuffer::GBuffer(uint width, uint height)
if (positionsBuffer == 0) : width(width), height(height),
glGenTextures(1, &positionsBuffer);
glBindTexture(GL_TEXTURE_2D, positionsBuffer);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA16F,
width,
height,
0,
GL_RGBA,
GL_FLOAT,
nullptr
);
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_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positionsBuffer, 0
);
}
void GBuffer::createNormalsBuffer() { colorBuffer {0, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, GL_COLOR_ATTACHMENT0},
if (normalsBuffer == 0) positionsBuffer {0, GL_RGBA16F, GL_RGBA, GL_FLOAT, GL_COLOR_ATTACHMENT1},
glGenTextures(1, &normalsBuffer); normalsBuffer {0, GL_RGBA16F, GL_RGB, GL_FLOAT, GL_COLOR_ATTACHMENT2},
glBindTexture(GL_TEXTURE_2D, normalsBuffer); emissionBuffer {0, GL_R8, GL_RED, GL_FLOAT, GL_COLOR_ATTACHMENT3},
glTexImage2D( depthBuffer {0, 0, 0, 0, 0},
GL_TEXTURE_2D, ssaoBuffer {0, GL_R16F, GL_RED, GL_FLOAT, 0}
0, {
GL_RGBA16F,
width,
height,
0,
GL_RGB,
GL_FLOAT,
nullptr
);
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_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normalsBuffer, 0
);
}
void GBuffer::createEmissionBuffer() {
if (emissionBuffer == 0)
glGenTextures(1, &emissionBuffer);
glBindTexture(GL_TEXTURE_2D, emissionBuffer);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_R8,
width,
height,
0,
GL_RED,
GL_FLOAT,
nullptr
);
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_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, emissionBuffer, 0
);
}
void GBuffer::createDepthBuffer() {
if (depthBuffer == 0)
glGenRenderbuffers(1, &depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(
GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer
);
}
void GBuffer::createSSAOBuffer() {
if (ssaoBuffer == 0)
glGenTextures(1, &ssaoBuffer);
glBindTexture(GL_TEXTURE_2D, ssaoBuffer);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_R16F,
width,
height,
0,
GL_RED,
GL_FLOAT,
nullptr
);
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_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GBuffer::GBuffer(uint width, uint height) : width(width), height(height) {
glGenFramebuffers(1, &fbo); glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo);
createColorBuffer(); createBuffer(colorBuffer);
createPositionsBuffer(); createBuffer(positionsBuffer);
createNormalsBuffer(); createBuffer(normalsBuffer);
createEmissionBuffer(); createBuffer(emissionBuffer);
GLenum attachments[4] = { GLenum attachments[4] = {
GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0,
@ -154,7 +73,7 @@ GBuffer::GBuffer(uint width, uint height) : width(width), height(height) {
}; };
glDrawBuffers(4, attachments); glDrawBuffers(4, attachments);
createDepthBuffer(); createBuffer(depthBuffer);
int status; int status;
if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) { if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
@ -164,9 +83,9 @@ GBuffer::GBuffer(uint width, uint height) : width(width), height(height) {
glGenFramebuffers(1, &ssaoFbo); glGenFramebuffers(1, &ssaoFbo);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFbo); glBindFramebuffer(GL_FRAMEBUFFER, ssaoFbo);
createSSAOBuffer(); createBuffer(ssaoBuffer);
glFramebufferTexture2D( glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoBuffer, 0 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoBuffer.buffer, 0
); );
GLenum ssaoAttachments[1] = {GL_COLOR_ATTACHMENT0}; GLenum ssaoAttachments[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, ssaoAttachments); glDrawBuffers(1, ssaoAttachments);
@ -179,12 +98,12 @@ GBuffer::GBuffer(uint width, uint height) : width(width), height(height) {
} }
GBuffer::~GBuffer() { GBuffer::~GBuffer() {
glDeleteTextures(1, &colorBuffer); glDeleteTextures(1, &colorBuffer.buffer);
glDeleteTextures(1, &positionsBuffer); glDeleteTextures(1, &positionsBuffer.buffer);
glDeleteTextures(1, &normalsBuffer); glDeleteTextures(1, &normalsBuffer.buffer);
glDeleteTextures(1, &emissionBuffer); glDeleteTextures(1, &emissionBuffer.buffer);
glDeleteTextures(1, &ssaoBuffer); glDeleteTextures(1, &ssaoBuffer.buffer);
glDeleteRenderbuffers(1, &depthBuffer); glDeleteRenderbuffers(1, &depthBuffer.buffer);
glDeleteFramebuffers(1, &fbo); glDeleteFramebuffers(1, &fbo);
glDeleteFramebuffers(1, &ssaoFbo); glDeleteFramebuffers(1, &ssaoFbo);
} }
@ -204,23 +123,23 @@ void GBuffer::unbind() const {
void GBuffer::bindBuffers() const { void GBuffer::bindBuffers() const {
glActiveTexture(GL_TEXTURE0 + TARGET_EMISSION); glActiveTexture(GL_TEXTURE0 + TARGET_EMISSION);
glBindTexture(GL_TEXTURE_2D, emissionBuffer); glBindTexture(GL_TEXTURE_2D, emissionBuffer.buffer);
glActiveTexture(GL_TEXTURE0 + TARGET_NORMALS); glActiveTexture(GL_TEXTURE0 + TARGET_NORMALS);
glBindTexture(GL_TEXTURE_2D, normalsBuffer); glBindTexture(GL_TEXTURE_2D, normalsBuffer.buffer);
glActiveTexture(GL_TEXTURE0 + TARGET_POSITIONS); glActiveTexture(GL_TEXTURE0 + TARGET_POSITIONS);
glBindTexture(GL_TEXTURE_2D, positionsBuffer); glBindTexture(GL_TEXTURE_2D, positionsBuffer.buffer);
glActiveTexture(GL_TEXTURE0 + TARGET_COLOR); glActiveTexture(GL_TEXTURE0 + TARGET_COLOR);
glBindTexture(GL_TEXTURE_2D, colorBuffer); glBindTexture(GL_TEXTURE_2D, colorBuffer.buffer);
if (TARGET_COLOR != 0) if (TARGET_COLOR != 0)
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
} }
void GBuffer::bindSSAOBuffer() const { void GBuffer::bindSSAOBuffer() const {
glBindTexture(GL_TEXTURE_2D, ssaoBuffer); glBindTexture(GL_TEXTURE_2D, ssaoBuffer.buffer);
} }
void GBuffer::bindDepthBuffer(int drawFbo) { void GBuffer::bindDepthBuffer(int drawFbo) {
@ -239,24 +158,24 @@ void GBuffer::resize(uint width, uint height) {
glBindFramebuffer(GL_FRAMEBUFFER, fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo);
createDepthBuffer(); createBuffer(depthBuffer);
createColorBuffer(); createBuffer(colorBuffer);
createPositionsBuffer(); createBuffer(positionsBuffer);
createNormalsBuffer(); createBuffer(normalsBuffer);
createEmissionBuffer(); createBuffer(emissionBuffer);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFbo); glBindFramebuffer(GL_FRAMEBUFFER, ssaoFbo);
createSSAOBuffer(); createBuffer(ssaoBuffer);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
std::unique_ptr<ImageData> GBuffer::toImage() const { std::unique_ptr<ImageData> GBuffer::toImage() const {
auto data = std::make_unique<ubyte[]>(width * height * 3); auto data = std::make_unique<ubyte[]>(width * height * 3);
glBindTexture(GL_TEXTURE_2D, colorBuffer); glBindTexture(GL_TEXTURE_2D, colorBuffer.buffer);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data.get()); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data.get());
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
return std::make_unique<ImageData>( return std::make_unique<ImageData>(

View file

@ -25,22 +25,25 @@ public:
std::unique_ptr<ImageData> toImage() const; std::unique_ptr<ImageData> toImage() const;
private: private:
struct Buffer {
uint buffer;
const int internalformat;
const uint format;
const uint type;
const uint attachment;
};
uint width; uint width;
uint height; uint height;
uint fbo; uint fbo;
uint colorBuffer = 0; Buffer colorBuffer;
uint positionsBuffer = 0; Buffer positionsBuffer;
uint normalsBuffer = 0; Buffer normalsBuffer;
uint emissionBuffer = 0; Buffer emissionBuffer;
uint depthBuffer = 0; Buffer depthBuffer;
uint ssaoFbo = 0; uint ssaoFbo;
uint ssaoBuffer = 0; Buffer ssaoBuffer;
void createColorBuffer(); void createBuffer(Buffer& buffer);
void createPositionsBuffer();
void createNormalsBuffer();
void createEmissionBuffer();
void createDepthBuffer();
void createSSAOBuffer();
}; };

View file

@ -1,4 +1,7 @@
#include "PostProcessing.hpp" #include "PostProcessing.hpp"
#include <GL/glew.h>
#include "Mesh.hpp" #include "Mesh.hpp"
#include "Shader.hpp" #include "Shader.hpp"
#include "GBuffer.hpp" #include "GBuffer.hpp"
@ -18,7 +21,7 @@ using namespace advanced_pipeline;
PostProcessing::PostProcessing(size_t effectSlotsCount) PostProcessing::PostProcessing(size_t effectSlotsCount)
: effectSlots(effectSlotsCount) { : effectSlots(effectSlotsCount) {
// Fullscreen quad mesh bulding // Fullscreen quad mesh building
PostProcessingVertex meshData[] { PostProcessingVertex meshData[] {
{{-1.0f, -1.0f}}, {{-1.0f, -1.0f}},
{{-1.0f, 1.0f}}, {{-1.0f, 1.0f}},
@ -49,7 +52,9 @@ PostProcessing::PostProcessing(size_t effectSlotsCount)
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
PostProcessing::~PostProcessing() = default; PostProcessing::~PostProcessing() {
glDeleteTextures(1, &noiseTexture);
}
void PostProcessing::use(DrawContext& context, bool gbufferPipeline) { void PostProcessing::use(DrawContext& context, bool gbufferPipeline) {
const auto& vp = context.getViewport(); const auto& vp = context.getViewport();
@ -105,8 +110,9 @@ void PostProcessing::configureEffect(
shader.uniform3f("u_cameraPos", camera.position); shader.uniform3f("u_cameraPos", camera.position);
shader.uniform1f("u_timer", timer); shader.uniform1f("u_timer", timer);
shader.uniformMatrix("u_projection", camera.getProjection()); shader.uniformMatrix("u_projection", camera.getProjection());
shader.uniformMatrix("u_view", camera.getView()); const auto view = camera.getView();
shader.uniformMatrix("u_inverseView", glm::inverse(camera.getView())); shader.uniformMatrix("u_view", view);
shader.uniformMatrix("u_inverseView", glm::inverse(view));
} }
void PostProcessing::renderDeferredShading( void PostProcessing::renderDeferredShading(

View file

@ -24,8 +24,6 @@ struct PostProcessingVertex {
}; };
/// @brief Framebuffer with blitting with shaders. /// @brief Framebuffer with blitting with shaders.
/// @attention Current implementation does not support multiple render passes
/// for multiple effects. Will be implemented in v0.21
class PostProcessing { class PostProcessing {
public: public:
PostProcessing(size_t effectSlotsCount); PostProcessing(size_t effectSlotsCount);
@ -73,12 +71,12 @@ private:
void refreshFbos(uint width, uint height); void refreshFbos(uint width, uint height);
/// @brief Main framebuffer (lasy field) /// @brief Main framebuffer (lazy field)
std::unique_ptr<Framebuffer> fbo; std::unique_ptr<Framebuffer> fbo;
std::unique_ptr<Framebuffer> fboSecond; std::unique_ptr<Framebuffer> fboSecond;
/// @brief Fullscreen quad mesh as the post-processing canvas /// @brief Fullscreen quad mesh as the post-processing canvas
std::unique_ptr<Mesh<PostProcessingVertex>> quadMesh; std::unique_ptr<Mesh<PostProcessingVertex>> quadMesh;
std::vector<std::shared_ptr<PostEffect>> effectSlots; std::vector<std::shared_ptr<PostEffect>> effectSlots;
std::unique_ptr<GBuffer> gbuffer; std::unique_ptr<GBuffer> gbuffer;
uint noiseTexture; uint noiseTexture = 0;
}; };

View file

@ -324,7 +324,8 @@ void WorldRenderer::renderInWorldLines(
auto ctx = pctx.sub(lineBatch.get()); auto ctx = pctx.sub(lineBatch.get());
bool culling = engine.getSettings().graphics.frustumCulling.get(); bool culling = engine.getSettings().graphics.frustumCulling.get();
level.entities->renderDebug( level.entities->renderDebug(
*lineBatch, culling ? frustumCulling.get() : nullptr, ctx *lineBatch, culling ? frustumCulling.get() : nullptr, ctx,
player.currentCamera.get() == player.fpCamera.get() ? player.getEntity() : 0
); );
} }
} }

View file

@ -1,8 +1,5 @@
#include "GUI.hpp" #include "GUI.hpp"
#include <algorithm>
#include <utility>
#include "assets/Assets.hpp" #include "assets/Assets.hpp"
#include "debug/Logger.hpp" #include "debug/Logger.hpp"
#include "elements/Label.hpp" #include "elements/Label.hpp"
@ -17,7 +14,6 @@
#include "graphics/core/Shader.hpp" #include "graphics/core/Shader.hpp"
#include "graphics/core/Font.hpp" #include "graphics/core/Font.hpp"
#include "graphics/core/DrawContext.hpp" #include "graphics/core/DrawContext.hpp"
#include "graphics/core/Shader.hpp"
#include "gui_util.hpp" #include "gui_util.hpp"
#include "window/Camera.hpp" #include "window/Camera.hpp"
#include "window/Window.hpp" #include "window/Window.hpp"

View file

@ -71,6 +71,9 @@ static int l_get_def(lua::State* L) {
static int l_spawn(lua::State* L) { static int l_spawn(lua::State* L) {
auto level = controller->getLevel(); auto level = controller->getLevel();
auto defname = lua::tostring(L, 1); auto defname = lua::tostring(L, 1);
if (defname == nullptr) {
throw std::runtime_error("string expected, got nil");
}
auto& def = content->entities.require(defname); auto& def = content->entities.require(defname);
auto pos = lua::tovec3(L, 2); auto pos = lua::tovec3(L, 2);
dv::value args = nullptr; dv::value args = nullptr;

View file

@ -211,59 +211,36 @@ static int l_tostring(lua::State* L) {
return lua::pushstring(L, ss.str()); return lua::pushstring(L, ss.str());
} }
#define VECLIB_BASE(n) \
{"add", lua::wrap<l_binop<n, std::plus>>}, \
{"sub", lua::wrap<l_binop<n, std::minus>>}, \
{"mul", lua::wrap<l_binop<n, std::multiplies>>}, \
{"div", lua::wrap<l_binop<n, std::divides>>}, \
{"distance", lua::wrap<l_distance<n>>}, \
{"normalize", lua::wrap<l_unaryop<n, glm::normalize>>}, \
{"length", lua::wrap<l_scalar_op<n, glm::length>>}, \
{"tostring", lua::wrap<l_tostring<n>>}, \
{"abs", lua::wrap<l_unaryop<n, glm::abs>>}, \
{"round", lua::wrap<l_unaryop<n, glm::round>>}, \
{"inverse", lua::wrap<l_inverse<n>>}, \
{"pow", lua::wrap<l_pow<n>>}, \
{"dot", lua::wrap<l_dot<n>>}, \
{"mix", lua::wrap<l_mix<n>>},
const luaL_Reg vec2lib[] = { const luaL_Reg vec2lib[] = {
{"add", lua::wrap<l_binop<2, std::plus>>}, VECLIB_BASE(2)
{"sub", lua::wrap<l_binop<2, std::minus>>},
{"mul", lua::wrap<l_binop<2, std::multiplies>>},
{"div", lua::wrap<l_binop<2, std::divides>>},
{"distance", lua::wrap<l_distance<2>>},
{"normalize", lua::wrap<l_unaryop<2, glm::normalize>>},
{"length", lua::wrap<l_scalar_op<2, glm::length>>},
{"tostring", lua::wrap<l_tostring<2>>},
{"abs", lua::wrap<l_unaryop<2, glm::abs>>},
{"round", lua::wrap<l_unaryop<2, glm::round>>},
{"inverse", lua::wrap<l_inverse<2>>},
{"pow", lua::wrap<l_pow<2>>},
{"dot", lua::wrap<l_dot<2>>},
{"angle", lua::wrap<l_vec2_angle>}, {"angle", lua::wrap<l_vec2_angle>},
{"mix", lua::wrap<l_mix<2>>},
{"rotate", lua::wrap<l_vec2_rotate>}, {"rotate", lua::wrap<l_vec2_rotate>},
{nullptr, nullptr} {nullptr, nullptr}
}; };
const luaL_Reg vec3lib[] = { const luaL_Reg vec3lib[] = {
{"add", lua::wrap<l_binop<3, std::plus>>}, VECLIB_BASE(3)
{"sub", lua::wrap<l_binop<3, std::minus>>},
{"mul", lua::wrap<l_binop<3, std::multiplies>>},
{"div", lua::wrap<l_binop<3, std::divides>>},
{"distance", lua::wrap<l_distance<3>>},
{"normalize", lua::wrap<l_unaryop<3, glm::normalize>>},
{"length", lua::wrap<l_scalar_op<3, glm::length>>},
{"tostring", lua::wrap<l_tostring<3>>},
{"abs", lua::wrap<l_unaryop<3, glm::abs>>},
{"round", lua::wrap<l_unaryop<3, glm::round>>},
{"inverse", lua::wrap<l_inverse<3>>},
{"pow", lua::wrap<l_pow<3>>},
{"dot", lua::wrap<l_dot<3>>},
{"spherical_rand", lua::wrap<l_spherical_rand>}, {"spherical_rand", lua::wrap<l_spherical_rand>},
{"mix", lua::wrap<l_mix<3>>},
{nullptr, nullptr} {nullptr, nullptr}
}; };
const luaL_Reg vec4lib[] = { const luaL_Reg vec4lib[] = {
{"add", lua::wrap<l_binop<4, std::plus>>}, VECLIB_BASE(4)
{"sub", lua::wrap<l_binop<4, std::minus>>},
{"mul", lua::wrap<l_binop<4, std::multiplies>>},
{"div", lua::wrap<l_binop<4, std::divides>>},
{"distance", lua::wrap<l_distance<4>>},
{"normalize", lua::wrap<l_unaryop<4, glm::normalize>>},
{"length", lua::wrap<l_scalar_op<4, glm::length>>},
{"tostring", lua::wrap<l_tostring<4>>},
{"abs", lua::wrap<l_unaryop<4, glm::abs>>},
{"round", lua::wrap<l_unaryop<4, glm::round>>},
{"inverse", lua::wrap<l_inverse<4>>},
{"pow", lua::wrap<l_pow<4>>},
{"dot", lua::wrap<l_dot<4>>},
{"mix", lua::wrap<l_mix<4>>},
{nullptr, nullptr} {nullptr, nullptr}
}; };

View file

@ -422,7 +422,7 @@ static void debug_render_skeleton(
} }
void Entities::renderDebug( void Entities::renderDebug(
LineBatch& batch, const Frustum* frustum, const DrawContext& pctx LineBatch& batch, const Frustum* frustum, const DrawContext& pctx, entityid_t fpsEntity
) { ) {
{ {
auto ctx = pctx.sub(&batch); auto ctx = pctx.sub(&batch);
@ -450,12 +450,15 @@ void Entities::renderDebug(
} }
} }
{ {
auto view = registry->view<Transform, rigging::Skeleton>(); auto view = registry->view<EntityId, Transform, rigging::Skeleton>();
auto ctx = pctx.sub(&batch); auto ctx = pctx.sub(&batch);
ctx.setDepthTest(false); ctx.setDepthTest(false);
ctx.setDepthMask(false); ctx.setDepthMask(false);
ctx.setLineWidth(2); ctx.setLineWidth(2);
for (auto [entity, transform, skeleton] : view.each()) { for (auto [entity, eid, transform, skeleton] : view.each()) {
if (eid.uid == fpsEntity) {
continue;
}
auto config = skeleton.config; auto config = skeleton.config;
if (config == nullptr) { if (config == nullptr) {
continue; continue;

View file

@ -58,7 +58,7 @@ public:
void update(float delta); void update(float delta);
void renderDebug( void renderDebug(
LineBatch& batch, const Frustum* frustum, const DrawContext& ctx LineBatch& batch, const Frustum* frustum, const DrawContext& ctx, entityid_t fpsEntity
); );
void render( void render(
const Assets& assets, const Assets& assets,