#include <freeglutGL/freeglut.h> ///*cube pos value*/ GLfloat rfCubeX = 0.0f; GLfloat rfCubeY = 0.0f; GLfloat rfCubeSize = 25.0f; GLfloat rfCubeXStep = 1.0f; GLfloat rfCubeYStep = 1.0f; ///*clip volume size*/ GLfloat rfClipVolumeHalfWidth = 0.0f; GLfloat rfClipVolumeHalfHeight = 0.0f; void fRenderScene(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f,0.0f,0.0f); glRectf(rfCubeX,rfCubeY,rfCubeX+rfCubeSize,rfCubeY-rfCubeSize); //glFlush(); glutSwapBuffers(); } void fReshapeScene(GLsizei w,GLsizei h) { GLfloat rfAspectRatio; if(!h) { h = 1; } rfAspectRatio = (GLfloat)w/(GLfloat)h; glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w <= h) { rfClipVolumeHalfWidth = 100.0f; rfClipVolumeHalfHeight = rfClipVolumeHalfWidth/rfAspectRatio; glOrtho(-100.0f,100.0f,-rfClipVolumeHalfHeight,rfClipVolumeHalfHeight,0.000000001f,0.0f); } else { rfClipVolumeHalfHeight = 100.0f; rfClipVolumeHalfWidth = rfClipVolumeHalfHeight*rfAspectRatio; glOrtho(-rfClipVolumeHalfWidth,rfClipVolumeHalfWidth,-100.0f,100.0f,0.00000001f,0.0f); } //glOrtho(-100.0f,100.0f,-100.0f/rfAspectRatio,100.0f/rfAspectRatio,1.0f,-1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void fSetupRC(void) { glClearColor(0.0f,1.0f,0.0f,1.0f); } void fTimerFunction(int iValue) { ///*turn*/ if(rfCubeX<=-rfClipVolumeHalfWidth||rfCubeX>=rfClipVolumeHalfWidth-rfCubeSize) { rfCubeXStep = -rfCubeXStep; } if(rfCubeY<=-rfClipVolumeHalfHeight+rfCubeSize||rfCubeY>=rfClipVolumeHalfHeight) { rfCubeYStep = -rfCubeYStep; } rfCubeX += rfCubeXStep; rfCubeY += rfCubeYStep; ///*horizontal overflow*/ if(rfCubeX<-rfClipVolumeHalfWidth) { rfCubeX = -rfClipVolumeHalfWidth; } else if( rfCubeX>(rfClipVolumeHalfWidth-rfCubeSize)) { rfCubeX = rfClipVolumeHalfWidth-rfCubeSize; } ///*vertical overflow*/ if(rfCubeY>rfClipVolumeHalfHeight) { rfCubeY = rfClipVolumeHalfHeight; } else if( rfCubeY<(-rfClipVolumeHalfHeight+rfCubeSize) ) { rfCubeY = -rfClipVolumeHalfHeight+rfCubeSize; } glutPostRedisplay(); glutTimerFunc(20,fTimerFunction,1); } int main(int argc,char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutInitWindowSize(300,400); glutCreateWindow("Animation"); glutDisplayFunc(fRenderScene); glutReshapeFunc(fReshapeScene); glutTimerFunc(20,fTimerFunction,1); fSetupRC(); glutMainLoop(); return (0); }
首先一个,原文有两个变量:windowWidth和windowHeight,我觉得命名不够准确,这里就改为了
///*clip volume size*/
GLfloat rfClipVolumeHalfWidth = 0.0f;
GLfloat rfClipVolumeHalfHeight = 0.0f;
也就是裁剪体半高半宽.
另外就是这两个变量的变化追踪:
if(w <= h) {
rfClipVolumeHalfWidth = 100.0f;
rfClipVolumeHalfHeight = rfClipVolumeHalfWidth/rfAspectRatio;
glOrtho(-100.0f,100.0f,-rfClipVolumeHalfHeight,rfClipVolumeHalfHeight,0.000000001f,0.0f);
} else
{
rfClipVolumeHalfHeight = 100.0f;
rfClipVolumeHalfWidth = rfClipVolumeHalfHeight*rfAspectRatio;
glOrtho(-rfClipVolumeHalfWidth,rfClipVolumeHalfWidth,-100.0f,100.0f,0.00000001f,0.0f);
}
定时动画:
//turn
if(rfCubeX<=-rfClipVolumeHalfWidth||rfCubeX>=rfClipVolumeHalfWidth-rfCubeSize) {
rfCubeXStep = -rfCubeXStep;
}
if(rfCubeY<=-rfClipVolumeHalfHeight+rfCubeSize||rfCubeY>=rfClipVolumeHalfHeight) {
rfCubeYStep = -rfCubeYStep;
}
rfCubeX += rfCubeXStep;
rfCubeY += rfCubeYStep;
///*horizontal overflow*/
if(rfCubeX<-rfClipVolumeHalfWidth) {
rfCubeX = -rfClipVolumeHalfWidth;
} else
if( rfCubeX>(rfClipVolumeHalfWidth-rfCubeSize)) {
rfCubeX = rfClipVolumeHalfWidth-rfCubeSize;
}
///*vertical overflow*/
if(rfCubeY>rfClipVolumeHalfHeight) {
rfCubeY = rfClipVolumeHalfHeight;
} else
if( rfCubeY<(-rfClipVolumeHalfHeight+rfCubeSize) ) {
rfCubeY = -rfClipVolumeHalfHeight+rfCubeSize;
}
原文的翻转坐标判断没有=,这样在窗口没有大小变化的时候,导致实际上方块会越界一个像素.