【问题标题】:OpenGL/OpenTK - Multiple objects not rendering as expectedOpenGL/OpenTK - 多个对象未按预期渲染
【发布时间】:2017-09-05 16:07:10
【问题描述】:

这是我第一次使用 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();
    }

【问题讨论】:

    标签: opengl opentk


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多