持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
之前的 OpenGL 环境搭建 - MacOS 文章中,我们完成了OpenGL的环境搭建和测试用的绘制一个正方形。今天我们接着来做一个能够随我们控制移动的多边形。 好的,话不多说,直接开始今天的内容吧:
方法一: 我们通过注册键盘按键的回调,来计算出四个顶点的移动,然后来绘制出移动后的正方形
1 main函数中注册键盘回调
// 注册键盘函数
glutSpecialFunc(KeyboardCallback);
复制代码
2 处理按键回调 (计算四个顶点移动后的位置,做边界控制,)
// 移动距离
GLfloat moveDistance = 0.13f;
// 键盘按键回调
void KeyboardCallback( int key, int x, int y ) {
// 1、计算各个顶点坐标
GLfloat blockX_A = coordinatePoints[0];
GLfloat blockY_A = coordinatePoints[1];
GLfloat blockX_B = coordinatePoints[3];
GLfloat blockY_B = coordinatePoints[4];
GLfloat blockX_C = coordinatePoints[6];
GLfloat blockY_C = coordinatePoints[7];
GLfloat blockX_D = coordinatePoints[9];
GLfloat blockY_D = coordinatePoints[10];
// 计算移动后的数据
if (key == GLUT_KEY_UP) {
if (blockY_C >= 1.f) {// 边界控制
blockY_A = 1.f-sideLength*2;
blockY_B = 1.f-sideLength*2;
blockY_C = 1.f;
blockY_D = 1.f;
}else {
blockY_A += moveDistance;
blockY_B += moveDistance;
blockY_C += moveDistance;
blockY_D += moveDistance;
}
}
if (key == GLUT_KEY_DOWN) {
if (blockY_A <= -1.f) {// 边界控制
blockY_A = -1.f;
blockY_B = -1.f+sideLength*2;
blockY_C = -1.f+sideLength*2;
blockY_D = -1.f;
}else {
blockY_A -= moveDistance;
blockY_B -= moveDistance;
blockY_C -= moveDistance;
blockY_D -= moveDistance;
}
}
if (key == GLUT_KEY_LEFT) {
if (blockX_A <= -1.f) {// 边界控制
blockX_A = -1.f;
blockX_B = -1.f+sideLength*2;
blockX_C = -1.f+sideLength*2;
blockX_D = -1.f;
}else {
blockX_A -= moveDistance;
blockX_B -= moveDistance;
blockX_C -= moveDistance;
blockX_D -= moveDistance;
}
}
if (key == GLUT_KEY_RIGHT) {
if (blockX_C >= 1.f) {// 边界控制
blockX_A = 1.f-sideLength*2;
blockX_B = 1.f;
blockX_C = 1.f;
blockX_D = 1.f-sideLength*2;
}else {
blockX_A += moveDistance;
blockX_B += moveDistance;
blockX_C += moveDistance;
blockX_D += moveDistance;
}
}
coordinatePoints[0] = blockX_A;
coordinatePoints[1] = blockY_A;
coordinatePoints[3] = blockX_B;
coordinatePoints[4] = blockY_B;
coordinatePoints[6] = blockX_C;
coordinatePoints[7] = blockY_C;
coordinatePoints[9] = blockX_D;
coordinatePoints[10] = blockY_D;
triangleBatch.CopyVertexData3f(coordinatePoints);
glutPostRedisplay();
}
复制代码
方法二:使用 平面着色器绘制
1 定义x坐标和y坐标移动的距离
GLfloat xMove = 0.f;//x坐标移动距离
GLfloat yMove = 0.f;//y坐标移动距离
复制代码
2 键盘按键回调的函数中处理 x、y坐标移动的距离;并提交渲染
// 键盘按键回调
void KeyboardCallback( int key, int x, int y ) {
// 计算移动后的数据
if (key == GLUT_KEY_UP) {
yMove += moveDistance;
}
if (key == GLUT_KEY_DOWN) {
yMove -= moveDistance;
}
if (key == GLUT_KEY_LEFT) {
xMove -= moveDistance;
}
if (key == GLUT_KEY_RIGHT) {
xMove += moveDistance;
}
// 碰撞检测
if (xMove < -1.f+sideLength) {
xMove = -1.f+sideLength;
}
if (xMove > 1.f-sideLength) {
xMove = 1.f-sideLength;
}
if (yMove<-1.f+sideLength) {
yMove = -1.f+sideLength;
}
if (yMove>1.f-sideLength) {
yMove = 1.f-sideLength;
}
//提交渲染 之后会执行 RenderScene 方法
glutPostRedisplay();
}
复制代码
3 开始渲染
//开始渲染
void RenderScene(void) {
//清除一个或一组特定的缓冲区
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
GLfloat red[] = {1.0f,0.0f,0.0f,0.0f};
// 矩阵
M3DMatrix44f mTransformMatrix;
// 平移矩阵,结果存储在 mTransformMatrix 中;
m3dTranslationMatrix44(mTransformMatrix, xMove, yMove, 0.f);
//平面着色器(固定着色器)
shaderManager.UseStockShader(GLT_SHADER_FLAT, mTransformMatrix,red);
//提交着色器 绘制
triangleBatch.Draw();
//将在后台缓冲区进行渲染,然后在结束时交换到前台
glutSwapBuffers();
}
复制代码
总结一下方法二,我们不用去计算每一个坐标点的位置:
通过定义 M3DMatrix44f
使用 m3dTranslationMatrix44 方法来讲移动后的结果保存到 M3DMatrix44f 中
接着提交渲染绘制就完成了
效果如下: