微信优惠券网站怎么做的,制作短链接网站,成都基金品牌设计,o2o的网站有哪些目录
一、实验内容
二、具体内容
(在实验2.3的基础上进行修改)
1、OFF格式三维模型文件的读取
2、三维模型的旋转动画
3、键盘鼠标的交互
4、模型的修改
三、代码 一、实验内容
读取实验提供的off格式三维模型#xff0c;并对其赋色。利用鼠标和键盘的交互#xff0…目录
一、实验内容
二、具体内容
(在实验2.3的基础上进行修改)
1、OFF格式三维模型文件的读取
2、三维模型的旋转动画
3、键盘鼠标的交互
4、模型的修改
三、代码 一、实验内容
读取实验提供的off格式三维模型并对其赋色。利用鼠标和键盘的交互控制动画效果模型的颜色自己可以自行设置好看就行。 二、具体内容
(在实验2.3的基础上进行修改)
1、OFF格式三维模型文件的读取
参考上机实验2.2的内容完成对OFF格式三维模型文件的读取与显示可改变物体的显示颜色尽量特别但不要太难看。 1修改init()方法读取OFF格式三维模型文件cow.off。 2修改颜色 在readoff()方法中将坐标值([-1,1])映射到颜色值([0,1]) 方法1坐标值加1除2结果和实验给的类似 方法2坐标值取绝对值 应该还不算难看 2、三维模型的旋转动画
参考实验2.1中动画的生成方式并结合实验2.3中对模型进行旋转变换的过程生成旋转动画。
默认绕X轴旋转每1000毫秒转一下rotateDelta角度。
定义相关变量 在mian函数中定义相关操作 3、键盘鼠标的交互
参考实验2.1中鼠标与键盘的交互通过键盘设定选择绕x、y、z轴进行旋转通过鼠标左右键控制动画的开始与暂停。 1通过键盘设定选择绕x、y、z轴进行旋转 在key_callback函数内增加增加如下代码通过按“X”、“Y”、“Z”控制。 2通过鼠标左右键控制动画的开始与暂停 增加mouse_button_callback函数 然后在main函数中绑定。 3修改提示语 4、模型的修改
参考以下代码通过键盘设定可以在cow.off和cube.off之间切换。
清除顶点数组缓存 glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
二维向量
std::vectorstd::vector?
其他STL相关代码可以查阅C STL 教程 | 菜鸟教程 (runoob.com) 1添加变量表示绘制的是牛还是方块 2修改init()函数通过判断currentModel选择读取的文件 3在key_callback函数中添加如下代码 通过按下“N”绘制牛按下“M”绘制方块。 4并修改相关提示语。 效果如下 三、代码
1、main.cpp
#include Angel.h
#include TriMesh.h
#include vector
#include string
//#include main.h
using namespace std;const int X_AXIS 0;
const int Y_AXIS 1;
const int Z_AXIS 2;const int TRANSFORM_SCALE 0;
const int TRANSFORM_ROTATE 1;
const int TRANSFORM_TRANSLATE 2;const double DELTA_DELTA 0.3; // Delta的变化率
const double DEFAULT_DELTA 0.5; // 默认的Delta值double scaleDelta DEFAULT_DELTA;
double rotateDelta DEFAULT_DELTA;
double translateDelta DEFAULT_DELTA;glm::vec3 scaleTheta(1.0, 1.0, 1.0); // 缩放控制变量
glm::vec3 rotateTheta(0.0, 0.0, 0.0); // 旋转控制变量
glm::vec3 translateTheta(0.0, 0.0, 0.0); // 平移控制变量int currentTransform TRANSFORM_ROTATE; // 设置当前变换
int mainWindow;//------------------------------------------------------------------------
bool isplaying true; // 动画状态
int rotationAxis X_AXIS; // 当前旋转轴默认为 X 轴
int rotationTime 1000; // 每1000帧旋转一次string currentModel cow;struct openGLObject
{// 顶点数组对象GLuint vao;// 顶点缓存对象GLuint vbo;// 着色器程序GLuint program;// 着色器文件std::string vshader;std::string fshader;// 着色器变量GLuint pLocation;GLuint cLocation;GLuint matrixLocation;GLuint darkLocation;
};openGLObject cube_object;TriMesh* cube new TriMesh();void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height);
}void bindObjectAndData(TriMesh* mesh, openGLObject object, const std::string vshader, const std::string fshader) {// 创建顶点数组对象glGenVertexArrays(1, object.vao); // 分配1个顶点数组对象glBindVertexArray(object.vao); // 绑定顶点数组对象// 创建并初始化顶点缓存对象glGenBuffers(1, object.vbo);glBindBuffer(GL_ARRAY_BUFFER, object.vbo);glBufferData(GL_ARRAY_BUFFER,mesh-getPoints().size() * sizeof(glm::vec3) mesh-getColors().size() * sizeof(glm::vec3),NULL,GL_STATIC_DRAW);// TODO: Task3-修改完TriMesh.cpp的代码成后再打开下面注释否则程序会报错glBufferSubData(GL_ARRAY_BUFFER, 0, mesh-getPoints().size() * sizeof(glm::vec3), mesh-getPoints()[0]);glBufferSubData(GL_ARRAY_BUFFER, mesh-getPoints().size() * sizeof(glm::vec3), mesh-getColors().size() * sizeof(glm::vec3), mesh-getColors()[0]);object.vshader vshader;object.fshader fshader;object.program InitShader(object.vshader.c_str(), object.fshader.c_str());// 从顶点着色器中初始化顶点的位置object.pLocation glGetAttribLocation(object.program, vPosition);glEnableVertexAttribArray(object.pLocation);glVertexAttribPointer(object.pLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));// 从顶点着色器中初始化顶点的颜色object.cLocation glGetAttribLocation(object.program, vColor);glEnableVertexAttribArray(object.cLocation);glVertexAttribPointer(object.cLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(mesh-getPoints().size() * sizeof(glm::vec3)));// 获得矩阵存储位置object.matrixLocation glGetUniformLocation(object.program, matrix);}void init()
{std::string vshader, fshader;// 读取着色器文件路径vshader shaders/vshader.glsl;fshader shaders/fshader.glsl;//cube-generateCube();//cube-readOff(./Models/cow.off);if (currentModel cow) {cube-readOff(./Models/cow.off);}else {cube-generateCube();}bindObjectAndData(cube, cube_object, vshader, fshader);// 设置背景色为黑色glClearColor(0.0, 0.0, 0.0, 1.0);
}// 渲染函数
void display()
{// 清空颜色缓冲和深度缓冲glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glUseProgram(cube_object.program);glBindVertexArray(cube_object.vao);// 初始化变换矩阵 glm::mat4表示 4x4 矩阵glm::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);// TODO: Task4-在此处修改函数计算最终的变换矩阵// 调用函数传入三种变化的变化量累加得到变化矩阵// 注意三种变化累加的顺序// 构建旋转矩阵glm::mat4 rotationMatrix glm::rotate(glm::mat4(1.0), rotateTheta.x, glm::vec3(1.0, 0.0, 0.0))* glm::rotate(glm::mat4(1.0), rotateTheta.y, glm::vec3(0.0, 1.0, 0.0))* glm::rotate(glm::mat4(1.0), rotateTheta.z, glm::vec3(0.0, 0.0, 1.0));// 构建缩放矩阵glm::mat4 scaleMatrix glm::scale(glm::mat4(1.0), glm::vec3(scaleTheta.x, scaleTheta.y, scaleTheta.z));// 构建平移矩阵glm::mat4 translateMatrix glm::translate(glm::mat4(1.0), glm::vec3(translateTheta.x, translateTheta.y, translateTheta.z));// 按照平移、旋转、缩放的顺序相乘得到最终的变换矩阵m translateMatrix * rotationMatrix * scaleMatrix;// 传递变换矩阵到着色器glUniformMatrix4fv(cube_object.matrixLocation, 1, GL_FALSE, glm::value_ptr(m));// 绘制立方体中的各个三角形glDrawArrays(GL_TRIANGLES, 0, cube-getPoints().size());
}// 通过Delta值更新Theta
// axis 表示坐标轴sign 表示增加或减少
// currentTransform 表示当前变换类型
void updateTheta(int axis, int sign) {switch (currentTransform) {// 根据变换类型增加或减少某种变换的变化量case TRANSFORM_SCALE://增加或减少缩放的 Theta 值scaleTheta[axis] sign * scaleDelta;break;case TRANSFORM_ROTATE://增加或减少旋转的 Theta 值rotateTheta[axis] sign * rotateDelta;break;case TRANSFORM_TRANSLATE://增加或减少平移的 Theta 值translateTheta[axis] sign * translateDelta;break;}
}// 复原Theta和Delta
void resetTheta()
{scaleTheta glm::vec3(1.0, 1.0, 1.0); //scaleTheta 表示缩放变换的角度rotateTheta glm::vec3(0.0, 0.0, 0.0);translateTheta glm::vec3(0.0, 0.0, 0.0);scaleDelta DEFAULT_DELTA; //缩放变换的单位变化量rotateDelta DEFAULT_DELTA;translateDelta DEFAULT_DELTA;
}// 更新变化Delta值
void updateDelta(int sign)
{switch (currentTransform) {// 根据变化类型增加或减少每一次变化的单位变化量case TRANSFORM_SCALE:scaleDelta sign * DELTA_DELTA;break;case TRANSFORM_ROTATE:rotateDelta sign * DELTA_DELTA;break;case TRANSFORM_TRANSLATE:translateDelta sign * DELTA_DELTA;break;}
}void cleanData();// 处理键盘输入的回调函数
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{switch (key){// 退出。case GLFW_KEY_ESCAPE:if (action GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE);break;// 1缩放模式case GLFW_KEY_1:if (action GLFW_PRESS) currentTransform TRANSFORM_SCALE;break;// 2: 旋转模式case GLFW_KEY_2:if (action GLFW_PRESS) currentTransform TRANSFORM_ROTATE;break;// 3: 移动模式case GLFW_KEY_3:if (action GLFW_PRESS) currentTransform TRANSFORM_TRANSLATE;break;// 4: 绘制线。case GLFW_KEY_4:if (action GLFW_PRESS) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);break;// 5: 绘制面。case GLFW_KEY_5:if (action GLFW_PRESS) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);break;// Q: 增加 x。case GLFW_KEY_Q:if (action GLFW_PRESS || action GLFW_REPEAT) updateTheta(X_AXIS, 1);break;// A: 减少 x。case GLFW_KEY_A:if (action GLFW_PRESS || action GLFW_REPEAT) updateTheta(X_AXIS, -1);break;// W: 增加 y。case GLFW_KEY_W:if (action GLFW_PRESS || action GLFW_REPEAT) updateTheta(Y_AXIS, 1);break;// S: 减少 y。case GLFW_KEY_S:if (action GLFW_PRESS || action GLFW_REPEAT) updateTheta(Y_AXIS, -1);break;// E: 增加 z。case GLFW_KEY_E:if (action GLFW_PRESS || action GLFW_REPEAT) updateTheta(Z_AXIS, 1);break;// D: 减少 z。case GLFW_KEY_D:if (action GLFW_PRESS || action GLFW_REPEAT) updateTheta(Z_AXIS, -1);break;// R: 增加变化量。case GLFW_KEY_R:if (action GLFW_PRESS) updateDelta(1);break;// F: 减少变化量。case GLFW_KEY_F:if (action GLFW_PRESS) updateDelta(-1);break;// T: 所有值重置。case GLFW_KEY_T:if (action GLFW_PRESS) resetTheta();break;//-------------------------------------------------------------------// 选择绕 X 轴旋转case GLFW_KEY_X:if (action GLFW_PRESS) rotationAxis X_AXIS;break;// 选择绕 Y 轴旋转case GLFW_KEY_Y:if (action GLFW_PRESS) rotationAxis Y_AXIS;break;// 选择绕 Z 轴旋转case GLFW_KEY_Z:if (action GLFW_PRESS) rotationAxis Z_AXIS;break;// N: 加载cow.off模型case GLFW_KEY_N:if (action GLFW_PRESS) {glBindVertexArray(0);//清除顶点数组缓存glBindBuffer(GL_ARRAY_BUFFER, 0);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);currentModel cow;init();}break;// M: 加载cube模型case GLFW_KEY_M:if (action GLFW_PRESS) {glBindVertexArray(0);//清除顶点数组缓存glBindBuffer(GL_ARRAY_BUFFER, 0);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);currentModel cube;init();}break;}}//-------------------------------------------------------------------------------
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{if (button GLFW_MOUSE_BUTTON_LEFT action GLFW_PRESS) {isplaying true; // 左键按下开始动画}if (button GLFW_MOUSE_BUTTON_RIGHT action GLFW_PRESS) {isplaying false; // 右键按下暂停动画}
}// 输出帮助信息
void printHelp() {printf(%s\n\n, 3D Transfomations);printf(Keyboard options:\n);printf(n: Draw cow\n);printf(m: Draw block\n);printf(left mouse button: start playing\n);printf(right mouse button: Pause playback\n);printf(x: Rotate around the X-axis\n);printf(y: Rotate around the Y-axis\n);printf(z: Rotate around the Z-axis\n);printf(The following are the operations previously used:\n);printf(1: Transform Scale\n);printf(2: Transform Rotate\n);printf(3: Transform Translate\n);printf(q: Increase x\n);printf(a: Decrease x\n);printf(w: Increase y\n);printf(s: Decrease y\n);printf(e: Increase z\n);printf(d: Decrease z\n);printf(r: Increase delta of currently selected transform\n);printf(f: Decrease delta of currently selected transform\n);printf(t: Reset all transformations and deltas\n);
}// 清理数据
void cleanData() {cube-cleanData();// 释放内存delete cube;cube NULL;// 删除绑定的对象glDeleteVertexArrays(1, cube_object.vao);glDeleteBuffers(1, cube_object.vbo);glDeleteProgram(cube_object.program);
}int main(int argc, char** argv)
{// 初始化GLFW库必须是应用程序调用的第一个GLFW函数glfwInit();// 配置GLFWglfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif//设置字符格式#pragma execution_character_set(GBK);GLFWwindow* window glfwCreateWindow(600, 600, homework, NULL, NULL);if (window NULL) {std::cout Failed to create GLFW window std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetKeyCallback(window, key_callback);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// 调用任何OpenGL的函数之前初始化GLADif (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout Failed to initialize GLAD std::endl;return -1;}init();// 输出帮助信息printHelp();// 启用深度测试glEnable(GL_DEPTH_TEST);//------------------------------------------------------------------------glfwSetMouseButtonCallback(window, mouse_button_callback); // 设置鼠标回调int flag clock();while (!glfwWindowShouldClose(window)){display();// 交换颜色缓冲 以及 检查有没有触发什么事件比如键盘输入、鼠标移动等glfwSwapBuffers(window);glfwPollEvents();//--------------------------------------------------------------------------------//处理动画int now clock();if (isplaying) {// 每1000帧旋转一定的角度if ((now - flag) rotationTime) {if (rotationAxis X_AXIS) {rotateTheta.x rotateDelta; // 沿X轴旋转}else if (rotationAxis Y_AXIS) {rotateTheta.y rotateDelta; // 沿Y轴旋转}else if (rotationAxis Z_AXIS) {rotateTheta.z rotateDelta; // 沿Z轴旋转}flag now;}}}cleanData();return 0;
}
2、TriMesh.cpp
#include TriMesh.h// 一些基础颜色
const glm::vec3 basic_colors[8] {glm::vec3(1.0, 1.0, 1.0), // Whiteglm::vec3(1.0, 1.0, 0.0), // Yellowglm::vec3(0.0, 1.0, 0.0), // Greenglm::vec3(0.0, 1.0, 1.0), // Cyanglm::vec3(1.0, 0.0, 1.0), // Magentaglm::vec3(1.0, 0.0, 0.0), // Redglm::vec3(0.0, 0.0, 0.0), // Blackglm::vec3(0.0, 0.0, 1.0) // Blue
};// 立方体的各个点
const glm::vec3 cube_vertices[8] {glm::vec3(-0.5, -0.5, -0.5),glm::vec3(0.5, -0.5, -0.5),glm::vec3(-0.5, 0.5, -0.5),glm::vec3(0.5, 0.5, -0.5),glm::vec3(-0.5, -0.5, 0.5),glm::vec3(0.5, -0.5, 0.5),glm::vec3(-0.5, 0.5, 0.5),glm::vec3(0.5, 0.5, 0.5)
};TriMesh::TriMesh()
{
}TriMesh::~TriMesh()
{
}std::vectorglm::vec3 TriMesh::getVertexPositions()
{return vertex_positions;
}std::vectorglm::vec3 TriMesh::getVertexColors()
{return vertex_colors;
}std::vectorvec3i TriMesh::getFaces()
{return faces;
}std::vectorglm::vec3 TriMesh::getPoints()
{return points;
}std::vectorglm::vec3 TriMesh::getColors()
{return colors;
}void TriMesh::cleanData() {vertex_positions.clear();vertex_colors.clear();faces.clear();points.clear();colors.clear();glBindVertexArray(0);glBindBuffer(GL_ARRAY_BUFFER, 0);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}void TriMesh::storeFacesPoints() {// TODO: Task-2修改此函数在points和colors容器中存储每个三角面片的各个点和颜色信息// 根据每个三角面片的顶点下标存储要传入GPU的数据// 清空points和colors容器 points.clear();colors.clear();// 遍历每个面 for (const auto face : faces) {// 根据索引获取顶点的位置和颜色 unsigned int x face.x;unsigned int y face.y;unsigned int z face.z;glm::vec3 pos1 vertex_positions[x];glm::vec3 col1 vertex_colors[x];glm::vec3 pos2 vertex_positions[y];glm::vec3 col2 vertex_colors[y];glm::vec3 pos3 vertex_positions[z];glm::vec3 col3 vertex_colors[z];// 将顶点位置和颜色添加到points和colors容器中 points.push_back(pos1);colors.push_back(col1);points.push_back(pos2);colors.push_back(col2);points.push_back(pos3);colors.push_back(col3);}}// 立方体生成12个三角形的顶点索引
void TriMesh::generateCube() {// 创建顶点前要先把那些vector清空cleanData();// TODO: Task1-修改此函数存储立方体的各个面信息// vertex_positions和vertex_colors先保存每个顶点的数据for (int i 0; i 8; i) {vertex_positions.push_back(cube_vertices[i]);// 这里简单使用基本颜色数组中的颜色每个顶点按顺序分配颜色 vertex_colors.push_back(basic_colors[i % 8]);}// faces再记录每个面片上顶点的下标// 立方体12个面的顶点索引 // 每个面由两个三角形组成 faces.push_back(vec3i(1, 3, 7)); // 前面 faces.push_back(vec3i(1, 7, 5));faces.push_back(vec3i(0, 2, 6)); // 后面 faces.push_back(vec3i(0, 6, 4));faces.push_back(vec3i(2, 6, 7)); // 右面 faces.push_back(vec3i(2, 7, 3));faces.push_back(vec3i(0, 4, 5)); // 左面 faces.push_back(vec3i(0, 5, 1));faces.push_back(vec3i(4, 5, 7)); // 顶面 faces.push_back(vec3i(4, 7, 6));faces.push_back(vec3i(0, 1, 3)); // 底面 faces.push_back(vec3i(0, 3, 2));storeFacesPoints();
}void TriMesh::readOff(const std::string filename)
{// fin打开文件读取文件信息if (filename.empty()){return;}std::ifstream fin;fin.open(filename);if (!fin){printf(File on error\n);return;}else{printf(File open success\n);cleanData();int nVertices, nFaces, nEdges;// 读取OFF字符串std::string str;fin str;// 读取文件中顶点数、面片数、边数fin nVertices nFaces nEdges;// 根据顶点数循环读取每个顶点坐标for (int i 0; i nVertices; i){glm::vec3 tmp_node;fin tmp_node.x tmp_node.y tmp_node.z;vertex_positions.push_back(tmp_node);//vertex_colors.push_back(tmp_node);// 将坐标值([-1,1])映射到颜色值([0,1])/*//方法1加1除2结果和实验给的一样glm::vec3 color (tmp_node glm::vec3(1.0f)) * 0.5f;*///方法2取坐标绝对值float a tmp_node.x0? tmp_node.x:-tmp_node.x;float b tmp_node.y0? tmp_node.y:-tmp_node.y;float g tmp_node.z0? tmp_node.z:-tmp_node.z;glm::vec3 color(a,b,g);vertex_colors.push_back(color);}// 根据面片数循环读取每个面片信息并用构建的vec3i结构体保存for (int i 0; i nFaces; i){int num, a, b, c;// num记录此面片由几个顶点构成a、b、c为构成该面片顶点序号fin num a b c;faces.push_back(vec3i(a, b, c));}}fin.close();storeFacesPoints();
};