0

所以我有一个 Triangle 类,我想绘制我的三角形的实例,但由于某些原因,只绘制了一个,它背后的逻辑超出了我的范围。

我一直在环顾四周,但我发现的只是所有三角形都绘制在同一个文件上的示例。

这是三角形类:

 public class Triangle:IGameObject
 {
    Vector3 position;
    int speed;

    public Triangle(int speed, Vector3 vec) {
        this.speed = speed;
        position = new Vector3(vec);
    }
    public void Update() { }

    public void Render()
    {
        Gl.glPushMatrix();
        Gl.glRotated(speed*Time.deltaTime,speed*Time.deltaTime,speed*Time.deltaTime,speed*Time.deltaTime);

        Gl.glBegin(Gl.GL_TRIANGLE_STRIP);

            Gl.glColor3f(1.0f, 0.0f, 0.0f);
            Gl.glVertex3d(position.x, 0, 0);
            Gl.glColor3d(0.0, 1.0, 0.0);
            Gl.glVertex3d(position.y, 0, 0);
            Gl.glColor3d(0.0, 0.0, 1.0);
            Gl.glVertex3d(0, position.z, 0);

        Gl.glEnd();
        Gl.glPopMatrix();
    }
}

这是 Form.cs

public partial class Form1 : Form
{
    Triangle _trA = new Triangle(100, new Vector3(0.1f,-0.2f,0.2f));
    Triangle _trB = new Triangle(50, new Vector3(0.5f, 0.3f, -0.1f));
    public Form1()
    {
        InitializeComponent();
        _openGLControl.InitializeContexts();

        if (_fullscreen)
        {
            FormBorderStyle = FormBorderStyle.None;
            WindowState = FormWindowState.Maximized;
        }
        else {
            ClientSize = new Size(1280,720);
        }
    }

    void GameLoop()
    {
        Gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
        _trA.Render();
        _trB.Render();
        _openGLControl.Refresh();
    }
}

我想我已经看到我应该在将矩阵用于对象之后(或之前)清除矩阵,但无法弄清楚。

有任何想法吗?

4

1 回答 1

2

有不同的问题:

glPush/glPop

你应该打电话

Gl.glPushMatrix();

在您的Render()方法开始时,并且

Gl.glPopMatrix();

在最后。

否则glRotated()会在您的所有通话中累积。调用glPushMatrix()复制您当前的 ModelView 矩阵,然后您可以应用旋转,并glPopMatrix()恢复前一个。

glLoadIdentity

您必须在 GameLoop 开始时重置 ModelView 矩阵,方法是调用:

Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();

这可以防止任何修改从先前的帧中累积。

累积 Time.deltaTime

我猜这Time.deltaTime是自上一帧以来已经过去的时间(以秒为单位)。这可能是一个常数,然后speed*Time.deltaTime也是一个常数,因此您始终显示以相同角度旋转的三角形,因此没有运动。您应该创建一个成员,并通过在每个 GameLoop 调用中angle调用来增加它。angle += speed * Time.deltaTime

glRotated

的最后三个参数glRotated表示围绕您正在转动的旋转轴。由于您使用的是 2D 场景,我假设您希望该轴成为相机正在查看的轴。那么你应该使用轴(0,0,1)而不是(angle,angle,angle).

结论

考虑到所有这些元素,您的代码应该是:

public class Triangle:IGameObject
{
    Vector3 position;
    int speed;
    double angle;

    public Triangle(int speed, Vector3 vec) {
        this.speed = speed;
        position = new Vector3(vec);
        angle = 0;
    }
    public void Update()
    { 
        angle += speed*Time.deltaTime;
    }

    public void Render()
    {
        Gl.glPushMatrix();
        Gl.glRotated(angle,0,0,1);

        Gl.glBegin(Gl.GL_TRIANGLE_STRIP);

            Gl.glColor3f(1.0f, 0.0f, 0.0f);
            Gl.glVertex3d(position.x, 0, 0);
            Gl.glColor3d(0.0, 1.0, 0.0);
            Gl.glVertex3d(position.y, 0, 0);
            Gl.glColor3d(0.0, 0.0, 1.0);
            Gl.glVertex3d(0, position.z, 0);

        Gl.glEnd();
        Gl.glPopMatrix();
    }
}

void GameLoop()
{
    // Update the scene
    _trA.Update();
    _trB.Update();

    // Draw the scene
    Gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
    Gl.glMatrixMode(Gl.GL_MODELVIEW);
    Gl.glLoadIdentity();
    _trA.Render();
    _trB.Render();
    _openGLControl.Refresh();
}
于 2013-07-07T02:06:54.477 回答