我创建了一个 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