在 OpenGL 中移动 3d 形状
Moving 3d Shape in OpenGL
我正在用 OpenGL/C++ 编写一个程序,它创建多个球体,然后将它们移动到屏幕附近,直到它们看不见。
我了解如何创建球体,但我似乎无法弄清楚如何在创建球体后移动它们。有谁知道我如何有效地更改 move() 函数,以便每次调用它时将 z 增加 1?或者如果有更好的方法来做到这一点,请告诉我。谢谢!
class Sphere {
public:
double x, y, z;
void create(double newx, double newy, double r, double g, double b) {
x = newx;
y = newy;
z = -175; // start at back of projection matrix
glPushMatrix();
glTranslatef(x, y, z);
glColor3f(r, g, b);
glScalef(1.0, 1.0, 1.0);
glutSolidSphere(1, 50, 50);
glPopMatrix();
}
void move() {
glPushMatrix();
//if z is at front, move to start over in the back
if (z >= 0) {
z = -176;
x = rand() % 100;
y = rand() % 100;
x = x - 50;
y = y - 50;
}
x = x;
y = y;
glPushMatrix();
z++;
glTranslatef(x, y, z);
glPopMatrix();
}
};
在 OpenGL 中,OpenGL 中没有 "models created. In fact there are not even "models"。只有一个数字 canvas,称为帧缓冲区,以及 OpenGL 提供的用于绘制点、线和三角形的绘图工具, 一次一个。当你用 OpenGL 画东西的那一刻,它已经忘记了它。
因此整个命名函数的概念 "create" 是错误的。相反,你有一个 "draw" 函数。
所以您要做的很简单:重新绘制场景,但几何体位于不同的位置。
为了改变球体的位置,不必在 move() 函数中调用 glPushMatrix() 和 glPopMatrix() 函数。您可以将 move() 函数简化为:
void Move() {
//if z is at front, move to start over in the back
if (z >= 0) {
z = -176;
}
z++;
}
此外,正如用户 datenwolf 所说,您不 创建 而是 'Draw' 或 'Render' 一个球体(或任何 3D 对象)想要 OpenGL 来显示)。举个例子,让我们使用 Render。
您想要的是创建一个 Render() 函数并将代码从您的 create() 函数移动到它。因为稍后要移动球体的位置,请将 x、y 和 z 坐标移动到 Sphere 的构造函数并初始化它们。
示例:
class Sphere {
public:
double x,y,z;
// We also set the color values of the sphere inside the sphere's
// constructor for simplicity sake.
double r,g,b;
Sphere(double _x, double _y, double _z) {
x = _x;
y = _y;
z = _z;
r = 1.0;
g = 0.0;
b = 0.0;
}
void Render() {
glPushMatrix();
glTranslatef(x, y, z);
glColor3f(r, g, b);
glScalef(1.0, 1.0, 1.0);
glutSolidSphere(1, 50, 50);
glPopMatrix();
}
};
OpenGL 使用名为 glutDisplayFunc() 的回调函数。您将一个函数传递给此 glutDisplayFunc() 以呈现您想要在屏幕上显示的所有内容。我会调用要传递的函数"void Render3DEnvironment()"。您需要找到您的 glutDisplayFunc() 和传递给它的函数,并在那里调用您的球体的 Render() 函数。
这是一个例子:
#include "Sphere.h"
Sphere* sphere;
void Render3DEnvironment()
{
sphere->Render();
sphere->Move();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
sphere = new Sphere(50,50,50);
glutDisplayFunc(Render3DEnvironment);
glutMainLoop();
return 0;
}
glutDisplayFunc() 函数将不断调用传递给它的函数,在本例中为 Render3DEnvironment() 函数。如您所见,Render3DEnviroment() 函数中也调用了 Move() 函数。这意味着您的球体也在 z 轴上(快速)移动,并在 z 达到等于 0 或大于 0 的值时跳回 -176。
提示:使用 GLfloat 而不是 double 作为 x、y、z 和 r、g、b 变量的数据类型,因为所讨论的 OpenGL 函数使用 GLfloat 变量。为您节省一些编译器警告。
我正在用 OpenGL/C++ 编写一个程序,它创建多个球体,然后将它们移动到屏幕附近,直到它们看不见。 我了解如何创建球体,但我似乎无法弄清楚如何在创建球体后移动它们。有谁知道我如何有效地更改 move() 函数,以便每次调用它时将 z 增加 1?或者如果有更好的方法来做到这一点,请告诉我。谢谢!
class Sphere {
public:
double x, y, z;
void create(double newx, double newy, double r, double g, double b) {
x = newx;
y = newy;
z = -175; // start at back of projection matrix
glPushMatrix();
glTranslatef(x, y, z);
glColor3f(r, g, b);
glScalef(1.0, 1.0, 1.0);
glutSolidSphere(1, 50, 50);
glPopMatrix();
}
void move() {
glPushMatrix();
//if z is at front, move to start over in the back
if (z >= 0) {
z = -176;
x = rand() % 100;
y = rand() % 100;
x = x - 50;
y = y - 50;
}
x = x;
y = y;
glPushMatrix();
z++;
glTranslatef(x, y, z);
glPopMatrix();
}
};
在 OpenGL 中,OpenGL 中没有 "models created. In fact there are not even "models"。只有一个数字 canvas,称为帧缓冲区,以及 OpenGL 提供的用于绘制点、线和三角形的绘图工具, 一次一个。当你用 OpenGL 画东西的那一刻,它已经忘记了它。
因此整个命名函数的概念 "create" 是错误的。相反,你有一个 "draw" 函数。
所以您要做的很简单:重新绘制场景,但几何体位于不同的位置。
为了改变球体的位置,不必在 move() 函数中调用 glPushMatrix() 和 glPopMatrix() 函数。您可以将 move() 函数简化为:
void Move() {
//if z is at front, move to start over in the back
if (z >= 0) {
z = -176;
}
z++;
}
此外,正如用户 datenwolf 所说,您不 创建 而是 'Draw' 或 'Render' 一个球体(或任何 3D 对象)想要 OpenGL 来显示)。举个例子,让我们使用 Render。
您想要的是创建一个 Render() 函数并将代码从您的 create() 函数移动到它。因为稍后要移动球体的位置,请将 x、y 和 z 坐标移动到 Sphere 的构造函数并初始化它们。
示例:
class Sphere {
public:
double x,y,z;
// We also set the color values of the sphere inside the sphere's
// constructor for simplicity sake.
double r,g,b;
Sphere(double _x, double _y, double _z) {
x = _x;
y = _y;
z = _z;
r = 1.0;
g = 0.0;
b = 0.0;
}
void Render() {
glPushMatrix();
glTranslatef(x, y, z);
glColor3f(r, g, b);
glScalef(1.0, 1.0, 1.0);
glutSolidSphere(1, 50, 50);
glPopMatrix();
}
};
OpenGL 使用名为 glutDisplayFunc() 的回调函数。您将一个函数传递给此 glutDisplayFunc() 以呈现您想要在屏幕上显示的所有内容。我会调用要传递的函数"void Render3DEnvironment()"。您需要找到您的 glutDisplayFunc() 和传递给它的函数,并在那里调用您的球体的 Render() 函数。
这是一个例子:
#include "Sphere.h"
Sphere* sphere;
void Render3DEnvironment()
{
sphere->Render();
sphere->Move();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
sphere = new Sphere(50,50,50);
glutDisplayFunc(Render3DEnvironment);
glutMainLoop();
return 0;
}
glutDisplayFunc() 函数将不断调用传递给它的函数,在本例中为 Render3DEnvironment() 函数。如您所见,Render3DEnviroment() 函数中也调用了 Move() 函数。这意味着您的球体也在 z 轴上(快速)移动,并在 z 达到等于 0 或大于 0 的值时跳回 -176。
提示:使用 GLfloat 而不是 double 作为 x、y、z 和 r、g、b 变量的数据类型,因为所讨论的 OpenGL 函数使用 GLfloat 变量。为您节省一些编译器警告。