案例:用OpenGL实现 通过上下左右键移动屏幕中的小方块
1.OpenGL 环境配置
2.执行流程
2.1
函数思维导图.png
3.案例代码
3.1引入头文件
//着色管理器类
#include "GLShaderManager.h"
//包含大部分GLTool中类似C语言的独立函数
#include "GLTools.h"
//GLUT
#include <GLUT/GLUT.h>
3.2准备工作
// 定义一个,着色管理器
GLShaderManager shaderManager;
// 简单的批次容器,是GLTools的一个简单的容器类
GLBatch triangleBatch;
// blockSize 边长
GLfloat blockSize = 0.1f;
// 正方形的4个坐标
GLfloat vVerts[] = {
-blockSize, blockSize, 0.0f, // 左上
blockSize, blockSize, 0.0f, // 右上
blockSize, -blockSize, 0.0f, // 右下
-blockSize, -blockSize, 0.0f // 左下
};
// x 方向的位移量
GLfloat xPos = 0.0f;
// y 方向的位移量
GLfloat yPos = 0.0f;
3.3main函数
int main(int argc, char *argv[])
{
// 设置当前工作目录
gltSetWorkingDirectory(argv[0]);
// 初始化 GLUT库
glutInit(&argc, argv);
// 初始化缓冲窗口
//其中标志GLUT_DOUBLE(双缓冲窗口)、GLUT_RGBA(RGBA颜色模式)、GLUT_DEPTH(深度测试)、GLUT_STENCIL(模板缓冲区)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
// GLUT窗口大小
glutInitWindowSize(500, 500);
// GLUT 标题
glutCreateWindow("Triangle");
// GLUT 内部运行一个本地消息循环,拦截适当的消息。然后调用我们不同时间注册的回调函数
// 注册窗口改变大小的回调函数
glutReshapeFunc(changeSize);
// 注册OpenGL渲染的回调函数
glutDisplayFunc(RenderScene);
// 注册特殊键位响应函数。(当用户使用特殊键位则会调用该函数)
glutSpecialFunc(SpecialKeys);
// 初始化一个 GLEW 库,确保 Opengl API 对程序完全可用
GLenum status = glewInit();
if (GLEW_OK != status) {
printf("GLEW Error:%s\n", glewGetErrorString(status));
return 1;
}
// 设置数据
setupRc();
//类似于iOS runloop 运行循环
glutMainLoop();
return 0;
}
3.4setupRC函数
/*
触发条件:
1.手动 main 函数触发
处理业务:
1.设置窗口背景颜色
2.初始化存储着色器 shaderManager
3.设置图形顶点数据
4.利用GLBatch 三角形批次类,将数据传递到着色器
*/
void setupRc()
{
//设置清屏颜色
glClearColor(0.9f, 0.0f, 0.0f, 1);
//初始化着色器
shaderManager.InitializeStockShaders();
//指定顶点
triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
triangleBatch.CopyVertexData3f(vVerts);
triangleBatch.End();
}
3.5changeSize函数
// 在窗口大小改变时,接收新的宽&高
/*
触发条件:
1.新建窗口
2.窗口尺寸发生调整
处理业务 :
1设置OpenGL 视口
2设置OpenGL 投影方式
*/
void changeSize(int w, int h)
{
glViewport(0, 0, w, h);
}
3.6RenderScene函数
/*
触发条件:
1.系统自动触发
2.开发者手动调用函数触发。
处理业务:
1.清理缓存区(颜色,深度,模板缓存区等)
2.使用存储着色器
3.绘制图形
*/
void RenderScene(void)
{
// 清除一个或者一组特定的缓存区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// 设置颜色RGBA
GLfloat VRed[] = {0.0f, 0.7f, 0.0f, 0.0f};
// 自定义矩阵
M3DMatrix44f mTransformMatrix, mRotationMartix;
// 平移
m3dTranslationMatrix44(mTransformMatrix, xPos, yPos, 0.0f);
//将矩阵结果 提交给固定着色器(平面着色器)中绘制
// 参数1 :存储着色器类型
// 参数2 :使用什么矩阵变换
// 参数3 :颜色
shaderManager.UseStockShader(GLT_SHADER_FLAT, mTransformMatrix, VRed);
// 提交着色器
triangleBatch.Draw();
// 执行交换缓冲区
glutSwapBuffers();
}
3.7SpecialKeys函数
// 特殊键位
void SpecialKeys (int key, int x, int y)
{
// 移动步长
GLfloat stepSize = 0.025f;
if (key == GLUT_KEY_UP) yPos += stepSize;
if (key == GLUT_KEY_DOWN) yPos -= stepSize;
if (key == GLUT_KEY_LEFT) xPos -= stepSize;
if (key == GLUT_KEY_RIGHT) xPos += stepSize;
printf("xPos = %lf, yPos = %lf\n", xPos, yPos);
// 碰撞检测
if (xPos < (-1.0 + blockSize)) xPos = -1.0 + blockSize;
if (xPos > 1.0 - blockSize) xPos = 1.0 - blockSize;
if (yPos < (-1.0 + blockSize)) yPos = -1.0 + blockSize;
if (yPos > (1.0 - blockSize)) yPos = 1.0 - blockSize;
printf("碰撞检测后:xPos = %lf, yPos = %lf\n", xPos, yPos);
glutPostRedisplay();
}
网友评论