Skip to content

Commit

Permalink
[31] Decals from multiple sources
Browse files Browse the repository at this point in the history
  • Loading branch information
numpad committed Jan 17, 2021
1 parent 5dde7ae commit f526fdc
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 21 deletions.
13 changes: 10 additions & 3 deletions res/glsl/proto/decal_instance_frag.glsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#version 450 core
#define MAX_BOUND_TEXTURES 10

uniform sampler2D uTextures[MAX_BOUND_TEXTURES];
uniform vec2 uResolution;
uniform sampler2D uTexDepth;
uniform mat4 uView;
Expand All @@ -8,6 +10,7 @@ uniform mat4 uProjection;
in vec3 vPosition;
in vec4 vTexOffset;
in mat4 vModelInv;
flat in uint vTextureIndex;

layout(location = 0) out vec4 Color;

Expand All @@ -19,9 +22,13 @@ void main() {
if (abs(objectPos.x) > 0.5) discard;
if (abs(objectPos.y) > 0.5) discard;
if (abs(objectPos.z) > 0.5) discard;
vec2 decalTexCoord = objectPos.xz + 0.5;

// calculate projected xz-coordinates onto surface, also flip texture x
vec2 decalTexCoord = objectPos.xz * vec2(-1., 1.) + 0.5;

// calculate texcoords inside subrect
vec2 subrectTexCoord = fma(decalTexCoord, vTexOffset.zw, vTexOffset.xy);

Color = vec4(subrectTexCoord.xy, 0., 1.0);
// get from selected texture
vec4 color = texture(uTextures[vTextureIndex], subrectTexCoord);
Color = color;
}
5 changes: 4 additions & 1 deletion res/glsl/proto/decal_instance_vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@ layout(location = 0) in vec3 aPosition;
layout(location = 1) in vec4 aTexOffset;
layout(location = 2) in mat4 aInstanceModel;
// location 2-5 reserved by aInstanceModel
layout(location = 6) in uint aTextureIndex;

out vec3 vPosition;
out vec4 vTexOffset;
out mat4 vModelInv;
flat out uint vTextureIndex;

void main() {
vec4 worldPosition = aInstanceModel * vec4(aPosition, 1.0);

vModelInv = inverse(aInstanceModel);
vPosition = worldPosition.xyz;
vTexOffset = aTexOffset;

vTextureIndex = aTextureIndex;

gl_Position = uProjection * uView * worldPosition;
}
Binary file added res/images/decals/coords.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/images/decals/explosion.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 33 additions & 9 deletions src/ecs/systems/DecalRenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@



DecalRenderSystem::DecalRenderSystem(entt::registry &registry, std::shared_ptr<Camera> camera)
: BaseUpdateSystem(registry), BaseRenderSystem(registry, camera) {
DecalRenderSystem::DecalRenderSystem(const entt::registry &registry, std::shared_ptr<Camera> camera)
: BaseRenderSystem(registry, camera) {

m_shader.load("res/glsl/proto/decal_instance_vert.glsl", sgl::shader::VERTEX);
m_shader.load("res/glsl/proto/decal_instance_frag.glsl", sgl::shader::FRAGMENT);
Expand All @@ -25,13 +25,7 @@ DecalRenderSystem::~DecalRenderSystem() {
destroyCube();
}

void DecalRenderSystem::update() {

}

void DecalRenderSystem::draw() {
collectInstanceData();

GLboolean prev_depthmask;
glGetBooleanv(GL_DEPTH_WRITEMASK, &prev_depthmask);
glDepthMask(GL_FALSE);
Expand All @@ -42,6 +36,9 @@ void DecalRenderSystem::draw() {
m_shader["uResolution"] = camera->getScreenSize();
m_shader["uTexDepth"] = 7; // TODO: dont hardcode this

m_shader.use();
collectInstanceData();

glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_instanceBuffer);
glDrawElementsInstanced(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0, m_aInstanceModels.size());
Expand Down Expand Up @@ -102,6 +99,8 @@ void DecalRenderSystem::destroyCube() {
void DecalRenderSystem::collectInstanceData() {
m_aInstanceTexOffsets.clear();
m_aInstanceModels.clear();
m_aInstanceTextures.clear();
m_boundTextures.clear();

cregistry.view<const CPosition, const COrientation, const CDecal>().each([this](const auto &pos, const auto &orient, const auto &decal) {
glm::mat4 model =
Expand All @@ -115,6 +114,23 @@ void DecalRenderSystem::collectInstanceData() {
),
decal.size);

const Texture *texture = decal.texture;
auto exists = std::find_if(m_boundTextures.begin(), m_boundTextures.end(),
[&](const auto &o) { return texture->getTexture() == o->getTexture(); });

if (exists == m_boundTextures.end()) { // texture is not bound
m_aInstanceTextures.push_back(m_boundTextures.size());
glActiveTexture(GL_TEXTURE0 + (GLuint)m_boundTextures.size());
glBindTexture(GL_TEXTURE_2D, (GLuint)*texture);

std::string uniformName = (std::string("uTextures[") + std::to_string(m_boundTextures.size()) + std::string("]"));
m_shader[uniformName.c_str()] = (GLint)m_boundTextures.size();

m_boundTextures.push_back(texture);
} else { // texture already bound
m_aInstanceTextures.push_back(std::distance(m_boundTextures.begin(), exists));
}

m_aInstanceTexOffsets.push_back(decal.texture_offset);
m_aInstanceModels.push_back(model);
});
Expand All @@ -124,7 +140,8 @@ void DecalRenderSystem::collectInstanceData() {
glBindBuffer(GL_ARRAY_BUFFER, m_instanceBuffer);

size_t required_instancebuffer_size = m_aInstanceTexOffsets.size() * sizeof(glm::vec4)
+ m_aInstanceModels.size() * sizeof(glm::mat4);
+ m_aInstanceModels.size() * sizeof(glm::mat4)
+ m_aInstanceTextures.size() * sizeof(GLuint);

if (required_instancebuffer_size > m_instanceBufferSize) {
m_instanceBufferSize = required_instancebuffer_size;
Expand All @@ -133,10 +150,12 @@ void DecalRenderSystem::collectInstanceData() {

glBufferSubData(GL_ARRAY_BUFFER, 0, m_aInstanceTexOffsets.size() * sizeof(glm::vec4), m_aInstanceTexOffsets.data());
glBufferSubData(GL_ARRAY_BUFFER, m_aInstanceTexOffsets.size() * sizeof(glm::vec4), m_aInstanceModels.size() * sizeof(glm::mat4), m_aInstanceModels.data());
glBufferSubData(GL_ARRAY_BUFFER, m_aInstanceTexOffsets.size() * sizeof(glm::vec4) + m_aInstanceModels.size() * sizeof(glm::mat4), m_aInstanceTextures.size() * sizeof(GLuint), m_aInstanceTextures.data());

// enable instancing
GLuint attribInstanceTexOffsets = 1;
GLuint attribInstanceModel = 2;
GLuint attribTextureIndex = 6;

glVertexAttribPointer(attribInstanceTexOffsets, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), NULL);
glEnableVertexAttribArray(attribInstanceTexOffsets);
Expand All @@ -147,5 +166,10 @@ void DecalRenderSystem::collectInstanceData() {
glEnableVertexAttribArray(attribInstanceModel + i);
glVertexAttribDivisor(attribInstanceModel + i, 1);
}

glVertexAttribIPointer(attribTextureIndex, 4, GL_UNSIGNED_INT, sizeof(GLuint), (void *)(m_aInstanceTexOffsets.size() * sizeof(glm::vec4) + m_aInstanceModels.size() * sizeof(glm::mat4)));
glEnableVertexAttribArray(attribTextureIndex);
glVertexAttribDivisor(attribTextureIndex, 1);

glBindVertexArray(0);
}
7 changes: 4 additions & 3 deletions src/ecs/systems/DecalRenderSystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,21 @@
#include <RenderObject/Camera.hpp>
#include <Util/Blackboard.hpp>

class DecalRenderSystem : public BaseUpdateSystem, public BaseRenderSystem {
class DecalRenderSystem : public BaseRenderSystem {
public:

DecalRenderSystem(entt::registry &registry, std::shared_ptr<Camera> camera);
DecalRenderSystem(const entt::registry &registry, std::shared_ptr<Camera> camera);
~DecalRenderSystem();

void update();
void draw();

private:
GLuint m_instanceBuffer;
size_t m_instanceBufferSize = 0;
std::vector<glm::vec4> m_aInstanceTexOffsets;
std::vector<glm::mat4> m_aInstanceModels;
std::vector<GLuint> m_aInstanceTextures;
std::vector<const Texture *> m_boundTextures;

GLuint m_vao, m_vbo, m_ebo;
sgl::shader m_shader;
Expand Down
8 changes: 6 additions & 2 deletions src/include/Debug/ImguiPresets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ void imguiEntityEdit(entt::registry &registry, entt::entity entity) {
if (registry.has<CDecal>(entity)) {
Text("Decal");
auto &decal = registry.get<CDecal>(entity);
DragFloat3("size", &decal.size[0], 0.001f);
DragFloat3("size##sizedecal", &decal.size[0], 0.001f);
if (Button("X##9")) {
registry.remove<CDecal>(entity);
}
Expand Down Expand Up @@ -152,6 +152,8 @@ void imguiEntitySpawn(World &world, bool spawn, glm::vec3 atpos) {
static float spawnveloff = 0.02f;
static int max_hp = 10;
static glm::vec3 size(1.f);
static char decal_texpath[512] = "res/images/decals/explosion.png";
static glm::vec4 subrect(0.f, 0.f, 1.f, 1.f);
static glm::vec3 orient(0.f, 1.f, 0.f);
static float orient_amount = 0.f;

Expand Down Expand Up @@ -244,6 +246,8 @@ void imguiEntitySpawn(World &world, bool spawn, glm::vec3 atpos) {
if (hasdecal) {
if (BeginMenu("CDecal")) {
DragFloat3("Size", &size[0], 0.001f);
InputText("Path", decal_texpath, 512);
SliderFloat4("Subrect", &subrect[0], 0.f, 1.f);
EndMenu();
}
}
Expand Down Expand Up @@ -294,7 +298,7 @@ void imguiEntitySpawn(World &world, bool spawn, glm::vec3 atpos) {
if (hasspawn) registry.emplace<CSpawnPoint>(entity, spawnpoint);
if (hasjumper) registry.emplace<CJumpTimer>(entity);
if (hashealth) registry.emplace<CHealth>(entity, max_hp);
if (hasdecal) registry.emplace<CDecal>(entity, size, nullptr, glm::vec4(0.f, 0.f, 1.f, 1.f));
if (hasdecal) registry.emplace<CDecal>(entity, size, world.getAssetManager().getTexture(decal_texpath), subrect);
if (hasorientation) registry.emplace<COrientation>(entity, orient, orient_amount);
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/source/World.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,6 @@ void World::loadSystems() {
});

// initialize update and render systems
auto decalRenderSystem = std::make_shared<DecalRenderSystem>(registry, camera);
auto billboardRenderSystem = std::make_shared<BillboardRenderSystem>(registry, camera);
auto textRenderSystem = std::make_shared<TextEventSystem>(registry, camera);
auto wayfindSystem = std::make_shared<WayfindSystem>(registry, camera);
Expand All @@ -260,15 +259,14 @@ void World::loadSystems() {
updateSystems.push_back(wayfindSystem);
updateSystems.emplace_back(new PressAwaySystem(registry));
updateSystems.emplace_back(new PositionUpdateSystem(registry));
updateSystems.push_back(decalRenderSystem);
updateSystems.push_back(billboardRenderSystem);
updateSystems.push_back(textRenderSystem);
updateSystems.push_back(primitiveRenderer);
updateSystems.emplace_back(new AudioSystem(registry, assetManager));

// and render systems
renderSystems.emplace_back(new TerrainRenderSystem(registry, camera, assetManager, chunkedWorld));
renderSystems.push_back(decalRenderSystem);
renderSystems.emplace_back(new DecalRenderSystem(registry, camera));
renderSystems.push_back(billboardRenderSystem);
renderSystems.push_back(textRenderSystem);
renderSystems.push_back(wayfindSystem);
Expand Down

0 comments on commit f526fdc

Please sign in to comment.