-1

我创建了一个 5 面的盒子,在里面放了一个球,让它在盒子里弹跳。我使用 glOrtho 创建了这个。

我想为我的课程创建一个 3d Brick Breaker 风格的游戏,所以我想把我的相机放进盒子里。我从 glOrtho 更改为 gluPerspective。我必须更改我的盒子的一些值才能正确渲染,但除非我把它放在原点上,否则球似乎已经丢失了。

这是我的值初始化:

void variableInits(){
    //Floor Plane
    pl1.pos.x = 0;   pl1.pos.y = -50;    pl1.pos.z = 0; 
    pl1.norm.x = 0; pl1.norm.y = 1; pl1.norm.z = 0;

    //Ceiling Plane
    pl2.pos.x = 0;   pl2.pos.y = 50;    pl2.pos.z = 0; 
    pl2.norm.x = 0; pl2.norm.y = -1; pl2.norm.z = 0;

    //Right Wall Plane
    pl3.pos.x = 50;    pl3.pos.y = 0;   pl3.pos.z = 0; 
    pl3.norm.x = -1; pl3.norm.y = 0; pl3.norm.z = 0;

    //Left Wall Plane
    pl4.pos.x = -50;  pl4.pos.y = 0;   pl4.pos.z = 0; 
    pl4.norm.x = 1; pl4.norm.y = 0; pl4.norm.z = 0;

    //Back Wall Plane
    pl5.pos.x = 0;   pl5.pos.y = 0;   pl5.pos.z = -100; 
    pl5.norm.x = 0; pl5.norm.y = 0; pl5.norm.z = 1;

    //Paddle Plane
    paddlePlane.max.x=.25; paddlePlane.max.y=.25; paddlePlane.max.z=1;
    paddlePlane.min.x=-.25; paddlePlane.min.y=-.25; paddlePlane.min.z=1;
    paddlePlane.normals.x=0; paddlePlane.normals.y=0;paddlePlane.normals.z=-0;

    //Ball Init
    b1.radius = 10;
    b1.pathDirection.x = 0; b1.pathDirection.y = 0; b1.pathDirection.z = 0;
    b1.pos.x = 0; b1.pos.y = 0, b1.pos.z = -25;

}

所以我的球应该在 Z 轴的 -25 值上以 10 的半径绘制。可悲的是它没有。

也许这是我的 gluPerspective 调用的问题?

void reshape(int width, int height)
{
    if (height==0)
    {
        height=1;
    }

    glViewport(0,0,width,height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.0f,50.0f);


    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

}

我会继续发布我的完整代码,但它有点长。

#include <stdio.h>
#include <gl/glut.h>
#include "pHeader.h"

#define EPSILON 1.0e-8
#define ZERO EPSILON


int g_mainWindow = -1;
float g_lightPos[] = {0, 0, 0, -50};
int angle = 0;
int g_moving;
int g_mouse_x;
int g_mouse_y;
int g_x_angle;
int g_y_angle;
double mX,mY,mZ;
float speed = 1;
plane pl1, pl2, pl3, pl4 ,pl5;
paddlePl paddlePlane;
float collDist = 1000;
ball b1;


void mouse(int button, int state, int x, int y)
{

    if (button == GLUT_LEFT_BUTTON && state==GLUT_DOWN)
    {
        g_moving = 1;

        g_mouse_x = x;
        g_mouse_y = y;
    }  
    else {
        g_moving = 0;

    }   
}

void mouseDrag(int x, int y)
{
    int dx, dy;

    if (g_moving){

        dx = x - g_mouse_x;
        dy = y - g_mouse_y;

        g_x_angle += dy;
        g_y_angle += dx;
        g_mouse_x = x;
        g_mouse_y = y;

    }



}

void paddle(int x, int y){
    GLint viewport[4];
    GLdouble modelview[16],projection[16];
    glGetIntegerv(GL_VIEWPORT,viewport);
    glGetDoublev(GL_MODELVIEW_MATRIX,modelview);
    glGetDoublev(GL_PROJECTION_MATRIX,projection);
    gluUnProject(x,viewport[3]-y,0,modelview,projection,viewport,&mX,&mY,&mZ);
}

/*************************************************
                Vector Math
**************************************************/

float dot(vector XYZ , vector nXYZ){
    return (XYZ.x * nXYZ.x) + (XYZ.y * nXYZ.x) + (XYZ.z * nXYZ.z);
}

vector cross(vector v1 , vector v2){
    vector result;
        result.x = v1.y * v2.z - v1.z * v2.y;

        result.y = v1.z * v2.x - v1.x * v2.z;

        result.z = v1.x * v2.y - v1.y * v2.x;

        return result;
}

vector vectScale(float scale, vector v1){
    vector result;

    result.x = v1.x * scale;
    result.y = v1.y * scale;
    result.z = v1.z * scale;

    return result;
}

