簡體   English   中英

glDrawElement,為什么會導致程序停止工作?

[英]glDrawElement, why does it cause the program to stop working?

我對此感到沮喪。 我正在嘗試使用“頂點緩沖對象”渲染一個多維數據集,並且正在學習有關“投影”的知識,所以我試圖制作一個多維數據集的框架。 但是,此代碼不起作用。 當我在Code :: Blocks上運行該程序時,該程序停止工作。

程序停止工作

我試圖通過注釋render()方法的內容來找出原因,然后程序不會停止工作。 所以這行代碼

glDrawElements(GL_TRIANGLES, m_index->size(), GL_UNSIGNED_INT, 0); // render the cube

可能是問題的根源。 但是我不知道如何解決這個問題,因為這就是我通常所做的(我編寫了類似的程序,並且它們起作用了)

非常感謝您的幫助!

ProjectionCube::ProjectionCube()
{
    rotationAngle = 0.0;
}

bool ProjectionCube::initialize()
{
#ifdef _WIN32
    glGenBuffers = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffers");
    glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
    glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
#else
    glGenBuffers = (PFNGLGENBUFFERSARBPROC)glXGetProcAddress((const GLubyte*)"glGenBuffers");
    glBindBuffer = (PFNGLBINDBUFFERPROC)glXGetProcAddress((const GLubyte*)"glBindBuffer");
    glBufferData = (PFNGLBUFFERDATAPROC)glXGetProcAddress((const GLubyte*)"glBufferData");
#endif

    if (!glGenBuffers || !glBindBuffer || !glBufferData)
    {
        std::cerr << "VBOs are not supported by your graphics card" << std::endl;
        return false;
    }

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    initializeVertexBuffers();

    // bind vertex buffer and index buffer
    // set vertex pointer to the buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbos[INDEX_BUFFER]);
    glBindBuffer(GL_ARRAY_BUFFER, m_vbos[VERTEX_BUFFER]);
    glVertexPointer(3, GL_FLOAT, 0, 0); 

    // no color buffer to bind
    return true;
}

void ProjectionCube::initializeVertexBuffers()
{
    const float size = 0.5f;
    m_vertex = getCubeVertices(size);

    for (int i = 0; i < m_vertex->size(); i++) {
        std::cout << m_vertex->at(i) << ", ";
    }
    std::cout << std::endl;

    static const unsigned int index[] = {//using triangles to render
                                  0, 1, 2, 0, 2, 3, //bottom
                                  0, 4, 5, 0, 1, 5, //back
                                  0, 4, 7, 0, 3, 7, //left
                                  1, 5, 6, 1, 2, 6, //right
                                  4, 5, 6, 4, 7, 6, //top
                                  2, 6, 7, 2, 3, 7}; // front

    m_index = new vector<unsigned int>(index, index + sizeof(index) / sizeof(index[0]));

    for (int i = 0; i < m_index->size(); i++) {
        std::cout << m_index->at(i) << ", ";
    }
    std::cout << std::endl;

    glGenBuffers(1, &m_vbos[VERTEX_BUFFER]);
    glBindBuffer(GL_ARRAY_BUFFER, m_vbos[VERTEX_BUFFER]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * m_vertex->size(),
                 &m_vertex->at(0), GL_STATIC_DRAW);

    glGenBuffers(1, &m_vbos[INDEX_BUFFER]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbos[INDEX_BUFFER]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * m_index->size(),
                 &m_index->at(0), GL_STATIC_DRAW);
}

void ProjectionCube::render(float m_x, float m_y, float m_z)
{
   glTranslatef(m_x, m_y, m_z); // move to where the cube is located
    //glRotatef(rotationAngle, 0.5f, 0.0f, 0.0f);
   glDrawElements(GL_TRIANGLES, m_index->size(), GL_UNSIGNED_INT, 0); // render the cube
}

void ProjectionCube::animate(float dt)
{
    const float SPEED = 15.0f;
    rotationAngle += SPEED * dt;

    if (rotationAngle >= 360 || rotationAngle <= 0) {
        rotationAngle = -rotationAngle;
    }
}

vector<GLfloat>* ProjectionCube::getCubeVertices(float r)
{
    static const GLfloat vertices[] = {//bottom square
                                       -r, -r, -r,
                                       r, -r, -r,
                                       r, -r, r,
                                       -r, -r, r,
                                       //top square
                                       -r, r, -r,
                                       r, r, -r,
                                       r, r, r,
                                       -r, r, r,};
    vector<GLfloat>* result = new vector<GLfloat>(vertices, vertices + sizeof(vertices) / sizeof(vertices[0]));
    return result;
}

由於您未在調用render時發布消息,因此我只能建議您不要使用new vector 據我所知,沒有必要。

由於在render函數中使用m_index並假設m_index是指向矢量的指針時會發生錯誤,因此不需要將其作為指針(假設它是ProjectionCube的成員變量)。

new vector有兩個問題。 為什么您的程序在getCubeVertices函數中動態分配a? 以下內容刪除了動態分配:

vector<GLfloat> ProjectionCube::getCubeVertices(float r)
{
    static const GLfloat vertices[] = {//bottom square
                                       -r, -r, -r,
                                       r, -r, -r,
                                       r, -r, r,
                                       -r, -r, r,
                                       //top square
                                       -r, r, -r,
                                       r, r, -r,
                                       r, r, r,
                                       -r, r, r,};
   return vector<GLfloat>(vertices, vertices + sizeof(vertices) / sizeof(vertices[0]));
}

然后在InitializeVertexBuffers()m_vertex成員變量不再是指針,而是對象:

std::vector<GLfloat> m_vertex;  // assuming these are member variables in your class
std::vector<unsigned int> m_index;
//...
void ProjectionCube::initializeVertexBuffers()
{
    const float size = 0.5f;
    m_vertex = getCubeVertices(size);
    //...
    m_index = vector<unsigned int>(index, index + sizeof(index) / sizeof(index[0]));

同樣,不需要new vector 現在,您使用m_index. m_vertex.

現在,與您之前所做的相比,這能給您帶來什么好處? 好了,現在可以保證調用renderm_index有效。 因為m_index不再是指針,所以m_index釋放m_index或損壞指針等。

您還可以使用上述方法消除潛在的內存泄漏。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM