C++ 在OpenGL中移动三维图形
我正在用OpenGL/C++编写一个程序,该程序创建了许多球体,然后将它们移到屏幕附近,直到看不见为止。 我知道如何创建球体,但我似乎不知道创建球体后如何移动它们。有人知道我如何有效地更改move()函数,使其在每次调用时增加z 1吗?或者如果有更好的方法,请告诉我。谢谢C++ 在OpenGL中移动三维图形,c++,opengl,visual-c++,glut,C++,Opengl,Visual C++,Glut,我正在用OpenGL/C++编写一个程序,该程序创建了许多球体,然后将它们移到屏幕附近,直到看不见为止。 我知道如何创建球体,但我似乎不知道创建球体后如何移动它们。有人知道我如何有效地更改move()函数,使其在每次调用时增加z 1吗?或者如果有更好的方法,请告诉我。谢谢 class Sphere { public: double x, y, z; void create(double newx, double newy, double r, double g, double
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中甚至没有“模型”。只有一个称为帧缓冲区的数字画布,以及OpenGL提供的绘图工具,可以一次一个地绘制点、线和三角形。当你用OpenGL绘制某样东西时,它已经忘记了它
因此,将函数命名为“create”的整个概念都是错误的。相反,这里的函数是“draw”函数
因此,您必须做的很简单:重新绘制场景,但将几何体放在不同的位置。在OpenGL中,没有创建“模型”。事实上,OpenGL中甚至没有“模型”。所有这些都是一个数字画布,称为帧缓冲区,以及OpenGL提供的绘图工具,用于一次一个地绘制点、线和三角形。当你用OpenGL画东西的时候,它已经忘记了
因此,将函数命名为“create”的整个概念是错误的。取而代之的是一个“绘制”函数
因此,您必须做的很简单:重新绘制场景,但几何体位于不同的位置。为了更改球体的位置,不必在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所说,您不创建球体,而是“绘制”或“渲染”球体(或希望OpenGL显示的任何3D对象)
您需要创建一个Render()函数,并将代码从create()函数移动到该函数。由于以后要移动球体的位置,请将x、y和z坐标移动到球体的构造函数并初始化它们
例如:
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变量。为您保存一些编译器警告。要更改球体的位置,无需在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所说,您不创建球体,而是“绘制”或“渲染”球体(或希望OpenGL显示的任何3D对象)
您需要创建一个Render()函数,并将代码从create()函数移动到该函数。由于以后要移动球体的位置,请将x、y和z坐标移动到球体的构造函数并初始化它们
例如:
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忘记了它制作的形状,要删除形状并重新绘制它们,我是否需要使用glClear(GL\u COLOR\u BUFFER\u BIT)清除整个屏幕,然后重新绘制?@Sarah:这是一般的想法是的。记住:OpenGL不知道什么是“场景”。帧缓冲区中只有点、线、三角形和像素。记住这一点,与OpenGL相关的一切都变得越来越容易。当编程OpenGL时,将屏幕空间中发生的事情视为像素是很有意义的;所以,既然OpenGL忘记了它所制作的形状,要删除形状并重新绘制它们,我是否需要使用glClear(GL_COLOR_BUFFER_BIT)清除整个屏幕,然后重新绘制?@Sarah:这是一般的想法是的。记住:OpenGL不知道什么是“场景”。帧缓冲区中只有点、线、三角形和像素。记住这一点,与OpenGL相关的一切都变得越来越容易。当编程OpenGL时,将屏幕空间中发生的事情视为像素是很有意义的;通过图像处理来做事情是最好的