diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arap.cpp | 9 | ||||
-rw-r--r-- | src/arap.h | 16 | ||||
-rwxr-xr-x | src/glwidget.cpp | 172 | ||||
-rwxr-xr-x | src/glwidget.h | 27 | ||||
-rw-r--r-- | src/graphics/shader.h | 1 | ||||
-rw-r--r-- | src/graphics/shape.cpp | 70 | ||||
-rw-r--r-- | src/graphics/shape.h | 19 | ||||
-rw-r--r-- | src/ocean/halftone.cpp | 47 | ||||
-rw-r--r-- | src/ocean/halftone.h | 19 | ||||
-rw-r--r-- | src/ocean/ocean_alt.cpp | 60 | ||||
-rw-r--r-- | src/ocean/ocean_alt.h | 43 | ||||
-rw-r--r-- | src/skybox.cpp | 167 | ||||
-rw-r--r-- | src/skybox.h | 220 |
13 files changed, 845 insertions, 25 deletions
diff --git a/src/arap.cpp b/src/arap.cpp index 2f10849..9bfbd27 100644 --- a/src/arap.cpp +++ b/src/arap.cpp @@ -38,6 +38,8 @@ void ARAP::init vertices = m_ocean.get_vertices(); triangles = m_ocean.get_faces(); m_shape.init(vertices, triangles); + m_foam_shape.init(vertices, triangles); + m_shape.setColor(0.27f, .803f, .96f); // Students, please don't touch this code: get min and max for viewport stuff @@ -104,8 +106,11 @@ void ARAP::update(double seconds) // the last update m_ocean.fft_prime(m_time); - // m_shape.setVertices_and_Normals(m_ocean.get_vertices(), m_ocean.getNormals()); - m_shape.setVertices(m_ocean.get_vertices()); + // m_shape.setVertices_and_Normals(m_ocean.get_vertices(), m_ocean.getNormals()); + m_shape.setVertices(m_ocean.get_vertices()); + + FoamConstants foam = m_ocean.getFoamConstants(); + m_foam_shape.setFoamInputs(m_shape.getVertices(), foam.wavelengths, foam.k_vectors, foam.texCoords); m_time += m_timestep; @@ -19,7 +19,8 @@ class ARAP { private: Shape m_shape; -// OceanShape m_oceanShape; + Shape m_foam_shape; + public: ARAP(); @@ -43,6 +44,17 @@ public: m_shape.draw(shader, mode); } + void drawFoam(Shader *shader, GLenum mode) + { + + + m_foam_shape.draw(shader, mode); + } + + double getTime() { + return m_time; + } + void initGroundPlane(std::string texturePath, float depth, Shader* shader) { m_shape.initGroundPlane(texturePath, depth, shader); } @@ -84,7 +96,7 @@ public: ocean_alt m_ocean; double m_time = 0.00; - double m_timestep = 0.03; + double m_timestep = 0.3; Eigen::Vector3f minCorner, maxCorner; }; diff --git a/src/glwidget.cpp b/src/glwidget.cpp index c13d476..f9bedc9 100755 --- a/src/glwidget.cpp +++ b/src/glwidget.cpp @@ -3,6 +3,11 @@ #include <QApplication> #include <QKeyEvent> #include <iostream> +#define STB_IMAGE_IMPLEMENTATION + +#include "stb/stb_image.h" + + #define SPEED 1.5 #define ROTATE_SPEED 0.0025 @@ -45,12 +50,20 @@ GLWidget::GLWidget(QWidget *parent) : // Function tick() will be called once per interva connect(&m_intervalTimer, SIGNAL(timeout()), this, SLOT(tick())); + + //m_skybox = new skybox(); } GLWidget::~GLWidget() { if (m_defaultShader != nullptr) delete m_defaultShader; if (m_pointShader != nullptr) delete m_pointShader; + if (m_foamShader != nullptr) delete m_foamShader; + + if (m_skyboxShader != nullptr) delete m_skyboxShader; + //if (m_skybox != nullptr) delete m_skybox; + + } // ================== Basic OpenGL Overrides @@ -65,8 +78,12 @@ void GLWidget::initializeGL() // Set clear color to white glClearColor(0, 0, 0, 1); +// glEnable(GL_DEPTH_TEST); +// glEnable(GL_CULL_FACE); +// glEnable(GL_BLEND); +// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - // Enable depth-testing and backface culling +// // Enable depth-testing and backface culling glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); @@ -78,9 +95,27 @@ void GLWidget::initializeGL() m_pointShader = new Shader(":resources/shaders/anchorPoint.vert", ":resources/shaders/anchorPoint.geom", ":resources/shaders/anchorPoint.frag"); // m_texture_shader = new Shader(":/resources/shaders/texture.vert", ":/resources/shaders/texture.frag"); m_colorShader = new Shader(":resources/shaders/color.vert", ":resources/shaders/color.frag"); + m_foamShader = new Shader(":resources/shaders/foam.vert", ":resources/shaders/foam.frag"); + m_skyboxShader = new Shader(":resources/shaders/skybox.vert", ":resources/shaders/skybox.frag"); + + // specify texture for skybox +// m_skyboxShader->bind(); +// glUniform1i(glGetUniformLocation(m_skyboxShader->id(), "cubeMap"), 9); // bind texture at slot 9 +// Eigen::Vector3f sc = Eigen::Vector3f(.77f, .85f, .99f); // skycolor for fade effect +// glUniform3f(glGetUniformLocation(m_skyboxShader->id(), "skyColor"), sc[0], sc[1], sc[2]); +// m_skyboxShader->unbind(); + + + m_halftone_tex = loadTextureFromFile("/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/halftone.png").textureID; + m_foam_tex = loadTextureFromFile("/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/foam3.png").textureID; + initCaustics(); + + // init skybox stuff + m_skybox.initializeVAO(); + // INITIALIZE TEXTURE STUFF // Prepare filepath @@ -161,6 +196,9 @@ void GLWidget::initializeGL() m_camera.lookAt(eye, target); m_camera.setOrbitPoint(target); m_camera.setPerspective(120, width() / static_cast<float>(height()), nearPlane, farPlane); + m_camera.setPosition(Eigen::Vector3f( 0, + 0, + -70289.5)); m_deltaTimeProvider.start(); m_intervalTimer.start(1000 / 60); @@ -306,9 +344,9 @@ void GLWidget::paintGL() glBindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO); // return; // paintTexture(m_ground_texture, false); -// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -// glEnable( GL_BLEND ); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable( GL_BLEND ); m_defaultShader->bind(); m_defaultShader->setUniform("proj", m_camera.getProjection()); @@ -335,8 +373,131 @@ void GLWidget::paintGL() // m_pointShader->setUniform("height", height()); // m_arap.draw(m_pointShader, GL_POINTS); // m_pointShader->unbind(); + + m_foamShader->bind(); + m_foamShader->setUniform("proj", m_camera.getProjection()); + m_foamShader->setUniform("view", m_camera.getView()); +// m_foamShader->setUniform("vSize", m_vSize); +// m_foamShader->setUniform("width", width()); +// m_foamShader->setUniform("height", height()); + glUniform1f(glGetUniformLocation(m_foamShader->id(), "time"), m_arap.getTime()); + glUniform1f(glGetUniformLocation(m_foamShader->id(), "phaseC"), 1.f); + m_foamShader->setUniform("widthBounds", m_arap.minCorner[0], m_arap.maxCorner[0]); + m_foamShader->setUniform("lengthBounds", m_arap.minCorner[2], m_arap.maxCorner[2]); + + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_2D, m_halftone_tex); + glUniform1i(glGetUniformLocation(m_foamShader->id(), "halftone_texture"), 5); + + glActiveTexture(GL_TEXTURE6); + glBindTexture(GL_TEXTURE_2D, m_foam_tex); + glUniform1i(glGetUniformLocation(m_foamShader->id(), "foam_texture"), 6); + + + + + m_arap.drawFoam(m_foamShader, GL_TRIANGLES); + m_foamShader->unbind(); + + // skybox + + + + m_skybox.draw(m_skyboxShader, m_camera); + + + } +TextureData GLWidget::loadTextureFromFile(const char *path) +{ + std::string filename = std::string(path); + + GLuint textureID; + glGenTextures(1, &textureID); + + int width, height, nrComponents; + stbi_set_flip_vertically_on_load(true); + unsigned char *data = stbi_load(filename.c_str(), &width, &height, &nrComponents, 0); + stbi_set_flip_vertically_on_load(false); + if (data) + { + GLenum format; + if (nrComponents == 1) + format = GL_RED; + else if (nrComponents == 3) + format = GL_RGB; + else if (nrComponents == 4) + format = GL_RGBA; + + glBindTexture(GL_TEXTURE_2D, textureID); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + glGenerateMipmap(GL_TEXTURE_2D); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + stbi_image_free(data); + + } + else + { + std::cout << "Texture failed to load at path: " << path << std::endl; + stbi_image_free(data); + } + + TextureData newtex; + newtex.textureID = textureID; + newtex.height = height; + newtex.width = width; + return newtex; +} + +GLuint GLWidget::loadCubeMap(std::vector<const char*> textureFiles){ + std::cout << "hello 111" << std::endl; + + // create empty texture + GLuint textureID; + glGenTextures(1, &textureID); + + std::cout << "hello fssd" << std::endl; + + + //glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + std::cout << "hello fssd" << std::endl; + + GLuint target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + for (int i=0; i<6; i++){ + std::string filename = std::string(textureFiles[i]);//directory + '/' + filename; + int width, height, nrChannels; + unsigned char* data = stbi_load(filename.c_str(), &width, &height, &nrChannels, 0); + + if (data){ + stbi_set_flip_vertically_on_load(false); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + stbi_image_free(data); + + } else { + std::cout << "Texture failed to load at path: " << textureFiles[i] << std::endl; + stbi_image_free(data); + } + } + + return textureID; +} + + + void GLWidget::resizeGL(int w, int h) { glViewport(0, 0, w, h); @@ -497,6 +658,8 @@ void GLWidget::tick() { float deltaSeconds = m_deltaTimeProvider.restart() / 1000.f; m_arap.update(deltaSeconds); + // rotate skybox + m_skybox.update(deltaSeconds); // Move camera auto look = m_camera.getLook(); @@ -508,6 +671,7 @@ void GLWidget::tick() moveVec *= deltaSeconds; m_camera.move(moveVec); + // Flag this view for repainting (Qt will call paintGL() soon after) update(); } diff --git a/src/glwidget.h b/src/glwidget.h index 810829a..006f027 100755 --- a/src/glwidget.h +++ b/src/glwidget.h @@ -1,8 +1,8 @@ #pragma once -#ifdef __APPLE__ -#define GL_SILENCE_DEPRECATION -#endif +#include "skybox.h" +#include <GL/glew.h> + #include "arap.h" #include "graphics/camera.h" @@ -13,6 +13,12 @@ #include <QTimer> #include <memory> +struct TextureData{ + GLuint textureID; + int width; + int height; +}; + class GLWidget : public QOpenGLWidget { Q_OBJECT @@ -45,6 +51,10 @@ private: void initCaustics(); void paintCaustics(); + TextureData loadTextureFromFile(const char *path); + GLuint loadCubeMap(std::vector<const char*> textureFiles); + + private slots: // Physics Tick void tick(); @@ -57,6 +67,10 @@ private: Shader *m_texture_shader; Shader *m_colorShader; + Shader *m_foamShader; + Shader *m_skyboxShader; + + GLuint m_fullscreen_vbo; GLuint m_fullscreen_vao; @@ -79,6 +93,11 @@ private: float m_vertexSelectionThreshold; float m_vSize; + // FOAM + GLuint m_halftone_tex; + GLuint m_foam_tex; + + // Timing QElapsedTimer m_deltaTimeProvider; // For measuring elapsed time QTimer m_intervalTimer; // For triggering timed events @@ -95,4 +114,6 @@ private: bool m_rightCapture; SelectMode m_rightClickSelectMode; int m_lastSelectedVertex = -1; + + skybox m_skybox; }; diff --git a/src/graphics/shader.h b/src/graphics/shader.h index 7e9dad4..5f7d7c6 100644 --- a/src/graphics/shader.h +++ b/src/graphics/shader.h @@ -10,6 +10,7 @@ #include <util/unsupportedeigenthing/OpenGLSupport> + class Shader { public: Shader(const std::string &vertexPath, const std::string &fragmentPath); diff --git a/src/graphics/shape.cpp b/src/graphics/shape.cpp index 7a33140..e0afb83 100644 --- a/src/graphics/shape.cpp +++ b/src/graphics/shape.cpp @@ -119,6 +119,29 @@ void Shape::setVertices_and_Normals(const vector<Vector3f> &vertices, const vect glBindBuffer(GL_ARRAY_BUFFER, 0); } +//// FOR FOAMM!!!! +/// + +void Shape::setFoamInputs(const vector<Vector3f> &vertices, const vector<float> &wavelengths, + const vector<Vector2f> &waveDirs, const vector<Vector2f> &textures){ + + m_vertices.clear(); + copy(vertices.begin(), vertices.end(), back_inserter(m_vertices)); + + vector<Vector3f> verts; + vector<Vector3f> normals; + vector<Vector3f> colors; + + updateMeshFoam(m_faces, vertices, wavelengths, waveDirs, verts, normals, colors); + + glBindBuffer(GL_ARRAY_BUFFER, m_surfaceVbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * ((verts.size() * 3) + (normals.size() * 3) + (colors.size() * 3)), nullptr, GL_DYNAMIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * verts.size() * 3, static_cast<const void *>(verts.data())); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(float) * verts.size() * 3, sizeof(float) * normals.size() * 3, static_cast<const void *>(normals.data())); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(float) * ((verts.size() * 3) + (normals.size() * 3)), sizeof(float) * colors.size() * 3, static_cast<const void *>(colors.data())); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + // ================== Model Matrix void Shape::setModelMatrix(const Affine3f &model) { m_modelMatrix = model.matrix(); } @@ -313,7 +336,7 @@ void Shape::updateMesh(const std::vector<Eigen::Vector3i> &faces, Vector3f n = getNormal(face); for (auto& v: {face[0], face[1], face[2]}) { - normals.push_back(n); + normals.push_back(Eigen::Vector3f(1,1,1)); verts.push_back(vertices[v]); if (m_anchors.find(v) == m_anchors.end()) { @@ -325,6 +348,51 @@ void Shape::updateMesh(const std::vector<Eigen::Vector3i> &faces, } } +void Shape::updateMeshFoam(const std::vector<Eigen::Vector3i> &faces, + const std::vector<Eigen::Vector3f> &vertices, + const std::vector<float> &wavelengths, + const vector<Vector2f> &waveDirs, + std::vector<Eigen::Vector3f>& verts, + std::vector<Eigen::Vector3f>& normals, + std::vector<Eigen::Vector3f>& colors) +{ + verts.reserve(faces.size() * 3); + normals.reserve(faces.size() * 3); + colors.reserve(faces.size() * 3); + + + for (const Eigen::Vector3i& face : faces) { + + for (auto& v: {face[0], face[1], face[2]}) { + normals.push_back(Eigen::Vector3f(wavelengths[v],0,0)); + verts.push_back(vertices[v]); + colors.push_back(Eigen::Vector3f(waveDirs[v][0], waveDirs[v][1], 0)); + } + } +} + +void Shape::updateFoam(const std::vector<Eigen::Vector3i> &faces, + const std::vector<Eigen::Vector3f> &vertices, + const std::vector<Eigen::Vector2f> &texCoords, + + std::vector<Eigen::Vector3f>& verts, + std::vector<Eigen::Vector2f>& tex, + std::vector<Eigen::Vector3f>& colors) +{ + //verts.reserve(faces.size() * 3); + tex.reserve(faces.size() * 3); + + for (const Eigen::Vector3i& face : faces) { + + for (auto& v: {face[0], face[1], face[2]}) { + tex.push_back(texCoords[v]); + //std::cout << texCoords[v] << std::endl; + //verts.push_back(vertices[v]); + + } + } +} + void Shape::updateMesh_withNormals(const std::vector<Eigen::Vector3i> &faces, const std::vector<Eigen::Vector3f> &vertices, const std::vector<Eigen::Vector3f> &calculated_norms, diff --git a/src/graphics/shape.h b/src/graphics/shape.h index 2915190..ab3c27a 100644 --- a/src/graphics/shape.h +++ b/src/graphics/shape.h @@ -31,6 +31,25 @@ public: void init(const std::vector<Eigen::Vector3f> &vertices, const std::vector<Eigen::Vector3i> &triangles); void setVertices(const std::vector<Eigen::Vector3f> &vertices); void setVertices_and_Normals(const std::vector<Eigen::Vector3f> &vertices, const std::vector<Eigen::Vector3f> &normals); + void setFoamInputs(const std::vector<Eigen::Vector3f> &verts, const std::vector<float> &wavelengths, + const std::vector<Eigen::Vector2f> &waveDirs, const std::vector<Eigen::Vector2f> &textureCoords); + void updateFoam(const std::vector<Eigen::Vector3i> &faces, + const std::vector<Eigen::Vector3f> &vertices, + const std::vector<Eigen::Vector2f> &texCoords, + + std::vector<Eigen::Vector3f>& verts, + std::vector<Eigen::Vector2f>& tex, + std::vector<Eigen::Vector3f>& colors); + + void updateMeshFoam(const std::vector<Eigen::Vector3i> &faces, + const std::vector<Eigen::Vector3f> &vertices, + const std::vector<float> &wavelengths, + const std::vector<Eigen::Vector2f> &waveDirs, + + std::vector<Eigen::Vector3f>& verts, + std::vector<Eigen::Vector3f>& normals, + std::vector<Eigen::Vector3f>& colors); + void setModelMatrix(const Eigen::Affine3f &model); diff --git a/src/ocean/halftone.cpp b/src/ocean/halftone.cpp new file mode 100644 index 0000000..6aa59cb --- /dev/null +++ b/src/ocean/halftone.cpp @@ -0,0 +1,47 @@ +#include "halftone.h" +#include <cmath> +#include <vector> + +halftone::halftone() +{ + +} + +//void halftone::init(int n, int m, float density){ +// N = n; +// M = m; +// // std::vector<std::vector<int>> m_halftone; +// // 1. intiialize pattern array with density +// for (int i=0; i<N; i++){ +// for (int j=0; j<M; j++){ +// // determine whether to place a 1 or 0 here based on density + +// // generate random number 0-1 +// float r = ((float) rand() / (float) RAND_MAX); +// if (r < density){ +// m_halftone[i][j] = 1; +// } else { +// m_halftone[i][j] = 0; +// } +// } +// } + +//} + +//void halftone::apply_gaussian(){ +// for (int i=0; i<N; i++){ +// for (int j=0; j<M; j++){ +// m_halftone[i][j] = radial_gaussian(i, j); +// } +// } + +//} + +//float halftone::radial_gaussian(int i, int j){ +// float r = sqrt((i-.5*N)*(i-.5*N) + (j-.5*M)*(j-.5*M)); +// float result = exp(-(r*r) / (2.f*m_sigma*m_sigma)); + +// return result; + +//} + diff --git a/src/ocean/halftone.h b/src/ocean/halftone.h new file mode 100644 index 0000000..e913eac --- /dev/null +++ b/src/ocean/halftone.h @@ -0,0 +1,19 @@ +#ifndef HALFTONE_H +#define HALFTONE_H + + +#include <vector> +class halftone +{ +public: + halftone(); + +private: + int N = 0; + int M = 0; + float m_sigma = 24.f; + std::vector<std::vector<int>> m_halftone; + +}; + +#endif // HALFTONE_H diff --git a/src/ocean/ocean_alt.cpp b/src/ocean/ocean_alt.cpp index 025e89b..20c663c 100644 --- a/src/ocean/ocean_alt.cpp +++ b/src/ocean/ocean_alt.cpp @@ -12,6 +12,7 @@ ocean_alt::ocean_alt() // initializes static constants (aka they are not time dependent) void ocean_alt::init_wave_index_constants(){ + float tex_step = 1.f/num_rows; for (int i=0; i<N; i++){ Eigen::Vector2i m_n = index_1d_to_2d(i); @@ -22,6 +23,23 @@ void ocean_alt::init_wave_index_constants(){ Eigen::Vector2d k_conj = get_k_vector(-n_prime, m_prime); +// Eigen::Vector3f v = Eigen::Vector3f(0,0,1); +// Eigen::Vector3f norm = Eigen::Vector3f(0,1,0); +// if (abs(norm[1]) < 1.f){ +// v = (Eigen::Vector3f(0,1,0) - norm[1]*norm).normalized(); +// } +// Eigen::Vector3f u = norm.cross(v).normalized(); + +// float u_coord = u.dot(Eigen::Vector3f(n_prime, 0, m_prime)) / 64.f; +// float v_coord = v.dot(Eigen::Vector3f(n_prime, 0, m_prime)) / 64.f; + +// //std::cout << u_coord << ", " << v_coord << std::endl; + + + // texture coord: + Eigen::Vector2f texCoord = Eigen::Vector2f(1, 1); + + // store h0'(n,m) and w'(n,m) for every index, to be used for later Eigen::Vector2d h0_prime = h_0_prime(k); @@ -36,7 +54,6 @@ void ocean_alt::init_wave_index_constants(){ wave_const.h0_prime = h0_prime; wave_const.h0_prime_conj = h0_prime_conj; wave_const.w_prime = w_prime; - wave_const.w_prime = w_prime; wave_const.base_horiz_pos = get_horiz_pos(i); wave_const.k_vector = k; @@ -48,6 +65,13 @@ void ocean_alt::init_wave_index_constants(){ m_slopes.push_back(Eigen::Vector2d(0.0, 0.0)); m_normals.push_back(Eigen::Vector3f(0.0, 1.0, 0.0)); + // initialize foam constant vectors + m_foam_constants.k_vectors.push_back(Eigen::Vector2f(k[0], k[1])); + m_foam_constants.positions.push_back(Eigen::Vector3f(0,0,0)); + m_foam_constants.wavelengths.push_back(0); + // m_foam_constants.texCoords.push_back(texCoord); + + } } @@ -195,7 +219,7 @@ Eigen::Vector2d ocean_alt::get_k_vector(int n_prime, int m_prime){ double M_ = (double)num_cols; double k_x = (2*M_PI*n_ - M_PI*N_)/Lx; - double k_z = (2*M_PI*m_ - M_PI*M_)/Lz; + double k_z = (2*M_PI*m_ - M_PI*M_)/Lz; return Eigen::Vector2d(k_x, k_z); } @@ -256,6 +280,17 @@ Eigen::Vector2d ocean_alt::complex_exp(double exponent){ std::vector<Eigen::Vector3f> ocean_alt::get_vertices() { std::vector<Eigen::Vector3f> vertices = std::vector<Eigen::Vector3f>(); + if (iterations < 10){ + for (int i = 0; i < N; i++){ + Eigen::Vector2d amplitude = m_current_h[i]; + float height = amplitude[0]; + + if (height < min) min = height; + if (height > max) max = height; + + } + iterations ++; + } for (int i = 0; i < N; i++){ Eigen::Vector2d horiz_pos = spacing*m_waveIndexConstants[i].base_horiz_pos; Eigen::Vector2d amplitude = m_current_h[i]; @@ -293,7 +328,26 @@ std::vector<Eigen::Vector3f> ocean_alt::get_vertices() vertices.push_back(Eigen::Vector3f(horiz_pos[0] + disp[0], height, horiz_pos[1] + disp[1])); m_normals[i] = norm.normalized();//Eigen::Vector3f(-slope[0], 1.0, -slope[1]).normalized(); //std::cout << "normal: " << m_normals[i] << std::endl + Eigen::Vector2i m_n = index_1d_to_2d(i); + + + // m_foam_constants.wavelengths[i] = 2.f* M_PI * m_slopes[i].dot(m_slopes[i]) / Lx; + float h_0 = m_waveIndexConstants[i].h0_prime[0]; // min*.2f; + float h_max = max*.01f; // the smaller the constant, the more foam there is + m_foam_constants.wavelengths[i] = (height - h_0 ) / (h_max - h_0); + +// if (i < 5){ +// std::cout << h_0 << ", " << h_max << std::endl; +// std::cout << m_foam_constants.wavelengths[i] << std::endl; +// } + + + } + + // populate foam constants + m_foam_constants.positions = vertices; + return vertices; } @@ -450,4 +504,4 @@ std::vector<Eigen::Vector2d> ocean_alt::fast_fft } return h; -}
\ No newline at end of file +} diff --git a/src/ocean/ocean_alt.h b/src/ocean/ocean_alt.h index 4bb1d54..219ad60 100644 --- a/src/ocean/ocean_alt.h +++ b/src/ocean/ocean_alt.h @@ -20,6 +20,13 @@ struct WaveIndexConstant{ Eigen::Vector2d k_vector = Eigen::Vector2d(0.f, 0.f); // static horiz pos with no displacement }; +struct FoamConstants{ + std::vector<Eigen::Vector3f> positions; + std::vector<Eigen::Vector2f> k_vectors; + std::vector<float> wavelengths; + std::vector<Eigen::Vector2f> texCoords; +}; + class ocean_alt { public: @@ -30,6 +37,10 @@ public: void fft_prime(double t); std::vector<Eigen::Vector3f> getNormals(); + FoamConstants getFoamConstants(){ + return m_foam_constants; + } + @@ -49,6 +60,9 @@ private: std::pair<double, double> sample_complex_gaussian(); + // FOAM + std::vector<float> m_saturation; + @@ -56,22 +70,22 @@ private: - std::map<int, WaveIndexConstant> m_waveIndexConstants; // stores constants that only need to be calculate once for each grid constant + std::map<int, WaveIndexConstant> m_waveIndexConstants; // stores constants that only need to be calculate once for each grid constant - const double Lx = 512.0; - const double Lz = 512.0; - const int num_rows = 256; - const int num_cols = 256; + const double Lx = 1024.0; + const double Lz = 1024.0; + const int num_rows = 256; + const int num_cols = 256; const int N = num_rows*num_cols; // total number of grid points - const double lambda = 0; // how much displacement matters - const double spacing = 35.0; // spacing between grid points + const double lambda = 2.5; // how much displacement matters + const double spacing = 25.0; // spacing between grid points - const double A = 100; // numeric constant for the Phillips spectrum - const double V = 50; // wind speed + const double A = 200; // numeric constant for the Phillips spectrum + const double V = 200; // wind speed const double gravity = 9.81; const double L = V*V/gravity; const Eigen::Vector2d omega_wind = Eigen::Vector2d(1.0, 0.0); // wind direction, used in Phillips equation @@ -81,7 +95,16 @@ private: std::vector<Eigen::Vector2d> m_slopes; // current displacement vector for each K //std::vector<Eigen::Vector3f> m_slope_vectors; // current displacement vector for each K - std::vector<Eigen::Vector3f> m_normals; // current displacement vector for each K + std::vector<Eigen::Vector3f> m_normals; // normal calculations + + // FOR FOAM: + FoamConstants m_foam_constants; + + + float max = 0; + float min = 0; + int iterations = 0; + diff --git a/src/skybox.cpp b/src/skybox.cpp new file mode 100644 index 0000000..3f6abd7 --- /dev/null +++ b/src/skybox.cpp @@ -0,0 +1,167 @@ +#include "skybox.h" + +#include "stb/stb_image.h" +#include <iostream> +#include <Eigen/Core> +#include <Eigen/Dense> +#include <Eigen/Sparse> +#include <Eigen/Geometry> + + + + + +skybox::skybox() +{ + //initializeVAO(); +} + +void skybox::initializeVAO(){ + sky_shape.init(m_vertices_eigen, m_faces); + std::cout << "hehee" << std::endl; + skybox_tex = loadCubeMap(m_skyboxTextureFiles); + + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glBindVertexArray(VAO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, m_vertices.size()*sizeof(float), m_vertices.data(), GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0); + + // unbind + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + + +void skybox::draw(Shader *skybox_shader, Camera m_camera){ + + + + + glDepthFunc(GL_LEQUAL); + glDisable(GL_CULL_FACE); + + skybox_shader->bind(); + Eigen::Vector3f sc = Eigen::Vector3f(.77f, .85f, .99f); // skycolor for fade effect + glUniform3f(glGetUniformLocation(skybox_shader->id(), "skyColor"), sc[0], sc[1], sc[2]); + + + // activate texture + glActiveTexture(GL_TEXTURE9); + glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_tex); + glUniform1i(glGetUniformLocation(skybox_shader->id(), "cubeMap"), 9); // bind texture at slot 9 + + + // manually set view and projection, for non-translating view + Eigen::Matrix4f projection = m_camera.getProjection(); + Eigen::Matrix4f view = m_camera.getView(); + view.col(3) = Eigen::Vector4f(0, 0, 0, 0); + + glUniformMatrix4fv(glGetUniformLocation(skybox_shader->id(), "view"), 1, GL_FALSE, view.data()); + glUniformMatrix4fv(glGetUniformLocation(skybox_shader->id(), "projection"), 1, GL_FALSE, projection.data()); + +// skybox_shader->setUniform("projection", projection); +// skybox_shader->setUniform("view", view); + + // apply rotation matrix + skybox_shader->setUniform("rotation", m_rotation_mat); + + //glUniformMatrix4fv(glGetUniformLocation(skybox_shader., "rotation"), 1, GL_FALSE, glm::value_ptr(m_rotation_mat->getRotation()[0])); + + //Global::graphics.setGlobalData(glm::vec3(.5f)); + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, m_vertices.size()); + + +// glDrawElements(GL_TRIANGLES, m_vertices.size(), GL_UNSIGNED_INT, reinterpret_cast<GLvoid *>(0)); +// glBindVertexArray(0); +//// glBindTexture(GL_TEXTURE_2D, 0); +/// +/// +/// +/// + + std::cout << m_camera.getPosition() << std::endl; + + // sky_shape.draw(skybox_shader, GL_TRIANGLES); + + glDepthFunc(GL_LESS); + + + skybox_shader->unbind(); + +} + +void skybox::update(double deltaTime){ + m_rotation += ROTATE_SPEED * deltaTime; + +// Eigen::Rotation2Df f = Eigen::Rotation2Df(m_rotation); + + +// m_rotation_mat = f.toRotationMatrix(); + + + auto sinA = std::sin(m_rotation / 2); + auto cosA = std::cos(m_rotation/ 2); + + Eigen::Quaternionf q; + q.x() = 0 * sinA; + q.y() = 1 * sinA; + q.z() = 0 * sinA; + q.w() = cosA; + + Eigen::Matrix3f mat3 = q.toRotationMatrix(); + Eigen::Matrix4f mat4 = Eigen::Matrix4f::Identity(); + mat4.block(0,0,3,3) = mat3; + + + m_rotation_mat = mat4; + + + + + + +} + +GLuint skybox::loadCubeMap(std::vector<const char*> textureFiles){ + // create empty texture + GLuint textureID; + glGenTextures(1, &textureID); + + std::cout << "hello fssd" << std::endl; + + + //glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + std::cout << "hello fssd" << std::endl; + + GLuint target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + for (int i=0; i<6; i++){ + std::string filename = std::string(textureFiles[i]);//directory + '/' + filename; + int width, height, nrChannels; + unsigned char* data = stbi_load(filename.c_str(), &width, &height, &nrChannels, 0); + + if (data){ + stbi_set_flip_vertically_on_load(false); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + stbi_image_free(data); + + } else { + std::cout << "Texture failed to load at path: " << textureFiles[i] << std::endl; + stbi_image_free(data); + } + } + + return textureID; +} diff --git a/src/skybox.h b/src/skybox.h new file mode 100644 index 0000000..94d1354 --- /dev/null +++ b/src/skybox.h @@ -0,0 +1,220 @@ +#ifndef SKYBOX_H +#define SKYBOX_H +#include "graphics/shape.h" +#define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT +#define EIGEN_DONT_VECTORIZE +#include "graphics/camera.h" +#include "graphics/shader.h" +#include <GL/glew.h> + +//#ifdef __APPLE__ +//#define GL_SILENCE_DEPRECATION +//#endif + +#include <QOpenGLWidget> +#include <QElapsedTimer> +#include <QTimer> +#include <memory> + + +class skybox +{ +public: + skybox(); + void draw(Shader *skybox_shader, Camera m_camera); + void update(double deltaTime); + + GLuint getVAO(){ + return VAO; + } + + GLuint getSkyboxTex(){ + return skybox_tex; + } + + std::vector<GLfloat> getVertices(){ + return m_vertices; + } + + Eigen::Matrix4f getRotMat(){ + return m_rotation_mat; + } + + std::vector<const char*> getTextureFiles(){ + return m_skyboxTextureFiles; + } + + void initializeVAO(); + + + private: + GLuint loadCubeMap(std::vector<const char*> textureFiles); + + + GLuint VAO; + GLuint VBO; + GLuint EBO; + GLuint skybox_tex; + + float SIZE = 100000000.f; //100000000.f; + + std::vector<int> m_vertex_indices = { + // Right + 1, 2, 6, + 6, 5, 1, + // Left + 0, 4, 7, + 7, 3, 0, + // Top + 4, 5, 6, + 6, 7, 4, + // Bottom + 0, 3, 2, + 2, 1, 0, + // Back + 0, 1, 5, + 5, 4, 0, + // Front + 3, 7, 6, + 6, 2, 3 + }; + + std::vector<Eigen::Vector3i> m_faces = { + // Right + Eigen::Vector3i( 1, 2, 6), + Eigen::Vector3i( 6, 5, 1), + // Left + Eigen::Vector3i( 0, 4, 7), + Eigen::Vector3i( 7, 3, 0), + // Top + Eigen::Vector3i( 4, 5, 6), + Eigen::Vector3i( 6, 7, 4), + // Bottom + Eigen::Vector3i( 0, 3, 2), + Eigen::Vector3i( 2, 1, 0), + // Back + Eigen::Vector3i( 0, 1, 5), + Eigen::Vector3i( 5, 4, 0), + // Front + Eigen::Vector3i( 3, 7, 6), + Eigen::Vector3i( 6, 2, 3) + }; + std::vector<GLfloat> m_vertices = { + -SIZE, SIZE, -SIZE, + -SIZE, -SIZE, -SIZE, + SIZE, -SIZE, -SIZE, + SIZE, -SIZE, -SIZE, + SIZE, SIZE, -SIZE, + -SIZE, SIZE, -SIZE, + + -SIZE, -SIZE, SIZE, + -SIZE, -SIZE, -SIZE, + -SIZE, SIZE, -SIZE, + -SIZE, SIZE, -SIZE, + -SIZE, SIZE, SIZE, + -SIZE, -SIZE, SIZE, + + SIZE, -SIZE, -SIZE, + SIZE, -SIZE, SIZE, + SIZE, SIZE, SIZE, + SIZE, SIZE, SIZE, + SIZE, SIZE, -SIZE, + SIZE, -SIZE, -SIZE, + + -SIZE, -SIZE, SIZE, + -SIZE, SIZE, SIZE, + SIZE, SIZE, SIZE, + SIZE, SIZE, SIZE, + SIZE, -SIZE, SIZE, + -SIZE, -SIZE, SIZE, + + -SIZE, SIZE, -SIZE, + SIZE, SIZE, -SIZE, + SIZE, SIZE, SIZE, + SIZE, SIZE, SIZE, + -SIZE, SIZE, SIZE, + -SIZE, SIZE, -SIZE, + + -SIZE, -SIZE, -SIZE, + -SIZE, -SIZE, SIZE, + SIZE, -SIZE, -SIZE, + SIZE, -SIZE, -SIZE, + -SIZE, -SIZE, SIZE, + SIZE, -SIZE, SIZE + }; + + std::vector<Eigen::Vector3f> m_vertices_eigen = { + Eigen::Vector3f( -SIZE, SIZE, -SIZE), + Eigen::Vector3f( -SIZE, -SIZE, -SIZE), + Eigen::Vector3f( SIZE, -SIZE, -SIZE), + Eigen::Vector3f( SIZE, -SIZE, -SIZE), + Eigen::Vector3f( SIZE, SIZE, -SIZE), + Eigen::Vector3f( -SIZE, SIZE, -SIZE), + + Eigen::Vector3f( -SIZE, -SIZE, SIZE), + Eigen::Vector3f( -SIZE, -SIZE, -SIZE), + Eigen::Vector3f( -SIZE, SIZE, -SIZE), + Eigen::Vector3f( -SIZE, SIZE, -SIZE), + Eigen::Vector3f( -SIZE, SIZE, SIZE), + Eigen::Vector3f( -SIZE, -SIZE, SIZE), + + Eigen::Vector3f( SIZE, -SIZE, -SIZE), + Eigen::Vector3f( SIZE, -SIZE, SIZE), + Eigen::Vector3f( SIZE, SIZE, SIZE), + Eigen::Vector3f( SIZE, SIZE, SIZE), + Eigen::Vector3f( SIZE, SIZE, -SIZE), + Eigen::Vector3f( SIZE, -SIZE, -SIZE), + + Eigen::Vector3f( -SIZE, -SIZE, SIZE), + Eigen::Vector3f( -SIZE, SIZE, SIZE), + Eigen::Vector3f( SIZE, SIZE, SIZE), + Eigen::Vector3f( SIZE, SIZE, SIZE), + Eigen::Vector3f( SIZE, -SIZE, SIZE), + Eigen::Vector3f( -SIZE, -SIZE, SIZE), + + Eigen::Vector3f( -SIZE, SIZE, -SIZE), + Eigen::Vector3f( SIZE, SIZE, -SIZE), + Eigen::Vector3f( SIZE, SIZE, SIZE), + Eigen::Vector3f( SIZE, SIZE, SIZE), + Eigen::Vector3f( -SIZE, SIZE, SIZE), + Eigen::Vector3f( -SIZE, SIZE, -SIZE), + + Eigen::Vector3f( -SIZE, -SIZE, -SIZE), + Eigen::Vector3f( -SIZE, -SIZE, SIZE), + Eigen::Vector3f( SIZE, -SIZE, -SIZE), + Eigen::Vector3f( SIZE, -SIZE, -SIZE), + Eigen::Vector3f( -SIZE, -SIZE, SIZE), + Eigen::Vector3f( SIZE, -SIZE, SIZE) + }; + + std::vector<const char*> m_skyboxTextureFiles = + +// { +// "/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/foam3.png", +// "/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/foam3.png", +// "/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/foam3.png", +// "/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/foam3.png", +// "/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/foam3.png", +// "/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/foam3.png" + +// }; + + + + + {"/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/cupertin-lake_rt.png", + "/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/cupertin-lake_lf.png", + "/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/cupertin-lake_up.png", + "/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/cupertin-lake_dn.png", + "/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/cupertin-lake_bk.png", + "/Users/jesswan/Desktop/cs2240/ocean-simulation/resources/images/cupertin-lake_ft.png", + }; + + float ROTATE_SPEED = .01f; // 1 degree per sec + float m_rotation = 0.f; + Eigen::Matrix4f m_rotation_mat = Eigen::Matrix4f::Identity(); + + Shape sky_shape; +}; + +#endif // SKYBOX_H |