#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_AX
没有合适的资源?快使用搜索试试~ 我知道了~
计算机图形学 实验二 三维模型读取与控制
共4个文件
off:2个
cpp:2个
0 下载量 55 浏览量
2024-11-08
12:29:03
上传
评论
收藏 65KB ZIP 举报
温馨提示
1.OFF格式三维模型文件的读取 参考上机实验2.2的内容,完成对OFF格式三维模型文件的读取与显示,可改变物体的显示颜色,尽量特别,但不要太难看。 2.三维模型的旋转动画 参考实验2.1中动画的生成方式,并结合实验2.3中对模型进行旋转变换的过程,生成旋转动画。 3.键盘鼠标的交互 参考实验2.1中鼠标与键盘的交互,通过键盘设定选择绕x、y、z轴进行旋转,通过鼠标左右键控制动画的开始与暂停。 4.模型的修改 参考以下代码,通过键盘设定可以在cow.off和cube.off之间切换。 清除顶点数组缓存: glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 二维向量: std::vector<std::vector<?>> 其他STL相关代码可以查阅C++ STL 教程 | 菜鸟教程 (runoob.com)
资源推荐
资源详情
资源评论
收起资源包目录
实验二 三维模型读取与控制.zip (4个子文件)
main.cpp 13KB
TriMesh.cpp 6KB
Models
cube.off 245B
cow.off 177KB
共 4 条
- 1
资源评论
草海桐
- 粉丝: 541
- 资源: 11
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 2024年新的全的2024年新的全的《建设工程造价鉴定规范》GBT51262-2017
- SimHei字体包(支持中文,正负号等)
- 基于Django+MySQL实现的校园智能点餐系统源码+数据库(高分项目)
- 基于Django实现校园智能点餐系统源码+数据库(高分期末大作业)
- 知识付费pc付费模板系统知识付费付费模板
- ARM Developer Guide
- Lazarus IDE 3.3-Free Pascal Windows版本
- 20190312-180244-旋转磁体产生的场造成激光功率减小
- 个人课程设计基于PCA和滑动窗口的网络入侵检测系统源码+项目说明.zip
- 基于尺度空间流的端到端视频压缩优化方法
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功