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

本文关键字:三角形 对象 绘制 OpenGl | 更新日期: 2023-09-27 18:21:22

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

我一直在四处寻找,但我发现的只是所有三角形都画在同一个文件上的例子。

这是三角形类:

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

我想我已经看到我应该在将矩阵用于对象之后(或之前)清除矩阵,但我无法解决这个问题。

有什么想法吗?

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

有不同的问题:

glPush/glPop

你应该打电话给

Gl.glPushMatrix();

Render()方法开始时,以及

Gl.glPopMatrix();

最后。

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

glLoadIdentity

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

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

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

累积时间。deltaTime

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

gl旋转

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