在OpenGL中移动3d形状

时间:2015-10-17 21:20:48

标签: c++ opengl visual-c++ glut

我正在用OpenGL / C ++编写一个程序,它创建了许多Spheres,然后将它们移动到屏幕附近,直到它们不在视线范围内。 我理解如何创建Spheres,但我似乎无法弄清楚如何在创建它们之后移动它们。有谁知道如何有效地改变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();
    }
};

2 个答案:

答案 0 :(得分:3)

为了改变球体的位置,不必在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'或者'渲染'一个球体(或者你希望OpenGL显示的任何3D物体)。举个例子,让我们一起使用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()函数。如您所见,Move()函数也在Render3DEnviroment()函数中调用。这意味着您的球体也在z轴上快速移动,当z达到等于0或大于0的值时,跳回到-176。

提示:使用GLfloat而不是double作为x,y,z和r,g,b变量的数据类型,因为有问题的OpenGL函数使用GLfloat变量。为您节省一些编译器警告。

答案 1 :(得分:1)

在OpenGL中没有创建"模型。实际上甚至没有"模型"在OpenGL中。所有这些都是一个数字画布,称为帧缓冲,以及OpenGL提供的绘图工具,一次一个地绘制点,线和三角形。你用OpenGL绘制东西的那一刻它已经忘记了它。

因此,整个概念命名一个函数"创建"是错的。相反,你所拥有的是一个" draw"功能

所以你需要做的就是简单:重绘场景,但将几何体放在不同的位置。