#include "Framebuffer3D.h"

Framebuffer3D::Framebuffer3D(int width, int height, int depth) {
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_3D, texture);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    glTexImage3D(GL_TEXTURE_3D, 0, GL_R32F, width, height, depth, 0, GL_RED, GL_FLOAT, nullptr);

    glGenFramebuffers(1, &buffer);
    glBindFramebuffer(GL_FRAMEBUFFER, buffer);

    GLenum c = GL_COLOR_ATTACHMENT0;

    glFramebufferTexture3D(GL_FRAMEBUFFER, c, GL_TEXTURE_3D, texture, 0, 0);
    glDrawBuffers(1, &c);
}

Framebuffer3D::~Framebuffer3D() {
    glDeleteFramebuffers(1, &buffer);
    glDeleteTextures(1, &texture);
}

void Framebuffer3D::bind_and_clear() {
    glBindFramebuffer(GL_FRAMEBUFFER, buffer);
    glClear(GL_COLOR_BUFFER_BIT);
}

void Framebuffer3D::bind_to(int unit) const {
    glActiveTexture(GL_TEXTURE0 + unit);
    glBindTexture(GL_TEXTURE_3D, texture);
}

void Framebuffer3D::bind_layer(int layer) {
    glBindFramebuffer(GL_FRAMEBUFFER, buffer);
    glFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, texture, 0, layer);
}