class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions {
public:
explicit GLWidget(QWidget* parent = nullptr)
: QOpenGLWidget(parent),
m_scale(1.0),
m_xRot(0),
m_yRot(0),
m_zRot(0),
m_xTrans(0),
m_yTrans(0) {}
~GLWidget() {
if (m_importer) {
m_importer.FreeScene();
}
}
void setXRotation(int angle) {
m_xRot = angle;
update();
}
void setYRotation(int angle) {
m_yRot = angle;
update();
}
void zoomIn() {
m_scale *= 1.1;
update();
}
void zoomOut() {
m_scale /= 1.1;
update();
}
protected:
void initializeGL() override {
initializeOpenGLFunctions();
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glEnable(GL_DEPTH_TEST);
m_importer.ReadFile(“model.stl”,
aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenNormals);
const aiScene* scene = m_importer.GetScene();
if (!scene || !scene->mRootNode) {
qFatal(“Failed to load model”);
return;
}
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
const aiMesh* mesh = scene->mMeshes[i];
for (unsigned int j = 0; j < mesh->mNumFaces; ++j) {
const aiFace& face = mesh->mFaces[j];
for (unsigned int k = 0; k < 3; ++k) {
const aiVector3D& pos = mesh->mVertices[face.mIndices[k]];
const aiVector3D& normal = mesh->mNormals[face.mIndices[k]];
m_vertices.push_back(pos.x);
m_vertices.push_back(pos.y);
m_vertices.push_back(pos.z);
m_normals.push_back(normal.x);
m_normals.push_back(normal.y);
m_normals.push_back(normal.z);
}
}
}
}
void paintGL() override {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)width()/height(), 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(m_xTrans, m_yTrans, -5.0f);
glRotatef(m_xRot, 1.0, 0.0, 0.0);
glRotatef(m_yRot, 0.0, 1.0, 0.0);
glRotatef(m_zRot, 0.0, 0.0, 1.0);
glScalef(m_scale, m_scale, m_scale);
GLfloat mat_ambient[] = { 0.24725, 0.1995, 0.0745, 1.0 };
GLfloat mat_diffuse[] = { 0.75164, 0.60648, 0.22648, 1.0 };
GLfloat mat_specular[] = { 0.628281, 0.555802, 0.366065, 1.0 };
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, 51.2f * 128.0f);
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glBegin(GL_TRIANGLES);
for (size_t i = 0; i < m_vertices.size(); i += 3) {
glNormal3f(m_normals[i], m_normals[i+1], m_normals[i+2]);
glVertex3f(m_vertices[i], m_vertices[i+1], m_vertices[i+2]);
}
glEnd();
}
void mousePressEvent(QMouseEvent* event) override {
m_lastPos = event->pos();
}
void mouseMoveEvent(QMouseEvent* event) override {
int dx = event->x() - m_lastPos.x();
int dy = event->y() - m_lastPos.y();
if (event->buttons() & Qt::LeftButton) {
setXRotation(m_xRot + dy);
setYRotation(m_yRot + dx);
} else if (event->buttons() & Qt::RightButton) {
m_xTrans += dx * 0.01;
m_yTrans -= dy * 0.01;
update();
}
m_lastPos = event->pos();
}
void wheelEvent(QWheelEvent* event) override {
QPoint numDegrees = event->angleDelta() / 8;
if (!numDegrees.isNull()) {
QPoint numSteps = numDegrees / 15;
numSteps.y() > 0 ? zoomIn() : zoomOut();
}
event->accept();
}
private:
float m_scale;
float m_xRot, m_yRot, m_zRot;
float m_xTrans, m_yTrans;
QPoint m_lastPos;
Assimp::Importer m_importer;
std::vector<float> m_vertices;
std::vector<float> m_normals;
};将模型的颜色变为黑色,背景色为白色,再加载另一个模型,一个位于中心点下方,一个位于中心点上方,两者距离200,其中以下方模型的中心点绘制一个绿色的平面,以中心点绘制出x,y,z坐标轴,x,y,z线为红色,操作模型旋转位移时,只有选中的模型旋转位移,未选中的模型保持不动,模型旋转时,以模型中心点进行旋转