#include<Angel.h>
#include<mat.h>
#include<vector>
#include<string>
#include<fstream>
#include<sstream>
#pragma comment(lib,"glew32.lib")
const double DEFAULT_DELTA = 0.03; //旋转偏移量
int sign = 1; //控制是顺时针旋转还是逆时针旋转,1为顺时针旋转。
//矩阵的存储位置
GLint matrixLocation;
int mainWindow;//
int Xaxis = 0;
int Yaxis = 1;
int Zaxis = 2;
int Axis = Xaxis; //控制是x轴、y轴、z轴旋转。默认是x轴
vec3 Theta(0.0, 0.0, 0.0);
//Num_Vertices为顶点的个数
const int NUM_VERTICES = 8;
const vec4 vertexColors[NUM_VERTICES] = {
vec4(0.0, 0.0, 0.0, 1.0), // Black
vec4(1.0, 0.0, 0.0, 1.0), // Red
vec4(1.0, 1.0, 0.0, 1.0), // Yellow
vec4(0.0, 1.0, 0.0, 1.0), // Green
vec4(0.0, 0.0, 1.0, 1.0), // Blue
vec4(1.0, 0.0, 1.0, 1.0), // Magenta
vec4(1.0, 1.0, 1.0, 1.0), // White
vec4(0.0, 1.0, 1.0, 1.0) // Cyan
};
int nVertices = 0;//顶点数
int nFaces = 0;//面数
int nEdges;//边数
std::vector<vec4> points; //存放每个顶点的信息
std::vector<vec4> colors; //存放每个顶点的颜色信息
std::vector<vec4> vertices; //存放每个顶点的坐标信息
/*
存放每个顶点的坐标和颜色信息
*/
void storePoints(int a, int b, int c)
{
points.push_back(vertices[a]);
points.push_back(vertices[b]);
points.push_back(vertices[c]);
colors.push_back(vertexColors[a]);
colors.push_back(vertexColors[b]);
colors.push_back(vertexColors[c]);
}
/*
读取off文件
*/
void read_off(const std::string filename)
{
if (filename.empty()) {//如果文件为空,则直接返回
return;
}
std::ifstream fin;
int i = 0;
fin.open(filename);
std::string str;
fin >> str; //str的内容为OFF
fin >> nVertices; //顶点数
fin >> nFaces; //面数
fin >> nEdges; //边数
for (i = 0; i < nVertices; i++) //读取off中的点坐标数据,存放在points中
{
double n1 = 0;
double n2 = 0;
double n3 = 0;
double n4 = 0;
fin >> n1; //其坐标值有四个
fin >> n2;
fin >> n3;
fin >> n4;
vec4 new_vec3(n1, n2, n3, n4);
vertices.push_back(new_vec3);
}
for (i = 0; i < nFaces; i++) //读取每个面的信息
{
int n1 = 0;
int n2 = 0; //每行的第一个为顶点数,
int n3 = 0;
int n4 = 0;
fin >> n1;
fin >> n2;
fin >> n3;
fin >> n4;
storePoints(n2, n3, n4);
}
fin.close();
}
void init()
{
read_off("cube.off");
// 创建顶点数组对象
GLuint vao[1];
glGenVertexArrays(1, vao);
glBindVertexArray(vao[0]);
// 创建并初始化顶点缓存对象
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, points.size() * sizeof(vec4) + colors.size() * sizeof(vec4),
NULL, GL_STATIC_DRAW);
// 分别读取数据
glBufferSubData(GL_ARRAY_BUFFER, 0, points.size() * sizeof(vec4), &points[0]);
glBufferSubData(GL_ARRAY_BUFFER, points.size() * sizeof(vec4), colors.size() * sizeof(vec4), &colors[0]);
// 读取着色器并使用
GLuint program = InitShader("vshader.glsl", "fshader.glsl");
glUseProgram(program);
// 从顶点着色器中初始化顶点的位置
GLuint pLocation = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(pLocation);
glVertexAttribPointer(pLocation, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
// 从片元着色器中初始化顶点的颜色
GLuint cLocation = glGetAttribLocation(program, "vColor");
glEnableVertexAttribArray(cLocation);
glVertexAttribPointer(cLocation, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(points.size() * sizeof(vec4)));
// 获得矩阵存储位置
matrixLocation = glGetUniformLocation(program, "matrix");
// 白色背景
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void display()
{
// 清理窗口
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 生成变换矩阵
mat4 m(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
m = m*RotateX(Theta[Xaxis]); //绕x轴旋转
m = m*RotateY(Theta[Yaxis]); //绕y轴旋转
m = m*RotateZ(Theta[Zaxis]); //绕z轴旋转
// 从指定位置中传入变换矩阵
glUniformMatrix4fv(matrixLocation, 1, GL_TRUE, m);
glDrawArrays(GL_TRIANGLES, 0, points.size());
glFlush();
glutSwapBuffers();
}
// 复原Theta和Delta
void reset()
{
Theta = vec3(0.0, 0.0, 0.0);
}
//更新Theta的值
void update()
{
Theta[Axis] += sign * DEFAULT_DELTA; //通过修改些值来生成对应的变化矩阵
glutPostWindowRedisplay(mainWindow); //重新显示窗口
}
void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
switch(button)
{
//sign控制是顺时针旋转还是逆时针旋转,1为顺时针旋转。
case GLUT_LEFT_BUTTON: sign = -1; break;
case GLUT_RIGHT_BUTTON:sign = 1; break;
}
}
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'x':case 'X':
Axis = Xaxis; //x轴旋转
break;
case 'y':case 'Y':
Axis = Yaxis; //y轴旋转
break;
case 'z':case 'Z':
Axis = Zaxis; //z轴旋转
break;
case 'r':case 'R' : //重置,还原为原始图
reset();
break;
case 033: //退出
case 'q':case 'Q':
exit(EXIT_SUCCESS);
break;
}
}
void printhelp()
{
std::cout << "鼠标右键为顺时针,鼠标左键为逆时针\n";
std::cout << "x/X: 沿X轴旋转\n";
std::cout << "y/Y: 沿Y轴旋转\n";
std::cout << "z/Z: 沿Z轴旋转\n";
std::cout << "r/R: 还原为初始图\n";
std::cout << "q/Q/Esc: 退出程序\n";
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); // 窗口支持双重缓冲和深度测试
glutInitWindowPosition(100, 100);
glutInitWindowSize(600, 600);
mainWindow = glutCreateWindow("欧阳炼均-2014150213-实验二");
glewExperimental = GL_TRUE;
glewInit();
init();
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutIdleFunc(update);
// 输出帮助信息
printhelp();
// 启用深度测试
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return 0;
}
Ouyang_Lianjun
- 粉丝: 2337
- 资源: 10
最新资源
- 国际象棋检测9-YOLO(v5至v11)、COCO、CreateML、Paligemma、TFRecord、VOC数据集合集.rar
- 2024年秋学季-C#课程的信息系统大作业winform
- 基于Spring Boot+Vue技术的湖南特产销售网站(编号:17755125).zip
- 基于Spring Boot的企业客源关系管理系统的设计与实现(编号:1778968).zip
- 基于spring boot的实验室开放管理系统_4ty8i0c9_203-wx.zip
- 基于Spring Boot的养老院管理系统的设计与实现_6575f5w2_223-wx(1).zip
- 基于Spring Boot的中药材管理系统(编号:25853136).zip
- 基于Spring Boot框架的网上蛋糕销售系统_30z8r428_231-wx.zip
- ZZU 面向对象Java实验报告
- 用python ollama qwen2.5 开发一个AI修仙游戏 MUD
- 基于Spring Cloud技术的智慧云停车场服务管理系统(编号:28065246).zip
- 基于spring mvc和mybatis的食品商城系统(编号:9025459).zip
- NET综合解决工具,windows平台必备
- 基于Spark的电影推荐系统源码(毕设)
- 明厨亮灶老鼠检测数据集:用于YOLO模型训练的高质量数据集
- 商城蛋糕数据库sql源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
前往页