feat: opengl point rendering
This commit is contained in:
@@ -36,6 +36,7 @@ set(GUI_SOURCES
|
|||||||
src/Gui/Viewport/GLCamera.cpp
|
src/Gui/Viewport/GLCamera.cpp
|
||||||
src/Gui/Viewport/GLMesh.cpp
|
src/Gui/Viewport/GLMesh.cpp
|
||||||
src/Gui/Viewport/GLGrid.cpp
|
src/Gui/Viewport/GLGrid.cpp
|
||||||
|
src/Gui/Viewport/GLPoints.cpp
|
||||||
src/Gui/Network/NetworkGraphicsView.cpp
|
src/Gui/Network/NetworkGraphicsView.cpp
|
||||||
src/Gui/Network/NetworkGraphicsScene.cpp
|
src/Gui/Network/NetworkGraphicsScene.cpp
|
||||||
src/Gui/Network/Network.cpp
|
src/Gui/Network/Network.cpp
|
||||||
|
|||||||
@@ -123,6 +123,10 @@ void GLCamera::changeRadius(float delta)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 GLCamera::getPos()
|
||||||
|
{
|
||||||
|
return camPos_;
|
||||||
|
};
|
||||||
|
|
||||||
glm::vec3 GLCamera::getRight()
|
glm::vec3 GLCamera::getRight()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public:
|
|||||||
void setCenter(float x, float y, float z);
|
void setCenter(float x, float y, float z);
|
||||||
void setUniform(uint uniformLocation);
|
void setUniform(uint uniformLocation);
|
||||||
|
|
||||||
|
glm::vec3 getPos();
|
||||||
glm::vec3 getForward();
|
glm::vec3 getForward();
|
||||||
glm::vec3 getRight();
|
glm::vec3 getRight();
|
||||||
glm::vec3 getUp();
|
glm::vec3 getUp();
|
||||||
|
|||||||
211
src/Gui/Viewport/GLPoints.cpp
Normal file
211
src/Gui/Viewport/GLPoints.cpp
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
|
||||||
|
#include "Gui/Viewport/GLPoints.h"
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <glm/fwd.hpp>
|
||||||
|
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
|
||||||
|
#include <glm/geometric.hpp>
|
||||||
|
#include <oneapi/tbb/blocked_range.h>
|
||||||
|
#include <oneapi/tbb/parallel_for.h>
|
||||||
|
#include "Engine/Types.h"
|
||||||
|
#include "Gui/Viewport/GLCamera.h"
|
||||||
|
#include "icecream.hpp"
|
||||||
|
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include <glm/gtx/norm.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
GLPoints::GLPoints()
|
||||||
|
{
|
||||||
|
initializeOpenGLFunctions();
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPoints::init()
|
||||||
|
{
|
||||||
|
glGenVertexArrays(1, &vao);
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
|
initBuffers();
|
||||||
|
initShaderProgram();
|
||||||
|
|
||||||
|
// unbind vertex array
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPoints::initBuffers()
|
||||||
|
{
|
||||||
|
const GLfloat billboardVertexPositions[] = {
|
||||||
|
-0.5f, -0.5f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.0f,
|
||||||
|
-0.5f, 0.5f, 0.0f,
|
||||||
|
0.5f, 0.5f, 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
points_ = {};
|
||||||
|
pointCount = points_.size();
|
||||||
|
|
||||||
|
glGenBuffers(1, &billboardVertexBuffer_);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, billboardVertexBuffer_);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(billboardVertexPositions), billboardVertexPositions, GL_STATIC_DRAW);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
|
||||||
|
|
||||||
|
glGenBuffers(1, &pointDataBuffer_);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, pointDataBuffer_);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, points_.size() * sizeof(Point), points_.data(), GL_STATIC_DRAW);
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Point), (void*)0);
|
||||||
|
glVertexAttribDivisor(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GLPoints::setPoints(enzo::geo::Geometry& geometry, GLCamera& camera)
|
||||||
|
{
|
||||||
|
const enzo::ga::Offset numPoints = geometry.getNumPoints();
|
||||||
|
const glm::vec3 camPosGlm = camera.getPos();
|
||||||
|
const enzo::bt::Vector3 camPos(camPosGlm.x, camPosGlm.y, camPosGlm.z);
|
||||||
|
|
||||||
|
points_ = std::vector<Point>(numPoints);
|
||||||
|
|
||||||
|
for(enzo::ga::Offset ptOffset=0; ptOffset<numPoints; ++ptOffset)
|
||||||
|
{
|
||||||
|
const enzo::bt::Vector3 pos = geometry.getPointPos(ptOffset);
|
||||||
|
points_[ptOffset] = {glm::vec3(pos.x(), pos.y(), pos.z()), static_cast<float>((pos-camPos).norm())*0.005f};
|
||||||
|
}
|
||||||
|
pointCount = points_.size();
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, pointDataBuffer_);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, points_.size() * sizeof(Point), points_.data(), GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPoints::updatePointSize(GLCamera& camera)
|
||||||
|
{
|
||||||
|
const glm::vec3 camPosGlm = camera.getPos();
|
||||||
|
|
||||||
|
for(Point& point : points_)
|
||||||
|
{
|
||||||
|
point = {point.position, glm::distance(point.position,camPosGlm)*0.005f};
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, pointDataBuffer_);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, points_.size() * sizeof(Point), points_.data(), GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void GLPoints::initShaderProgram()
|
||||||
|
{
|
||||||
|
// vertex shader
|
||||||
|
const std::string vertexShaderSource = R"(
|
||||||
|
#version 330 core
|
||||||
|
uniform mat4 uView;
|
||||||
|
uniform mat4 uProj;
|
||||||
|
layout(location = 0) in vec3 aPos;
|
||||||
|
layout(location = 1) in vec4 aOffsetScale;
|
||||||
|
|
||||||
|
out vec2 vLocal;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec3 right = vec3(uView[0][0], uView[1][0], uView[2][0]);
|
||||||
|
vec3 up = vec3(uView[0][1], uView[1][1], uView[2][1]);
|
||||||
|
|
||||||
|
vLocal = aPos.xy;
|
||||||
|
vec3 worldPos = aOffsetScale.xyz +
|
||||||
|
(right * aPos.x + up * aPos.y) * aOffsetScale.w;
|
||||||
|
|
||||||
|
gl_Position = uProj * uView * vec4(worldPos, 1.0);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
// shader type
|
||||||
|
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
// convert source
|
||||||
|
const GLchar* vertexShaderSourceC = vertexShaderSource.c_str();
|
||||||
|
// create shader object
|
||||||
|
glShaderSource(vertexShader, 1, &vertexShaderSourceC, NULL);
|
||||||
|
// compile shader object
|
||||||
|
glCompileShader(vertexShader);
|
||||||
|
|
||||||
|
|
||||||
|
// log shader error
|
||||||
|
int success;
|
||||||
|
char infoLog[512];
|
||||||
|
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
|
||||||
|
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "success\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// fragment shader
|
||||||
|
const std::string fragmentShaderSource = R"(
|
||||||
|
#version 330 core
|
||||||
|
in vec2 vLocal;
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
if (length(vLocal) > 0.5) discard;
|
||||||
|
FragColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
const GLchar* fragmentShaderSourceC = fragmentShaderSource.c_str();
|
||||||
|
glShaderSource(fragmentShader, 1, &fragmentShaderSourceC, NULL);
|
||||||
|
glCompileShader(fragmentShader);
|
||||||
|
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
|
||||||
|
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "success\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// create shader program
|
||||||
|
shaderProgram = glCreateProgram();
|
||||||
|
// attach shaders
|
||||||
|
glAttachShader(shaderProgram, vertexShader);
|
||||||
|
glAttachShader(shaderProgram, fragmentShader);
|
||||||
|
// link program
|
||||||
|
glLinkProgram(shaderProgram);
|
||||||
|
|
||||||
|
// delete shaders now that the program is complete
|
||||||
|
glDeleteShader(vertexShader);
|
||||||
|
glDeleteShader(fragmentShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void GLPoints::bind()
|
||||||
|
{
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPoints::useProgram()
|
||||||
|
{
|
||||||
|
glUseProgram(shaderProgram);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GLPoints::unbind()
|
||||||
|
{
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPoints::draw()
|
||||||
|
{
|
||||||
|
bind();
|
||||||
|
|
||||||
|
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, pointCount);
|
||||||
|
}
|
||||||
43
src/Gui/Viewport/GLPoints.h
Normal file
43
src/Gui/Viewport/GLPoints.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Engine/Types.h"
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <QOpenGLFunctions_3_3_Core>
|
||||||
|
#include <glm/ext/vector_float3.hpp>
|
||||||
|
#include <qopenglversionfunctions.h>
|
||||||
|
#include "Engine/Operator/Geometry.h"
|
||||||
|
#include "Gui/Viewport/GLCamera.h"
|
||||||
|
|
||||||
|
struct Point
|
||||||
|
{
|
||||||
|
glm::vec3 position;
|
||||||
|
float scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GLPoints
|
||||||
|
: protected QOpenGLFunctions_3_3_Core
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GLPoints();
|
||||||
|
GLuint vao;
|
||||||
|
|
||||||
|
GLuint billboardVertexBuffer_;
|
||||||
|
GLuint pointDataBuffer_;
|
||||||
|
GLuint shaderProgram;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<GLint> faceIndexData;
|
||||||
|
std::vector<Point> points_;
|
||||||
|
|
||||||
|
enzo::ga::Offset pointCount;
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void initBuffers();
|
||||||
|
void initShaderProgram();
|
||||||
|
void setPoints(enzo::geo::Geometry& geometry, GLCamera& camera);
|
||||||
|
void updatePointSize(GLCamera& camera);
|
||||||
|
void useProgram();
|
||||||
|
void bind();
|
||||||
|
void unbind();
|
||||||
|
void draw();
|
||||||
|
};
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "Engine/Operator/AttributeHandle.h"
|
#include "Engine/Operator/AttributeHandle.h"
|
||||||
#include "Engine/Types.h"
|
#include "Engine/Types.h"
|
||||||
#include "Gui/Viewport/GLMesh.h"
|
#include "Gui/Viewport/GLMesh.h"
|
||||||
|
#include "Gui/Viewport/GLPoints.h"
|
||||||
#include <glm/mat4x4.hpp>
|
#include <glm/mat4x4.hpp>
|
||||||
#include <glm/ext/matrix_clip_space.hpp>
|
#include <glm/ext/matrix_clip_space.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
@@ -21,9 +22,9 @@ void ViewportGLWidget::initializeGL()
|
|||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
|
||||||
enzo::geo::Geometry geo = enzo::geo::Geometry();
|
enzo::geo::Geometry geo = enzo::geo::Geometry();
|
||||||
// triangleMesh_ = meshFromGeo(geo);
|
|
||||||
triangleMesh_ = std::make_unique<GLMesh>();
|
triangleMesh_ = std::make_unique<GLMesh>();
|
||||||
gridMesh_ = std::make_unique<GLGrid>();
|
gridMesh_ = std::make_unique<GLGrid>();
|
||||||
|
points_ = std::make_unique<GLPoints>();
|
||||||
|
|
||||||
QSurfaceFormat fmt = context()->format();
|
QSurfaceFormat fmt = context()->format();
|
||||||
std::cout << "format: " << (fmt.renderableType() == QSurfaceFormat::OpenGLES ? "GLES" : "Desktop") << "\n";
|
std::cout << "format: " << (fmt.renderableType() == QSurfaceFormat::OpenGLES ? "GLES" : "Desktop") << "\n";
|
||||||
@@ -154,9 +155,10 @@ void ViewportGLWidget::paintGL()
|
|||||||
1000.0f // far plane
|
1000.0f // far plane
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
gridMesh_->useProgram();
|
gridMesh_->useProgram();
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "uProj"), 1, GL_FALSE, glm::value_ptr(projMatrix));
|
glUniformMatrix4fv(glGetUniformLocation(gridMesh_->shaderProgram, "uProj"), 1, GL_FALSE, glm::value_ptr(projMatrix));
|
||||||
curCamera.setUniform(glGetUniformLocation(shaderProgram, "uView"));
|
curCamera.setUniform(glGetUniformLocation(gridMesh_->shaderProgram, "uView"));
|
||||||
|
|
||||||
|
|
||||||
gridMesh_->draw();
|
gridMesh_->draw();
|
||||||
@@ -170,26 +172,36 @@ void ViewportGLWidget::paintGL()
|
|||||||
|
|
||||||
triangleMesh_->draw();
|
triangleMesh_->draw();
|
||||||
|
|
||||||
|
points_->useProgram();
|
||||||
|
points_->bind();
|
||||||
|
points_->updatePointSize(curCamera);
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(points_->shaderProgram, "uProj"), 1, GL_FALSE, glm::value_ptr(projMatrix));
|
||||||
|
curCamera.setUniform(glGetUniformLocation(points_->shaderProgram, "uView"));
|
||||||
|
|
||||||
|
glUniform3fv(glGetUniformLocation(points_->shaderProgram, "uCameraRight"), 1, glm::value_ptr(curCamera.getRight()));
|
||||||
|
glUniform3fv(glGetUniformLocation(points_->shaderProgram, "uCameraUp"), 1, glm::value_ptr(curCamera.getUp()));
|
||||||
|
points_->draw();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GLMesh> ViewportGLWidget::meshFromGeo(enzo::geo::Geometry& geometry)
|
// std::unique_ptr<GLMesh> ViewportGLWidget::meshFromGeo(enzo::geo::Geometry& geometry)
|
||||||
{
|
// {
|
||||||
using namespace enzo;
|
// using namespace enzo;
|
||||||
|
|
||||||
auto mesh = std::make_unique<GLMesh>();
|
// auto mesh = std::make_unique<GLMesh>();
|
||||||
|
//
|
||||||
std::shared_ptr<ga::Attribute> PAttr = geometry.getAttribByName(ga::AttrOwner::POINT, "P");
|
// std::shared_ptr<ga::Attribute> PAttr = geometry.getAttribByName(ga::AttrOwner::POINT, "P");
|
||||||
ga::AttributeHandleVector3 PAttrHandle = ga::AttributeHandleVector3(PAttr);
|
// ga::AttributeHandleVector3 PAttrHandle = ga::AttributeHandleVector3(PAttr);
|
||||||
|
|
||||||
|
|
||||||
mesh->setPosBuffer(geometry);
|
// mesh->setPosBuffer(geometry);
|
||||||
mesh->setIndexBuffer(geometry);
|
// mesh->setIndexBuffer(geometry);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return mesh;
|
// return mesh;
|
||||||
}
|
// }
|
||||||
|
|
||||||
void ViewportGLWidget::geometryChanged(enzo::geo::Geometry& geometry)
|
void ViewportGLWidget::geometryChanged(enzo::geo::Geometry& geometry)
|
||||||
{
|
{
|
||||||
@@ -199,4 +211,6 @@ void ViewportGLWidget::geometryChanged(enzo::geo::Geometry& geometry)
|
|||||||
|
|
||||||
triangleMesh_->setPosBuffer(geometry);
|
triangleMesh_->setPosBuffer(geometry);
|
||||||
triangleMesh_->setIndexBuffer(geometry);
|
triangleMesh_->setIndexBuffer(geometry);
|
||||||
|
|
||||||
|
points_->setPoints(geometry, curCamera);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Gui/Viewport/GLCamera.h"
|
#include "Gui/Viewport/GLCamera.h"
|
||||||
#include "Gui/Viewport/GLMesh.h"
|
#include "Gui/Viewport/GLMesh.h"
|
||||||
#include "Gui/Viewport/GLGrid.h"
|
#include "Gui/Viewport/GLGrid.h"
|
||||||
|
#include "Gui/Viewport/GLPoints.h"
|
||||||
#include "Engine/Operator/Geometry.h"
|
#include "Engine/Operator/Geometry.h"
|
||||||
|
|
||||||
class ViewportGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_2_Core
|
class ViewportGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_2_Core
|
||||||
@@ -17,8 +18,9 @@ public:
|
|||||||
GLCamera curCamera;
|
GLCamera curCamera;
|
||||||
std::unique_ptr<GLMesh> triangleMesh_ ;
|
std::unique_ptr<GLMesh> triangleMesh_ ;
|
||||||
std::unique_ptr<GLGrid> gridMesh_ ;
|
std::unique_ptr<GLGrid> gridMesh_ ;
|
||||||
|
std::unique_ptr<GLPoints> points_ ;
|
||||||
|
|
||||||
std::unique_ptr<GLMesh> meshFromGeo(enzo::geo::Geometry& geometry);
|
// std::unique_ptr<GLMesh> meshFromGeo(enzo::geo::Geometry& geometry);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initializeGL() override;
|
void initializeGL() override;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ int main(int argc, char **argv)
|
|||||||
// set up rendering
|
// set up rendering
|
||||||
QSurfaceFormat format;
|
QSurfaceFormat format;
|
||||||
format.setRenderableType(QSurfaceFormat::OpenGL);
|
format.setRenderableType(QSurfaceFormat::OpenGL);
|
||||||
format.setVersion(3, 2);
|
format.setVersion(3, 3);
|
||||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||||
format.setSamples(4);
|
format.setSamples(4);
|
||||||
QSurfaceFormat::setDefaultFormat(format);
|
QSurfaceFormat::setDefaultFormat(format);
|
||||||
|
|||||||
Reference in New Issue
Block a user