修复glRasterPos()位置?

时间:2015-03-24 15:17:31

标签: c opengl

我正在使用C项目开发OPENGL。在这个项目中,一个球会在那里,它将随机运动,与窗户的墙壁碰撞并随机移动。玩家需要点击球,左上角显示的分数将增加1,球的速度将增加1.我们还有1分钟右上角显示的计时器。 1分钟后游戏结束,最终得分将显示给玩家。

到目前为止,我已经完成了球的随机运动。显示分数文字。问题是得分随球移动,左上角不是静态的。那怎么办呢?

这是我的代码:

#include<GL/glut.h>
#include<math.h>
#include<stdbool.h>
#define PI 3.14159265f

//Variable defined outside globally 

GLfloat ballRadius = 0.2;   //Radius of the bouncing ball
GLfloat ballX = 0.0f;   //Ball's center(x,y) position
GLfloat ballY = 0.0f;
GLfloat ballXMax,ballXMin,ballYMax,ballYMin;    //Ball's center (x,y) bounds
GLfloat xSpeed = 0.02f;  //Ball's speed in x and y direction
GLfloat ySpeed = 0.007f;
int refreshMills = 30;  
int x1,xa,ya; //refresh period in milliseconds
int score=0;
int last_mx = 0, last_my = 0, cur_mx = 0, cur_my = 0;
int arcball_on = false;
//Projection clipping area
GLdouble clipAreaXLeft,clipAreaXRight,clipAreaYBottom,clipAreaYTop;


// Initialize OpenGL Graphics

void initGL()
{
    glClearColor(0.0,0.0,0.0,1.0);                //Set background(clear) color to green


}


// Callback handler for window re-paint event

void display()
{

    glClear(GL_COLOR_BUFFER_BIT);  //Clear the color buffer

    glMatrixMode(GL_MODELVIEW);        //To operate on the model-view matrix

    glLoadIdentity();    //Reset model-view matrix
    glTranslatef(ballX,ballY,0.0f);  //Translate to (xPos,yPos)

    glBegin(GL_TRIANGLE_FAN);    //Use triangular segments to form a circle
    glColor3ub( rand()%1000, rand()%1000, rand()%1000 );     //Red
    glVertex2f(0.0f,0.0f);      //Center of circle
    int numSegments = 100;      //ball shape temp...

    GLfloat angle;
    int i;
    for(i=0;i<=numSegments;i++)   //Last vertex same as first vertex
    {
        angle = i*2.0f*PI/numSegments;   //360 degree for all segments
        glVertex2f(cos(angle)*ballRadius,sin(angle)*ballRadius);


    }
    glEnd();    
    glFlush();  //Swap front and back buffers

    //Animation Control - compute the location for next refresh
    ballX += xSpeed;
    ballY += ySpeed;

    //Check if the ball exceeds the edges
    if(ballX > ballXMax)
    {   xa=ballX;
        ballX = ballXMax;
        xSpeed = -xSpeed;

    }
    else if(ballX < ballXMin)
    {   xa=ballX;
        ballX = ballXMin;
        xSpeed = -xSpeed;

    }
    if(ballY > ballYMax)
    {   ya=ballY;
        ballY = ballYMax;
        ySpeed = -ySpeed;

    }
    else if(ballY < ballYMin)
    {   ya=ballY;
        ballY = ballYMin;
        ySpeed = -ySpeed;

    }

     glColor3f(1.0,0.0,0.0);
    glRasterPos2f(-1.0,0.0);
    glutBitmapCharacter (GLUT_BITMAP_8_BY_13,'S');
    glutBitmapCharacter (GLUT_BITMAP_8_BY_13,'C');
    glutBitmapCharacter (GLUT_BITMAP_8_BY_13,'O');
    glutBitmapCharacter (GLUT_BITMAP_8_BY_13,'R');
    glutBitmapCharacter (GLUT_BITMAP_8_BY_13,'E');
    glutBitmapCharacter (GLUT_BITMAP_8_BY_13,':');
    glFlush();
}

void onMouse(int button, int state, int x, int y) {
  if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
    arcball_on = true;
    last_mx = cur_mx = x;
    last_my = cur_my = y;
  } else {
    arcball_on = false;

    if(cur_mx==x && cur_my==y)
    {
        score=score+1;
    }
    printf("%d",score);
  }
}

