Voxelizer.cpp 2.77 KB
Newer Older
Bastian Krayer's avatar
Bastian Krayer committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include "Voxelizer.h"

Voxelizer::Voxelizer(glm::ivec3 res, CVK::Geometry& geometry)
    : m_ortho(-1, 1, -1, 1, -1, 1), m_res(res) {

    // todo: Aufgabe 3a) -->
    m_bb.min = glm::vec3(-1);
    m_bb.max = glm::vec3(1);

    m_ortho.setOrtho(-1, 1, -1, 1, -1, 1);
    // <--

    // load voxelization shader
    std::vector<std::string> shadernames = {
        CVK::State::getInstance()->getShaderPath() +
            "/Voxelization/voxelization.vert",
        CVK::State::getInstance()->getShaderPath() +
            "/Voxelization/voxelization.geom",
        CVK::State::getInstance()->getShaderPath() +
            "/Voxelization/voxelization.frag"};

    m_voxelizationShader.generateShaderProgram(
        VERTEX_SHADER_BIT | GEOMETRY_SHADER_BIT | FRAGMENT_SHADER_BIT,
        shadernames);

    // init voxel texture
    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &m_voxelTexture);
    glBindTexture(GL_TEXTURE_3D, m_voxelTexture);

    glTexStorage3D(GL_TEXTURE_3D, 1, GL_R8, m_res.x, m_res.y, m_res.z);

    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    m_resUniform =
        glGetUniformLocation(m_voxelizationShader.getProgramID(), "res");
    m_projUniform =
        glGetUniformLocation(m_voxelizationShader.getProgramID(), "projection");
    m_modelUniform =
        glGetUniformLocation(m_voxelizationShader.getProgramID(), "model");
}

void Voxelizer::voxelize(CVK::Geometry& geometry) {
    // save current viewport
    GLint m_viewport[4];
    glGetIntegerv(GL_VIEWPORT, m_viewport);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glViewport(0, 0, m_res.x, m_res.y);

    m_voxelizationShader.useProgram();
    glUniformMatrix4fv(m_projUniform, 1, false,
                       glm::value_ptr(m_ortho.getProjMatrix()));
    glUniformMatrix4fv(m_modelUniform, 1, false,
                       glm::value_ptr(glm::mat4(1.f)));
    glUniform3iv(m_resUniform, 1, glm::value_ptr(m_res));

    unsigned char clear = 0;
    glClearTexImage(m_voxelTexture, 0, GL_RED, GL_UNSIGNED_BYTE, &clear);
    glBindImageTexture(0, m_voxelTexture, 0, GL_TRUE, 0, GL_READ_WRITE,
                       GL_R8UI);

    geometry.render();

    glMemoryBarrier(GL_ALL_BARRIER_BITS);

    // restore viewport
    glViewport(m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3]);
}

GLuint Voxelizer::getVoxelTexture() { return m_voxelTexture; }

BoundingBox Voxelizer::getBB() { return m_bb; }

void Voxelizer::free() { glDeleteTextures(1, &m_voxelTexture); }

Voxelizer::~Voxelizer() { free(); }