Merge branch 'master' of http://141.30.224.77/hodasemi/CGI
This commit is contained in:
commit
624c3a4997
7 changed files with 230 additions and 17 deletions
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
in vec4 fragment_color;
|
in vec4 fragment_color;
|
||||||
in vec2 vertex_pos;
|
in vec2 vertex_pos;
|
||||||
|
in vec2 julia_position;
|
||||||
|
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ const int i_max = 200;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec2 z = vertex_pos * m;
|
vec2 z = julia_position * m;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < i_max; i++) {
|
for(i = 0; i < i_max; i++) {
|
||||||
|
|
|
@ -9,8 +9,11 @@ in vec4 in_color;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
uniform mat4 proj;
|
uniform mat4 proj;
|
||||||
|
|
||||||
|
uniform vec2 julia_positions[3];
|
||||||
|
|
||||||
out vec4 fragment_color;
|
out vec4 fragment_color;
|
||||||
out vec2 vertex_pos;
|
out vec2 vertex_pos;
|
||||||
|
out vec2 julia_position;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,13 +47,9 @@ class Viewer : public nse::gui::AbstractViewer
|
||||||
GLint julia_m_id;
|
GLint julia_m_id;
|
||||||
GLint julia_c_id;
|
GLint julia_c_id;
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
// Read, Compile and link the shader codes to a shader program
|
|
||||||
=======
|
|
||||||
GLint julia_pos_id;
|
GLint julia_pos_id;
|
||||||
|
|
||||||
// Read, Compile and link the shader codes to a shader program
|
// Read, Compile and link the shader codes to a shader program
|
||||||
>>>>>>> 8b4276f6ab9ed1d7d6e1909f36944eaa9a8964da
|
|
||||||
void CreateShaders();
|
void CreateShaders();
|
||||||
// Create and define the vertex array and add a number of vertex buffers
|
// Create and define the vertex array and add a number of vertex buffers
|
||||||
void CreateVertexBuffers();
|
void CreateVertexBuffers();
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#include "glsl.h"
|
#include "glsl.h"
|
||||||
|
|
||||||
|
using namespace nse::gui;
|
||||||
|
|
||||||
Viewer::Viewer()
|
Viewer::Viewer()
|
||||||
: AbstractViewer("CG1 Exercise 1")
|
: AbstractViewer("CG1 Exercise 1")
|
||||||
{
|
{
|
||||||
|
@ -29,6 +31,8 @@ Viewer::Viewer()
|
||||||
julia_m_id = glGetUniformLocation(program_id, "m");
|
julia_m_id = glGetUniformLocation(program_id, "m");
|
||||||
julia_c_id = glGetUniformLocation(program_id, "c");
|
julia_c_id = glGetUniformLocation(program_id, "c");
|
||||||
|
|
||||||
|
julia_pos_id = glGetUniformLocation(program_id, "julia_positions");
|
||||||
|
|
||||||
modelViewMatrix.setIdentity();
|
modelViewMatrix.setIdentity();
|
||||||
projectionMatrix.setIdentity();
|
projectionMatrix.setIdentity();
|
||||||
|
|
||||||
|
@ -254,6 +258,13 @@ void Viewer::drawContents()
|
||||||
else
|
else
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
// create uniform buffer for julia_positions
|
||||||
|
float julia_positions[6] = {
|
||||||
|
point1X->value(), point1Y->value(),
|
||||||
|
point2X->value(), point2Y->value(),
|
||||||
|
point3X->value(), point3Y->value()
|
||||||
|
};
|
||||||
|
|
||||||
// Activate the shader program
|
// Activate the shader program
|
||||||
glUseProgram(program_id);
|
glUseProgram(program_id);
|
||||||
|
|
||||||
|
@ -269,6 +280,8 @@ void Viewer::drawContents()
|
||||||
glUniform1f(julia_m_id, juliaZoom);
|
glUniform1f(julia_m_id, juliaZoom);
|
||||||
glUniform2fv(julia_c_id, 1, juliaC.data());
|
glUniform2fv(julia_c_id, 1, juliaC.data());
|
||||||
|
|
||||||
|
glUniform2fv(julia_pos_id, 6, julia_positions);
|
||||||
|
|
||||||
// Bind the vertex array
|
// Bind the vertex array
|
||||||
glBindVertexArray(vertex_array_id);
|
glBindVertexArray(vertex_array_id);
|
||||||
// Draw the bound vertex array. Start at element 0 and draw 3 vertices
|
// Draw the bound vertex array. Start at element 0 and draw 3 vertices
|
||||||
|
|
BIN
exercise2/A2.pdf
Normal file
BIN
exercise2/A2.pdf
Normal file
Binary file not shown.
|
@ -29,7 +29,7 @@ const vec2 offsets[6] = vec2[6](
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 terrain_position = vec4(position.x, getTerrainHeight(vec2(position.x, position.z)), position.z, position.w);
|
vec4 terrain_position = vec4(position.x, getTerrainHeight(vec2(position.x, position.z)), position.z, position.w);
|
||||||
n = calculate_normal(position);
|
n = calculate_normal(terrain_position);
|
||||||
//n = vec3(0.0, 1.0, 0.0);
|
//n = vec3(0.0, 1.0, 0.0);
|
||||||
|
|
||||||
uv = vec2(terrain_position.x / 255.0, terrain_position.z / 255.0);
|
uv = vec2(terrain_position.x / 255.0, terrain_position.z / 255.0);
|
||||||
|
@ -48,8 +48,8 @@ float perlinNoise(vec2 p )
|
||||||
{
|
{
|
||||||
vec2 ij = floor(p);
|
vec2 ij = floor(p);
|
||||||
vec2 xy = p - ij;
|
vec2 xy = p - ij;
|
||||||
//xy = 3.*xy*xy-2.*xy*xy*xy;
|
xy = 3.*xy*xy-2.*xy*xy*xy;
|
||||||
xy = .5*(1.-cos(3.1415926 * xy));
|
//xy = .5*(1.-cos(3.1415926 * xy));
|
||||||
float a = rand((ij+vec2(0.,0.)));
|
float a = rand((ij+vec2(0.,0.)));
|
||||||
float b = rand((ij+vec2(1.,0.)));
|
float b = rand((ij+vec2(1.,0.)));
|
||||||
float c = rand((ij+vec2(0.,1.)));
|
float c = rand((ij+vec2(0.,1.)));
|
||||||
|
@ -77,8 +77,9 @@ float getTerrainHeight(vec2 p)
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 offset_point(vec4 base, vec2 offset) {
|
vec4 offset_point(vec4 base, vec2 offset) {
|
||||||
float y = getTerrainHeight(vec2(base.x, base.z) + offset);
|
vec2 new_pos = vec2(base.x, base.z) + offset;
|
||||||
return vec4(base.x + offset.x, y, base.z + offset.y, base.w);
|
float y = getTerrainHeight(new_pos);
|
||||||
|
return vec4(new_pos.x, y, new_pos.y, base.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the position of the first vertex in this square
|
// calculate the position of the first vertex in this square
|
||||||
|
@ -115,11 +116,11 @@ vec3 calculate_normal(vec4 terrain_position) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create connection vectors
|
// create connection vectors
|
||||||
vec3 p1 = (points[0] - terrain_position).xyz;
|
vec3 v1 = (points[0] - terrain_position).xyz;
|
||||||
vec3 p2 = (points[1] - terrain_position).xyz;
|
vec3 v2 = (points[1] - terrain_position).xyz;
|
||||||
|
|
||||||
// calculate normal
|
// calculate normal
|
||||||
vec3 normal = normalize(cross(p1, p2));
|
vec3 normal = normalize(cross(v1, v2));
|
||||||
|
|
||||||
// naively assume that a normal always has to look upwards
|
// naively assume that a normal always has to look upwards
|
||||||
if (normal.y < 0.0) {
|
if (normal.y < 0.0) {
|
||||||
|
|
|
@ -10,15 +10,22 @@
|
||||||
|
|
||||||
#include <gui/SliderHelper.h>
|
#include <gui/SliderHelper.h>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
#include "glsl.h"
|
#include "glsl.h"
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
//using vec4 = Eigen::Vector4f;
|
||||||
|
/*
|
||||||
|
#define Eigen::Vector4f vec4
|
||||||
|
#define Eigen::Vector3f vec3
|
||||||
|
#define Eigen::Vector2f vec2
|
||||||
|
*/
|
||||||
|
|
||||||
constexpr bool REFERENCE = true;
|
constexpr bool REFERENCE = true;
|
||||||
constexpr uint32_t PATCH_SIZE = 256; //number of vertices along one side of the terrain patch
|
constexpr uint32_t PATCH_SIZE = 256; //number of vertices along one side of the terrain patch
|
||||||
|
@ -154,11 +161,142 @@ std::string vec4_to_str(Eigen::Vector4f &v)
|
||||||
<< v.z() << ", "
|
<< v.z() << ", "
|
||||||
<< v.w() << ")";
|
<< v.w() << ")";
|
||||||
|
|
||||||
//std::cout << ss.str() << std::endl;
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string vec3_to_str(Eigen::Vector3f& v) {
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << "(" << v.x() << ", "
|
||||||
|
<< v.y() << ", "
|
||||||
|
<< v.z() << ")";
|
||||||
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float length(Eigen::Vector2f v) {
|
||||||
|
return sqrt(v.x() * v.x() + v.y() * v.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
float dot(Eigen::Vector2f v1, Eigen::Vector2f v2) {
|
||||||
|
return (v1.x() * v2.x() + v1.y() * v2.y()) / length(v1) * length(v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
float mix(float f1, float f2, float value) {
|
||||||
|
float difference = f1 - f2;
|
||||||
|
|
||||||
|
return f1 + difference * value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//source: https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83
|
||||||
|
float rand(Eigen::Vector2f c)
|
||||||
|
{
|
||||||
|
double dummy;
|
||||||
|
return 2 * modf(sin(dot(c, Eigen::Vector2f(12.9898f, 78.233f))) * 43758.5453, &dummy) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eigen::Vector2f mul(Eigen::Vector2f v1, Eigen::Vector2f v2) {
|
||||||
|
return Eigen::Vector2f(v1.x() * v2.x(), v1.y() * v2.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
float perlinNoise(Eigen::Vector2f p)
|
||||||
|
{
|
||||||
|
Eigen::Vector2f ij = Eigen::Vector2f(floor(p.x()), floor(p.y()));
|
||||||
|
Eigen::Vector2f xy = p - ij;
|
||||||
|
xy = (3.0f * mul(xy, xy)) - (2.0f * mul(mul(xy, xy), xy));
|
||||||
|
//xy = 0.5f * (1.0f - cos(3.1415926 * xy));
|
||||||
|
float a = rand((ij + Eigen::Vector2f(0.0f, 0.0f)));
|
||||||
|
float b = rand((ij + Eigen::Vector2f(1.0f, 0.0f)));
|
||||||
|
float c = rand((ij + Eigen::Vector2f(0.0f, 1.0f)));
|
||||||
|
float d = rand((ij + Eigen::Vector2f(1.0f, 1.0f)));
|
||||||
|
float x1 = mix(a, b, xy.x());
|
||||||
|
float x2 = mix(c, d, xy.x());
|
||||||
|
return mix(x1, x2, xy.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
//based on https://www.seedofandromeda.com/blogs/58-procedural-heightmap-terrain-generation
|
||||||
|
float getTerrainHeight(Eigen::Vector2f p)
|
||||||
|
{
|
||||||
|
float total = 0.0;
|
||||||
|
float maxAmplitude = 0.0;
|
||||||
|
float amplitude = 1.0;
|
||||||
|
float frequency = 0.02;
|
||||||
|
for (int i = 0; i < 11; i++)
|
||||||
|
{
|
||||||
|
total += ((1.0 - abs(perlinNoise(p * frequency))) * 2.0 - 1.0) * amplitude;
|
||||||
|
frequency *= 2.0;
|
||||||
|
maxAmplitude += amplitude;
|
||||||
|
amplitude *= 0.45;
|
||||||
|
}
|
||||||
|
return 15 * total / maxAmplitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eigen::Vector3f vec4_to_vec3(Eigen::Vector4f v) {
|
||||||
|
return Eigen::Vector3f(v.x(), v.y(), v.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
Eigen::Vector3f calculate_gpu_normal(Eigen::Vector4f pos, int gl_VertexID) {
|
||||||
|
const Eigen::Vector2f offsets[6] = {
|
||||||
|
Eigen::Vector2f(0.0, 0.0),
|
||||||
|
Eigen::Vector2f(0.0, 1.0),
|
||||||
|
Eigen::Vector2f(1.0, 0.0),
|
||||||
|
Eigen::Vector2f(0.0, 1.0),
|
||||||
|
Eigen::Vector2f(1.0, 0.0),
|
||||||
|
Eigen::Vector2f(1.0, 1.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
int offset_index = gl_VertexID % 6;
|
||||||
|
|
||||||
|
Eigen::Vector4f base_vertex = Eigen::Vector4f(pos.x() - offsets[offset_index].x(), pos.y(), pos.z() - offsets[offset_index].y(), pos.w());
|
||||||
|
|
||||||
|
// the other 2 points from the triangle
|
||||||
|
int points_index = 0;
|
||||||
|
Eigen::Vector4f points[2];
|
||||||
|
|
||||||
|
int iterator_offset = 0;
|
||||||
|
|
||||||
|
// second triangle offset
|
||||||
|
if (offset_index > 2) {
|
||||||
|
iterator_offset = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = iterator_offset; i < (3 + iterator_offset); i++) {
|
||||||
|
// skip for current vertex
|
||||||
|
if (i == offset_index) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eigen::Vector2f new_pos = Eigen::Vector2f(base_vertex.x(), base_vertex.z()) + offsets[i];
|
||||||
|
float y = getTerrainHeight(new_pos);
|
||||||
|
points[points_index] = Eigen::Vector4f(new_pos.x(), y, new_pos.y(), base_vertex.w());
|
||||||
|
|
||||||
|
points_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create connection vectors
|
||||||
|
Eigen::Vector3f v1 = vec4_to_vec3(points[0] - pos);
|
||||||
|
Eigen::Vector3f v2 = vec4_to_vec3(points[1] - pos);
|
||||||
|
|
||||||
|
v1.normalize();
|
||||||
|
v2.normalize();
|
||||||
|
|
||||||
|
Eigen::Vector3f normal = v1.cross(v2).normalized();
|
||||||
|
|
||||||
|
return normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eigen::Vector3f calculate_reference_normal(Eigen::Vector4f p1, Eigen::Vector4f p2, Eigen::Vector4f p3) {
|
||||||
|
Eigen::Vector3f v1 = vec4_to_vec3(p1 - p2);
|
||||||
|
Eigen::Vector3f v2 = vec4_to_vec3(p1 - p3);
|
||||||
|
|
||||||
|
v1.normalize();
|
||||||
|
v2.normalize();
|
||||||
|
|
||||||
|
Eigen::Vector3f normal = v1.cross(v2).normalized();
|
||||||
|
|
||||||
|
return normal;
|
||||||
|
}
|
||||||
|
|
||||||
void Viewer::CreateGeometry()
|
void Viewer::CreateGeometry()
|
||||||
{
|
{
|
||||||
//empty VAO for sky
|
//empty VAO for sky
|
||||||
|
@ -219,7 +357,7 @@ void Viewer::CreateGeometry()
|
||||||
{
|
{
|
||||||
for (int j = 0; j < PATCH_SIZE; j++)
|
for (int j = 0; j < PATCH_SIZE; j++)
|
||||||
{
|
{
|
||||||
ref_pos.emplace_back((float)j, 0.0f, (float)i, 1.0f);
|
ref_pos.emplace_back((float)j, getTerrainHeight(Eigen::Vector2f((float)j, (float)i)), (float)i, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,6 +382,67 @@ void Viewer::CreateGeometry()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// ---------------- Debugging Area ------------------
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
for (int i = 0; i < ref_ind.size(); i+=6) {
|
||||||
|
struct Point {
|
||||||
|
Eigen::Vector4f position;
|
||||||
|
Eigen::Vector3f normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Point> gpu_points;
|
||||||
|
std::vector<Point> ref_points;
|
||||||
|
|
||||||
|
for (int j = i; j < i+6; j++) {
|
||||||
|
// gpu
|
||||||
|
{
|
||||||
|
auto position = ref_pos[j];
|
||||||
|
auto normal = calculate_gpu_normal(position, j);
|
||||||
|
|
||||||
|
gpu_points.emplace_back(Point { position, normal });
|
||||||
|
}
|
||||||
|
|
||||||
|
// reference
|
||||||
|
{
|
||||||
|
int index = j % 6;
|
||||||
|
auto position = ref_pos[j];
|
||||||
|
Eigen::Vector3f normal;
|
||||||
|
|
||||||
|
if (index < 3) {
|
||||||
|
normal = calculate_reference_normal(ref_pos[i], ref_pos[i+1], ref_pos[i+2]);
|
||||||
|
} else {
|
||||||
|
normal = calculate_reference_normal(ref_pos[i+3], ref_pos[i+4], ref_pos[i+5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_points.emplace_back(Point { position, normal });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string gpu_output = "gpu_points: \n";
|
||||||
|
std::string ref_output = "ref_points: \n";
|
||||||
|
|
||||||
|
for (Point& point : gpu_points) {
|
||||||
|
gpu_output += "\tpos: " + vec4_to_str(point.position) + "\tnormal: " + vec3_to_str(point.normal) + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Point& point : ref_points) {
|
||||||
|
ref_output += "\tpos: " + vec4_to_str(point.position) + "\tnormal: " + vec3_to_str(point.normal) + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << gpu_output << std::endl;
|
||||||
|
std::cout << ref_output << std::endl;
|
||||||
|
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// -------------- Debugging Area End ----------------
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
referenceVB.uploadData(ref_pos)
|
referenceVB.uploadData(ref_pos)
|
||||||
.bindToAttribute("position");
|
.bindToAttribute("position");
|
||||||
referenceIB.uploadData(ref_ind.size() * sizeof(uint32_t), ref_ind.data());
|
referenceIB.uploadData(ref_ind.size() * sizeof(uint32_t), ref_ind.data());
|
||||||
|
|
Loading…
Reference in a new issue