使用vertexBuffer不起作用的纹理

时间:2014-06-07 12:48:39

标签: c++ opengl textures vertex-buffer

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

我认为错误在draw函数中的某处:

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] = %s\n", 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 load\n", aux);
        delete[] aux;
    }

我的最终结果是绘制了所有顶点但未应用纹理的模型。

我对OpenGL很新,所以如果事实证明这是一个简单的错误,我会提前道歉。

1 个答案:

答案 0 :(得分:0)

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

glActiveTexture(GL_TEXTURE0);

直接

之前
glBindTexture(GL_TEXTURE_2D, texturemap_IDs[0]);