feat: Render 3D cube with camera controls (zoom, pan, rotate)

Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
2026-02-09 15:51:37 -07:00
parent 6df2657eb9
commit 9584471932
4 changed files with 166 additions and 5 deletions

View File

@@ -8,11 +8,12 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt6 COMPONENTS Widgets REQUIRED)
find_package(Qt6 COMPONENTS Widgets OpenGLWidgets REQUIRED)
add_executable(OpenCAD
src/main.cpp
src/MainWindow.cpp
src/ViewportWidget.cpp
)
target_link_libraries(OpenCAD PRIVATE Qt6::Widgets)
target_link_libraries(OpenCAD PRIVATE Qt6::Widgets Qt6::OpenGLWidgets)

View File

@@ -1,7 +1,7 @@
#include "MainWindow.h"
#include "ViewportWidget.h"
#include <QToolBar>
#include <QWidget>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
@@ -11,7 +11,6 @@ MainWindow::MainWindow(QWidget *parent)
QToolBar *toolBar = addToolBar("Tools");
QWidget *viewport = new QWidget;
viewport->setStyleSheet("background-color: darkgray;");
ViewportWidget *viewport = new ViewportWidget;
setCentralWidget(viewport);
}

123
src/ViewportWidget.cpp Normal file
View File

@@ -0,0 +1,123 @@
#include "ViewportWidget.h"
#include <QMouseEvent>
#include <QWheelEvent>
#include <QApplication>
ViewportWidget::ViewportWidget(QWidget *parent)
: QOpenGLWidget(parent)
{
}
void ViewportWidget::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glEnable(GL_DEPTH_TEST);
}
void ViewportWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 model;
model.translate(panX, panY, zoom);
model.rotate(xRot / 16.0f, 1, 0, 0);
model.rotate(yRot / 16.0f, 0, 1, 0);
// 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());
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(model.constData());
drawCube();
}
void ViewportWidget::resizeGL(int w, int h)
{
projection.setToIdentity();
projection.perspective(45.0f, w / float(h), 0.01f, 100.0f);
}
void ViewportWidget::mousePressEvent(QMouseEvent *event)
{
lastPos = event->pos();
}
void ViewportWidget::mouseMoveEvent(QMouseEvent *event)
{
int dx = event->pos().x() - lastPos.x();
int dy = event->pos().y() - lastPos.y();
if (event->buttons() & Qt::MiddleButton) {
if (QApplication::keyboardModifiers() & Qt::ShiftModifier) {
// Pan
panX += dx / 100.0f;
panY -= dy / 100.0f;
} else {
// Rotate
xRot += 8 * dy;
yRot += 8 * dx;
}
}
lastPos = event->pos();
update();
}
void ViewportWidget::wheelEvent(QWheelEvent *event)
{
QPoint numDegrees = event->angleDelta() / 8;
if (!numDegrees.isNull()) {
zoom += numDegrees.y() / 5.0f;
}
update();
}
void ViewportWidget::drawCube()
{
glBegin(GL_QUADS);
// Front face
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-0.5, -0.5, 0.5);
glVertex3f(0.5, -0.5, 0.5);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
// Back face
glColor3f(0.0, 1.0, 0.0);
glVertex3f(-0.5, -0.5, -0.5);
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f(0.5, 0.5, -0.5);
glVertex3f(0.5, -0.5, -0.5);
// Top face
glColor3f(0.0, 0.0, 1.0);
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(0.5, 0.5, -0.5);
// Bottom face
glColor3f(1.0, 1.0, 0.0);
glVertex3f(-0.5, -0.5, -0.5);
glVertex3f(0.5, -0.5, -0.5);
glVertex3f(0.5, -0.5, 0.5);
glVertex3f(-0.5, -0.5, 0.5);
// Right face
glColor3f(1.0, 0.0, 1.0);
glVertex3f(0.5, -0.5, -0.5);
glVertex3f(0.5, 0.5, -0.5);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(0.5, -0.5, 0.5);
// Left face
glColor3f(0.0, 1.0, 1.0);
glVertex3f(-0.5, -0.5, -0.5);
glVertex3f(-0.5, -0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, -0.5);
glEnd();
}

38
src/ViewportWidget.h Normal file
View File

@@ -0,0 +1,38 @@
#ifndef VIEWPORTWIDGET_H
#define VIEWPORTWIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QMatrix4x4>
#include <QPoint>
class ViewportWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit ViewportWidget(QWidget *parent = nullptr);
protected:
void initializeGL() override;
void paintGL() override;
void resizeGL(int w, int h) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
private:
void drawCube();
QMatrix4x4 projection;
float xRot = 0;
float yRot = 0;
float zoom = -5.0f;
float panX = 0;
float panY = 0;
QPoint lastPos;
};
#endif // VIEWPORTWIDGET_H