OPENGL_SB4TH_RECORD(2)

#include <gltools.h>

#include <stdio.h>
#ifdef __cplusplus
extern "C"
#endif
FILE _iob[3] = {__iob_func()[0], __iob_func()[1], __iob_func()[2]};

GLfloat x = 0.0f;
GLfloat y = 0.0f;
GLfloat rsize = 25.0f;
GLfloat xstep = 1.0f;
GLfloat ystep = 1.0f;
GLfloat fWinHorRadius = 100.0f;//actual window size or size in the clip volume ? Latter. the rect doesn't even know the existence of clipping volume :-)
GLfloat fWinVerRadius = 100.0f;

void SetupRC()
{
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);

}

void ChangeSize(int w, int h)
{
    if(h == 0)
        h = 1;

    glViewport(0, 0, w, h);

    GLfloat fRatio = w * 1.0f / h;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if(w < h)
    {
        fWinVerRadius = 100.0f / fRatio;
        fWinHorRadius = 100.0f;        
    }
    else
    {
        fWinHorRadius = 100.0f * fRatio;
        fWinVerRadius = 100.0f;
    }
    glOrtho(-1.0*fWinHorRadius, 1.0*fWinHorRadius, -1.0*fWinVerRadius, 1.0*fWinVerRadius, 1.0, -1.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glutPostRedisplay();  
}

void RenderScene()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f, 0.0f, 0.0f);
    glRectf(x, y, x+rsize, y-rsize);
    glutSwapBuffers();
    //glFlush();  //glFlush for GLUT_SINGLE and glutSwapBuffers for GLUT_DOUBLE
}

void TimerFunc(int value)
{
    //collision detection
    if(x > fWinHorRadius-rsize || x < fWinHorRadius*(-1.0f))
        xstep *= (-1.0);
    
    if(y > fWinVerRadius || y < ((fWinVerRadius-rsize)*(-1.0f)))
        ystep *= (-1.0);

    x += xstep;
    y += ystep;

    //handle situation when the rect is out of clip volume because of suddenly changing size (smaller)
    if(x > fWinHorRadius-rsize+xstep) //+xstep is very necessary coz if not,the rect will keep shivering near the bounder
        x = fWinHorRadius-rsize -1;
    else if(x < -fWinHorRadius+xstep)
        x = -fWinHorRadius+1;

    if(y > fWinVerRadius+ystep)
        y = fWinVerRadius-1;
    else if(y < -fWinVerRadius+rsize+ystep)
        y = -fWinVerRadius+rsize+1;

    glutPostRedisplay();

    glutTimerFunc(33, TimerFunc, 1);
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Bounce Test");
    
    
    glutReshapeFunc(ChangeSize);
    glutTimerFunc(33, TimerFunc, 1);
    glutDisplayFunc(RenderScene);

    SetupRC();

    glutMainLoop();

    return 0;
}

总结的几点:

1. glutSwapBuffers() 应该只在回调函数RenderScene()中调用;

2. 当突然将窗口的尺寸变小时,可能rect已经out of clip volume,这时肯定rect就再进不来了。所以这个异常情况一定要考虑进去而且还不是那么容易解决的哦。

疑问:

1. 虽然使用了GLUT_DOUBLE(相应的glutSwapBuffers)仍然感觉闪烁,有更好的优化方案吗?

这种突然改变窗口大小后只能上下移动的情况出现原因和解决方法一定得有:

posted @ 2013-12-11 11:29  Tup  阅读(217)  评论(0)    收藏  举报