Использование glDrawElements не рисует мой файл .obj - PullRequest
1 голос
/ 16 января 2011

Я пытаюсь правильно импортировать файл .OBJ из 3ds Max.Я получил это с помощью glBegin () и glEnd () из предыдущего вопроса здесь, но, очевидно, имел очень низкую производительность, поэтому сейчас я пытаюсь использовать glDrawElements.

Я импортирую шахматную доску, ее игровые фигуры и т. Д. Доска, каждая игровая фигура и каждый квадрат на доске хранятся в структуре GroupObject.Я храню данные следующим образом:

struct Vertex
{
    float position[3];
    float texCoord[2];
    float normal[3];
    float tangent[4];
    float bitangent[3];
};

struct Material
{
    float ambient[4];
    float diffuse[4];
    float specular[4];
    float shininess;        // [0 = min shininess, 1 = max shininess]
    float alpha;            // [0 = fully transparent, 1 = fully opaque]

    std::string name;
    std::string colorMapFilename;
    std::string bumpMapFilename;

   std::vector<int> indices;
   int id;
  };

 //A chess piece or square
 struct GroupObject
 {
     std::vector<Material *> materials;
     std::string    objectName;
     std::string    groupName;
     int      index;
 };

Все вершины - это треугольники, поэтому всегда есть 3 точки.Когда я перебираю секцию граней f в файле obj, я сохраняю v0, v1 и v2 в индексах Material->.(Я делаю v [0-2] - 1, чтобы учесть, что файлы obj основаны на 1, а мои векторы основаны на 0.

Поэтому, когда я добираюсь до метода рендеринга, я пытаюсь перебратькаждый объект, который проходит через каждый материал, прикрепленный к этому объекту. Я устанавливаю информацию о материале и пытаюсь использовать glDrawElements. Однако экран черный. Мне удалось нарисовать модель очень хорошо, когда я прошел через каждый отдельный материал со всемииндексы, связанные с этим материалом, и это вывело модель на отлично. На этот раз я могу использовать буфер трафарета для выбора GroupObject s, я изменил цикл, но экран черный.

UPDATE Заменен исходный цикл рендеринга на текущий и снимок экрана с его результатом. Вот мой цикл рендеринга. Единственное, что я изменил, это цикл (ы) for, чтобы они проходили через каждый объект и каждый материал в объекте.очередь.

void GLEngine::drawModel()
{
ModelTextures::const_iterator iter;
GLuint texture = 0;

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

// Vertex arrays setup
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer(3, GL_FLOAT, model.getVertexSize(), model.getVertexBuffer()->position);

glEnableClientState( GL_NORMAL_ARRAY );
glNormalPointer(GL_FLOAT, model.getVertexSize(), model.getVertexBuffer()->normal);

glClientActiveTexture( GL_TEXTURE0 );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer(2, GL_FLOAT, model.getVertexSize(), model.getVertexBuffer()->texCoord);

glUseProgram(blinnPhongShader);

objects = model.getObjects();
// Loop through objects...
for( int i=0 ; i < objects.size(); ++i ) 
{
    ModelOBJ::GroupObject *object = objects[i];

    // Loop through materials used by object...
    for( int j=0 ; j<object->materials.size() ; ++j ) 
    {
        ModelOBJ::Material *pMaterial = object->materials[j];

        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pMaterial->ambient);
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pMaterial->diffuse);
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pMaterial->specular);
        glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, pMaterial->shininess * 128.0f);

        if (pMaterial->bumpMapFilename.empty())
        {

             //Bind the color map texture.
            texture = nullTexture;
            if (enableTextures)
            {
                iter = modelTextures.find(pMaterial->colorMapFilename);

                if (iter != modelTextures.end())
                    texture = iter->second;
            }

            glActiveTexture(GL_TEXTURE0);
            glEnable(GL_TEXTURE_2D);
            glBindTexture(GL_TEXTURE_2D, texture);

             //Update shader parameters.
            glUniform1i(glGetUniformLocation(
                blinnPhongShader, "colorMap"), 0);
            glUniform1f(glGetUniformLocation(
                blinnPhongShader, "materialAlpha"), pMaterial->alpha);
        }
        //glDrawElements( GL_TRIANGLES, pMaterial->triangleCount * 3, GL_UNSIGNED_INT, &pMaterial->indices.front() );
        glDrawElements( GL_TRIANGLES, pMaterial->triangleCount * 3, GL_UNSIGNED_INT, model.getIndexBuffer() + pMaterial->startIndex );

    }

}
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glBindTexture(GL_TEXTURE_2D, 0);
    glUseProgram(0);
    glDisable(GL_BLEND);
}

Вот что рисует вышеупомянутый метод: http://img844.imageshack.us/img844/3793/chess4.png

Я не знаю, чего мне не хватает, это важно.Также полезно, здесь я читаю грань 'f' и сохраняю информацию в импорте obj в индексах pMaterial->.

 else if (sscanf(buffer, "%d/%d/%d", &v[0], &vt[0], &vn[0]) == 3) // v/vt/vn
        {
            fscanf(pFile, "%d/%d/%d", &v[1], &vt[1], &vn[1]);
            fscanf(pFile, "%d/%d/%d", &v[2], &vt[2], &vn[2]);

            v[0] = (v[0] < 0) ? v[0] + numVertices - 1 : v[0] - 1;
            v[1] = (v[1] < 0) ? v[1] + numVertices - 1 : v[1] - 1;
            v[2] = (v[2] < 0) ? v[2] + numVertices - 1 : v[2] - 1;

currentMaterial->indices.push_back(v[0]);
currentMaterial->indices.push_back(v[1]);
currentMaterial->indices.push_back(v[2]);

ОБНОВЛЕНИЕ 2

Токовый выход: http://img337.imageshack.us/img337/860/chess4s.png

1 Ответ

0 голосов
/ 17 января 2011

Мне удалось исправить модель с помощью следующего кода

glDrawElements( GL_TRIANGLES, pMaterial->triangleCount * 3, GL_UNSIGNED_INT, model.getIndexBuffer() + pMaterial->startIndex );

Когда я закончил импорт модели, я выполнил запуск triangleCount и установил startIndex следующим образом. Это было мое решение:

for (int i = 0; i < static_cast<int>(m_attributeBuffer.size()); i++)
{
    if (m_attributeBuffer[i] != materialId)
    {
        materialId = m_attributeBuffer[i];
        ++numMaterials;
    }
}

// Allocate memory for the materials and reset counters.
m_numberOfObjectMaterials = numMaterials;
m_materials.resize(m_numberOfObjectMaterials);
numMaterials = 0;
materialId = -1;

// Build the meshes. One mesh for each unique material.
for (int i = 0; i < static_cast<int>(m_attributeBuffer.size()); i++)
{
    if (m_attributeBuffer[i] != materialId)
    {
        materialId = m_attributeBuffer[i];
        m = m_ObjectMaterials[materialId];
        m->startIndex = i * 3;
        m->triangleCount = 0;
        ++m->triangleCount;
    }
    else
    {
        ++m->triangleCount;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...