Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL DrawArray仅绘制一个三角形/直线/点(OpenTK/C#)_C#_Opengl_Glsl_Opentk - Fatal编程技术网

OpenGL DrawArray仅绘制一个三角形/直线/点(OpenTK/C#)

OpenGL DrawArray仅绘制一个三角形/直线/点(OpenTK/C#),c#,opengl,glsl,opentk,C#,Opengl,Glsl,Opentk,在这个基本的渲染测试中,我从一个文件中加载了32个顶点的数据。当它绘制时,它将只绘制一个基本体,而忽略数组的其余部分。例如,如果我调用GL.drawArray(PrimitiveType.Triangles,I,3)它将绘制元素I 数组包含的数据远不止一个三角形,因为这里的示例代码每次单击时都会绘制一个不同的三角形,但每次渲染时也只有一个三角形。如果我使用不同的int-first参数多次调用DrawArrays,它还会为每次调用绘制一个额外的三角形。(我敢肯定,将所有数据放入GPU缓冲区的目的不

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

数组包含的数据远不止一个三角形,因为这里的示例代码每次单击时都会绘制一个不同的三角形,但每次渲染时也只有一个三角形。如果我使用不同的int-first参数多次调用
DrawArrays
,它还会为每次调用绘制一个额外的三角形。(我敢肯定,将所有数据放入GPU缓冲区的目的不是为了让您可以进行无数次draw调用。)

我曾尝试使用DrawArray的drawelements作为替代品,但无论我为参数设置了什么,我都会得到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&f着色器:

#版本450核心
vec4位置的布局(位置=0);
真空总管(真空)
{
gl_位置=位置;
}
#版本450核心
out vec4 FragColor;
真空总管(真空)
{
FragColor=vec4(1.0,1.0,1.0,1.0);
}

中说明了
元素数组缓冲区
,因此必须先绑定顶点数组对象,然后才能绑定元素数组缓冲区。看

图纸:

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

中说明了
元素数组缓冲区
,因此必须先绑定顶点数组对象,然后才能绑定元素数组缓冲区。看

图纸:

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

@拉比它第一次渲染的时候就是这样的,因为第一次我是0。它只渲染一个三角形(使用顶点0,1,2),然后停止。下一次通过它渲染一个三角形(使用顶点1、2、3)等。我还使用它渲染了一个使用所有32个顶点的lineloop/linestrip,这很有效(它渲染了一大堆线),所以这是另一种方式,我确定所有(或至少超过3个)顶点都可用。使用DrawArray时没有访问冲突。如果我将它设置为31,它将只绘制一条线,>31它不会绘制任何内容,但不会崩溃或报告任何错误。我只有在尝试使用抽屉元素时才会遇到accessviolation。问题是,“如何让它渲染整个数组,而不仅仅是一个三角形?”如果我将它设置为从0开始,并且有32个顶点,那么它(据我所知)应该渲染三角形,直到顶点用完为止。32不能被3整除。但是
GL.drawArray(PrimitiveType.Triangles,0,30)将呈现10个三角形primitives@Rabbid76这正是它第一次渲染时所做的,因为第一次渲染时i为0。它只渲染一个三角形(使用顶点0,1,2),然后停止。下一次通过它渲染一个三角形(使用顶点1、2、3)等。我还使用它渲染了一个使用所有32个顶点的lineloop/linestrip,这很有效(它渲染了一大堆线),所以这是另一种方式,我确定所有(或至少超过3个)顶点都可用。使用DrawArray时没有访问冲突。如果我将它设置为31,它将只绘制一条线,>31它不会绘制任何内容,但不会崩溃或报告任何错误。我只有在尝试使用抽屉元素时才会遇到accessviolation。问题是,“如何让它渲染整个数组,而不仅仅是一个三角形?”如果我将它设置为从0开始,并且有32个顶点,那么它(据我所知)应该渲染三角形,直到顶点用完为止。32不能被3整除。但是
GL.drawArray(PrimitiveType.Triangles,0,30)
将渲染10个三角形基本体,这至少消除了崩溃。我想我还需要设置atttributes并启用此缓冲区等,以使其绘制面,但使用顶点数组作为模板应该更容易。谢谢,这至少消除了崩溃。我想我还必须设置AttAttributes并启用此缓冲区等,才能让它绘制面,但使用顶点数组作为模板应该更容易。
GL.DrawElements(BeginMode.Triangles, indexCount, DrawElementsType.UnsignedInt, 0);