OpenGl,绘制多个三角形对象C#

时间:2013-07-06 14:26:21

标签: c# opengl render

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

我一直在四处寻找,但我找到的只是在同一个文件上绘制所有三角形的例子。

这是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();
    }
}

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

有什么想法吗?

1 个答案:

答案 0 :(得分: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也是一个常数,所以你总是以相同的角度显示旋转的三角形,因此没有运动。您应该创建一个angle成员,并在每次GameLoop调用时调用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();
}