OpenGL / OpenTK - 多个对象无法按预期呈现

时间:2017-04-10 14:39:27

标签: opengl opentk

这是我第一次使用OpenGL / OpenTK,并且在尝试渲染两个对象时,其中一个对象无法正确渲染。我已经尝试过代码,似乎无法弄清楚正在发生什么。我坚持认为我错误地使用了mVAO / mVBO数组。

The object on top of the cylinder is the one that isn't rendering properly

and this is how that object should look

第二个物体只是一个圆柱体,它不会像第一个物体那样变形。

这是我的代码:

    private int[] mVBO_IDs = new int[4];
    private int[] mVAO_IDs = new int[3];
    private ShaderUtility mShader;
    private ModelUtility mSphereModelUtility;
    private ModelUtility mCylinderModelUtility;
    private Matrix4 mView, mSphereModel, mGroundModel, mCylinderModel;

    protected override void OnLoad(EventArgs e)
    {
        // Set some GL state
        GL.ClearColor(Color4.LightBlue);
        GL.Enable(EnableCap.DepthTest);
        GL.Enable(EnableCap.CullFace);

        mShader = new ShaderUtility(@"Lab3/Shaders/vPassThrough.vert", @"Lab3/Shaders/fLighting.frag");
        GL.UseProgram(mShader.ShaderProgramID);
        int vPositionLocation = GL.GetAttribLocation(mShader.ShaderProgramID, "vPosition");
        int vNormalLocation = GL.GetAttribLocation(mShader.ShaderProgramID, "vNormal");

        GL.GenVertexArrays(mVAO_IDs.Length, mVAO_IDs);
        GL.GenBuffers(mVBO_IDs.Length, mVBO_IDs);

        float[] squareVertices = new float[] {-10, 0, -10,0,1,0,
                                         -10, 0, 10,0,1,0,
                                         10, 0, 10,0,1,0,
                                         10, 0, -10,0,1,0,};

        /// Floor
        GL.BindVertexArray(mVAO_IDs[0]);
        GL.BindBuffer(BufferTarget.ArrayBuffer, mVBO_IDs[0]);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(squareVertices.Length * sizeof(float)), squareVertices, BufferUsageHint.StaticDraw);

        int size;
        GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out size);
        if (squareVertices.Length * sizeof(float) != size)
        {
            throw new ApplicationException("Vertex data not loaded onto graphics card correctly");
        }

        GL.EnableVertexAttribArray(vPositionLocation);
        GL.VertexAttribPointer(vPositionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0);
        GL.EnableVertexAttribArray(vNormalLocation);
        GL.VertexAttribPointer(vNormalLocation, 3, VertexAttribPointerType.Float, true, 6 * sizeof(float), 3);

        /// Model 1
        mSphereModelUtility = ModelUtility.LoadModel(@"Utility/Models/model.bin"); 

        GL.BindVertexArray(mVAO_IDs[1]);
        GL.BindBuffer(BufferTarget.ArrayBuffer, mVBO_IDs[1]);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(mSphereModelUtility.squareVertices.Length * sizeof(float)), mSphereModelUtility.squareVertices, BufferUsageHint.StaticDraw);           
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, mVBO_IDs[2]);
        GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(mSphereModelUtility.Indices.Length * sizeof(float)), mSphereModelUtility.Indices, BufferUsageHint.StaticDraw);

        GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out size);
        if (mSphereModelUtility.squareVertices.Length * sizeof(float) != size)
        {
            throw new ApplicationException("Vertex data not loaded onto graphics card correctly");
        }

        GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out size);
        if (mSphereModelUtility.Indices.Length * sizeof(float) != size)
        {
            throw new ApplicationException("Index data not loaded onto graphics card correctly");
        }

        GL.EnableVertexAttribArray(vPositionLocation);
        GL.VertexAttribPointer(vPositionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0);
        GL.EnableVertexAttribArray(vNormalLocation);
        GL.VertexAttribPointer(vNormalLocation, 3, VertexAttribPointerType.Float, true, 6 * sizeof(float), 0);

        GL.BindVertexArray(0);

        /// Model 2
        mCylinderModelUtility = ModelUtility.LoadModel(@"Utility/Models/cylinder.bin");

        GL.BindVertexArray(mVAO_IDs[2]);
        GL.BindBuffer(BufferTarget.ArrayBuffer, mVBO_IDs[2]);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(mCylinderModelUtility.squareVertices.Length * sizeof(float)), mCylinderModelUtility.squareVertices, BufferUsageHint.StaticDraw);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, mVBO_IDs[3]);
        GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(mCylinderModelUtility.Indices.Length * sizeof(float)), mCylinderModelUtility.Indices, BufferUsageHint.StaticDraw);

        GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out size);
        if (mCylinderModelUtility.squareVertices.Length * sizeof(float) != size)
        {
            throw new ApplicationException("Vertex data not loaded onto graphics card correctly");
        }

        GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out size);
        if (mCylinderModelUtility.Indices.Length * sizeof(float) != size)
        {
            throw new ApplicationException("Index data not loaded onto graphics card correctly");
        }

        GL.EnableVertexAttribArray(vPositionLocation);
        GL.VertexAttribPointer(vPositionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0);
        GL.EnableVertexAttribArray(vNormalLocation);
        GL.VertexAttribPointer(vNormalLocation, 3, VertexAttribPointerType.Float, true, 6 * sizeof(float), 0);

        GL.BindVertexArray(0);

        /// Positions
        mView = Matrix4.CreateTranslation(0, -1.5f, 0);
        int uView = GL.GetUniformLocation(mShader.ShaderProgramID, "uView");
        GL.UniformMatrix4(uView, true, ref mView);

        mGroundModel = Matrix4.CreateTranslation(0, 0, -5f);
        mSphereModel = Matrix4.CreateTranslation(0, 3f, -5f);
        mCylinderModel = Matrix4.CreateTranslation(0, 1f, -5f);

        Vector3 t = mSphereModel.ExtractTranslation();
        Matrix4 translation = Matrix4.CreateTranslation(t);
        Matrix4 inverseTranslation = Matrix4.CreateTranslation(-t);
        mSphereModel = mSphereModel * inverseTranslation * Matrix4.CreateRotationY((float)(Math.PI * -90 / 180.0)) *
        translation;

        t = mCylinderModel.ExtractTranslation();
        translation = Matrix4.CreateTranslation(t);
        inverseTranslation = Matrix4.CreateTranslation(-t);
        mCylinderModel = mCylinderModel * inverseTranslation * Matrix4.CreateRotationY((float)(Math.PI * -90 / 180.0)) *
        translation;

        /// Lighting
        int uLightPositionLocation = GL.GetUniformLocation(mShader.ShaderProgramID, "uLightPosition");
        Vector4 lightPosition = Vector4.Transform(new Vector4(3, 5, -5f, 1), mView);
        GL.Uniform4(uLightPositionLocation, lightPosition);

        base.OnLoad(e);
    }

    protected override void OnRenderFrame(FrameEventArgs e)
    {
        base.OnRenderFrame(e);
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);


        int uModel = GL.GetUniformLocation(mShader.ShaderProgramID, "uModel");
        GL.UniformMatrix4(uModel, true, ref mGroundModel);  

        GL.BindVertexArray(mVAO_IDs[0]);
        GL.DrawArrays(PrimitiveType.TriangleFan, 0, 4);

        Matrix4 m = mSphereModel * mGroundModel;
        uModel = GL.GetUniformLocation(mShader.ShaderProgramID, "uModel");
        GL.UniformMatrix4(uModel, true, ref m); 

        GL.BindVertexArray(mVAO_IDs[1]);
        GL.DrawElements(PrimitiveType.Triangles, mSphereModelUtility.Indices.Length, DrawElementsType.UnsignedInt, 0);

        m = mCylinderModel * mGroundModel;
        uModel = GL.GetUniformLocation(mShader.ShaderProgramID, "uModel");
        GL.UniformMatrix4(uModel, true, ref m);

        GL.BindVertexArray(mVAO_IDs[2]);
        GL.DrawElements(PrimitiveType.Triangles, mCylinderModelUtility.Indices.Length, DrawElementsType.UnsignedInt, 0);

        GL.BindVertexArray(0);
        this.SwapBuffers();
    }

1 个答案:

答案 0 :(得分:0)

事实证明,我怀疑是错误地绑定了mVAO / mVBO阵列。我只需要增加mVBO数组大小,然后将缓冲区绑定到正确的数组索引。