diff --git a/CMakeLists.txt b/CMakeLists.txt index b8d0746..99798dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable(OpenCAD src/main.cpp src/MainWindow.cpp src/ViewportWidget.cpp + src/ViewCube.cpp ) target_link_libraries(OpenCAD PRIVATE Qt6::Widgets Qt6::OpenGLWidgets) diff --git a/src/ViewCube.cpp b/src/ViewCube.cpp new file mode 100644 index 0000000..91bedf6 --- /dev/null +++ b/src/ViewCube.cpp @@ -0,0 +1,138 @@ +#include "ViewCube.h" +#include +#include + +ViewCube::ViewCube() +{ +} + +void ViewCube::initializeGL() +{ + initializeOpenGLFunctions(); + createFaceTextures(); +} + +void ViewCube::paintGL(const QMatrix4x4& viewMatrix, int width, int height) +{ + int viewCubeSize = 150; + glViewport(width - viewCubeSize, height - viewCubeSize, viewCubeSize, viewCubeSize); + glClear(GL_DEPTH_BUFFER_BIT); + + QMatrix4x4 viewCubeProjection; + viewCubeProjection.ortho(-2, 2, -2, 2, -10, 10); + + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(viewCubeProjection.constData()); + + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(viewMatrix.constData()); + + drawViewCube(); + drawAxes(); +} + +void ViewCube::createFaceTextures() +{ + QStringList labels = {"FRONT", "BACK", "TOP", "BOTTOM", "RIGHT", "LEFT"}; + glGenTextures(6, faceTextures); + + for (int i = 0; i < 6; ++i) { + QImage image(128, 128, QImage::Format_RGBA8888); + image.fill(qRgba(204, 204, 204, 255)); // light gray background + + QPainter painter(&image); + painter.setPen(Qt::black); + painter.setFont(QFont("Arial", 24, QFont::Bold)); + painter.drawText(image.rect(), Qt::AlignCenter, labels[i]); + + QImage glImage = image.mirrored(false, true); + + glBindTexture(GL_TEXTURE_2D, faceTextures[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glImage.width(), glImage.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, glImage.bits()); + } +} + +void ViewCube::drawViewCube() +{ + float size = 0.75; + glEnable(GL_TEXTURE_2D); + glColor3f(1.0, 1.0, 1.0); // Use white so texture colors are not modulated + + // Front face + glBindTexture(GL_TEXTURE_2D, faceTextures[0]); + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size, size); + glTexCoord2f(1.0, 0.0); glVertex3f(size, -size, size); + glTexCoord2f(1.0, 1.0); glVertex3f(size, size, size); + glTexCoord2f(0.0, 1.0); glVertex3f(-size, size, size); + glEnd(); + + // Back face + glBindTexture(GL_TEXTURE_2D, faceTextures[1]); + glBegin(GL_QUADS); + glTexCoord2f(1.0, 0.0); glVertex3f(-size, -size, -size); + glTexCoord2f(1.0, 1.0); glVertex3f(-size, size, -size); + glTexCoord2f(0.0, 1.0); glVertex3f(size, size, -size); + glTexCoord2f(0.0, 0.0); glVertex3f(size, -size, -size); + glEnd(); + + // Top face + glBindTexture(GL_TEXTURE_2D, faceTextures[2]); + glBegin(GL_QUADS); + glTexCoord2f(0.0, 1.0); glVertex3f(-size, size, -size); + glTexCoord2f(0.0, 0.0); glVertex3f(-size, size, size); + glTexCoord2f(1.0, 0.0); glVertex3f(size, size, size); + glTexCoord2f(1.0, 1.0); glVertex3f(size, size, -size); + glEnd(); + + // Bottom face + glBindTexture(GL_TEXTURE_2D, faceTextures[3]); + glBegin(GL_QUADS); + glTexCoord2f(1.0, 1.0); glVertex3f(-size, -size, -size); + glTexCoord2f(0.0, 1.0); glVertex3f(size, -size, -size); + glTexCoord2f(0.0, 0.0); glVertex3f(size, -size, size); + glTexCoord2f(1.0, 0.0); glVertex3f(-size, -size, size); + glEnd(); + + // Right face + glBindTexture(GL_TEXTURE_2D, faceTextures[4]); + glBegin(GL_QUADS); + glTexCoord2f(1.0, 0.0); glVertex3f(size, -size, -size); + glTexCoord2f(1.0, 1.0); glVertex3f(size, size, -size); + glTexCoord2f(0.0, 1.0); glVertex3f(size, size, size); + glTexCoord2f(0.0, 0.0); glVertex3f(size, -size, size); + glEnd(); + + // Left face + glBindTexture(GL_TEXTURE_2D, faceTextures[5]); + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size, -size); + glTexCoord2f(1.0, 0.0); glVertex3f(-size, -size, size); + glTexCoord2f(1.0, 1.0); glVertex3f(-size, size, size); + glTexCoord2f(0.0, 1.0); glVertex3f(-size, size, -size); + glEnd(); + + glDisable(GL_TEXTURE_2D); +} + +void ViewCube::drawAxes() +{ + glLineWidth(2.0f); + glBegin(GL_LINES); + // X-axis (red) + glColor3f(1.0, 0.0, 0.0); + glVertex3f(0.0, 0.0, 0.0); + glVertex3f(1.5, 0.0, 0.0); + // Y-axis (green) + glColor3f(0.0, 1.0, 0.0); + glVertex3f(0.0, 0.0, 0.0); + glVertex3f(0.0, 1.5, 0.0); + // Z-axis (blue) + glColor3f(0.0, 0.0, 1.0); + glVertex3f(0.0, 0.0, 0.0); + glVertex3f(0.0, 0.0, 1.5); + glEnd(); + glLineWidth(1.0f); +} diff --git a/src/ViewCube.h b/src/ViewCube.h new file mode 100644 index 0000000..f09b9e8 --- /dev/null +++ b/src/ViewCube.h @@ -0,0 +1,24 @@ +#ifndef VIEWCUBE_H +#define VIEWCUBE_H + +#include +#include +#include // For GLuint + +class ViewCube : protected QOpenGLFunctions +{ +public: + ViewCube(); + + void initializeGL(); + void paintGL(const QMatrix4x4& viewMatrix, int width, int height); + +private: + void createFaceTextures(); + void drawViewCube(); + void drawAxes(); + + GLuint faceTextures[6]; +}; + +#endif // VIEWCUBE_H diff --git a/src/ViewportWidget.cpp b/src/ViewportWidget.cpp index aa410bf..1aa54a2 100644 --- a/src/ViewportWidget.cpp +++ b/src/ViewportWidget.cpp @@ -1,14 +1,18 @@ #include "ViewportWidget.h" +#include "ViewCube.h" #include #include #include -#include -#include -#include ViewportWidget::ViewportWidget(QWidget *parent) : QOpenGLWidget(parent) { + m_viewCube = new ViewCube(); +} + +ViewportWidget::~ViewportWidget() +{ + delete m_viewCube; } void ViewportWidget::initializeGL() @@ -16,7 +20,7 @@ void ViewportWidget::initializeGL() initializeOpenGLFunctions(); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glEnable(GL_DEPTH_TEST); - createFaceTextures(); + m_viewCube->initializeGL(); } void ViewportWidget::paintGL() @@ -40,26 +44,11 @@ void ViewportWidget::paintGL() drawCube(); - // View cube rendering in top right - int viewCubeSize = 150; - glViewport(width() - viewCubeSize, height() - viewCubeSize, viewCubeSize, viewCubeSize); - glClear(GL_DEPTH_BUFFER_BIT); - - QMatrix4x4 viewCubeProjection; - viewCubeProjection.ortho(-2, 2, -2, 2, -10, 10); - + // View cube rendering QMatrix4x4 viewCubeModel; viewCubeModel.rotate(xRot / 16.0f, 1, 0, 0); viewCubeModel.rotate(yRot / 16.0f, 0, 1, 0); - - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(viewCubeProjection.constData()); - - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(viewCubeModel.constData()); - - drawViewCube(); - drawAxes(); + m_viewCube->paintGL(viewCubeModel, width(), height()); glViewport(0, 0, width(), height()); } @@ -104,112 +93,6 @@ void ViewportWidget::wheelEvent(QWheelEvent *event) update(); } -void ViewportWidget::createFaceTextures() -{ - QStringList labels = {"FRONT", "BACK", "TOP", "BOTTOM", "RIGHT", "LEFT"}; - glGenTextures(6, faceTextures); - - for (int i = 0; i < 6; ++i) { - QImage image(128, 128, QImage::Format_RGBA8888); - image.fill(qRgba(204, 204, 204, 255)); // light gray background - - QPainter painter(&image); - painter.setPen(Qt::black); - painter.setFont(QFont("Arial", 24, QFont::Bold)); - painter.drawText(image.rect(), Qt::AlignCenter, labels[i]); - - QImage glImage = image.mirrored(false, true); - - glBindTexture(GL_TEXTURE_2D, faceTextures[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glImage.width(), glImage.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, glImage.bits()); - } -} - -void ViewportWidget::drawViewCube() -{ - float size = 0.75; - glEnable(GL_TEXTURE_2D); - glColor3f(1.0, 1.0, 1.0); // Use white so texture colors are not modulated - - // Front face - glBindTexture(GL_TEXTURE_2D, faceTextures[0]); - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size, size); - glTexCoord2f(1.0, 0.0); glVertex3f(size, -size, size); - glTexCoord2f(1.0, 1.0); glVertex3f(size, size, size); - glTexCoord2f(0.0, 1.0); glVertex3f(-size, size, size); - glEnd(); - - // Back face - glBindTexture(GL_TEXTURE_2D, faceTextures[1]); - glBegin(GL_QUADS); - glTexCoord2f(1.0, 0.0); glVertex3f(-size, -size, -size); - glTexCoord2f(1.0, 1.0); glVertex3f(-size, size, -size); - glTexCoord2f(0.0, 1.0); glVertex3f(size, size, -size); - glTexCoord2f(0.0, 0.0); glVertex3f(size, -size, -size); - glEnd(); - - // Top face - glBindTexture(GL_TEXTURE_2D, faceTextures[2]); - glBegin(GL_QUADS); - glTexCoord2f(0.0, 1.0); glVertex3f(-size, size, -size); - glTexCoord2f(0.0, 0.0); glVertex3f(-size, size, size); - glTexCoord2f(1.0, 0.0); glVertex3f(size, size, size); - glTexCoord2f(1.0, 1.0); glVertex3f(size, size, -size); - glEnd(); - - // Bottom face - glBindTexture(GL_TEXTURE_2D, faceTextures[3]); - glBegin(GL_QUADS); - glTexCoord2f(1.0, 1.0); glVertex3f(-size, -size, -size); - glTexCoord2f(0.0, 1.0); glVertex3f(size, -size, -size); - glTexCoord2f(0.0, 0.0); glVertex3f(size, -size, size); - glTexCoord2f(1.0, 0.0); glVertex3f(-size, -size, size); - glEnd(); - - // Right face - glBindTexture(GL_TEXTURE_2D, faceTextures[4]); - glBegin(GL_QUADS); - glTexCoord2f(1.0, 0.0); glVertex3f(size, -size, -size); - glTexCoord2f(1.0, 1.0); glVertex3f(size, size, -size); - glTexCoord2f(0.0, 1.0); glVertex3f(size, size, size); - glTexCoord2f(0.0, 0.0); glVertex3f(size, -size, size); - glEnd(); - - // Left face - glBindTexture(GL_TEXTURE_2D, faceTextures[5]); - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size, -size); - glTexCoord2f(1.0, 0.0); glVertex3f(-size, -size, size); - glTexCoord2f(1.0, 1.0); glVertex3f(-size, size, size); - glTexCoord2f(0.0, 1.0); glVertex3f(-size, size, -size); - glEnd(); - - glDisable(GL_TEXTURE_2D); -} - -void ViewportWidget::drawAxes() -{ - glLineWidth(2.0f); - glBegin(GL_LINES); - // X-axis (red) - glColor3f(1.0, 0.0, 0.0); - glVertex3f(0.0, 0.0, 0.0); - glVertex3f(1.5, 0.0, 0.0); - // Y-axis (green) - glColor3f(0.0, 1.0, 0.0); - glVertex3f(0.0, 0.0, 0.0); - glVertex3f(0.0, 1.5, 0.0); - // Z-axis (blue) - glColor3f(0.0, 0.0, 1.0); - glVertex3f(0.0, 0.0, 0.0); - glVertex3f(0.0, 0.0, 1.5); - glEnd(); - glLineWidth(1.0f); -} - void ViewportWidget::drawCube() { glBegin(GL_QUADS); diff --git a/src/ViewportWidget.h b/src/ViewportWidget.h index 015d5fb..a3207ed 100644 --- a/src/ViewportWidget.h +++ b/src/ViewportWidget.h @@ -6,12 +6,15 @@ #include #include +class ViewCube; + class ViewportWidget : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT public: explicit ViewportWidget(QWidget *parent = nullptr); + ~ViewportWidget(); protected: void initializeGL() override; @@ -24,12 +27,9 @@ protected: private: void drawCube(); - void drawViewCube(); - void drawAxes(); - void createFaceTextures(); QMatrix4x4 projection; - GLuint faceTextures[6]; + ViewCube* m_viewCube; float xRot = 0; float yRot = 0;