vector vectorSub(vector v1, vector v2){
    vector result;

    result.x = v1.x - v2.x;
    result.y = v1.y - v2.y;
    result.z = v1.z - v2.y;

    return result;
}

vector flipVect(vector v1){
    vector result;

    result.x = -v1.x;
    result.y = -v1.y;
    result.z = -v1.z;

    return result;
}

vector vectorAdd(vector v1, vector v2){
    vector result;

    result.x = v1.x + v2.x;
    result.y = v1.y + v2.y;
    result.z = v1.z + v2.z;

    return result;
}
/****************************************************
           End Vecotor Math
****************************************************/


void planeCollision(){
    //Check Ceiling
    if(b1.pos.y + b1.radius >= 50){
        b1.pathDirection = vectorAdd((2 * dot(flipVect(b1.pathDirection), pl2.norm) , pl2.norm) , b1.pathDirection);
    }

    //Check Floor
    if(b1.pos.y-b1.radius <= -50){
        b1.pathDirection = vectorAdd((2 * dot(flipVect(b1.pathDirection), pl1.norm) , pl1.norm) , b1.pathDirection);
    }

    //Check Right Wall
    if(b1.pos.x + b1.radius >= 1){
        b1.pathDirection = vectorAdd((2 * dot(flipVect(b1.pathDirection), pl3.norm) , pl3.norm) , b1.pathDirection);
    }

    //Check Left Wall
    if(b1.pos.x - b1.radius <= -1){
        b1.pathDirection = vectorAdd((2 * dot(flipVect(b1.pathDirection), pl4.norm) , pl4.norm) , b1.pathDirection);
    }

    //Check Back Wall
    if(b1.pos.z - b1.radius <= -1){
        b1.pathDirection = vectorAdd((2 * dot(flipVect(b1.pathDirection), pl5.norm) , pl5.norm) , b1.pathDirection);
    }

    //Check paddle
    if(b1.pos.z + b1.radius >= paddlePlane.max.z && b1.pos.x >= paddlePlane.min.x && b1.pos.x <= paddlePlane.max.x && b1.pos.y >= paddlePlane.min.y && b1.pos.y <= paddlePlane.max.y){
        b1.pathDirection = vectorAdd((2 * dot(flipVect(b1.pathDirection), paddlePlane.normals) , paddlePlane.normals) , b1.pathDirection);
    }
}



void drawPlanes(){
    glBegin(GL_QUADS);
        //Floor
        glColor3f(1,0,0);
        glNormal3f( 0.0f , 1.0f, 0.0f);

        glVertex3f( 050.0f , -050.0f , -100.0f);
        glVertex3f(-050.0f , -050.0f , -100.0f);
        glVertex3f(-050.0f , -050.0f ,  000.0f);
        glVertex3f( 050.0f , -050.0f ,  000.0f);

        //Ceiling
        glColor3f(1,0,1);
        glNormal3f(0.0f,-1.0f,0.0f);

        glVertex3f( 050.0f, 050.0f, -100.0f);
        glVertex3f(-050.0f, 050.0f, -100.0f);
        glVertex3f(-050.0f, 050.0f,  000.0f);
        glVertex3f( 050.0f, 050.0f,  000.0f);

        //Right Wall
        glColor3f(0,1,0);
        glNormal3f( -1.0f , 0.0f, 0.0f);

        glVertex3f(050.0f , 050.0f ,  000.0f);
        glVertex3f(050.0f , 050.0f , -100.0f);
        glVertex3f(050.0f ,-050.0f , -100.0f);
        glVertex3f(050.0f ,-050.0f,   000.0f);

        //LeftWall

        glColor3f(0,1,1);
        glNormal3f( 1.0f , 0.0f, 0.0f);

        glVertex3f(-050.0f ,  050.0f , -100.0f);
        glVertex3f(-050.0f ,  050.0f ,  000.0f);
        glVertex3f(-050.0f , -050.0f ,  000.0f);
        glVertex3f(-050.0f , -050.0f , -100.0f);

        //Back Wall
        glColor3f(0,0,1);
        glNormal3f( 0.0f , 0.0f, 1.0f);

        glVertex3f( 050.0f ,  050.0f , -100.0f);
        glVertex3f(-050.0f ,  050.0f , -100.0f);
        glVertex3f(-050.0f , -050.0f , -100.0f);
        glVertex3f( 050.0f , -050.0f , -100.0f);


    glEnd();

}

void ballMove(){
    glPushMatrix();
        glColor3f(1,1,0);
        b1.pos.x += (b1.pathDirection.x * speed); b1.pos.y += (b1.pathDirection.y * speed); b1.pos.z += (b1.pathDirection.z * speed);
        glTranslatef(b1.pos.x,b1.pos.y,b1.pos.z);
        glutSolidSphere(b1.radius,100,100);
        printf("%.2f %.2f %.2f\n", b1.pos.x, b1.pos.y, b1.pos.z);
    glPopMatrix();
    planeCollision();
}

