This commit is contained in:
fruitstaa 2018-11-27 21:32:35 +01:00
commit 624c3a4997
7 changed files with 230 additions and 17 deletions

View file

@ -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++) {

View file

@ -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()
{ {

View file

@ -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();

View file

@ -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

Binary file not shown.

View file

@ -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) {

View file

@ -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());