opengl super bible 方块动画的改进代码

#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;
}


原文的翻转坐标判断没有=,这样在窗口没有大小变化的时候,导致实际上方块会越界一个像素.

你可能感兴趣的:(opengl super bible 方块动画的改进代码)