OpenGL:如何在Intel HD Graphics 4000 GPU上渲染2个简单的VAO?

时间:2014-11-11 23:15:32

标签: opengl 3d gpu intel opentk

总结:我的原始问题和观察结果后面是英特尔高清显卡4000 GPU的更新工作OpenGL代码。

原始问题: Nvidia NVS 4200m GPU上显示了两个立方体,Intel HD Graphics 4000 GPU上显示了一个立方体。

  • 使用OpenGL 3.2前向配置文件和OpenTK在屏幕上呈现2个简单的多维数据集
  • 它显示了在Intel HD Graphics 4000上以(0,0,0)为中心的第一个多维数据集,其中包含最新的GPU驱动程序7/2/2014 ver 10.18.0010.3621。它应该显示2个立方体。
  • 我们正在使用顶点数组对象(VAO),顶点缓冲区,索引缓冲区,属性,法线和GLSL着色器
  • 在激活VAO之后重新绑定元素数组缓冲区,之后glDrawElements()仍然在Intel上显示一个多维数据集,在Nvidia上显示两个多维数据集(VAO and element array buffer state
  • 着色
  • glGetError()调用在每次OpenGL调用后完成,并且没有返回任何错误。
  • 第一个立方体以(0,0,0)为中心,第二个立方体偏移到(4,0,0),两个立方体围绕(0,0,0)
  • 旋转
  • 我们首先构建缓冲区,然后构建属性,然后创建VAO并将缓冲区/属性挂钩到VAO。英特尔是否需要特殊订购?请参阅:OpenGL, VAOs and multiple buffers
  • glDrawElements()似乎没有帮助后停用VAO

以下是基于OpenTK示例程序“Open GL 3.0”的源代码。它应该显示两个立方体,用定向光源旋转大约(0,0,0)。

更新:2014年11月17日:以下代码适用于Nvidia和Intel HD Graphics 4000 GPU。
变化:

  • 在为与VAO相关联的顶点,索引,...创建缓冲区之前创建VAO
  • 将GL.BindAttribLocation()调用移至链接着色器之前
  • 在使用GL.DrawElements()渲染3d对象之前重新绑定元素数组缓冲区
  • 渲染后取消激活缓冲区和VAO

    using System;
    using System.Diagnostics;
    using System.IO;
    
    using OpenTK;
    using OpenTK.Graphics;
    using OpenTK.Graphics.OpenGL;
    
    namespace Examples.Tutorial
    {
        [Example("OpenGL 3.0 v2 2 vao works", ExampleCategory.OpenGL, "3.x", Documentation="HelloGL3 - v2 - create vao first")]
        public class HelloGL3v3 : GameWindow
        {
            string vertexShaderSource = @"
    #version 130
    
    precision highp float;
    
    uniform mat4 projection_matrix;
    uniform mat4 modelview_matrix;
    
    in vec3 in_position;
    in vec3 in_normal;
    
    out vec3 normal;
    
    void main(void)
    {
      //works only for orthogonal modelview
      normal = (modelview_matrix * vec4(in_normal, 0)).xyz;
    
      gl_Position = projection_matrix * modelview_matrix * vec4(in_position, 1);
    }";
    
            string fragmentShaderSource = @"
    #version 130
    
    precision highp float;
    
    const vec3 ambient = vec3(0.1, 0.1, 0.1);
    const vec3 lightVecNormalized = normalize(vec3(0.5, 0.5, 20.0));
    //const vec3 lightVecNormalized = normalize(vec3(0.5, 0.5, 2.0));
    const vec3 lightColor = vec3(0.9, 0.9, 0.7);
    
    in vec3 normal;
    
    out vec4 out_frag_color;
    
    void main(void)
    {
      float diffuse = clamp(dot(lightVecNormalized, normalize(normal)), 0.0, 1.0);
      out_frag_color = vec4(ambient + diffuse * lightColor, 1.0);
    }";
    
            int vertexShaderHandle,
                fragmentShaderHandle,
                shaderProgramHandle,
                modelviewMatrixLocation,
                projectionMatrixLocation;
    
    
            Matrix4 projectionMatrix, modelviewMatrix;
    
            public HelloGL3v3() : base(800, 600,
                new GraphicsMode(), "OpenGL 3 Example", 0,
                DisplayDevice.Default, 3, 2,
                GraphicsContextFlags.ForwardCompatible | GraphicsContextFlags.Debug)
            { }
    
            protected override void OnLoad (System.EventArgs e)
            {
                VSync = VSyncMode.On;
    
                CreateShaders();
                CreateVaoOne();
                CreateVaoTwo();
    
                // Other state
                GL.Enable(EnableCap.DepthTest);    E();
                GL.ClearColor(System.Drawing.Color.MidnightBlue);  E();
            }
    
            void CreateShaders()
            {
                vertexShaderHandle = GL.CreateShader(ShaderType.VertexShader);            E();
                fragmentShaderHandle = GL.CreateShader(ShaderType.FragmentShader);            E();
    
                GL.ShaderSource(vertexShaderHandle, vertexShaderSource);            E();
                GL.ShaderSource(fragmentShaderHandle, fragmentShaderSource);            E();
    
                GL.CompileShader(vertexShaderHandle);            E();
                GL.CompileShader(fragmentShaderHandle);            E();
    
                Debug.WriteLine(GL.GetShaderInfoLog(vertexShaderHandle));
                Debug.WriteLine(GL.GetShaderInfoLog(fragmentShaderHandle));
    
                // Create program
                shaderProgramHandle = GL.CreateProgram();            E();
    
                GL.AttachShader(shaderProgramHandle, vertexShaderHandle);            E();
                GL.AttachShader(shaderProgramHandle, fragmentShaderHandle);            E();
    
                //BindAttribLocation() for shader needs to be done before linking the shader program
                GL.BindAttribLocation(shaderProgramHandle, 0, "in_position");           E();
                GL.BindAttribLocation(shaderProgramHandle, 1, "in_normal");            E();
    
                GL.LinkProgram(shaderProgramHandle);            E();
    
                Debug.WriteLine(GL.GetProgramInfoLog(shaderProgramHandle));
    
                GL.UseProgram(shaderProgramHandle);           E();
    
                // get uniform locations
                projectionMatrixLocation = GL.GetUniformLocation(shaderProgramHandle, "projection_matrix");      E();
                modelviewMatrixLocation = GL.GetUniformLocation(shaderProgramHandle, "modelview_matrix");       E();
    
                float aspectRatio = ClientSize.Width / (float)(ClientSize.Height);
                Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspectRatio, 1, 100, out projectionMatrix);
                modelviewMatrix = Matrix4.LookAt(new Vector3(0, 13, 15), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
    
                GL.UniformMatrix4(projectionMatrixLocation, false, ref projectionMatrix);       E();
                GL.UniformMatrix4(modelviewMatrixLocation, false, ref modelviewMatrix);      E();
            }
    
            int vaoHandle,
                eboHandle;
    
            int[] indicesVboData = new int[]{
                 // front face
                    0, 1, 2, 2, 3, 0,
                    // top face
                    3, 2, 6, 6, 7, 3,
                    // back face
                    7, 6, 5, 5, 4, 7,
                    // left face
                    4, 0, 3, 3, 7, 4,
                    // bottom face
                    0, 1, 5, 5, 4, 0,
                    // right face
                    1, 5, 6, 6, 2, 1, };
    
    
            void CreateVaoOne()
            {
                int positionVboHandle,
                normalVboHandle;
    
                Vector3[] positionVboData = new Vector3[]{
                new Vector3(-1.0f, -1.0f,  1.0f),
                new Vector3( 1.0f, -1.0f,  1.0f),
                new Vector3( 1.0f,  1.0f,  1.0f),
                new Vector3(-1.0f,  2.0f,  1.0f),
                new Vector3(-1.0f, -1.0f, -1.0f),
                new Vector3( 1.0f, -1.0f, -1.0f), 
                new Vector3( 1.0f,  1.0f, -1.0f),
                new Vector3(-1.0f,  1.0f, -1.0f) };
    
    
                // GL3 allows us to store the vertex layout in a "vertex array object" (VAO).
                // This means we do not have to re-issue VertexAttribPointer calls
                // every time we try to use a different vertex layout - these calls are
                // stored in the VAO so we simply need to bind the correct VAO.
                GL.GenVertexArrays(1, out vaoHandle);            E();
                GL.BindVertexArray(vaoHandle);            E();
                //----------------------------------------------------------------------------
                {
                    GL.GenBuffers(1, out positionVboHandle);                E();
                    GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle);                E();
                    GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, new IntPtr(positionVboData.Length * Vector3.SizeInBytes), positionVboData, BufferUsageHint.StaticDraw);                E();
    
                    GL.EnableVertexAttribArray(0);                E();
                    GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle);                E();
                    GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);                E();
                    //GL.BindAttribLocation(shaderProgramHandle, 0, "in_position");                E();
                }
                //----------------------------------------------------------------------------
                {
                    GL.GenBuffers(1, out normalVboHandle);                E();
    
                    GL.BindBuffer(BufferTarget.ArrayBuffer, normalVboHandle);                E();
                    GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, new IntPtr(positionVboData.Length * Vector3.SizeInBytes), positionVboData, BufferUsageHint.StaticDraw);                E();
    
                    GL.EnableVertexAttribArray(1);                E();
                    GL.BindBuffer(BufferTarget.ArrayBuffer, normalVboHandle);                E();
                    GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);                E();
                    //GL.BindAttribLocation(shaderProgramHandle, 1, "in_normal");                E();
                }
    
                {
                    GL.GenBuffers(1, out eboHandle);                E();
    
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle);                E();
    
                    GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(sizeof(uint) * indicesVboData.Length), indicesVboData, BufferUsageHint.StaticDraw);  E();
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle);       E();
                }
                //----------------------------------------------------------------------------
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);    E();
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);    E();
    
                GL.BindVertexArray(0);   E();
            }
    
            int vaoHandle2,
                eboHandle2;
    
            int[] indicesVboData2 = new int[]{
                 // front face
                    0, 1, 2, 2, 3, 0,
                    // top face
                    3, 2, 6, 6, 7, 3,
                    // back face
                    7, 6, 5, 5, 4, 7,
                    // left face
                    4, 0, 3, 3, 7, 4,
                    // bottom face
                    0, 1, 5, 5, 4, 0,
                    // right face
                    1, 5, 6, 6, 2, 1, };
    
            void CreateVaoTwo()
            {
                int positionVboHandle2,
                 normalVboHandle2;
    
                Vector3[] positionVboData2 = new Vector3[]{
                new Vector3(-0.5f, -0.5f,  0.5f),
                new Vector3( 0.5f, -0.5f,  0.5f),
                new Vector3( 0.5f,  0.5f,  0.5f),
                new Vector3(-0.5f,  0.5f,  5.5f),
                new Vector3(-0.5f, -0.5f, -0.5f),
                new Vector3( 0.5f, -0.5f, -0.5f), 
                new Vector3( 0.5f,  0.5f, -0.5f),
                new Vector3(-0.5f,  0.5f, -0.5f) };
    
                Vector3[] normalsVboData2 = new Vector3[]{
                new Vector3(-1.0f, -1.0f,  1.0f),
                new Vector3( 1.0f, -1.0f,  1.0f),
                new Vector3( 1.0f,  1.0f,  1.0f),
                new Vector3(-1.0f,  1.0f,  1.0f),
                new Vector3(-1.0f, -1.0f, -1.0f),
                new Vector3( 1.0f, -1.0f, -1.0f), 
                new Vector3( 1.0f,  1.0f, -1.0f),
                new Vector3(-1.0f,  1.0f, -1.0f) };
    
                //translate the points in the second cube away from the origin
                for (int i = 0; i < positionVboData2.Length; i++)
                    positionVboData2[i] = Vector3.Add(positionVboData2[i], new Vector3(2.0f, 0f, 0f));
    
                GL.GenVertexArrays(1, out vaoHandle2);  E();
                GL.BindVertexArray(vaoHandle2);  E();
    
                //----------------------------------------------------------------------------
                //vertex array
                GL.GenBuffers(1, out positionVboHandle2);            E();
                GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle2);            E();
                GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, new IntPtr(positionVboData2.Length * Vector3.SizeInBytes), positionVboData2, BufferUsageHint.StaticDraw);            E();
    
                GL.EnableVertexAttribArray(0);  E();
                GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle2);  E();
                GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);  E();
                //GL.BindAttribLocation(shaderProgramHandle, 0, "in_position");  E();
    
                //------------------------------------------------------------
                //normals array
                GL.GenBuffers(1, out normalVboHandle2);     E();
                GL.BindBuffer(BufferTarget.ArrayBuffer, normalVboHandle2);     E();
                GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, new IntPtr(normalsVboData2.Length * Vector3.SizeInBytes), normalsVboData2, BufferUsageHint.StaticDraw);     E();
    
                GL.EnableVertexAttribArray(1);   E();
                GL.BindBuffer(BufferTarget.ArrayBuffer, normalVboHandle2);   E();
                GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);  E();
                //GL.BindAttribLocation(shaderProgramHandle, 1, "in_normal");  E();
    
                //------------------------------------------------------------
                //element (index) array
                GL.GenBuffers(1, out eboHandle2);       E();
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle2);      E();
                GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(sizeof(uint) * indicesVboData2.Length), indicesVboData2, BufferUsageHint.StaticDraw);      E();
    
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle2); E();
    
                //------------------------------------------------------------
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0); E();
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);   E();
    
                GL.BindVertexArray(0);   E();
            }
    
            protected override void OnUpdateFrame(FrameEventArgs e)
            {
                if ((Keyboard[OpenTK.Input.Key.ControlLeft]) || (Keyboard[OpenTK.Input.Key.ControlRight]))
                    return;
    
                Matrix4 rotation = Matrix4.CreateRotationY((float)e.Time);
                Matrix4.Mult(ref rotation, ref modelviewMatrix, out modelviewMatrix);
                GL.UniformMatrix4(modelviewMatrixLocation, false, ref modelviewMatrix);
    
                if (Keyboard[OpenTK.Input.Key.Escape])
                    Exit();
            }
    
            protected override void OnRenderFrame(FrameEventArgs e)
            {
                GL.Viewport(0, 0, Width, Height);  E();
    
                GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);  E();
    
                //GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
    
                GL.BindVertexArray(vaoHandle);  E();
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle);    E();
                GL.DrawElements(BeginMode.Triangles, indicesVboData.Length, DrawElementsType.UnsignedInt, IntPtr.Zero); E();
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
                GL.BindVertexArray(0);
    
                //-----------------------------------------------------------------------
                GL.BindVertexArray(vaoHandle2); E();
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle2);   E();
                GL.DrawElements(BeginMode.Triangles, indicesVboData2.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);  E();
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);     E();
                GL.BindVertexArray(0);   E();
    
                SwapBuffers(); E();
            }
    
            [STAThread]
            public static void Main()
            {
                using (HelloGL3v3 example = new HelloGL3v3())
                {
                    Utilities.SetWindowTitle(example);
                    example.Run(30);
                }
            }
    
            private void E()
            {
                ErrorCode errorCode = GL.GetError();
                if (errorCode == ErrorCode.NoError)
                    return;
    
                throw new Exception("Error code - " + errorCode.ToString()); // some open GL Error
            }
        }
    }
    

0 个答案:

没有答案