From 7a61605e57d96bf5c699c9c759288376b8c94eac Mon Sep 17 00:00:00 2001 From: Sebastian Park Date: Fri, 10 May 2024 00:12:48 -0400 Subject: Add simpleshape. --- src/graphics/simpleshape.cpp | 272 +++++++++++++++++++++++++++++++++++++++++++ src/graphics/simpleshape.h | 89 ++++++++++++++ 2 files changed, 361 insertions(+) create mode 100644 src/graphics/simpleshape.cpp create mode 100644 src/graphics/simpleshape.h (limited to 'src') diff --git a/src/graphics/simpleshape.cpp b/src/graphics/simpleshape.cpp new file mode 100644 index 0000000..567dab3 --- /dev/null +++ b/src/graphics/simpleshape.cpp @@ -0,0 +1,272 @@ +#include "simpleshape.h" + +#include +#include "graphics/shader.h" + +using namespace Eigen; +using namespace std; + +// ================== Constructor + +SimpleShape::SimpleShape() : + m_surfaceVao(), + m_surfaceVbo(), + m_surfaceIbo(), + m_numSurfaceVertices(), + m_verticesSize(), + m_red(), + m_blue(), + m_green(), + m_alpha(), + m_faces(), + m_vertices(), + m_anchors(), + m_modelMatrix(Matrix4f::Identity()), + lastSelected(-1) +{} + +// ================== Initialization and Updating + +void SimpleShape::init(const vector &vertices, const vector &triangles) +{ + m_vertices.clear(); + copy(vertices.begin(), vertices.end(), back_inserter(m_vertices)); + + vector verts; + vector normals; + vector colors; + vector faces; + faces.reserve(triangles.size()); + + for (int s = 0; s < triangles.size() * 3; s+=3) faces.push_back(Vector3i(s, s + 1, s + 2)); + updateMesh(triangles, vertices, verts, normals, colors); + + glGenBuffers(1, &m_surfaceVbo); + glGenBuffers(1, &m_surfaceIbo); + glGenVertexArrays(1, &m_surfaceVao); + + 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(verts.data())); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(float) * verts.size() * 3, sizeof(float) * normals.size() * 3, static_cast(normals.data())); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(float) * ((verts.size() * 3) + (normals.size() * 3)), sizeof(float) * colors.size() * 3, static_cast(colors.data())); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_surfaceIbo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 3 * faces.size(), static_cast(faces.data()), GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindVertexArray(m_surfaceVao); + glBindBuffer(GL_ARRAY_BUFFER, m_surfaceVbo); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, static_cast(0)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast(sizeof(float) * verts.size() * 3)); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast(sizeof(float) * (verts.size() * 3 + colors.size() * 3))); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_surfaceIbo); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + m_numSurfaceVertices = faces.size() * 3; + m_verticesSize = vertices.size(); + m_faces = triangles; + m_red = 0.5f + 0.5f * rand() / ((float) RAND_MAX); + m_blue = 0.5f + 0.5f * rand() / ((float) RAND_MAX); + m_green = 0.5f + 0.5f * rand() / ((float) RAND_MAX); + m_alpha = 1.0f; +} + +void SimpleShape::setVertices(const vector &vertices) +{ + m_vertices.clear(); + copy(vertices.begin(), vertices.end(), back_inserter(m_vertices)); + + vector verts; + vector normals; + vector colors; + + updateMesh(m_faces, vertices, 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(verts.data())); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(float) * verts.size() * 3, sizeof(float) * normals.size() * 3, static_cast(normals.data())); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(float) * ((verts.size() * 3) + (normals.size() * 3)), sizeof(float) * colors.size() * 3, static_cast(colors.data())); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +// ================== Model Matrix + +void SimpleShape::setModelMatrix(const Affine3f &model) { m_modelMatrix = model.matrix(); } + +// ================== General Graphics Stuff + +void SimpleShape::draw(Shader *shader, GLenum mode) +{ + Eigen::Matrix3f m3 = m_modelMatrix.topLeftCorner(3, 3); + Eigen::Matrix3f inverseTransposeModel = m3.inverse().transpose(); + + switch(mode) { + case GL_TRIANGLES: + { + shader->setUniform("wire", 0); + shader->setUniform("model", m_modelMatrix); + shader->setUniform("inverseTransposeModel", inverseTransposeModel); + shader->setUniform("red", m_red); + shader->setUniform("green", m_green); + shader->setUniform("blue", m_blue); + shader->setUniform("alpha", m_alpha); + glBindVertexArray(m_surfaceVao); + glDrawElements(mode, m_numSurfaceVertices, GL_UNSIGNED_INT, reinterpret_cast(0)); + glBindVertexArray(0); + break; + } + case GL_POINTS: + { + shader->setUniform("model", m_modelMatrix); + shader->setUniform("inverseTransposeModel", inverseTransposeModel); + glBindVertexArray(m_surfaceVao); + glDrawElements(mode, m_numSurfaceVertices, GL_UNSIGNED_INT, reinterpret_cast(0)); + glBindVertexArray(0); + break; + } + } +} + +SelectMode SimpleShape::select(Shader *shader, int closest_vertex) +{ + if (closest_vertex == -1) return SelectMode::None; + + bool vertexIsNowSelected = m_anchors.find(closest_vertex) == m_anchors.end(); + + if (vertexIsNowSelected) { + m_anchors.insert(closest_vertex); + } else { + m_anchors.erase(closest_vertex); + } + + selectHelper(); + + return vertexIsNowSelected ? SelectMode::Anchor : SelectMode::Unanchor; +} + +bool SimpleShape::selectWithSpecifiedMode(Shader *shader, int closest_vertex, SelectMode mode) +{ + switch (mode) { + case SelectMode::None: { + return false; + } + case SelectMode::Anchor: { + if (m_anchors.find(closest_vertex) != m_anchors.end()) return false; + m_anchors.insert(closest_vertex); + break; + } + case SelectMode::Unanchor: { + if (m_anchors.find(closest_vertex) == m_anchors.end()) return false; + m_anchors.erase(closest_vertex); + break; + } + } + + selectHelper(); + + return true; +} + +int SimpleShape::getClosestVertex(Vector3f start, Vector3f ray, float threshold) +{ + int closest_vertex = -1; + int i = 0; + float dist = numeric_limits::max(); + ParametrizedLine line = ParametrizedLine::Through(start, start + ray); + + for (const Vector3f &v : m_vertices) { + float d = line.distance(v); + if (d= threshold) closest_vertex = -1; + + return closest_vertex; +} + +bool SimpleShape::getAnchorPos(int lastSelected, + Eigen::Vector3f& pos, + Eigen::Vector3f ray, + Eigen::Vector3f start) +{ + bool isAnchor = m_anchors.find(lastSelected) != m_anchors.end(); + if (isAnchor) { + Eigen::Vector3f oldPos = m_vertices[lastSelected]; + Eigen::ParametrizedLine line = ParametrizedLine::Through(start, start+ray); + pos = line.projection(oldPos); + } + return isAnchor; +} + +// ================== Accessors + +const vector &SimpleShape::getVertices() { return m_vertices; } +const vector &SimpleShape::getFaces() { return m_faces; } +const unordered_set &SimpleShape::getAnchors() { return m_anchors; } + +// ================== Helpers + +void SimpleShape::selectHelper() +{ + vector verts; + vector normals; + vector colors; + updateMesh(m_faces, m_vertices, 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(verts.data())); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(float) * verts.size() * 3, sizeof(float) * normals.size() * 3, static_cast(normals.data())); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(float) * ((verts.size() * 3) + (normals.size() * 3)), sizeof(float) * colors.size() * 3, static_cast(colors.data())); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +Vector3f SimpleShape::getNormal(const Vector3i& face) +{ + Vector3f& v1 = m_vertices[face[0]]; + Vector3f& v2 = m_vertices[face[1]]; + Vector3f& v3 = m_vertices[face[2]]; + Vector3f e1 = v2 - v1; + Vector3f e2 = v3 - v1; + Vector3f n = e1.cross(e2); + return n.normalized(); +} + +void SimpleShape::updateMesh(const std::vector &faces, + const std::vector &vertices, + std::vector& verts, + std::vector& normals, + std::vector& colors) +{ + verts.reserve(faces.size() * 3); + normals.reserve(faces.size() * 3); + + for (const Eigen::Vector3i& face : faces) { + Vector3f n = getNormal(face); + + for (auto& v: {face[0], face[1], face[2]}) { + normals.push_back(n); + verts.push_back(vertices[v]); + + if (m_anchors.find(v) == m_anchors.end()) { + colors.push_back(Vector3f(1,0,0)); + } else { + colors.push_back(Vector3f(0, 1 - m_green, 1 - m_blue)); + } + } + } +} + diff --git a/src/graphics/simpleshape.h b/src/graphics/simpleshape.h new file mode 100644 index 0000000..03db726 --- /dev/null +++ b/src/graphics/simpleshape.h @@ -0,0 +1,89 @@ +#pragma once + +#include +#include +#include +#include + +#define EIGEN_DONT_VECTORIZE +#define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT +//#include "Eigen/StdVector" +//EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Matrix2f) +//EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Matrix3f) +//EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Matrix3i) +#include "Eigen/Dense" + +enum SelectMode +{ + None = 0, + Anchor = 1, + Unanchor = 2 +}; + + + + +struct Edge{ + std::pair ij; + float weight = 0.f; + std::set opposite_two; +}; + +struct Cell{ + int center_index = 0; // this is i + std::set neighbor_js; // this is neighboring j's + std::set edge_ids; // this is ids if ij edges in edge vector +}; + + +class Shader; + +class SimpleShape +{ +public: + SimpleShape(); + + void init(const std::vector &vertices, const std::vector &triangles); + void setVertices(const std::vector &vertices); + + void setModelMatrix(const Eigen::Affine3f &model); + + void draw(Shader *shader, GLenum mode); + SelectMode select(Shader *shader, int vertex); + bool selectWithSpecifiedMode(Shader *shader, int vertex, SelectMode mode); + int getClosestVertex(Eigen::Vector3f start, Eigen::Vector3f ray, float threshold); + bool getAnchorPos(int lastSelected, Eigen::Vector3f& pos, Eigen::Vector3f ray, Eigen::Vector3f start); + + const std::vector& getVertices(); + const std::vector& getFaces(); + const std::unordered_set& getAnchors(); + +private: + GLuint m_surfaceVao; + GLuint m_surfaceVbo; + GLuint m_surfaceIbo; + + unsigned int m_numSurfaceVertices; + unsigned int m_verticesSize; + float m_red; + float m_blue; + float m_green; + float m_alpha; + + std::vector m_faces; + std::vector m_vertices; + std::unordered_set m_anchors; + + Eigen::Matrix4f m_modelMatrix; + int lastSelected = -1; + + // Helpers + + void selectHelper(); + Eigen::Vector3f getNormal(const Eigen::Vector3i& face); + void updateMesh(const std::vector &triangles, + const std::vector &vertices, + std::vector& verts, + std::vector& normals, + std::vector& colors); +}; -- cgit v1.2.3-70-g09d2 From 8f61cdb6c394b7c32a495966c7ad3a088c91c17b Mon Sep 17 00:00:00 2001 From: Sebastian Park Date: Fri, 10 May 2024 00:33:27 -0400 Subject: Fix messed up bind framebuffer. --- resources/shaders/caustics.frag | 2 +- resources/shaders/caustics.vert | 2 +- src/arap.cpp | 2 +- src/glwidget.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/resources/shaders/caustics.frag b/resources/shaders/caustics.frag index f746896..5d2569d 100644 --- a/resources/shaders/caustics.frag +++ b/resources/shaders/caustics.frag @@ -14,7 +14,7 @@ void main() { float oldArea = length(dFdx(vec3(pos[0], pos[2], pos[1]))) * length(dFdy(vec3(pos[0], pos[2], pos[1]))); float newArea = length(dFdx(vec3(newPos[0], newPos[2], newPos[1]))) * length(dFdy(vec3(newPos[0], newPos[2], newPos[1]))); float areaRatio = oldArea / newArea; - float intensity = pow(areaRatio * .3f, 1.5f); + float intensity = pow(areaRatio * 1.f, 1.5f); fragColor = vec4(0.98, 1, .78, intensity * refractProb); // fragColor = col; } diff --git a/resources/shaders/caustics.vert b/resources/shaders/caustics.vert index 298f5e1..f1e80be 100644 --- a/resources/shaders/caustics.vert +++ b/resources/shaders/caustics.vert @@ -45,7 +45,7 @@ void main() { vec4 sampledNormal = texture(normSamp, vec2((pos + 1) / 2)); sampledNormal = (sampledNormal * 2.f) - 1.f; col = sampledNormal; - vec4 newPosAndProb = refractToFloor(vec3(0, 0, 1), pos, normalize(vec3(sampledNormal)), 0.01f); + vec4 newPosAndProb = refractToFloor(vec3(0, 0, 1), pos, normalize(vec3(sampledNormal)), 0.005f); newPos = vec3(newPosAndProb[0], newPosAndProb[1], 0.f); refractProb = newPosAndProb[3]; // newPos = pos; diff --git a/src/arap.cpp b/src/arap.cpp index ae7240d..2e4532b 100644 --- a/src/arap.cpp +++ b/src/arap.cpp @@ -52,7 +52,7 @@ void ARAP::init minCorner = coeffMin; maxCorner = coeffMax; - initCausticsShape(10); + initCausticsShape(1000); } void ARAP::update(double seconds) diff --git a/src/glwidget.cpp b/src/glwidget.cpp index 1e9b26b..8a35a4f 100755 --- a/src/glwidget.cpp +++ b/src/glwidget.cpp @@ -212,7 +212,7 @@ void GLWidget::paintCaustics() { // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glBindFramebuffer(GL_FRAMEBUFFER, m_fbo_texture); + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable( GL_BLEND ); -- cgit v1.2.3-70-g09d2