feat: Render view cube labels as OpenGL textures

Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
2026-02-09 16:01:00 -07:00
parent 6198236db3
commit be35ae3196
2 changed files with 71 additions and 61 deletions

View File

@@ -16,6 +16,7 @@ void ViewportWidget::initializeGL()
initializeOpenGLFunctions(); initializeOpenGLFunctions();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
createFaceTextures();
} }
void ViewportWidget::paintGL() void ViewportWidget::paintGL()
@@ -61,40 +62,6 @@ void ViewportWidget::paintGL()
drawAxes(); drawAxes();
glViewport(0, 0, width(), height()); glViewport(0, 0, width(), height());
// Text rendering with QPainter
QPainter painter(this);
painter.setPen(Qt::white);
painter.setFont(QFont("Arial", 10));
struct Face {
QString name;
QVector3D center;
QVector3D normal;
};
QVector<Face> faces = {
{"FRONT", {0, 0, 1.0}, {0, 0, 1}},
{"BACK", {0, 0, -1.0}, {0, 0, -1}},
{"TOP", {0, 1.0, 0}, {0, 1, 0}},
{"BOTTOM",{0, -1.0, 0}, {0, -1, 0}},
{"RIGHT", {1.0, 0, 0}, {1, 0, 0}},
{"LEFT", {-1.0, 0, 0}, {-1, 0, 0}}
};
for (const auto& face : faces) {
QVector3D transformedNormal = viewCubeModel.mapVector(face.normal);
// Use a small epsilon for floating point comparison
if (transformedNormal.z() > 0.1) { // Simple back-face culling
QRect viewportRect(width() - viewCubeSize, 0, viewCubeSize, viewCubeSize);
QVector3D pos2D = face.center.project(viewCubeModel, viewCubeProjection, viewportRect);
QFontMetrics metrics(painter.font());
int textWidth = metrics.horizontalAdvance(face.name);
int textHeight = metrics.height();
QRect textRect(pos2D.x() - textWidth / 2, pos2D.y() - textHeight / 2, textWidth, textHeight);
painter.drawText(textRect, Qt::AlignCenter, face.name);
}
}
} }
void ViewportWidget::resizeGL(int w, int h) void ViewportWidget::resizeGL(int w, int h)
@@ -137,49 +104,90 @@ void ViewportWidget::wheelEvent(QWheelEvent *event)
update(); 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() void ViewportWidget::drawViewCube()
{ {
float size = 0.75; float size = 0.75;
glBegin(GL_QUADS); glEnable(GL_TEXTURE_2D);
// All faces are light gray glColor3f(1.0, 1.0, 1.0); // Use white so texture colors are not modulated
glColor3f(0.8, 0.8, 0.8);
// Front face // Front face
glVertex3f(-size, -size, size); glBindTexture(GL_TEXTURE_2D, faceTextures[0]);
glVertex3f(size, -size, size); glBegin(GL_QUADS);
glVertex3f(size, size, size); glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size, size);
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 // Back face
glVertex3f(-size, -size, -size); glBindTexture(GL_TEXTURE_2D, faceTextures[1]);
glVertex3f(-size, size, -size); glBegin(GL_QUADS);
glVertex3f(size, size, -size); glTexCoord2f(1.0, 0.0); glVertex3f(-size, -size, -size);
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 // Top face
glVertex3f(-size, size, -size); glBindTexture(GL_TEXTURE_2D, faceTextures[2]);
glVertex3f(-size, size, size); glBegin(GL_QUADS);
glVertex3f(size, size, size); glTexCoord2f(0.0, 1.0); glVertex3f(-size, size, -size);
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 // Bottom face
glVertex3f(-size, -size, -size); glBindTexture(GL_TEXTURE_2D, faceTextures[3]);
glVertex3f(size, -size, -size); glBegin(GL_QUADS);
glVertex3f(size, -size, size); glTexCoord2f(1.0, 1.0); glVertex3f(-size, -size, -size);
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 // Right face
glVertex3f(size, -size, -size); glBindTexture(GL_TEXTURE_2D, faceTextures[4]);
glVertex3f(size, size, -size); glBegin(GL_QUADS);
glVertex3f(size, size, size); glTexCoord2f(1.0, 0.0); glVertex3f(size, -size, -size);
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 // Left face
glVertex3f(-size, -size, -size); glBindTexture(GL_TEXTURE_2D, faceTextures[5]);
glVertex3f(-size, -size, size); glBegin(GL_QUADS);
glVertex3f(-size, size, size); glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size, -size);
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(); glEnd();
glDisable(GL_TEXTURE_2D);
} }
void ViewportWidget::drawAxes() void ViewportWidget::drawAxes()

View File

@@ -26,8 +26,10 @@ private:
void drawCube(); void drawCube();
void drawViewCube(); void drawViewCube();
void drawAxes(); void drawAxes();
void createFaceTextures();
QMatrix4x4 projection; QMatrix4x4 projection;
GLuint faceTextures[6];
float xRot = 0; float xRot = 0;
float yRot = 0; float yRot = 0;