准备工作:
需要用到资源 CLTools, glew, libGLTools.a。获取这三个资源可以查看我的上一篇文章。链接[https://www.jianshu.com/p/4026a8ef0f32�].
具体实现步骤:
- 程序的入口是
main()
函数,我们在main函数里先要初始化GLUT
库,设置双缓冲窗口和窗口的大小,并且要注册2个回调函数ChangeSize()
,RenderScene()
, 注册特殊函数SpecialKeys()
,来保证我们的图形能旋转并且移动(我们以正方形为例)。glutMainLoop()
函数是循环调用,相当于RunLoop。
int main(int argc,char* argv[]) {
//设置当前工作目录,针对MAC OS X
gltSetWorkingDirectory(argv[0]);
//初始化GLUT库
glutInit(&argc, argv);
/*初始化双缓冲窗口,其中标志GLUT_DOUBLE、GLUT_RGBA、GLUT_DEPTH、GLUT_STENCIL分别指双缓冲窗口、RGBA颜色模式、深度测试、模板缓冲区*/
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
//GLUT窗口大小,标题窗口
glutInitWindowSize(500,500);
glutCreateWindow("Triangle");
//注册回调函数
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
//注册特殊函数
glutSpecialFunc(SpecialKeys);
//驱动程序的初始化中没有出现任何问题。
GLenum err = glewInit();
if(GLEW_OK != err) {
fprintf(stderr,"glew error:%s\n",glewGetErrorString(err));
return 1;
}
//设置我们的渲染环境
SetupRC();
//循环调用,相当于RunLoop
glutMainLoop();
return 0;
}
- 定义全局变量,正方形的边长
blockSize
以及4个顶点坐标,定义中心点坐标(xPos, yPos)
为原点进行移动
//blockSize 边长
GLfloat blockSize = 0.1f;
//正方形的4个点坐标,a,b,c,d四个顶点,每个顶点有x,y,z轴
GLfloat vVerts[] = {
-blockSize,-blockSize,0.0f,
blockSize,-blockSize,0.0f,
blockSize,blockSize,0.0f,
-blockSize,blockSize,0.0f
};
//中心点x, y开始的坐标
GLfloat xPos = 0.0f;
GLfloat yPos = 0.0f;
-
SetupRC()
为程序做一次性设置,该方法就只调用一次,设置一些必要条件
void SetupRC() {
//设置背景颜色
glClearColor(0.0f,0.0f,1.0f,1.0f);
//初始化着色管理器
shaderManager.InitializeStockShaders();
//修改为GL_TRIANGLE_FAN ,顶点收尾相连,4个顶点(正方形)
/*
GL_LINES, GL_LINE_LOOP, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, GL_POLYGON , 这几个枚举值是设置顶点的连接方式,自己可以每个都试一下。
*/
triangleBatch.Begin(GL_TRIANGLE_FAN,4);
triangleBatch.CopyVertexData3f(vVerts);
triangleBatch.End();
}
-
changeSize()
函数是设置窗口的大小,实时接收新的宽高。
void changeSize(int w,int h) {
/*
x,y 参数代表窗口中视图的左下角坐标,而宽度、高度是像素为表示,通常x,y 都是为0
*/
glViewport(0, 0, w, h);
}
-
RenderScene()
是设置显示在屏幕上的函数,用到了4x4的矩阵M3DMatrix44f
方法来进行设置
void RenderScene() {
//1.清除一个或者一组特定的缓存区
/*
缓冲区是一块存在图像信息的储存空间,红色、绿色、蓝色和alpha分量通常一起分量通常一起作为颜色缓存区或像素缓存区引用。
OpenGL 中不止一种缓冲区(颜色缓存区、深度缓存区和模板缓存区)
清除缓存区对数值进行预置
参数:指定将要清除的缓存的
GL_COLOR_BUFFER_BIT :指示当前激活的用来进行颜色写入缓冲区
GL_DEPTH_BUFFER_BIT :指示深度缓存区
GL_STENCIL_BUFFER_BIT:指示模板缓冲区
*/
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
//2.设置一组浮点数来表示红色
GLfloat vRed[] = {1.0f,0.0f,0.0f,0.0f};
//定义一个4x4的矩阵
M3DMatrix44f mFinalTransform,mTransfromMatrix,mRotationMartix;
//调用平移方法
m3dTranslationMatrix44(mTransfromMatrix, xPos, yPos, 0.0f);
//每次平移时,旋转5度
static float yRot = 0.0f;
yRot += 5.0f;
//调用旋转方法
m3dRotationMatrix44(mRotationMartix, m3dDegToRad(yRot), 0.0f, 0.0f, 1.0f);
//将旋转和移动的矩阵结果 合并到mFinalTransform (矩阵相乘)
m3dMatrixMultiply44(mFinalTransform, mTransfromMatrix, mRotationMartix);
//将矩阵结果 提交给固定着色器(平面着色器)中绘制
shaderManager.UseStockShader(GLT_SHADER_FLAT,mFinalTransform,vRed);
//提交着色器
triangleBatch.Draw();
//执行交换缓存区
glutSwapBuffers();
}
-
SpecialKeys()
函数实时计算正方形根据键盘上下左右移动的距离,并且要进行碰撞检测(正方形移动到窗口边缘后不能移出窗口的检测)
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;
}
//碰撞检测
//移动到最左边
if (xPos < (-1.0f + blockSize)) {
xPos = -1.0f + blockSize;
}
//移动到最右边
if (xPos > (1.0f - blockSize)) {
xPos = 1.0f - blockSize;
}
//移动到最下面
if (yPos < (-1.0f + blockSize)) {
yPos = -1.0f + blockSize;
}
//移动到最上面
if (yPos > (1.0f - blockSize)) {
yPos = 1.0f - blockSize;
}
//重新绘制
glutPostRedisplay();
}
-
至此已经完成了用OpenGL实现了一个正方形移动并且旋转的小Demo。