// // Created by sebastian on 14.02.26. // #include "WorldSpriteRenderer.h" #include #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 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 uvs = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f }; std::vector indices = { 0, 1, 2, 2, 1, 3 }; quadModel = std::make_unique(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> 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(); //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; }