AI真强,OBJ/STP/STL 3D模型浏览器
使用glut,编写一个wrl和obj模型文件浏览工具,可以通过鼠标左键进行上下左右旋转3D模型,x键放大y键缩小。有基础的全局环境光照和透视效果。
让这个代码支持stp stl文件
回到最初的代码,让opengl显示出模型棱角的线条
#include <GL/glut.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <cstring>
#include <stdlib.h>
// 模型数据
std::vector<float> vertices;
std::vector<int> indices;
// 旋转角度
float rotateX = 0.0f;
float rotateY = 0.0f;
// 缩放因子
float scaleFactor = 1.0f;
// 鼠标状态
bool mouseLeftDown = false;
int lastMouseX = 0;
int lastMouseY = 0;
// 读取OBJ文件
void loadOBJ(const std::string& filename) {
std::ifstream file(filename.c_str());
if (!file.is_open()) {
std::cerr << "无法打开文件: " << filename << std::endl;
return;
}
std::string line;
while (std::getline(file, line)) {
std::istringstream iss(line);
std::string type;
iss >> type;
if (type == "v") {
float x, y, z;
iss >> x >> y >> z;
vertices.push_back(x);
vertices.push_back(y);
vertices.push_back(z);
} else if (type == "f") {
int v1, v2, v3;
std::string vertex1, vertex2, vertex3;
iss >> vertex1 >> vertex2 >> vertex3;
v1 = atol(vertex1.substr(0, vertex1.find('/')).c_str()) - 1;
v2 = atol(vertex2.substr(0, vertex2.find('/')).c_str()) - 1;
v3 = atol(vertex3.substr(0, vertex3.find('/')).c_str()) - 1;
indices.push_back(v1);
indices.push_back(v2);
indices.push_back(v3);
}
}
file.close();
}
// 读取 ASCII STL 文件
void loadASCIISTL(const std::string& filename) {
std::ifstream file(filename.c_str());
if (!file.is_open()) {
std::cerr << "无法打开文件: " << filename << std::endl;
return;
}
std::string line;
while (std::getline(file, line)) {
std::istringstream iss(line);
std::string type;
iss >> type;
if (type == "vertex") {
float x, y, z;
iss >> x >> y >> z;
vertices.push_back(x);
vertices.push_back(y);
vertices.push_back(z);
indices.push_back(vertices.size() / 3 - 1);
}
}
file.close();
}
// 读取二进制 STL 文件
void loadBinarySTL(const std::string& filename) {
std::ifstream file(filename.c_str(), std::ios::binary);
if (!file.is_open()) {
std::cerr << "无法打开文件: " << filename << std::endl;
return;
}
char header;
file.read(header, 80);
unsigned int numTriangles;
file.read(reinterpret_cast<char*>(&numTriangles), 4);
for (unsigned int i = 0; i < numTriangles; ++i) {
float normal;
file.read(reinterpret_cast<char*>(normal), 12);
for (int j = 0; j < 3; ++j) {
float vertex;
file.read(reinterpret_cast<char*>(vertex), 12);
vertices.push_back(vertex);
vertices.push_back(vertex);
vertices.push_back(vertex);
indices.push_back(vertices.size() / 3 - 1);
}
unsigned short attributeByteCount;
file.read(reinterpret_cast<char*>(&attributeByteCount), 2);
}
file.close();
}
// 自动检测并加载 STL 文件
void loadSTL(const std::string& filename) {
std::ifstream file(filename.c_str());
std::string firstLine;
std::getline(file, firstLine);
file.close();
if (firstLine.find("solid") != std::string::npos) {
loadASCIISTL(filename);
} else {
loadBinarySTL(filename);
}
}
// 初始化OpenGL设置
void init() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
// 启用光照
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// 设置环境光
GLfloat ambientLight[] = {0.2f, 0.2f, 0.2f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
// 设置光源位置
GLfloat lightPosition[] = {1.0f, 1.0f, 1.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
// 设置材质属性
GLfloat materialDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
glMaterialfv(GL_FRONT, GL_DIFFUSE, materialDiffuse);
// 设置多边形渲染模式为线框模式
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
// 显示回调函数
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// 设置相机位置
gluLookAt(0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
// 应用旋转和缩放
glRotatef(rotateX, 1.0f, 0.0f, 0.0f);
glRotatef(rotateY, 0.0f, 1.0f, 0.0f);
glScalef(scaleFactor, scaleFactor, scaleFactor);
// 绘制模型
glBegin(GL_TRIANGLES);
for (size_t i = 0; i < indices.size(); i++) {
int index = indices;
glVertex3f(vertices, vertices, vertices);
}
glEnd();
glutSwapBuffers();
}
// 调整窗口大小回调函数
void reshape(int width, int height) {
if (height == 0) height = 1;
float aspect = (float)width / (float)height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
}
// 鼠标事件回调函数
void mouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON) {
if (state == GLUT_DOWN) {
mouseLeftDown = true;
lastMouseX = x;
lastMouseY = y;
} else {
mouseLeftDown = false;
}
}
}
// 鼠标移动事件回调函数
void motion(int x, int y) {
if (mouseLeftDown) {
int dx = x - lastMouseX;
int dy = y - lastMouseY;
rotateX += dy * 0.5f;
rotateY += dx * 0.5f;
lastMouseX = x;
lastMouseY = y;
glutPostRedisplay();
}
}
// 键盘事件回调函数
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 'x':
scaleFactor *= 1.1f;
glutPostRedisplay();
break;
case 'y':
scaleFactor /= 1.1f;
glutPostRedisplay();
break;
case 27: // ESC键退出
exit(0);
break;
}
}
// 检测文件扩展名并加载相应文件
void loadFile(const std::string& filename) {
size_t dotPos = filename.find_last_of('.');
if (dotPos != std::string::npos) {
std::string extension = filename.substr(dotPos + 1);
if (extension == "obj") {
loadOBJ(filename);
} else if (extension == "stl") {
loadSTL(filename);
} else {
std::cerr << "不支持的文件格式: " << extension << std::endl;
}
} else {
std::cerr << "无法识别文件扩展名" << std::endl;
}
}
int main(int argc, char** argv) {
if (argc < 2) {
std::cerr << "用法: " << argv << " <文件路径>" << std::endl;
return 1;
}
// 加载文件
loadFile(argv);
// 初始化GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("3D模型浏览工具");
// 初始化OpenGL
init();
// 设置回调函数
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);
// 进入主循环
glutMainLoop();
return 0;
} 完整的聊天内容
https://www.doubao.com/thread/wfcf390627b7ee34c 现在AI确实强大,经常让AI作诗作文章来读 无处不AI啊,连怀旧论坛也在AI:lol
页:
[1]