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:
@@ -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()
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user