Commit 90bf0d86 authored by Bastian Krayer's avatar Bastian Krayer
Browse files

added voxelization ex

parent 4f9ca71b
cmake_minimum_required(VERSION 2.8)
include(${CMAKE_MODULE_PATH}/DefaultExecutable.cmake)
\ No newline at end of file
#include "VoxelVisualizer.h"
VoxelVisualizer::VoxelVisualizer(glm::ivec3 res, BoundingBox bb)
: m_res(res), m_bb(bb) {
// load visualization shader
std::vector<std::string> shadernames = {
CVK::State::getInstance()->getShaderPath() +
"/Voxelization/voxelVis.vert",
CVK::State::getInstance()->getShaderPath() +
"/Voxelization/voxelVis.geom",
CVK::State::getInstance()->getShaderPath() +
"/Voxelization/voxelVis.frag"};
m_voxelVisualizationShader.generateShaderProgram(
VERTEX_SHADER_BIT | GEOMETRY_SHADER_BIT | FRAGMENT_SHADER_BIT,
shadernames);
std::vector<glm::uvec3> grid;
for (int x = 0; x < m_res.x; x++)
for (int y = 0; y < m_res.y; y++)
for (int z = 0; z < m_res.z; z++)
grid.emplace_back(glm::uvec3(x, y, z));
m_voxelCount = grid.size();
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glEnableVertexAttribArray(VERTICES);
glVertexAttribPointer(VERTICES, 3, GL_UNSIGNED_INT, GL_FALSE, 0, nullptr);
glBufferData(GL_ARRAY_BUFFER, m_voxelCount * sizeof(glm::uvec3),
grid.data(), GL_STATIC_DRAW);
m_voxelVisualizationShader.useProgram();
m_projUniform = glGetUniformLocation(
m_voxelVisualizationShader.getProgramID(), "projection");
m_modelUniform = glGetUniformLocation(
m_voxelVisualizationShader.getProgramID(), "model");
m_viewUniform =
glGetUniformLocation(m_voxelVisualizationShader.getProgramID(), "view");
}
void VoxelVisualizer::free() {
glDeleteBuffers(1, &m_vbo);
glDeleteVertexArrays(1, &m_vao);
}
void VoxelVisualizer::visualize(GLuint voxelTexture, CVK::Camera& cam) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_voxelVisualizationShader.useProgram();
glBindImageTexture(0, voxelTexture, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R8UI);
glm::vec3 diag(1.f / glm::vec3(m_res));
glm::vec3 delta_b = (m_bb.max - m_bb.min) / glm::vec3(m_res);
glm::mat4 scale = glm::scale(glm::mat4(1.f), delta_b);
glm::mat4 trans = glm::translate(glm::mat4(1.f), m_bb.min + 0.5f * delta_b);
glUniformMatrix4fv(m_projUniform, 1, false,
glm::value_ptr(cam.getProjection()->getProjMatrix()));
glUniformMatrix4fv(m_modelUniform, 1, false, glm::value_ptr(trans * scale));
glUniformMatrix4fv(m_viewUniform, 1, false, glm::value_ptr(cam.getView()));
glBindVertexArray(m_vao);
glDrawArrays(GL_POINTS, 0, m_voxelCount);
}
VoxelVisualizer::~VoxelVisualizer() { free(); }
#ifndef SS18CG3_VOXELVISUALIZER_H
#define SS18CG3_VOXELVISUALIZER_H
#include "Voxelizer.h"
#include <CVK_2/CVK_Framework.h>
class VoxelVisualizer {
public:
explicit VoxelVisualizer(glm::ivec3 res, BoundingBox bb);
~VoxelVisualizer();
void visualize(GLuint voxelTexture, CVK::Camera& cam);
void free();
protected:
CVK::ShaderSet m_voxelVisualizationShader;
GLuint m_vao = 0;
GLuint m_vbo = 0;
GLint m_projUniform = -1;
GLint m_viewUniform = -1;
GLint m_modelUniform = -1;
GLsizei m_voxelCount = 0;
glm::ivec3 m_res;
BoundingBox m_bb;
};
#endif // SS18CG3_VOXELVISUALIZER_H
#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(); }
#ifndef SS18CG3_VOXELIZER_H
#define SS18CG3_VOXELIZER_H
#include <CVK_2/CVK_Framework.h>
struct BoundingBox {
glm::vec3 min;
glm::vec3 max;
};
class Voxelizer {
public:
Voxelizer(glm::ivec3 res, CVK::Geometry& geometry);
~Voxelizer();
void voxelize(CVK::Geometry& geometry);
void free();
GLuint getVoxelTexture();
BoundingBox getBB();
protected:
CVK::ShaderSet m_voxelizationShader;
GLuint m_voxelTexture;
GLint m_resUniform;
GLint m_projUniform;
GLint m_modelUniform;
CVK::Ortho m_ortho;
glm::ivec3 m_res;
BoundingBox m_bb;
};
#endif // SS18CG3_VOXELIZER_H
CVK_2
\ No newline at end of file
#include <glad/glad.h>
#include <CVK_2/CVK_CompatibilityTools.h>
#include <CVK_2/CVK_ShaderSet.h>
#include <CVK_2/CVK_Teapot.h>
#include <CVK_2/CVK_Trackball.h>
#include "VoxelVisualizer.h"
#include "Voxelizer.h"
constexpr int width = 800;
constexpr int height = 800;
constexpr glm::ivec3 VOXEL_RESOLUTION{64};
class ExVoxelization : public CVK::GlfwBase {
public:
ExVoxelization();
void display();
};
int main() {
ExVoxelization demo;
demo.display();
return 0;
}
ExVoxelization::ExVoxelization() {
m_window = glfwCreateWindow(width, height, "GPU Voxelization", 0, 0);
glfwSetWindowPos(m_window, 600, 50);
glfwMakeContextCurrent(m_window);
// init opengl
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cerr << "Failed to initialize OpenGL context" << std::endl;
throw std::runtime_error("Failed to initialize OpenGL context");
}
}
void ExVoxelization::display() {
// Trackball camera
auto proj = std::make_shared<CVK::Perspective>(
glm::radians(45.0f), float(width) / float(height), 0.5f, 10.f);
CVK::Trackball cam(m_window, width, height, proj);
cam.setRadius(4);
CVK::Teapot teapot;
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_3D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Voxelizer voxelizer(VOXEL_RESOLUTION, teapot);
VoxelVisualizer voxelVisualizer(VOXEL_RESOLUTION, voxelizer.getBB());
double lastTime = glfwGetTime();
double deltaTime = 0, nowTime = 0;
while (!glfwWindowShouldClose(m_window) &&
glfwGetKey(m_window, GLFW_KEY_Q) != GLFW_PRESS) {
nowTime = glfwGetTime();
deltaTime = nowTime - lastTime;
lastTime = nowTime;
cam.update(deltaTime);
voxelizer.voxelize(teapot);
voxelVisualizer.visualize(voxelizer.getVoxelTexture(), cam);
glfwSwapBuffers(m_window);
glfwPollEvents();
}
}
\ No newline at end of file
#version 430 core
in VertexData {
vec3 pos;
vec3 normal;
vec4 col;
}
fs_in;
out vec4 fragmentColor;
void main() {
vec3 light = vec3(-10, 10, 10);
vec3 lvec = normalize(light - fs_in.pos);
float cos_phi = max(dot(fs_in.normal, lvec), 0.0f);
vec3 eye = normalize(-fs_in.pos);
vec3 reflection = normalize(reflect(-lvec, fs_in.normal));
float cos_psi = pow(max(dot(reflection, eye), 0.0f), 15);
fragmentColor =
0.3 * fs_in.col + 0.7 * cos_phi * fs_in.col + 0.3 * cos_psi * vec4(1);
fragmentColor.a = 0.85;
}
\ No newline at end of file
#version 430 core
layout(points) in;
layout(triangle_strip, max_vertices = 24) out;
layout(binding = 0, r8ui) uniform uimage3D grid;
uniform mat4 model, view, projection;
out VertexData {
vec3 pos;
vec3 normal;
vec4 col;
}
gs_out;
void main(void) {
vec4 color = vec4(0.5, 0.5, 1, 1);
ivec3 index = ivec3(gl_in[0].gl_Position.x, gl_in[0].gl_Position.y,
gl_in[0].gl_Position.z);
uint value = imageLoad(grid, index).r;
if (value != 0) {
mat4 MVP = projection * view * model;
mat4 MV = view * model;
vec3 offset = vec3(0.475, 0.475, 0.475);
vec4 A = vec4(-offset.x, offset.y, offset.z, 0);
vec4 B = vec4(-offset.x, -offset.y, offset.z, 0);
vec4 C = vec4(offset.x, -offset.y, offset.z, 0);
vec4 D = vec4(offset.x, offset.y, offset.z, 0);
vec4 E = vec4(offset.x, offset.y, -offset.z, 0);
vec4 F = vec4(offset.x, -offset.y, -offset.z, 0);
vec4 G = vec4(-offset.x, -offset.y, -offset.z, 0);
vec4 H = vec4(-offset.x, offset.y, -offset.z, 0);
vec4 nA = vec4(0.0f, 0.0f, 1.0f, 0);
vec4 nB = vec4(-1.0f, 0.0f, 0.0f, 0);
vec4 nC = vec4(1.0f, 0.0f, 0.0f, 0);
vec4 nD = vec4(0.0f, 1.0f, 0.0f, 0);
vec4 nE = vec4(0.0f, -1.0f, 0.0f, 0);
vec4 nF = vec4(0.0f, 0.0f, -1.0f, 0);
vec4 pos = gl_in[0].gl_Position;
gs_out.col = color;
// front
gs_out.normal = normalize(vec3(MV * nA));
gs_out.pos = vec3(MV * (pos + A));
gl_Position = MVP * (pos + A);
EmitVertex();
gs_out.pos = vec3(MV * (pos + B));
gl_Position = MVP * (pos + B);
EmitVertex();
gs_out.pos = vec3(MV * (pos + D));
gl_Position = MVP * (pos + D);
EmitVertex();
gs_out.pos = vec3(MV * (pos + C));
gl_Position = MVP * (pos + C);
EmitVertex();
EndPrimitive();
// left
gs_out.normal = normalize(vec3(MV * nB));
gs_out.pos = vec3(MV * (pos + H));
gl_Position = MVP * (pos + H);
EmitVertex();
gs_out.pos = vec3(MV * (pos + G));
gl_Position = MVP * (pos + G);
EmitVertex();
gs_out.pos = vec3(MV * (pos + A));
gl_Position = MVP * (pos + A);
EmitVertex();
gs_out.pos = vec3(MV * (pos + B));
gl_Position = MVP * (pos + B);
EmitVertex();
EndPrimitive();
// right
gs_out.normal = normalize(vec3(MV * nC));
gs_out.pos = vec3(MV * (pos + D));
gl_Position = MVP * (pos + D);
EmitVertex();
gs_out.pos = vec3(MV * (pos + C));
gl_Position = MVP * (pos + C);
EmitVertex();
gs_out.pos = vec3(MV * (pos + E));
gl_Position = MVP * (pos + E);
EmitVertex();
gs_out.pos = vec3(MV * (pos + F));
gl_Position = MVP * (pos + F);
EmitVertex();
EndPrimitive();
// top
gs_out.normal = normalize(vec3(MV * nD));
gs_out.pos = vec3(MV * (pos + H));
gl_Position = MVP * (pos + H);
EmitVertex();
gs_out.pos = vec3(MV * (pos + A));
gl_Position = MVP * (pos + A);
EmitVertex();
gs_out.pos = vec3(MV * (pos + E));
gl_Position = MVP * (pos + E);
EmitVertex();
gs_out.pos = vec3(MV * (pos + D));
gl_Position = MVP * (pos + D);
EmitVertex();
EndPrimitive();
// bottom
gs_out.normal = normalize(vec3(MV * nE));
gs_out.pos = vec3(MV * (pos + B));
gl_Position = MVP * (pos + B);
EmitVertex();
gs_out.pos = vec3(MV * (pos + G));
gl_Position = MVP * (pos + G);
EmitVertex();
gs_out.pos = vec3(MV * (pos + C));
gl_Position = MVP * (pos + C);
EmitVertex();
gs_out.pos = vec3(MV * (pos + F));
gl_Position = MVP * (pos + F);
EmitVertex();
EndPrimitive();
// back
gs_out.normal = normalize(vec3(MV * nF));
gs_out.pos = vec3(MV * (pos + E));
gl_Position = MVP * (pos + E);
EmitVertex();
gs_out.pos = vec3(MV * (pos + F));
gl_Position = MVP * (pos + F);
EmitVertex();
gs_out.pos = vec3(MV * (pos + H));
gl_Position = MVP * (pos + H);
EmitVertex();
gs_out.pos = vec3(MV * (pos + G));
gl_Position = MVP * (pos + G);
EmitVertex();
EndPrimitive();
}
}
\ No newline at end of file
#version 430 core
layout(location = 0) in vec3 Position;
void main() { gl_Position = vec4(Position, 1); }
\ No newline at end of file
#version 420 core
layout(binding = 0, r8ui) uniform uimage3D voxelTexture;
uniform ivec3 res;
out vec4 fragmentColor;
void main() {
ivec3 voxelPos =
ivec3(gl_FragCoord.x, gl_FragCoord.y, res.z * (1 - gl_FragCoord.z));
imageStore(voxelTexture, voxelPos, uvec4(1));
fragmentColor = vec4(vec3(voxelPos) / vec3(res), 1);
}
\ No newline at end of file
#version 420 core
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
uniform mat4 projection;
void main() {
vec4 pos[3];
pos[0] = projection * gl_in[0].gl_Position;
pos[1] = projection * gl_in[1].gl_Position;
pos[2] = projection * gl_in[2].gl_Position;
// TODO Aufgabe 3 b)
gl_Position = pos[0];
EmitVertex();
gl_Position = pos[1];
EmitVertex();
gl_Position = pos[2];
EmitVertex();
EndPrimitive();
}
\ No newline at end of file
#version 420 core
layout(location = 0) in vec4 Position;
uniform mat4 model;
void main() { gl_Position = model * Position; }
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment