feat: opengl point rendering

This commit is contained in:
parker
2025-08-04 22:56:06 +01:00
parent 065e5f73ac
commit 123f6d30fe
8 changed files with 292 additions and 16 deletions

View File

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

View File

@@ -123,6 +123,10 @@ void GLCamera::changeRadius(float delta)
}
glm::vec3 GLCamera::getPos()
{
return camPos_;
};
glm::vec3 GLCamera::getRight()
{

View File

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

View 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);
}

View 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();
};

View File

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

View File

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

View File

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