以下是一个使用 C++ 和 OpenGL 实现鼠标拾取三角网格的简单代码示例
以下是一个使用 C++ 和 OpenGL 实现鼠标拾取三角网格的简单代码示例:
#include <GL/glut.h>
#include <iostream>
#include <vector>
// 存储三角网格的顶点信息
struct Triangle {
GLfloat vertices[9];
};
// 存储三角网格的列表
std::vector<Triangle> triangles;
// 初始化 OpenGL 环境和三角网格数据
void init() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, 1.0, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// 创建一些简单的三角网格数据(这里只是示例,你可以根据实际情况读取或生成更复杂的三角网格)
Triangle t1 = {
{0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f}
};
Triangle t2 = {
{1.0f, 1.0f, 0.0f,
1.5f, 0.0f, 0.0f,
0.5f, 0.0f, 0.0f}
};
triangles.push_back(t1);
triangles.push_back(t2);
}
// 绘制三角网格
void drawTriangles() {
glBegin(GL_TRIANGLES);
for (const auto &triangle : triangles) {
for (int i = 0; i < 9; i += 3) {
glVertex3f(triangle.vertices[i], triangle.vertices[i + 1], triangle.vertices[i + 2]);
}
}
glEnd();
}
// 鼠标点击事件处理函数
void mouseClick(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
// 进入选择模式
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
GLuint selectBuffer[512];
glSelectBuffer(512, selectBuffer);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
// 保存当前的投影矩阵和模型视图矩阵
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix(x, viewport[3] - y, 5, 5, viewport);
gluPerspective(45.0, (GLfloat) viewport[2] / viewport[3], 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// 重新绘制场景用于选择
drawTriangles();
// 恢复原来的矩阵模式
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
// 返回渲染模式
GLint numHits = glRenderMode(GL_RENDER);
if (numHits > 0) {
GLuint *ptr = selectBuffer;
for (int i = 0; i < numHits; ++i) {
int names = *ptr++;
int minZ = *ptr++;
int maxZ = *ptr++;
// 这里可以根据你的需求处理每个选中的物体
std::cout << "Hit " << i + 1 << ", " << names << " objects were picked." << std::endl;
}
}
}
}
// 显示函数,用于绘制场景
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// 绘制三角网格
drawTriangles();
glutSwapBuffers();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("Triangle Picking Example");
init();
glutMouseFunc(mouseClick);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
在上述代码中:
init
函数用于初始化 OpenGL 环境,设置背景颜色、投影矩阵和模型视图矩阵等。同时创建了一些简单的三角网格数据用于测试。drawTriangles
函数用于绘制所有的三角网格。mouseClick
函数是鼠标点击事件的处理函数。当鼠标左键按下时,进入选择模式,设置选择缓冲区,保存当前的投影矩阵和模型视图矩阵,然后重新绘制场景用于选择。最后,根据选择缓冲区中的信息确定选中的物体。display
函数用于在正常渲染模式下绘制场景,包括三角网格。
请注意,这只是一个简单的示例,在实际应用中,你可能需要根据具体的需求对代码进行进一步的扩展和优化,例如处理更复杂的场景、更精确的选择等。同时,确保你的 OpenGL 环境已经正确配置并且支持相关的功能。