void onMotion(int x, int y) {
  if (arcball_on) {  // if left button is pressed
    cur_mx = x;
    cur_my = y;
  }
}

/*void mouseClicks(int button, int state, int x, int y) {
    if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
   utton == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
}
*/

//Call back when the windows is re-sized

void reshape(GLsizei width,GLsizei height)
{

    //Compute aspect ratio of the new window
    if(height ==0) height = 1;                                 //To prevent divide by 0                         
    GLfloat aspect = (GLfloat)width / (GLfloat)height;

    //Set the viewport to cover the new window
    glViewport(0,0,width,height);

    //Set the aspect ratio of the clipping area to match the viewport
    glMatrixMode(GL_PROJECTION);    //To operate on the Projection matrix
    glLoadIdentity();               //Reset the Projection Matrix
    if(width >=height)
    {
        clipAreaXLeft = -1.0 * aspect;
        clipAreaXRight = 1.0 * aspect;
        clipAreaYBottom = -1.0;
        clipAreaYTop = 1.0;
    }
    else
    {
        clipAreaXLeft = -1.0;
        clipAreaXRight = 1.0 ;
        clipAreaYBottom = -1.0 / aspect;
        clipAreaYTop = 1.0 / aspect;
    }
    gluOrtho2D(clipAreaXLeft,clipAreaXRight,clipAreaYBottom,clipAreaYTop+0.25);
    ballXMin = clipAreaXLeft + ballRadius;
    ballXMax =  clipAreaXRight - ballRadius;
    ballYMin =  clipAreaYBottom + ballRadius;
    ballYMax =  clipAreaYTop - ballRadius;
}

//Call back when the timer expired

void Timer(int value)
{
    glutPostRedisplay();       //Post a paint request to activate display()
    glutTimerFunc(refreshMills,Timer,5);    //subsequent timer call at milliseconds

}

int windowWidth = 500;  //Window mode's width
int windowHeight = 500; //Window mode's height
int windowPosX = 100;    //Window mode's top-left corner x
int windowPosY = 100;


//Main function: GLUT runs as a console application starting at main()

int main(int argc,char* argv[])
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);                 //Enable double buffered mode
    glutInitWindowSize(windowWidth,windowHeight);     //Initial window width and height
    glutInitWindowPosition(windowPosX,windowPosY);    //Initial window top-left corner(x,y)
    glutCreateWindow("Bouncing Ball"); 
    glutMouseFunc(onMouse);
    glutMotionFunc(onMotion);
    glutDisplayFunc(display);                  //Register callback handler for window re-paint
    //glutMouseFunc(mouseClicks);
    glutReshapeFunc(reshape);    
    glutPostRedisplay();                           //Register callback handler for window re-shape
    glutTimerFunc(0,Timer,0);                          //First timer call immediately
    initGL();                                          //Our own OpenGL initialization
    glutMainLoop();                                    //Enter event processing loop

}

1 个答案:

答案 0 :(得分:1)

省略球的绘图代码,你有这个代码序列:

glLoadIdentity();    //Reset model-view matrix
glTranslatef(ballX,ballY,0.0f);  //Translate to (xPos,yPos)
...
glRasterPos2f(-1.0,0.0);
glutBitmapCharacter (GLUT_BITMAP_8_BY_13,'S');

当前模型视图转换适用于您使用glRasterPos2f()指定的位置,其中包含您使用glTranslatef()指定的翻译。

您可以通过以下几种方法解决此问题:

  1. 在调用glRasterPos2f()之前重置转换:

    glLoadIdentity();
    glRasterPos2f(-1.0,0.0);
    glutBitmapCharacter (GLUT_BITMAP_8_BY_13,'S');
    
  2. 按下/弹出用于绘制球的变换,在完成绘制球后恢复上一次变换:

    glLoadIdentity();    //Reset model-view matrix
    glPushMatrix();
    glTranslatef(ballX,ballY,0.0f);  //Translate to (xPos,yPos)
    ...
    glPopMatrix();
    glRasterPos2f(-1.0,0.0);
    glutBitmapCharacter (GLUT_BITMAP_8_BY_13,'S');
    
  3. 使用glWindowPos()代替glRasterPos(),它允许您指定以像素为单位的位置,而不是将要转换的坐标。