Open GL DrawArrays仅绘制一个三角形/直线/点(OpenTK / C#)

比萨饼

在这个基本的渲染测试中,我从文件中加载了32个顶点的数据。绘制时,它只会绘制一个图元,而忽略数组的其余部分。例如,如果我调用GL.DrawArrays(PrimitiveType.Triangles, i, 3)它将绘制元素i。

该阵列确实包含的数据远不止一个三角形的价值,这里的例子代码将您单击每次画一个三角形不同,但同样只有一个它呈现各一次。如果我DrawArrays使用不同的int first参数进行多次调用,则还将为每个调用绘制一个额外的三角形。(我很确定将所有数据放入GPU上的缓冲区的目的不是为了使您可以进行不计其数的绘制调用。)

我试过使用drawelements作为drawarrays的替代方法,但是无论我为参数输入什么,都得到了System.AccessViolationException。我能找到的所有教程总是只画一个三角形和/或使用画图元素,因此我无法找到代码示例来帮助我弄清楚绘制多个图元的不同之处。

Form1只是一个带有glcontrol的空白表单。我正在使用NuGet软件包OpenTK 3.1.0和OpenTK.GLControl 3.1.0。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenTK.Graphics.OpenGL4;
using OpenTK;

namespace _3dRenderingTesting
{
    public partial class Form1 : Form
    {
        int program;
        int myVAO;
        int i = 0;
        private void glControl1_MouseClick(object sender, MouseEventArgs e)
        {
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.Enable(EnableCap.DepthTest);
            GL.UseProgram(program);
            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
            GL.DrawArrays(PrimitiveType.Triangles, i, 3);
            glControl1.SwapBuffers();
            i++;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            program = compileShaders();
            getMeshFromFile();
        }

        public Form1()
        {
            InitializeComponent();
        }

        private int compileShaders()
        {
            string vShader;
            using (System.IO.StreamReader file = new System.IO.StreamReader(@"vertexshader.txt"))
            {
                vShader = file.ReadToEnd();
            }

            string fShader = "";
            using (System.IO.StreamReader file = new System.IO.StreamReader(@"fragmentshader.txt"))
            {
                fShader = file.ReadToEnd();
            }

            int vertexShader = GL.CreateShader(ShaderType.VertexShader);
            GL.ShaderSource(vertexShader, vShader);
            GL.CompileShader(vertexShader);

            int fragmentShader = GL.CreateShader(ShaderType.FragmentShader);
            GL.ShaderSource(fragmentShader, fShader);
            GL.CompileShader(fragmentShader);

            int program = GL.CreateProgram();
            GL.AttachShader(program, vertexShader);
            GL.AttachShader(program, fragmentShader);

            GL.LinkProgram(program);
            GL.DeleteShader(vertexShader);
            GL.DeleteShader(fragmentShader);
            return program;
        }

        private int vertBuffer;
        private int vertLength;

        private void getMeshFromFile()
        {
            List<string> fileContents = new List<string>();
            List<float> fVerts = new List<float>();
            List<int> fFaces = new List<int>();
            System.IO.StreamReader file = new System.IO.StreamReader(@"C:\Users\abc\Desktop\32 Vertex Sphere.obj");
            while (!file.EndOfStream)
            {
                string ts = file.ReadLine().Trim().ToLower();
                //find all lines that begin with "v"
                //these are vertices
                if (ts.Length > 0)
                {
                    if (ts.Substring(0, 1) == "v")
                    {
                        const string reduceMultiSpace = @"[ ]{2,}";
                        string[] tSplit = System.Text.RegularExpressions.Regex.Replace(ts.Replace(" ", ",").Replace("\t", ","), reduceMultiSpace, ",").Split(',');
                        if (tSplit.Length < 4)
                        {
                            MessageBox.Show("Vertex list failure (< 3 vertices)");
                            Application.Exit();
                        }
                        fVerts.Add(float.Parse(tSplit[1]));
                        fVerts.Add(float.Parse(tSplit[2]));
                        fVerts.Add(float.Parse(tSplit[3]));
                    }
                    if (ts.Substring(0, 1) == "f")
                    {
                        const string reduceMultiSpace = @"[ ]{2,}";
                        string[] tSplit = System.Text.RegularExpressions.Regex.Replace(ts.Replace(" ", ",").Replace("\t", ","), reduceMultiSpace, ",").Split(',');
                        if (tSplit.Length < 4)
                        {
                            MessageBox.Show("Face list failure (< 3 vertices)");
                            Application.Exit();
                        }
                        fFaces.Add(int.Parse(tSplit[1]));
                        fFaces.Add(int.Parse(tSplit[2]));
                        fFaces.Add(int.Parse(tSplit[3]));
                    }
                }
            }
            file.Close();

            float[] fVArray = new float[fVerts.Count];
            for (int i = 0; i < fVerts.Count; i++) fVArray[i] = fVerts[i];

            GL.CreateBuffers(1, out vertBuffer);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vertBuffer);
            GL.NamedBufferStorage(vertBuffer, sizeof(float) * fVerts.Count, fVArray, BufferStorageFlags.MapWriteBit | BufferStorageFlags.MapReadBit);
            vertLength = fVerts.Count;

            GL.CreateVertexArrays(1, out myVAO);
            GL.BindVertexArray(myVAO);
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0); 
            GL.EnableVertexAttribArray(0);
        }
    }
}

