feat: opengl point rendering
This commit is contained in:
@@ -36,6 +36,7 @@ set(GUI_SOURCES
|
||||
src/Gui/Viewport/GLCamera.cpp
|
||||
src/Gui/Viewport/GLMesh.cpp
|
||||
src/Gui/Viewport/GLGrid.cpp
|
||||
src/Gui/Viewport/GLPoints.cpp
|
||||
src/Gui/Network/NetworkGraphicsView.cpp
|
||||
src/Gui/Network/NetworkGraphicsScene.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()
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ public:
|
||||
void setCenter(float x, float y, float z);
|
||||
void setUniform(uint uniformLocation);
|
||||
|
||||
glm::vec3 getPos();
|
||||
glm::vec3 getForward();
|
||||
glm::vec3 getRight();
|
||||
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/Types.h"
|
||||
#include "Gui/Viewport/GLMesh.h"
|
||||
#include "Gui/Viewport/GLPoints.h"
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
@@ -21,9 +22,9 @@ void ViewportGLWidget::initializeGL()
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
enzo::geo::Geometry geo = enzo::geo::Geometry();
|
||||
// triangleMesh_ = meshFromGeo(geo);
|
||||
triangleMesh_ = std::make_unique<GLMesh>();
|
||||
gridMesh_ = std::make_unique<GLGrid>();
|
||||
points_ = std::make_unique<GLPoints>();
|
||||
|
||||
QSurfaceFormat fmt = context()->format();
|
||||
std::cout << "format: " << (fmt.renderableType() == QSurfaceFormat::OpenGLES ? "GLES" : "Desktop") << "\n";
|
||||
@@ -154,9 +155,10 @@ void ViewportGLWidget::paintGL()
|
||||
1000.0f // far plane
|
||||
);
|
||||
|
||||
|
||||
gridMesh_->useProgram();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "uProj"), 1, GL_FALSE, glm::value_ptr(projMatrix));
|
||||
curCamera.setUniform(glGetUniformLocation(shaderProgram, "uView"));
|
||||
glUniformMatrix4fv(glGetUniformLocation(gridMesh_->shaderProgram, "uProj"), 1, GL_FALSE, glm::value_ptr(projMatrix));
|
||||
curCamera.setUniform(glGetUniformLocation(gridMesh_->shaderProgram, "uView"));
|
||||
|
||||
|
||||
gridMesh_->draw();
|
||||
@@ -170,26 +172,36 @@ void ViewportGLWidget::paintGL()
|
||||
|
||||
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)
|
||||
{
|
||||
using namespace enzo;
|
||||
// std::unique_ptr<GLMesh> ViewportGLWidget::meshFromGeo(enzo::geo::Geometry& geometry)
|
||||
// {
|
||||
// using namespace enzo;
|
||||
|
||||
auto mesh = std::make_unique<GLMesh>();
|
||||
|
||||
std::shared_ptr<ga::Attribute> PAttr = geometry.getAttribByName(ga::AttrOwner::POINT, "P");
|
||||
ga::AttributeHandleVector3 PAttrHandle = ga::AttributeHandleVector3(PAttr);
|
||||
// auto mesh = std::make_unique<GLMesh>();
|
||||
//
|
||||
// std::shared_ptr<ga::Attribute> PAttr = geometry.getAttribByName(ga::AttrOwner::POINT, "P");
|
||||
// ga::AttributeHandleVector3 PAttrHandle = ga::AttributeHandleVector3(PAttr);
|
||||
|
||||
|
||||
mesh->setPosBuffer(geometry);
|
||||
mesh->setIndexBuffer(geometry);
|
||||
// mesh->setPosBuffer(geometry);
|
||||
// mesh->setIndexBuffer(geometry);
|
||||
|
||||
|
||||
|
||||
return mesh;
|
||||
}
|
||||
// return mesh;
|
||||
// }
|
||||
|
||||
void ViewportGLWidget::geometryChanged(enzo::geo::Geometry& geometry)
|
||||
{
|
||||
@@ -199,4 +211,6 @@ void ViewportGLWidget::geometryChanged(enzo::geo::Geometry& geometry)
|
||||
|
||||
triangleMesh_->setPosBuffer(geometry);
|
||||
triangleMesh_->setIndexBuffer(geometry);
|
||||
|
||||
points_->setPoints(geometry, curCamera);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Gui/Viewport/GLCamera.h"
|
||||
#include "Gui/Viewport/GLMesh.h"
|
||||
#include "Gui/Viewport/GLGrid.h"
|
||||
#include "Gui/Viewport/GLPoints.h"
|
||||
#include "Engine/Operator/Geometry.h"
|
||||
|
||||
class ViewportGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_2_Core
|
||||
@@ -17,8 +18,9 @@ public:
|
||||
GLCamera curCamera;
|
||||
std::unique_ptr<GLMesh> triangleMesh_ ;
|
||||
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:
|
||||
void initializeGL() override;
|
||||
|
||||
@@ -10,7 +10,7 @@ int main(int argc, char **argv)
|
||||
// set up rendering
|
||||
QSurfaceFormat format;
|
||||
format.setRenderableType(QSurfaceFormat::OpenGL);
|
||||
format.setVersion(3, 2);
|
||||
format.setVersion(3, 3);
|
||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
format.setSamples(4);
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
|
||||
Reference in New Issue
Block a user