Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@
*.exe
*.out
*.app

# Custom
.idea/*
build/*
bindings/*
66 changes: 66 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
cmake_minimum_required(VERSION 3.0)
set(PROJECT_NAME "Task-4-metaballs")
set(CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})
set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
set(CMAKE_CXX_STANDARD 17)

project(${PROJECT_NAME} CXX)

# CONFIG option is important so that CMake doesnt search for modules into the default modules directory
find_package(imgui CONFIG)
find_package(glfw CONFIG)
find_package(glew CONFIG)
find_package(fmt CONFIG)
find_package(glm CONFIG)
find_package(stb CONFIG)

add_executable(
${PROJECT_NAME}

src/main.cpp
src/utils/settings.h
src/utils/buffers.h

src/utils/shader.cpp
src/elements/camera.h

src/elements/opengl.h
src/elements/window.h
src/elements/cubemap.h
src/elements/metaballs.h

bindings/imgui_impl_glfw.cpp
bindings/imgui_impl_opengl3.cpp

# Shaders
assets/cubemap/shaders/vertex.glsl
assets/cubemap/shaders/fragment.glsl

assets/metaballs/shaders/fragment.glsl
assets/metaballs/shaders/geometry.glsl
assets/metaballs/shaders/vertex.glsl
)

add_custom_command(
TARGET ${PROJECT_NAME}

POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/assets ${PROJECT_BINARY_DIR}/assets
)

target_compile_definitions(
${PROJECT_NAME}
PUBLIC
IMGUI_IMPL_OPENGL_LOADER_GLEW
)

target_link_libraries(
${PROJECT_NAME}

imgui::imgui
GLEW::glew_s
glfw::glfw
fmt::fmt
glm::glm
stb::stb
)
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
# ComputerGraphics-OpenGL
# GPU metaballs marching cubes

### Условие
Динамические metaball'ы c отражением и преломлением

## Запуск
Собираем проект:
1) Windows `build.bat`
2) Linux `build.sh`

Далее запускаем `build/Task-4-metaballs`

## Примеры
![](screenshots/metaballs.png)
11 changes: 11 additions & 0 deletions assets/cubemap/shaders/fragment.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#version 430 core

out vec4 gl_FragColor;

in vec3 shader_texture_position;

uniform samplerCube u_skybox;

void main() {
gl_FragColor = texture(u_skybox, shader_texture_position);
}
15 changes: 15 additions & 0 deletions assets/cubemap/shaders/vertex.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#version 430 core

layout (location = 0) in vec3 in_position;

out vec3 shader_texture_position;

uniform mat4 u_view;
uniform mat4 u_projection;

void main() {
shader_texture_position = in_position;
vec4 pos = u_projection * u_view * vec4(in_position, 1.0);

gl_Position = pos.xyww;
}
Binary file added assets/cubemap/textures/simple/back.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cubemap/textures/simple/bottom.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cubemap/textures/simple/front.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cubemap/textures/simple/left.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cubemap/textures/simple/right.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cubemap/textures/simple/top.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions assets/metaballs/shaders/fragment.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#version 430 core

uniform vec3 u_camera_pos;
uniform samplerCube u_skybox;

float u_refraction_value = 1000;

in vec3 shader_position;
in vec3 shader_normal;

out vec4 gl_FragColor;

float coefficient_refraction = 0.25f;
float coefficient_reflection = 0.75f;
float fresnel_alpha = 0.5f;

void main() {
vec3 reflection = reflect(u_camera_pos, shader_normal);
vec3 refraction = refract(u_camera_pos, shader_normal, 1 / coefficient_refraction);

gl_FragColor = mix(
vec4(texture(u_skybox, refraction).rgb, 1.0),
vec4(texture(u_skybox, reflection).rgb, 1.0),
0.2f
);
}
98 changes: 98 additions & 0 deletions assets/metaballs/shaders/geometry.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#version 430 core
layout (points) in;
layout (triangle_strip, max_vertices = 24) out;

layout(std430, binding = 1) buffer edge_table_buffer { int edge_table[]; };
layout(std430, binding = 2) buffer triangle_table_buffer { int triangle_table[256][16]; };

uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_projection;

const float CUBE_SIZE = 0.05f;

out vec3 shader_normal;

float vertex_function(vec3 point) {
vec3 metaball_center1 = vec3(0.0f, 0.0f, 0.0f);
vec3 metaball_center2 = vec3(0.1f, -0.2f, 0.5f);
vec3 metaball_center3 = vec3(-0.5f, 0.5f, -0.5f);

vec3 delta1 = point - metaball_center1;
vec3 delta2 = point - metaball_center2;
vec3 delta3 = point - metaball_center3;

float radius = 0.25f;
float sum = (1 / dot(delta1, delta1)) + (1 / dot(delta2, delta2)) + (1 / dot(delta3, delta3));

return radius * radius * sum - 1;
}

vec3 evaluate_normal(vec3 point) {
return normalize(vec3(
vertex_function(point + vec3(CUBE_SIZE / 8, 0, 0)) - vertex_function(point - vec3(CUBE_SIZE / 8, 0, 0)),
vertex_function(point + vec3(0, CUBE_SIZE / 8, 0)) - vertex_function(point - vec3(0, CUBE_SIZE / 8, 0)),
vertex_function(point + vec3(0, 0, CUBE_SIZE / 8)) - vertex_function(point - vec3(0, 0, CUBE_SIZE / 8))
));
}

vec3 lerp(vec3 point1, vec3 point2) {
float coefficient = abs(vertex_function(point1)) / (abs(vertex_function(point1)) + abs(vertex_function(point2)));
return point1 + (point2 - point1) * coefficient;
}

void main() {
vec3 cube[8] = {
gl_in[0].gl_Position.xyz + vec3(-CUBE_SIZE / 2, -CUBE_SIZE/ 2, -CUBE_SIZE/ 2),
gl_in[0].gl_Position.xyz + vec3(CUBE_SIZE/ 2, -CUBE_SIZE/ 2, -CUBE_SIZE/ 2),
gl_in[0].gl_Position.xyz + vec3(CUBE_SIZE/ 2, -CUBE_SIZE/ 2, CUBE_SIZE/ 2),
gl_in[0].gl_Position.xyz + vec3(-CUBE_SIZE/ 2, -CUBE_SIZE/ 2, CUBE_SIZE/ 2),
gl_in[0].gl_Position.xyz + vec3(-CUBE_SIZE/ 2, CUBE_SIZE/ 2, -CUBE_SIZE/ 2),
gl_in[0].gl_Position.xyz + vec3(CUBE_SIZE/ 2, CUBE_SIZE/ 2, -CUBE_SIZE/ 2),
gl_in[0].gl_Position.xyz + vec3(CUBE_SIZE/ 2, CUBE_SIZE/ 2, CUBE_SIZE/ 2),
gl_in[0].gl_Position.xyz + vec3(-CUBE_SIZE/ 2, CUBE_SIZE/ 2, CUBE_SIZE/ 2)
};

int cubeBitMaskIndex = 0;
if (vertex_function(cube[0]) < 0) cubeBitMaskIndex |= 1;
if (vertex_function(cube[1]) < 0) cubeBitMaskIndex |= 2;
if (vertex_function(cube[2]) < 0) cubeBitMaskIndex |= 4;
if (vertex_function(cube[3]) < 0) cubeBitMaskIndex |= 8;
if (vertex_function(cube[4]) < 0) cubeBitMaskIndex |= 16;
if (vertex_function(cube[5]) < 0) cubeBitMaskIndex |= 32;
if (vertex_function(cube[6]) < 0) cubeBitMaskIndex |= 64;
if (vertex_function(cube[7]) < 0) cubeBitMaskIndex |= 128;

vec3 vertexOnEdge[12];
int edges = edge_table[cubeBitMaskIndex];
if (edges == 0) return;
if ((edges & 1) != 0) vertexOnEdge[0] = lerp(cube[0], cube[1]);
if ((edges & 2) != 0) vertexOnEdge[1] = lerp(cube[1], cube[2]);
if ((edges & 4) != 0) vertexOnEdge[2] = lerp(cube[2], cube[3]);
if ((edges & 8) != 0) vertexOnEdge[3] = lerp(cube[3], cube[0]);
if ((edges & 16) != 0) vertexOnEdge[4] = lerp(cube[4], cube[5]);
if ((edges & 32) != 0) vertexOnEdge[5] = lerp(cube[5], cube[6]);
if ((edges & 64) != 0) vertexOnEdge[6] = lerp(cube[6], cube[7]);
if ((edges & 128) != 0) vertexOnEdge[7] = lerp(cube[7], cube[4]);
if ((edges & 256) != 0) vertexOnEdge[8] = lerp(cube[0], cube[4]);
if ((edges & 512) != 0) vertexOnEdge[9] = lerp(cube[1], cube[5]);
if ((edges & 1024) != 0) vertexOnEdge[10] = lerp(cube[2], cube[6]);
if ((edges & 2048) != 0) vertexOnEdge[11] = lerp(cube[3], cube[7]);

mat4 mvp = u_projection * u_view * u_model;
for (int i = 0; triangle_table[cubeBitMaskIndex][i] != -1; i += 3) {
gl_Position = mvp * vec4(vertexOnEdge[triangle_table[cubeBitMaskIndex][i]], 1);
shader_normal = evaluate_normal(vertexOnEdge[triangle_table[cubeBitMaskIndex][i]]);
EmitVertex();

gl_Position = mvp * vec4(vertexOnEdge[triangle_table[cubeBitMaskIndex][i + 1]], 1);
shader_normal = evaluate_normal(vertexOnEdge[triangle_table[cubeBitMaskIndex][i + 1]]);
EmitVertex();

gl_Position = mvp * vec4(vertexOnEdge[triangle_table[cubeBitMaskIndex][i + 2]], 1);
shader_normal = evaluate_normal(vertexOnEdge[triangle_table[cubeBitMaskIndex][i + 2]]);
EmitVertex();

EndPrimitive();
}
}
7 changes: 7 additions & 0 deletions assets/metaballs/shaders/vertex.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#version 430 core

layout (location = 0) in vec3 in_position;

void main() {
gl_Position = vec4(in_position, 1.0);
}
9 changes: 9 additions & 0 deletions build.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@ECHO ON

RMDIR /Q /S build
MKDIR build
PUSHD build

conan install ..
cmake .. -G "Visual Studio 15 2017 Win64"
cmake --build . --config Release
13 changes: 13 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

set -e
set -x

rm -rf build
mkdir build
pushd build

export CONAN_SYSREQUIRES_MODE=enabled
conan install ..
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
21 changes: 21 additions & 0 deletions conanfile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[requires]
imgui/1.74
glfw/3.3.2
glew/2.1.0
fmt/7.0.3
glm/0.9.9.8
stb/20200203
assimp/5.0.1

[generators]
cmake_find_package_multi

[options]
glew:shared=False
fmt:header_only=True

[imports]
./res/bindings, imgui_impl_glfw.cpp -> ../bindings
./res/bindings, imgui_impl_opengl3.cpp -> ../bindings
./res/bindings, imgui_impl_glfw.h -> ../bindings
./res/bindings, imgui_impl_opengl3.h -> ../bindings
Binary file added screenshots/metaballs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions src/elements/camera.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once

#include <vector>

#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

class Camera {
const GLfloat MOUSE_SENSITIVITY = 45.0f;

glm::vec3 position_{};

GLfloat pitch_ = 0.0f;
GLfloat yaw_ = 0.0f;

GLfloat zoom_ = 45.0f;

public:
explicit Camera(glm::vec3 position) {
position_ = position;
}

[[nodiscard]]
glm::mat4 view() const {
return glm::lookAt(
position(),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f)
);
}

void process_mouse_movement(GLfloat offset_x, GLfloat offset_y) {
yaw_ += offset_x * MOUSE_SENSITIVITY;
pitch_ += offset_y * MOUSE_SENSITIVITY;

if (pitch_ > 89.0f) pitch_ = 89.0f;
if (pitch_ < -89.0f) pitch_ = -89.0f;
}

void process_mouse_scroll(GLfloat offset_y) {
if (offset_y < 0) zoom_ *= 1.2;
else zoom_ /= 1.2;
}

[[nodiscard]]
glm::vec3 position() const {
glm::vec3 pos = position_ * zoom_;

auto rotate = glm::rotate(
glm::identity<glm::mat4>(),
glm::radians(yaw_),
glm::vec3(0.0f, 1.0f, 0.0f)
);
pos = glm::vec3(rotate * glm::vec4(pos, 1.0f));

auto inverse = glm::vec3(rotate * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
rotate = glm::rotate(
glm::identity<glm::mat4>(),
glm::radians(pitch_),
inverse
);

return pos = glm::vec3(rotate * glm::vec4(pos, 1.0f));
}
};
Loading