101 lines
3.2 KiB
C++
101 lines
3.2 KiB
C++
//
|
|
// Created by sebastian on 14.02.26.
|
|
//
|
|
|
|
#include "WorldSpriteRenderer.h"
|
|
|
|
#include <vector>
|
|
|
|
#include "../layer/entities/Camera.h"
|
|
#include "../toolbox/MathUtils.h"
|
|
#include "glm/ext/matrix_transform.hpp"
|
|
#include "loader/Loader.h"
|
|
|
|
WorldSpriteRenderer::WorldSpriteRenderer(const glm::mat4& projectionMatrix) : projectionMatrix(projectionMatrix) {
|
|
std::vector<float> positions = {
|
|
-0.5f, 0.5f, 0.0f, // oben links
|
|
-0.5f, -0.5f, 0.0f, // unten links
|
|
0.5f, 0.5f, 0.0f, // oben rechts
|
|
0.5f, -0.5f, 0.0f // unten rechts
|
|
};
|
|
|
|
std::vector<float> uvs = {
|
|
0.0f, 1.0f,
|
|
0.0f, 0.0f,
|
|
1.0f, 1.0f,
|
|
1.0f, 0.0f
|
|
};
|
|
|
|
std::vector<int> indices = {
|
|
0, 1, 2,
|
|
2, 1, 3
|
|
};
|
|
|
|
quadModel = std::make_unique<RawModel>(Loader::instance().loadToVAO(positions, uvs, indices));
|
|
}
|
|
|
|
void WorldSpriteRenderer::prepare(const Camera &camera) {
|
|
glm::mat4 viewMatrix = MathUtils::createViewMatrix(camera);
|
|
glm::mat4 projectionViewMatrix = projectionMatrix * viewMatrix;
|
|
worldSpriteShader.start();
|
|
worldSpriteShader.loadProjectionViewMatrix(projectionViewMatrix);
|
|
}
|
|
|
|
void WorldSpriteRenderer::render(std::unordered_map<ModelTexture*, std::vector<WorldSpriteRenderingData>> worldSprites, const Camera &camera) {
|
|
glDepthMask(false);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
for (auto& batch : worldSprites) {
|
|
glBindTexture(GL_TEXTURE_2D, batch.first->getTextureID());
|
|
|
|
for (auto& sprite : batch.second) {
|
|
glm::mat4 model = buildWorldSpriteMatrix(*sprite.worldSpriteTransform, *sprite.worldSpriteComponent, camera);
|
|
worldSpriteShader.loadModelMatrix(model);
|
|
worldSpriteShader.loadAlpha(sprite.worldSpriteComponent->alpha);
|
|
|
|
glBindVertexArray(quadModel->vaoID);
|
|
glEnableVertexAttribArray(0);
|
|
glEnableVertexAttribArray(1);
|
|
glDrawElements(GL_TRIANGLES, quadModel->vertexCount, GL_UNSIGNED_INT, 0);
|
|
glDisableVertexAttribArray(0);
|
|
glDisableVertexAttribArray(1);
|
|
glBindVertexArray(0);
|
|
}
|
|
}
|
|
glDepthMask(true);
|
|
glDisable(GL_BLEND);
|
|
}
|
|
|
|
void WorldSpriteRenderer::finalize() {
|
|
worldSpriteShader.stop();
|
|
}
|
|
|
|
glm::mat4 WorldSpriteRenderer::buildWorldSpriteMatrix(const TransformComponent &objectTransform,
|
|
const WorldSpriteComponent &worldSpriteComponent,
|
|
const Camera &camera
|
|
) {
|
|
glm::vec3 worldPos = objectTransform.position + worldSpriteComponent.offset;
|
|
|
|
auto model = glm::identity<glm::mat4>();
|
|
|
|
//Transform
|
|
model = glm::translate(model, worldPos);
|
|
|
|
//Billboard (nur y Achse)
|
|
if (worldSpriteComponent.billboard) {
|
|
glm::vec3 camPos = camera.getPosition();
|
|
glm::vec3 direction = camPos - worldPos;
|
|
direction.y = 0.0f;
|
|
direction = glm::normalize(direction);
|
|
|
|
float angle = std::atan2(direction.x, direction.z);
|
|
model = glm::rotate(model, angle, glm::vec3(0, 1, 0));
|
|
}
|
|
|
|
//Scale
|
|
model = glm::scale(model, glm::vec3(worldSpriteComponent.scale.x, worldSpriteComponent.scale.y, 1.0f));
|
|
|
|
return model;
|
|
|
|
}
|