三角形渲染
OpenGL正方形渲染与移动
渲染
-
将正方形顶点存储在全局数组
GLfloat vVerts[] = { -blockSize,-blockSize,0.0f, blockSize,-blockSize,0.0f, blockSize,blockSize,0.0f, -blockSize,blockSize,0.0f };
-
初始化
void setupRC() { //设置清屏颜色(背景颜色) glClearColor(0.98f, 0.40f, 0.7f, 1); shaderManager.InitializeStockShaders(); //修改为GL_TRIANGLE_FAN 链接方式,4个顶点 triangleBatch.Begin(GL_TRIANGLE_FAN, 4); triangleBatch.CopyVertexData3f(vVerts); triangleBatch.End(); }
-
重塑函数(glutReshapeFunc回调)
/* 在窗口大小改变时,接收新的宽度&高度。 */ void changeSize(int w,int h) { /* x,y 参数代表窗口中视图的左下角坐标,而宽度、高度是像素为表示,通常x,y 都是为0 */ glViewport(0, 0, w, h); }
-
渲染函数(glutDisplayFunc回调)
void RenderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); GLfloat vRed[] = {1.0,0.0,0.0,1.0f}; //传递到存储着色器,即GLT_SHADER_IDENTITY着色器,这个着色器只是使 用指定颜色以默认笛卡尔坐标第在屏幕上渲染几何图形 shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vRed); //提交着色器 triangleBatch.Draw(); //在开始的设置openGL 窗口的时候,我们指定要一个双缓冲区的渲染环 境。这就意味着将在后台缓冲区进行渲染,渲染结束后交换给前台。这种方式可以防止观察者看到可能伴随着动画帧与动画帧之间的闪烁的渲染过程。缓冲区交换平台将以平台特定的方式进行。 //将后台缓冲区进行渲染,然后结束后交换给前台 glutSwapBuffers(); }
监听键盘函数
GLUT提供了另一个回调函数glutSpecialFunc,监听了特殊按键被调用的函数,例如功能键或方向键。
在Main函数中加入以下代码,注册SpecialKeys回调函数
glutSpecialFunc(SpecialKeys)
-
通过点更新坐标的方式移动正方形,并增加碰撞检测
triangleBatch.CopyVertexData3f(vVerts);
复制顶点数据更新批次位置;glutPostRedisplay();
告知GLUT需要更新内容void SpecialKeys(int key, int x, int y){ GLfloat stepSize = 0.025f; GLfloat blockX = vVerts[0]; GLfloat blockY = vVerts[10]; printf("v[0] = %f\n",blockX); printf("v[10] = %f\n",blockY); if (key == GLUT_KEY_UP) { blockY += stepSize; } if (key == GLUT_KEY_DOWN) { blockY -= stepSize; } if (key == GLUT_KEY_LEFT) { blockX -= stepSize; } if (key == GLUT_KEY_RIGHT) { blockX += stepSize; } //触碰到边界(4个边界)的处理 //当正方形移动超过最左边的时候 if (blockX < -1.0f) { blockX = -1.0f; } //当正方形移动到最右边时 //1.0 - blockSize * 2 = 总边长 - 正方形的边长 = 最左边点的位置 if (blockX > (1.0 - blockSize * 2)) { blockX = 1.0f - blockSize * 2; } //当正方形移动到最下面时 //-1.0 - blockSize * 2 = Y(负轴边界) - 正方形边长 = 最下面点的位置 if (blockY < -1.0f + blockSize * 2 ) { blockY = -1.0f + blockSize * 2; } //当正方形移动到最上面时 if (blockY > 1.0f) { blockY = 1.0f; } printf("blockX = %f\n",blockX); printf("blockY = %f\n",blockY); // Recalculate vertex positions vVerts[0] = blockX; vVerts[1] = blockY - blockSize*2; printf("(%f,%f)\n",vVerts[0],vVerts[1]); vVerts[3] = blockX + blockSize*2; vVerts[4] = blockY - blockSize*2; printf("(%f,%f)\n",vVerts[3],vVerts[4]); vVerts[6] = blockX + blockSize*2; vVerts[7] = blockY; printf("(%f,%f)\n",vVerts[6],vVerts[7]); vVerts[9] = blockX; vVerts[10] = blockY; printf("(%f,%f)\n",vVerts[9],vVerts[10]); triangleBatch.CopyVertexData3f(vVerts); glutPostRedisplay(); }
-
通过矩阵更新坐标的方式移动正方形,并增加碰撞检测
设置矩阵渲染
void RenderScene(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); GLfloat vRed[] = {1.0f,0.0f,0.0f,0.0f}; 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(); }
更新x与y坐标移动
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(); }