使用纹理与vertexBuffer不工作

Using textures with vertexBuffer not working

本文关键字:工作 vertexBuffer 纹理      更新时间:2023-10-16

我试图使用纹理映射缓冲与顶点缓冲一起,它不工作。我正在使用lib3ds加载3DS模型。我到处搜索,我看不到我的代码有任何错误。

我认为错误是在绘制函数的某个地方:

void CModel3DS::Draw() const
{
    assert(m_TotalFaces != 0);
    glEnable(GL_TEXTURE_2D);
    // Not working!! Why?                                   
    glBindTexture(GL_TEXTURE_2D, texturemap_IDs[0]);
    glBindBuffer(GL_ARRAY_BUFFER, m_TexcoorVBO);
    glClientActiveTexture(GL_TEXTURE0);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    // Enable vertex and normal arrays
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    // Bind the vbo with the normals
    glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);
    // The pointer for the normals is NULL which means that OpenGL will use the currently bound vbo
    glNormalPointer(GL_FLOAT, 0, NULL);
    glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
    glVertexPointer(3, GL_FLOAT, 0, NULL);
    // Render the triangles
    glDrawArrays(GL_TRIANGLES, 0, m_TotalFaces * 3);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
}
CModel3DS * model;

初始化缓冲区:

// Copy vertices and normals to the memory of the GPU
void CModel3DS::CreateVBO()
{
    assert(m_model != NULL);
    // Calculate the number of faces we have in total
    GetFaces();
    // Allocate memory for our vertices and normals
    float(*vertices)[3] = new float[m_TotalFaces * 3][3];
    float(*normals)[3] = new float[m_TotalFaces * 3][3];
    float(*textures)[2] = new float[m_TotalFaces * 3][2];
    Lib3dsMesh ** meshes = m_model->meshes;
    unsigned int FinishedFaces = 0;
    // Loop through all the meshes
    for (int i = 0; i < m_model->nmeshes; i++)
    {
        lib3ds_mesh_calculate_face_normals(meshes[i], &normals[FinishedFaces * 3]);
        // Loop through every face
        for (unsigned int cur_face = 0; cur_face < meshes[i]->nfaces; cur_face++)
        {
            Lib3dsFace * face = &meshes[i]->faces[cur_face];
            for (unsigned int j = 0; j < 3; j++)
            {
                memcpy(&vertices[FinishedFaces * 3 + j], meshes[i]->vertices[face->index[j]], 3 * sizeof(float));
                memcpy(&textures[FinishedFaces * 3 + j], meshes[i]->texcos[face->index[j]], 2 * sizeof(float));
            }
            FinishedFaces++;
        }
    }
    // Generate a Vertex Buffer Object and store it with our vertices
    glGenBuffers(1, &m_VertexVBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
    glBufferData(GL_ARRAY_BUFFER, 3* sizeof(float) * 3 * m_TotalFaces, vertices, GL_STATIC_DRAW);
    // Generate another Vertex Buffer Object and store the normals in it
    glGenBuffers(1, &m_NormalVBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);
    glBufferData(GL_ARRAY_BUFFER, 3* sizeof(float) * 3 * m_TotalFaces, normals, GL_STATIC_DRAW);
    // Generate Vertex Buffer Object and store texture coordinates in it
    glGenBuffers(1, &m_TexcoorVBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_TexcoorVBO);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(float)* 2) * 3 * m_TotalFaces, textures, GL_STATIC_DRAW);
    // Clean up our allocated memory
    delete[] vertices;
    delete[] normals;
    delete[] textures;
    // We no longer need lib3ds
    lib3ds_file_free(m_model);
    m_model = NULL;
}

最后加载tga纹理,我使用外部库,所以我的代码很简单:

for (int i = 0; i < m_model->nmaterials; i++)
    {
        char * aux = new char[strlen("tex/") + strlen(m_model->materials[i]->texture1_map.name) + 1];
        strcpy(aux, "tex/");
        strcat(aux, m_model->materials[i]->texture1_map.name);
        printf("Map[%d] = %sn", i, aux);
        texturemap_IDs[i] = load_texture_TGA(aux, NULL, NULL, GL_REPEAT, GL_REPEAT);
        if (texturemap_IDs[i] == 0)
            printf("%s texture failed to loadn", aux);
        delete[] aux;
    }

我的最终结果是一个所有顶点绘制的模型,但没有应用纹理。

我对OpenGL非常陌生,所以如果它被证明是一个简单的错误,我提前道歉。

据我所知,在绑定纹理之前,你需要指向,你想要绑定在哪里。尝试添加

glActiveTexture(GL_TEXTURE0);

glBindTexture(GL_TEXTURE_2D, texturemap_IDs[0]);