void drawPaddle(){
    //printf("x %f  y %f\n" , mX , mY);
    glPushMatrix();
    glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
        glBegin(GL_QUADS);
            glColor3f(1,1,1);    
            glVertex3f(mX +  25.0f , mY +  25.0f , 0.0f);
            glVertex3f(mX + -25.0f , mY +  25.0f , 0.0f);
            glVertex3f(mX + -25.0f , mY + -25.0f , 0.0f);
            glVertex3f(mX +  25.0f , mY + -25.0f , 0.0f);
        glEnd();
    glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
    glPopMatrix();

    paddlePlane.max.x=mX +  0.25f;  paddlePlane.max.y=mY +  0.25f; paddlePlane.max.z=1;
    paddlePlane.min.x=mX +  -0.25f; paddlePlane.min.y=mY + -0.25f; paddlePlane.min.z=1;

}



void display()
{   
    float red[] = {1,0,0,1};
    float blue[] = {0,0,1,1};
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_NORMALIZE);

    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);

    glPushMatrix();
        glRotated(g_y_angle, 0, 1, 0);
        glRotated(g_x_angle,1,0,0);
        glTranslated(0,0,-100);

        drawPaddle();
        ballMove();
        drawPlanes();


    glPopMatrix();

    angle += 1;



    glFlush();
    glutSwapBuffers();
}

void reshape(int width, int height)
{
    if (height==0)
    {
        height=1;
    }

    glViewport(0,0,width,height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.0f,50.0f);


    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

}


void idle()
{
    glutSetWindow(g_mainWindow);
    glutPostRedisplay();
}

void variableInits(){
    //Floor Plane
    pl1.pos.x = 0;   pl1.pos.y = -50;    pl1.pos.z = 0; 
    pl1.norm.x = 0; pl1.norm.y = 1; pl1.norm.z = 0;

    //Ceiling Plane
    pl2.pos.x = 0;   pl2.pos.y = 50;    pl2.pos.z = 0; 
    pl2.norm.x = 0; pl2.norm.y = -1; pl2.norm.z = 0;

    //Right Wall Plane
    pl3.pos.x = 50;    pl3.pos.y = 0;   pl3.pos.z = 0; 
    pl3.norm.x = -1; pl3.norm.y = 0; pl3.norm.z = 0;

    //Left Wall Plane
    pl4.pos.x = -50;  pl4.pos.y = 0;   pl4.pos.z = 0; 
    pl4.norm.x = 1; pl4.norm.y = 0; pl4.norm.z = 0;

    //Back Wall Plane
    pl5.pos.x = 0;   pl5.pos.y = 0;   pl5.pos.z = -100; 
    pl5.norm.x = 0; pl5.norm.y = 0; pl5.norm.z = 1;

    //Paddle Plane
    paddlePlane.max.x=.25; paddlePlane.max.y=.25; paddlePlane.max.z=1;
    paddlePlane.min.x=-.25; paddlePlane.min.y=-.25; paddlePlane.min.z=1;
    paddlePlane.normals.x=0; paddlePlane.normals.y=0;paddlePlane.normals.z=-0;

    //Ball Init
    b1.radius = 10;
    b1.pathDirection.x = 0; b1.pathDirection.y = 0; b1.pathDirection.z = 0;
    b1.pos.x = 0; b1.pos.y = 0, b1.pos.z = -25;

}

int main(int ac, char* av[])
{
    glutInit(&ac, av);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);

    g_mainWindow = glutCreateWindow("Hello, glut");
    variableInits();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    glutMouseFunc(mouse);
    glutMotionFunc(mouseDrag);
    glutPassiveMotionFunc(paddle);


    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
    glLightfv(GL_LIGHT0, GL_POSITION, g_lightPos);


    glShadeModel(GL_SMOOTH);                            
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);               
    glClearDepth(1.0f);                                                         
    glDepthFunc(GL_LEQUAL);                             
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);




    glutMainLoop(); //no return
}

标题

#pragma once
#ifndef pHeader_INCLUDED
#define pHeader_H_INCLUDED


typedef struct vector{
    float x,y,z;
}vector;

typedef struct ball{
    float radius;
    vector pathDirection;
    vector pos;
} ball;


typedef struct planeStruc{
    vector pos;
    vector norm;
} plane;

typedef struct paddlePlane{
    vector min;
    vector max;
    vector normals;
} paddlePl;



#endif
4

1 回答 1

1

gluPerspective近平面的值不能为 0.0,它要么产生错误(我不确定),要么导致发生一些奇怪的无穷大数学,这肯定不是你想要的。

您应该使近平面的值大于零,并且在不切断您想看到的东西的情况下尽可能大。如果你把它做得太小,你会损失很多 z 精度。

尝试从 0.1 开始。

于 2012-04-12T07:04:14.707 回答