实现方式主要两种:坐标更新方式、矩阵方式
坐标更新方式
1.设置自定义窗口大小
//窗口大小改变时接受新的宽度和高度,其中0,0代表窗口中视口的左下角坐标,w,h代表像素
void ChangeSize(int w,int h)
{
glViewport(0,0, w, h);
}
2.定义图形颜色并交给存储着色器进行渲染
void RenderScene(void){
//清除一个或一组特定的缓冲区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//设置一组浮点数k来表示红色
GLfloatvRed[] = {1.0f,0.0f,0.0f,1.0f};
//传递到存储着色器,即GLT_SHADER_INENTITY着色器,这个着色器只是使用指定颜色以默认笛卡尔坐标第在屏幕上渲染几何图形
shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vRed);
//提交着色器
triangleBatch.Draw();
//将在后台缓冲区进行渲染,然后在结束时交换到前台 glutSwapBuffers();
}
3.进行一系列的准备工作
void SetupRC(){
//设置背景颜色
glClearColor(0.98f, 0.40f, 0.7f, 1.0f);
//初始化着色管理器
shaderManager.InitializeStockShaders();
//批次处理
triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
triangleBatch.CopyVertexData3f(vVerts);
triangleBatch.End();
}
4.计算出每个坐标移动值并进行更新
void SpecialKeys(int key,int x,int y){
GLfloat stepSize =0.025f;
GLfloat blockX=vVerts[0];
GLfloat blockY=vVerts[10];
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;
}
//触碰到四个边界的处理
//最左边
if(blockX < -1.0f) {
blockX = -1.0f;
}
//最右边
if(blockX > (1.0-blockSize*2)) {
blockX =1.0F-blockSize*2;
}
//最下面
if(blockY < -1.0f+blockSize*2) {
blockY = -1.0f+blockSize*2;
}
//最上面
if(blockY >1.0f) {
blockY =1.0f;
}
vVerts[0] = blockX;
vVerts[1] = blockY -blockSize*2;
vVerts[3] = blockX +blockSize*2;
vVerts[4] = blockY -blockSize*2;
vVerts[6] = blockX +blockSize*2;
vVerts[7] = blockY;
vVerts[9] = blockX;
vVerts[10] = blockY;
triangleBatch.CopyVertexData3f(vVerts);
glutPostRedisplay();
}
这种方式有个弊端就是要是有100个顶点或者更多顶点的话,每次去计算的话,实现起来会非常复杂,而且效率会非常的低
矩阵方式
1.改变窗口大小
同上
2.通过矩阵方式将矩阵结果提交给平面着色器(固定着色器)进行渲染
void RenderScene(void){
//清除一个或一组特定的缓冲区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//设置一组浮点数k来表示红色
GLfloatvRed[] = {1.0f,0.0f,0.0f,1.0f};
//通过矩阵方式进行渲染
M3DMatrix44fmTransfromMatrix;
//平移
m3dTranslationMatrix44(mTransfromMatrix, xPos, yPos, 0.0f);
//将矩阵结果 提交给固定着色器(平面着色器)中绘制 shaderManager.UseStockShader(GLT_SHADER_FLAT,mTransfromMatrix,vRed);
triangleBatch.Draw();
//将在后台缓冲区进行渲染,然后在结束时交换到前台
glutSwapBuffers();
}
3.准备工作
同上
4.通过矩阵方式计算出步长以及边界处理
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();
}
这种方式实现起来就比较简单,完整实现见github地址
网友评论