Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在OpenGL中移动三维图形_C++_Opengl_Visual C++_Glut - Fatal编程技术网

C++ 在OpenGL中移动三维图形

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

我正在用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中甚至没有“模型”。只有一个称为帧缓冲区的数字画布,以及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时,将屏幕空间中发生的事情视为像素是很有意义的;通过图像处理来做事情是最好的