refactor: Migrate ViewportWidget to shader-based OpenGL rendering (FFP disabled)
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
@@ -22,6 +22,8 @@
|
||||
#include <QParallelAnimationGroup>
|
||||
#include <cmath>
|
||||
#include <QtMath>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QVector>
|
||||
|
||||
ViewportWidget::ViewportWidget(QWidget *parent)
|
||||
: QOpenGLWidget(parent)
|
||||
@@ -45,6 +47,12 @@ ViewportWidget::ViewportWidget(QWidget *parent)
|
||||
|
||||
ViewportWidget::~ViewportWidget()
|
||||
{
|
||||
makeCurrent();
|
||||
delete m_shaderProgram;
|
||||
m_vbo.destroy();
|
||||
m_vao.destroy();
|
||||
doneCurrent();
|
||||
|
||||
delete m_viewCube;
|
||||
delete m_sketchGrid;
|
||||
delete m_featureBrowser;
|
||||
@@ -60,6 +68,21 @@ void ViewportWidget::initializeGL()
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||
|
||||
initShaders();
|
||||
|
||||
m_vao.create();
|
||||
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
|
||||
m_vbo.create();
|
||||
m_vbo.bind();
|
||||
m_vbo.allocate(nullptr, 0); // Allocate when drawing
|
||||
|
||||
// Position attribute
|
||||
m_shaderProgram->enableAttributeArray(0);
|
||||
m_shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, 0);
|
||||
|
||||
m_vbo.release();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
m_viewCube->initializeGL();
|
||||
m_sketchGrid->initializeGL();
|
||||
@@ -71,30 +94,34 @@ void ViewportWidget::paintGL()
|
||||
glViewport(0, 0, width(), height());
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if (!m_shaderProgram || !m_shaderProgram->isLinked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
QMatrix4x4 model = m_camera->modelViewMatrix();
|
||||
m_shaderProgram->bind();
|
||||
m_shaderProgram->setUniformValue(m_projMatrixLoc, projection);
|
||||
m_shaderProgram->setUniformValue(m_mvMatrixLoc, model);
|
||||
|
||||
// For simplicity, we'll use a fixed-function pipeline style for drawing.
|
||||
// In a real app, this would use shaders.
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(projection.constData());
|
||||
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(model.constData());
|
||||
// Sketch grid rendering - temporarily disabled as it uses the fixed-function pipeline
|
||||
// if (m_isSelectingPlane) {
|
||||
// if (m_highlightedPlane != SketchPlane::NONE) {
|
||||
// m_sketchGrid->paintGL(static_cast<SketchGrid::SketchPlane>(m_highlightedPlane), projection, model);
|
||||
// }
|
||||
// }
|
||||
// if (m_currentPlane != SketchPlane::NONE) {
|
||||
// m_sketchGrid->paintGL(static_cast<SketchGrid::SketchPlane>(m_currentPlane), projection, model);
|
||||
// }
|
||||
|
||||
if (m_isSelectingPlane) {
|
||||
if (m_highlightedPlane != SketchPlane::NONE) {
|
||||
m_sketchGrid->paintGL(static_cast<SketchGrid::SketchPlane>(m_highlightedPlane), projection, model);
|
||||
}
|
||||
drawSelectionPlanes();
|
||||
}
|
||||
|
||||
if (m_currentPlane != SketchPlane::NONE) {
|
||||
m_sketchGrid->paintGL(static_cast<SketchGrid::SketchPlane>(m_currentPlane), projection, model);
|
||||
}
|
||||
|
||||
if (m_document) {
|
||||
for (Feature* feature : m_document->features()) {
|
||||
if (auto sketch = dynamic_cast<SketchFeature*>(feature)) {
|
||||
@@ -103,66 +130,67 @@ void ViewportWidget::paintGL()
|
||||
}
|
||||
}
|
||||
|
||||
QVector<GLfloat> vertices;
|
||||
if (m_isSnappingOrigin) {
|
||||
const float rectSize = 0.0075f * -m_camera->zoom();
|
||||
glColor4f(1.0, 1.0, 0.0, 0.5f);
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
vertices << -rectSize << 0 << -rectSize << rectSize << 0 << -rectSize;
|
||||
vertices << rectSize << 0 << -rectSize << rectSize << 0 << rectSize;
|
||||
vertices << rectSize << 0 << rectSize << -rectSize << 0 << rectSize;
|
||||
vertices << -rectSize << 0 << rectSize << -rectSize << 0 << -rectSize;
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
vertices << -rectSize << -rectSize << 0 << rectSize << -rectSize << 0;
|
||||
vertices << rectSize << -rectSize << 0 << rectSize << rectSize << 0;
|
||||
vertices << rectSize << rectSize << 0 << -rectSize << rectSize << 0;
|
||||
vertices << -rectSize << rectSize << 0 << -rectSize << -rectSize << 0;
|
||||
} else if (m_currentPlane == SketchPlane::YZ) {
|
||||
vertices << 0 << -rectSize << -rectSize << 0 << rectSize << -rectSize;
|
||||
vertices << 0 << rectSize << -rectSize << 0 << rectSize << rectSize;
|
||||
vertices << 0 << rectSize << rectSize << 0 << -rectSize << rectSize;
|
||||
vertices << 0 << -rectSize << rectSize << 0 << -rectSize << -rectSize;
|
||||
}
|
||||
m_shaderProgram->setUniformValue(m_colorLoc, QVector4D(1.0f, 1.0f, 0.0f, 0.5f));
|
||||
m_vbo.bind();
|
||||
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
glVertex3f(-rectSize, 0, -rectSize);
|
||||
glVertex3f( rectSize, 0, -rectSize);
|
||||
glVertex3f( rectSize, 0, rectSize);
|
||||
glVertex3f(-rectSize, 0, rectSize);
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
glVertex3f(-rectSize, -rectSize, 0);
|
||||
glVertex3f( rectSize, -rectSize, 0);
|
||||
glVertex3f( rectSize, rectSize, 0);
|
||||
glVertex3f(-rectSize, rectSize, 0);
|
||||
} else if (m_currentPlane == SketchPlane::YZ) {
|
||||
glVertex3f(0, -rectSize, -rectSize);
|
||||
glVertex3f(0, rectSize, -rectSize);
|
||||
glVertex3f(0, rectSize, rectSize);
|
||||
glVertex3f(0, -rectSize, rectSize);
|
||||
}
|
||||
glEnd();
|
||||
glDrawArrays(GL_LINES, 0, vertices.size() / 3);
|
||||
glDisable(GL_BLEND);
|
||||
} else if (m_isSnappingVertex) {
|
||||
const float rectSize = 0.0075f * -m_camera->zoom();
|
||||
glColor4f(1.0, 1.0, 0.0, 0.5f);
|
||||
const auto& v = m_snapVertex;
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
vertices << v.X() - rectSize << v.Y() << v.Z() - rectSize << v.X() + rectSize << v.Y() << v.Z() - rectSize;
|
||||
vertices << v.X() + rectSize << v.Y() << v.Z() - rectSize << v.X() + rectSize << v.Y() << v.Z() + rectSize;
|
||||
vertices << v.X() + rectSize << v.Y() << v.Z() + rectSize << v.X() - rectSize << v.Y() << v.Z() + rectSize;
|
||||
vertices << v.X() - rectSize << v.Y() << v.Z() + rectSize << v.X() - rectSize << v.Y() << v.Z() - rectSize;
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
vertices << v.X() - rectSize << v.Y() - rectSize << v.Z() << v.X() + rectSize << v.Y() - rectSize << v.Z();
|
||||
vertices << v.X() + rectSize << v.Y() - rectSize << v.Z() << v.X() + rectSize << v.Y() + rectSize << v.Z();
|
||||
vertices << v.X() + rectSize << v.Y() + rectSize << v.Z() << v.X() - rectSize << v.Y() + rectSize << v.Z();
|
||||
vertices << v.X() - rectSize << v.Y() + rectSize << v.Z() << v.X() - rectSize << v.Y() - rectSize << v.Z();
|
||||
} else if (m_currentPlane == SketchPlane::YZ) {
|
||||
vertices << v.X() << v.Y() - rectSize << v.Z() - rectSize << v.X() << v.Y() + rectSize << v.Z() - rectSize;
|
||||
vertices << v.X() << v.Y() + rectSize << v.Z() - rectSize << v.X() << v.Y() + rectSize << v.Z() + rectSize;
|
||||
vertices << v.X() << v.Y() + rectSize << v.Z() + rectSize << v.X() << v.Y() - rectSize << v.Z() + rectSize;
|
||||
vertices << v.X() << v.Y() - rectSize << v.Z() + rectSize << v.X() << v.Y() - rectSize << v.Z() - rectSize;
|
||||
}
|
||||
m_shaderProgram->setUniformValue(m_colorLoc, QVector4D(1.0f, 1.0f, 0.0f, 0.5f));
|
||||
m_vbo.bind();
|
||||
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
glVertex3f(m_snapVertex.X() - rectSize, m_snapVertex.Y(), m_snapVertex.Z() - rectSize);
|
||||
glVertex3f(m_snapVertex.X() + rectSize, m_snapVertex.Y(), m_snapVertex.Z() - rectSize);
|
||||
glVertex3f(m_snapVertex.X() + rectSize, m_snapVertex.Y(), m_snapVertex.Z() + rectSize);
|
||||
glVertex3f(m_snapVertex.X() - rectSize, m_snapVertex.Y(), m_snapVertex.Z() + rectSize);
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
glVertex3f(m_snapVertex.X() - rectSize, m_snapVertex.Y() - rectSize, m_snapVertex.Z());
|
||||
glVertex3f(m_snapVertex.X() + rectSize, m_snapVertex.Y() - rectSize, m_snapVertex.Z());
|
||||
glVertex3f(m_snapVertex.X() + rectSize, m_snapVertex.Y() + rectSize, m_snapVertex.Z());
|
||||
glVertex3f(m_snapVertex.X() - rectSize, m_snapVertex.Y() + rectSize, m_snapVertex.Z());
|
||||
} else if (m_currentPlane == SketchPlane::YZ) {
|
||||
glVertex3f(m_snapVertex.X(), m_snapVertex.Y() - rectSize, m_snapVertex.Z() - rectSize);
|
||||
glVertex3f(m_snapVertex.X(), m_snapVertex.Y() + rectSize, m_snapVertex.Z() - rectSize);
|
||||
glVertex3f(m_snapVertex.X(), m_snapVertex.Y() + rectSize, m_snapVertex.Z() + rectSize);
|
||||
glVertex3f(m_snapVertex.X(), m_snapVertex.Y() - rectSize, m_snapVertex.Z() + rectSize);
|
||||
}
|
||||
glEnd();
|
||||
glDrawArrays(GL_LINES, 0, vertices.size() / 3);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
if (m_isDefiningLine && m_activeTool == static_cast<int>(ApplicationController::ToolType::Line)) {
|
||||
vertices.clear();
|
||||
QVector3D worldPos = unproject(m_currentMousePos, m_currentPlane);
|
||||
if (m_isSnappingOrigin) {
|
||||
worldPos.setX(0);
|
||||
worldPos.setY(0);
|
||||
worldPos.setZ(0);
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_isSnappingVertex) {
|
||||
worldPos.setX(m_snapVertex.X());
|
||||
worldPos.setY(m_snapVertex.Y());
|
||||
worldPos.setZ(m_snapVertex.Z());
|
||||
worldPos.setX(m_snapVertex.X()); worldPos.setY(m_snapVertex.Y()); worldPos.setZ(m_snapVertex.Z());
|
||||
} else if (m_isSnappingHorizontal) {
|
||||
if (m_currentPlane == SketchPlane::XY) worldPos.setZ(m_firstLinePoint.Z());
|
||||
else if (m_currentPlane == SketchPlane::XZ) worldPos.setY(m_firstLinePoint.Y());
|
||||
@@ -172,56 +200,58 @@ void ViewportWidget::paintGL()
|
||||
else if (m_currentPlane == SketchPlane::XZ) worldPos.setX(m_firstLinePoint.X());
|
||||
else if (m_currentPlane == SketchPlane::YZ) worldPos.setY(m_firstLinePoint.Y());
|
||||
}
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(1.0, 1.0, 0.0);
|
||||
glVertex3d(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
|
||||
glVertex3d(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
glEnd();
|
||||
vertices << m_firstLinePoint.X() << m_firstLinePoint.Y() << m_firstLinePoint.Z();
|
||||
vertices << worldPos.x() << worldPos.y() << worldPos.z();
|
||||
|
||||
m_shaderProgram->setUniformValue(m_colorLoc, QVector4D(1.0f, 1.0f, 0.0f, 1.0f));
|
||||
m_vbo.bind();
|
||||
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
|
||||
if (m_isSnappingHorizontal || m_isSnappingVertical) {
|
||||
vertices.clear();
|
||||
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
|
||||
QVector3D midPoint = (startPos + worldPos) / 2.0;
|
||||
const float indicatorSize = 0.02f * -m_camera->zoom();
|
||||
const float indicatorOffset = 0.02f * -m_camera->zoom();
|
||||
|
||||
glColor3f(1.0, 1.0, 0.0);
|
||||
glBegin(GL_LINES);
|
||||
|
||||
if (m_isSnappingHorizontal) {
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
glVertex3f(midPoint.x() - indicatorSize, midPoint.y(), midPoint.z() + indicatorOffset);
|
||||
glVertex3f(midPoint.x() + indicatorSize, midPoint.y(), midPoint.z() + indicatorOffset);
|
||||
vertices << midPoint.x() - indicatorSize << midPoint.y() << midPoint.z() + indicatorOffset;
|
||||
vertices << midPoint.x() + indicatorSize << midPoint.y() << midPoint.z() + indicatorOffset;
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
glVertex3f(midPoint.x() - indicatorSize, midPoint.y() + indicatorOffset, midPoint.z());
|
||||
glVertex3f(midPoint.x() + indicatorSize, midPoint.y() + indicatorOffset, midPoint.z());
|
||||
vertices << midPoint.x() - indicatorSize << midPoint.y() + indicatorOffset << midPoint.z();
|
||||
vertices << midPoint.x() + indicatorSize << midPoint.y() + indicatorOffset << midPoint.z();
|
||||
} else if (m_currentPlane == SketchPlane::YZ) {
|
||||
glVertex3f(midPoint.x(), midPoint.y() - indicatorSize, midPoint.z() + indicatorOffset);
|
||||
glVertex3f(midPoint.x(), midPoint.y() + indicatorSize, midPoint.z() + indicatorOffset);
|
||||
vertices << midPoint.x() << midPoint.y() - indicatorSize << midPoint.z() + indicatorOffset;
|
||||
vertices << midPoint.x() << midPoint.y() + indicatorSize << midPoint.z() + indicatorOffset;
|
||||
}
|
||||
} else { // m_isSnappingVertical
|
||||
if (m_currentPlane == SketchPlane::XY) {
|
||||
glVertex3f(midPoint.x() + indicatorOffset, midPoint.y(), midPoint.z() - indicatorSize);
|
||||
glVertex3f(midPoint.x() + indicatorOffset, midPoint.y(), midPoint.z() + indicatorSize);
|
||||
vertices << midPoint.x() + indicatorOffset << midPoint.y() << midPoint.z() - indicatorSize;
|
||||
vertices << midPoint.x() + indicatorOffset << midPoint.y() << midPoint.z() + indicatorSize;
|
||||
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||
glVertex3f(midPoint.x() + indicatorOffset, midPoint.y() - indicatorSize, midPoint.z());
|
||||
glVertex3f(midPoint.x() + indicatorOffset, midPoint.y() + indicatorSize, midPoint.z());
|
||||
vertices << midPoint.x() + indicatorOffset << midPoint.y() - indicatorSize << midPoint.z();
|
||||
vertices << midPoint.x() + indicatorOffset << midPoint.y() + indicatorSize << midPoint.z();
|
||||
} else if (m_currentPlane == SketchPlane::YZ) {
|
||||
glVertex3f(midPoint.x(), midPoint.y() + indicatorOffset, midPoint.z() - indicatorSize);
|
||||
glVertex3f(midPoint.x(), midPoint.y() + indicatorOffset, midPoint.z() + indicatorSize);
|
||||
vertices << midPoint.x() << midPoint.y() + indicatorOffset << midPoint.z() - indicatorSize;
|
||||
vertices << midPoint.x() << midPoint.y() + indicatorOffset << midPoint.z() + indicatorSize;
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
m_vbo.bind();
|
||||
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// View cube rendering
|
||||
QMatrix4x4 viewCubeModel;
|
||||
viewCubeModel.rotate(m_camera->xRotation() / 16.0f, 1, 0, 0);
|
||||
viewCubeModel.rotate(m_camera->yRotation() / 16.0f, 0, 1, 0);
|
||||
m_viewCube->paintGL(viewCubeModel, width(), height());
|
||||
m_shaderProgram->release();
|
||||
|
||||
// View cube rendering - temporarily disabled as it uses the fixed-function pipeline
|
||||
// QMatrix4x4 viewCubeModel;
|
||||
// viewCubeModel.rotate(m_camera->xRotation() / 16.0f, 1, 0, 0);
|
||||
// viewCubeModel.rotate(m_camera->yRotation() / 16.0f, 0, 1, 0);
|
||||
// m_viewCube->paintGL(viewCubeModel, width(), height());
|
||||
|
||||
glViewport(0, 0, width(), height());
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
@@ -701,28 +731,61 @@ void ViewportWidget::drawSketch(const SketchFeature* sketch)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glLineWidth(2.0f);
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
glPointSize(5.0f);
|
||||
|
||||
QVector<GLfloat> lineVertices;
|
||||
QVector<GLfloat> pointVertices;
|
||||
|
||||
for (const auto& obj : sketch->objects()) {
|
||||
if (obj->type() == SketchObject::ObjectType::Line) {
|
||||
auto line = static_cast<const SketchLine*>(obj);
|
||||
const auto& start = line->startPoint();
|
||||
const auto& end = line->endPoint();
|
||||
glBegin(GL_LINES);
|
||||
glVertex3d(start.X(), start.Y(), start.Z());
|
||||
glVertex3d(end.X(), end.Y(), end.Z());
|
||||
glEnd();
|
||||
lineVertices << start.X() << start.Y() << start.Z();
|
||||
lineVertices << end.X() << end.Y() << end.Z();
|
||||
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3d(start.X(), start.Y(), start.Z());
|
||||
glVertex3d(end.X(), end.Y(), end.Z());
|
||||
glEnd();
|
||||
pointVertices << start.X() << start.Y() << start.Z();
|
||||
pointVertices << end.X() << end.Y() << end.Z();
|
||||
}
|
||||
}
|
||||
|
||||
m_shaderProgram->setUniformValue(m_colorLoc, QVector4D(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
m_vbo.bind();
|
||||
|
||||
if (!lineVertices.isEmpty()) {
|
||||
m_vbo.allocate(lineVertices.constData(), lineVertices.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_LINES, 0, lineVertices.size() / 3);
|
||||
}
|
||||
if (!pointVertices.isEmpty()) {
|
||||
m_vbo.allocate(pointVertices.constData(), pointVertices.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_POINTS, 0, pointVertices.size() / 3);
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void ViewportWidget::initShaders()
|
||||
{
|
||||
m_shaderProgram = new QOpenGLShaderProgram(this);
|
||||
|
||||
if (!m_shaderProgram->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/simple.vert")) {
|
||||
qCritical() << "Vertex shader compilation failed:" << m_shaderProgram->log();
|
||||
return;
|
||||
}
|
||||
if (!m_shaderProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/simple.frag")) {
|
||||
qCritical() << "Fragment shader compilation failed:" << m_shaderProgram->log();
|
||||
return;
|
||||
}
|
||||
if (!m_shaderProgram->link()) {
|
||||
qCritical() << "Shader program linking failed:" << m_shaderProgram->log();
|
||||
return;
|
||||
}
|
||||
|
||||
m_projMatrixLoc = m_shaderProgram->uniformLocation("projectionMatrix");
|
||||
m_mvMatrixLoc = m_shaderProgram->uniformLocation("modelViewMatrix");
|
||||
m_colorLoc = m_shaderProgram->uniformLocation("objectColor");
|
||||
}
|
||||
|
||||
void ViewportWidget::drawSelectionPlanes()
|
||||
{
|
||||
const float planeSize = 5.0f;
|
||||
@@ -734,61 +797,36 @@ void ViewportWidget::drawSelectionPlanes()
|
||||
glLineWidth(2.0f);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
// Draw back to front for proper blending
|
||||
m_vbo.bind();
|
||||
QVector<GLfloat> vertices;
|
||||
|
||||
// XY Plane (Top), normal is Y (green)
|
||||
glColor4f(1.0f, 1.0f, 0.0f, m_highlightedPlane == SketchPlane::XY ? 0.5f : 0.2f);
|
||||
if (m_highlightedPlane == SketchPlane::XY) {
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(planeOffset, 0, planeOffset);
|
||||
glVertex3f(planeOffset + planeSize, 0, planeOffset);
|
||||
glVertex3f(planeOffset + planeSize, 0, planeOffset + planeSize);
|
||||
glVertex3f(planeOffset, 0, planeOffset + planeSize);
|
||||
glEnd();
|
||||
}
|
||||
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(planeOffset, 0, planeOffset);
|
||||
glVertex3f(planeOffset + planeSize, 0, planeOffset);
|
||||
glVertex3f(planeOffset + planeSize, 0, planeOffset + planeSize);
|
||||
glVertex3f(planeOffset, 0, planeOffset + planeSize);
|
||||
glEnd();
|
||||
auto drawPlane = [&](const QVector<GLfloat>& quadVerts, bool highlighted) {
|
||||
// Draw fill
|
||||
if (highlighted) {
|
||||
m_shaderProgram->setUniformValue(m_colorLoc, QVector4D(1.0f, 1.0f, 0.0f, 0.5f));
|
||||
m_vbo.allocate(quadVerts.constData(), quadVerts.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
// Draw outline
|
||||
m_shaderProgram->setUniformValue(m_colorLoc, QVector4D(1.0f, 1.0f, 0.0f, 1.0f));
|
||||
m_vbo.allocate(quadVerts.constData(), quadVerts.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_LINE_LOOP, 0, 4);
|
||||
};
|
||||
|
||||
// XZ Plane (Front), normal is Z (blue)
|
||||
glColor4f(1.0f, 1.0f, 0.0f, m_highlightedPlane == SketchPlane::XZ ? 0.5f : 0.2f);
|
||||
if (m_highlightedPlane == SketchPlane::XZ) {
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(planeOffset, planeOffset, 0);
|
||||
glVertex3f(planeOffset + planeSize, planeOffset, 0);
|
||||
glVertex3f(planeOffset + planeSize, planeOffset + planeSize, 0);
|
||||
glVertex3f(planeOffset, planeOffset + planeSize, 0);
|
||||
glEnd();
|
||||
}
|
||||
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(planeOffset, planeOffset, 0);
|
||||
glVertex3f(planeOffset + planeSize, planeOffset, 0);
|
||||
glVertex3f(planeOffset + planeSize, planeOffset + planeSize, 0);
|
||||
glVertex3f(planeOffset, planeOffset + planeSize, 0);
|
||||
glEnd();
|
||||
// XY Plane (Top)
|
||||
QVector<GLfloat> xyQuad = { planeOffset, 0, planeOffset, planeOffset + planeSize, 0, planeOffset,
|
||||
planeOffset + planeSize, 0, planeOffset + planeSize, planeOffset, 0, planeOffset + planeSize };
|
||||
drawPlane(xyQuad, m_highlightedPlane == SketchPlane::XY);
|
||||
|
||||
// YZ Plane (Right), normal is X (red)
|
||||
glColor4f(1.0f, 1.0f, 0.0f, m_highlightedPlane == SketchPlane::YZ ? 0.5f : 0.2f);
|
||||
if (m_highlightedPlane == SketchPlane::YZ) {
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(0, planeOffset, planeOffset);
|
||||
glVertex3f(0, planeOffset + planeSize, planeOffset);
|
||||
glVertex3f(0, planeOffset + planeSize, planeOffset + planeSize);
|
||||
glVertex3f(0, planeOffset, planeOffset + planeSize);
|
||||
glEnd();
|
||||
}
|
||||
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(0, planeOffset, planeOffset);
|
||||
glVertex3f(0, planeOffset + planeSize, planeOffset);
|
||||
glVertex3f(0, planeOffset + planeSize, planeOffset + planeSize);
|
||||
glVertex3f(0, planeOffset, planeOffset + planeSize);
|
||||
glEnd();
|
||||
// XZ Plane (Front)
|
||||
QVector<GLfloat> xzQuad = { planeOffset, planeOffset, 0, planeOffset + planeSize, planeOffset, 0,
|
||||
planeOffset + planeSize, planeOffset + planeSize, 0, planeOffset, planeOffset + planeSize, 0 };
|
||||
drawPlane(xzQuad, m_highlightedPlane == SketchPlane::XZ);
|
||||
|
||||
// YZ Plane (Right)
|
||||
QVector<GLfloat> yzQuad = { 0, planeOffset, planeOffset, 0, planeOffset + planeSize, planeOffset,
|
||||
0, planeOffset + planeSize, planeOffset + planeSize, 0, planeOffset, planeOffset + planeSize };
|
||||
drawPlane(yzQuad, m_highlightedPlane == SketchPlane::YZ);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#include <QRect>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <QMap>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLBuffer>
|
||||
|
||||
class QSvgRenderer;
|
||||
class ViewCube;
|
||||
@@ -56,6 +59,7 @@ protected:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
private:
|
||||
void initShaders();
|
||||
QVector3D project(const QVector3D& worldCoord, const QMatrix4x4& modelView, const QMatrix4x4& projection, const QRect& viewport);
|
||||
QVector3D unproject(const QPoint& screenPos, SketchPlane plane);
|
||||
void drawAxisLabels(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection);
|
||||
@@ -64,6 +68,14 @@ private:
|
||||
ViewportWidget::SketchPlane checkPlaneSelection(const QPoint& screenPos);
|
||||
|
||||
QMatrix4x4 projection;
|
||||
QOpenGLShaderProgram* m_shaderProgram = nullptr;
|
||||
QOpenGLVertexArrayObject m_vao;
|
||||
QOpenGLBuffer m_vbo;
|
||||
|
||||
// Shader uniform locations
|
||||
int m_projMatrixLoc = -1;
|
||||
int m_mvMatrixLoc = -1;
|
||||
int m_colorLoc = -1;
|
||||
Camera* m_camera = nullptr;
|
||||
ViewCube* m_viewCube;
|
||||
SketchGrid* m_sketchGrid = nullptr;
|
||||
|
||||
6
src/shaders/shaders.qrc
Normal file
6
src/shaders/shaders.qrc
Normal file
@@ -0,0 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/shaders">
|
||||
<file>simple.vert</file>
|
||||
<file>simple.frag</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
10
src/shaders/simple.frag
Normal file
10
src/shaders/simple.frag
Normal file
@@ -0,0 +1,10 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform vec4 objectColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = objectColor;
|
||||
}
|
||||
11
src/shaders/simple.vert
Normal file
11
src/shaders/simple.vert
Normal file
@@ -0,0 +1,11 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4(aPos, 1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user