代码之家  ›  专栏  ›  技术社区  ›  MFischer

VAO在不调用glDeleteVertexArrays()的情况下被删除

  •  -1
  • MFischer  · 技术社区  · 7 年前

    立方体模型。h

     #pragma once
     #include <vector>
     #include <glad\glad.h>
    
     class CubeModel
     {
     public:
         //x y and z are dimensions of the cube
         CubeModel();
         CubeModel( float x, float y, float z);
         ~CubeModel();
    
         void Bind();
         void Unbind();
    
    private:
    
         unsigned int m_VAO, m_VBO;
    
         std::vector<float> m_vertices = {
            -0.5f, -0.5f, 0.0f,
             0.5f, -0.5f, 0.0f,
             0.0f,  0.5f, 0.0f
         };
    
         std::vector<float> m_vertices2 = {
            -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
             0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
             0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
             0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
            -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
            -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
    
            -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
             0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
             0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
             0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
            -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
            -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
    
            -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
            -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
            -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
            -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
            -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
            -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    
             0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
             0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
             0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
             0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
             0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
             0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    
            -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
             0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
             0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
             0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
            -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
            -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    
            -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
             0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
             0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
             0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
            -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
            -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
        };
    };
    

    立方体模型。清洁石油产品

    #include "CubeModel.h"
    
    CubeModel::CubeModel()
    {
        CubeModel(1.0f, 1.0f, 1.0f);
    }
    
    CubeModel::CubeModel(float x, float y, float z)
    {
        unsigned int VAO, VBO;
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
    
        glBindVertexArray(VAO);
    
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertices[0]) * m_vertices.size(), 
        m_vertices.data(), GL_STATIC_DRAW);
    
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(0);
    
        glBindVertexArray(0);
    
        m_VAO = VAO;
        m_VBO = VBO;
    }
    
    CubeModel::~CubeModel()
    {
        glDeleteVertexArrays(1, &m_VAO);
        glDeleteBuffers(1, &m_VBO);
    }
    
    void CubeModel::Bind()
    {
        glBindVertexArray(m_VAO);
    }
    
    void CubeModel::Unbind()
    {
        glBindVertexArray(0);
    }
    

    Game_状态。h(使用立方体模型):

    #pragma once
    #include "Window.h"
    #include "Shader.h"
    #include "CubeModel.h"
    
    #define TIMESTEP 1.0f/100.0f
    
    class Game_State
    {
    public:
        Game_State();
        ~Game_State();
    
        int             Run();
        bool            IsDone();
    
    private:
        void            HandleInput();
        void            Update(double deltatime);
        void            Render();
    
        Window          m_window;
        double          m_elapsedTime = 0;
        Shader          m_cubeShader;
        CubeModel       m_testCube;
    };
    

    Game_状态。cpp:

    #include "Game_State.h"
    
    Game_State::Game_State()
        : m_window("Title to be determined...", glm::vec2(1920, 1080))
        , m_cubeShader("cubeshader.vs","cubeshader.fs")
    {
    }
    
    Game_State::~Game_State()
    {
    }
    
    int Game_State::Run()
    {
    
        while (m_elapsedTime > TIMESTEP)
        {
            m_elapsedTime -= TIMESTEP;
            HandleInput();
            Update(m_elapsedTime);
        }
    
        Render();
    
        m_elapsedTime += glfwGetTime();
        glfwSetTime(0.0f);
    
        return 0;
    }
    
    void Game_State::Update(double deltatime)
    {
        m_window.Update();
    }
    
    void Game_State::Render()
    {
    
        m_window.BeginDraw(0.7f, 0.5f, 0.3f, 1.0f);
    
        m_cubeShader.use();
    
        m_testCube.Bind();
        glDrawArrays(GL_TRIANGLES, 0, 6);
    
        m_testCube.Unbind();
    
        m_window.EndDraw();
    
    }
    
    void Game_State::HandleInput()
    {
        if (glfwGetKey(m_window.GetWindow(), GLFW_KEY_F11) == GLFW_PRESS)
        {
            m_window.ToggleFullscreen();
        }
    
        if (glfwGetKey(m_window.GetWindow(), GLFW_KEY_ESCAPE) == GLFW_PRESS)
        {
            m_window.CloseWindow();
        }
    }
    
    bool Game_State::IsDone() { return m_window.IsDone(); }
    

    当我尝试调试代码时,一切正常,VAO和VBO都获得了一个ID,但当我在单独的渲染函数中将其绘制到屏幕之前调用bind函数时,它将ID为0的数组绑定。调用bind()时,m\u VAO和m\u VBO都重置为0,这是什么原因?!?!我已经尝试过直接在渲染函数中使用这个精确的代码,它可以正常工作,因此渲染看起来很好。(我正在使用GLFW和GLAD)

    2 回复  |  直到 7 年前
        1
  •  4
  •   Nicol Bolas    7 年前

    这:

    CubeModel::CubeModel()
    {
        CubeModel(1.0f, 1.0f, 1.0f);
    }
    

    是错误的。这创造了一个 CubeModel 在构造函数内。这和 delegating the constructor . 如果这是您想要的,您必须使用正确的C++11语法:

    CubeModel::CubeModel() : CubeModel(1.0f, 1.0f, 1.0f)
    {}
    

    例如 立方体模型 在技术上是可以复制的,但是 是你对复制没有特别的津贴(从本质上来说,这将 不得不

    CubeModel(const CubeModel &) = delete;
    CubeModel(CubeModel &&other) : m_VAO(other.m_VAO), m_VBO(other.m_VBO)
    {
      other.m_VAO = 0;
      other.m_VBO = 0;
    }
    

    并对移动分配操作执行类似操作。或者让它成为不可分配的。

        2
  •  1
  •   BDL Vyxzl    7 年前

    在C++中,您不能像这里那样从另一个构造函数中调用构造函数:

    CubeModel::CubeModel()
    {
        CubeModel(1.0f, 1.0f, 1.0f);
    }
    

    这里实际发生的是创建一个临时的、未命名的立方体模型,当保留默认构造函数时,该立方体模型将被删除。这就是你的VAO被删除的时候。