Рисование сетки OpenGL неправильно

Я пытаюсь создать движок OpenGL на C++, но не могу правильно отображать сетки. Меши при рендеринге создают грани, которые соединяют две случайные точки на сетке или случайную точку на сетке с 0,0,0.

Проблема видна здесь:

Поврежденный рендеринг каркаса

(Я сделал каркас, чтобы лучше видеть проблему)

Код:

// Render all meshes (Graphics.cpp)
for( int curMesh = 0; curMesh < numMesh; curMesh++ ) {
    // Save pointer of buffer
    meshes[curMesh]->updatebuf();
    Buffer buffer = meshes[curMesh]->buffer;

    // Update model matrix
    glm::mat4 mvp = Proj*View*(meshes[curMesh]->model);

    // Initialize vertex array
    glBindBuffer( GL_ARRAY_BUFFER, vertbuffer );
    glBufferData( GL_ARRAY_BUFFER, sizeof(GLfloat)*buffer.numcoords*3, meshes[curMesh]->verts, GL_STATIC_DRAW );

    // Pass information to shader
    GLuint posID = glGetAttribLocation( shader, "s_vPosition" );
    glVertexAttribPointer( posID, 3, GL_FLOAT, GL_FALSE, 0, (void*)0 );
    glEnableVertexAttribArray( posID );
    
    // Check if texture applicable
    if( meshes[curMesh]->texID != NULL && meshes[curMesh]->uvs != NULL ) {
        // Initialize uv array
        glBindBuffer( GL_ARRAY_BUFFER, uvbuffer );
        glBufferData( GL_ARRAY_BUFFER, sizeof(GLfloat)*buffer.numcoords*2, meshes[curMesh]->uvs, GL_STATIC_DRAW );

        // Pass information to shader
        GLuint uvID = glGetAttribLocation( shader, "s_vUV" );
        glVertexAttribPointer( uvID, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0) );        
        glEnableVertexAttribArray( uvID );
        
        // Set mesh texture
        glActiveTexture( GL_TEXTURE0 );
        glBindTexture( GL_TEXTURE_2D, meshes[curMesh]->texID );
        GLuint texID = glGetUniformLocation( shader, "Sampler" );
        glUniform1i( texID, 0 );
    }

    // Actiavte shader
    glUseProgram( shader );
        
    // Set MVP matrix
    GLuint mvpID = glGetUniformLocation( shader, "MVP" );
    glUniformMatrix4fv( mvpID, 1, GL_FALSE, &mvp[0][0] );

    // Draw verticies on screen
    bool wireframe = true;
    if( wireframe )
        for(int i = 0; i < buffer.numcoords; i += 3)
            glDrawArrays(GL_LINE_LOOP, i, 3);
    else
        glDrawArrays( GL_TRIANGLES, 0, buffer.numcoords );
}
// Mesh Class (Graphics.h)
class mesh {
public:
    mesh();
    void updatebuf();
    Buffer buffer;
    GLuint texID;
    bool updated;

    GLfloat* verts;
    GLfloat* uvs;

    glm::mat4 model;
};

Мой код загрузки Obj находится здесь: https://www.dropbox.com/s/tdcpg4vok11lf9d/ObjReader.txt (это довольно грубо и не организовано, но все равно должно работать)


person Nicholas Pipitone    schedule 05.04.2014    source источник
comment
Можете ли вы опубликовать свой файл примера? Вы делаете кучу предположений в своем загрузчике, которые могут или не могут учитываться данными, но без данных трудно сказать.   -  person DirkR    schedule 06.04.2014
comment
@DirkR Возможно, проблема в этом, вот файл teapot.obj, который я использую: dropbox.com/s/z8fy46x3zeadg0s/teapot.obj.txt   -  person Nicholas Pipitone    schedule 13.04.2014
comment
Хм, хорошо, это настолько тривиально, насколько это возможно, это должно работать. Так что на самом деле я рекомендую просто отказаться от собственного загрузчика и вместо этого использовать assimp (assimp.sourceforge.net), который поддерживает гораздо больше форматов и широко используется.   -  person DirkR    schedule 15.04.2014
comment
Однако написать свой собственный работающий загрузчик не невозможно. Я бы внимательно проверил данные и посмотрел, соответствует ли содержимое буфера тому, что вы ожидаете. Это утомительно, но вы обязательно найдете первопричину таким образом. Одна распространенная ошибка, которую часто допускают, заключается в том, что индексы не сдвигаются на 1 (OpenGL считает с 0, OBJ с 1). Я бы попытался вручную удалить некоторые лица из объектного файла, чтобы оставить только проблемные вершины, а затем сначала убедиться, что VBO действительно имеет правильные данные.   -  person Bartek Banachewicz    schedule 07.08.2020


Ответы (2)


Для меня это выглядит как примитивная проблема перезапуска. Трудно сказать, в чем именно проблема, не видя кода. Было бы очень полезно увидеть около 20 строк выше и ниже, включая вызовы рисования, отображающие чайник. т.е. 20 строк перед соответствующим вызовом glDrawArrays, glDrawElements или glBegin и 20 строк после.

person datenwolf    schedule 05.04.2014
comment
Я думал, что это как-то связано с перезапуском треугольников, но в файле OBJ нет ничего, что указывало бы на точку разрыва вершин, так как я узнаю, когда начинается новый список треугольников? (Кстати, я разместил код) - person Nicholas Pipitone; 05.04.2014

Это потому, что ваши треугольники не соединены, чтобы каркас выглядел идеально. В случае, если треугольники не соединены, вы должны построить индексный буфер.

person ZhefengJin    schedule 07.08.2020