顶点文件:

v 0 -1 0
v -0.4924088 0.7946551 -0.3550447
v 0.5536816 0.7946597 -0.2489026
v -0.06729457 -0.74536 0.6632572
v -0.9165487 0.3333308 -0.220973
v 0.06729444 0.7453622 -0.6632546
v 0.2669053 0.3333269 0.9042426
v -0.06128498 0.7946486 0.6039683
v 0.8958825 -0.1875861 -0.4027478
v -5.442639E-06 1 9.193043E-06
v -0.6496407 -0.3333396 0.6832653
v 0.6080519 -0.7453524 -0.2733544
v -0.5536865 -0.7946557 0.2489048
v -0.8958843 0.1875851 0.4027444
v 0.4430935 -0.3333268 -0.8322027
v 0.9422514 0.3333381 -0.03236934
v -0.5407486 -0.7453555 -0.3899181
v -0.09915181 -0.1875999 0.9772283
v 0.4924095 -0.7946548 0.3550446
v -0.9422525 -0.333336 0.03236436
v 0.0612843 -0.7946532 -0.6039625
v 0.91655 -0.3333305 0.2209681
v 0.4991637 -0.3333373 0.7998261
v -0.4430951 0.3333244 0.8322028
v -0.2669008 -0.3333296 -0.9042429
v -0.7967249 -0.1875918 -0.5744899
v 0.5407484 0.7453554 0.3899185
v 0.7967286 0.1875919 0.5744848
v 0.09915482 0.1876006 -0.9772278
v 0.6496406 0.3333421 -0.6832644
v -0.6080542 0.7453504 0.2733551
v -0.4991595 0.3333374 -0.7998286

简单的v&f着色器:

#version 450 core
layout (location = 0) in vec4 position;

void main(void)
{
    gl_Position = position;
}
#version 450 core
out vec4 FragColor;

void main(void)
{
    FragColor = vec4(1.0,1.0,1.0,1.0);
}
拉比德76

ELEMENT_ARRAY_BUFFER在陈述顶点数组对象,所以顶点数组对象具有被束缚,可结合元件阵列缓冲器之前。请参阅索引缓冲区

# create vertex buffer
GL.CreateBuffers(1, out vertBuffer);
GL.NamedBufferStorage(vertBuffer, sizeof(float) * fVerts.Count, fVArray,
                      BufferStorageFlags.MapWriteBit | BufferStorageFlags.MapReadBit);
vertLength = fVerts.Count;

# create index buffer
GL.CreateBuffers(1, out indexBuffer);
GL.NamedBufferStorage(indexBuffer, sizeof(int) * fFaces.Count, fFaces , 
                      BufferStorageFlags.None);
indexCount = fFaces.Count;

# bind vertex array object
GL.CreateVertexArrays(1, out myVAO);
GL.BindVertexArray(myVAO);

# specify array of generic vertex attribute data for currently bound vertex array object
GL.BindBuffer(BufferTarget.ArrayBuffer, vertBuffer);
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0); 
GL.EnableVertexAttribArray(0);

# associate index buffer to currently bound vertex array object
GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer);

画画:

GL.DrawElements(BeginMode.Triangles, indexCount, DrawElementsType.UnsignedInt, 0);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章