2015-04-13 3 views
0

Я портировал приложение OpenGL на рабочий стол в Android NDK (под OpenGL ES 2), и, похоже, происходит случайная деформация моей сетки. На большинстве трасс приложений, это выглядит 100% совершенным, но иногда это выглядит следующим образом:Android OpenGL ES 2 Случайная деформация модели

enter image description here

Противоречивость проблемы является наиболее относительно меня. Я не знаю, из-за моего симулятора Android, или если это что-то еще. Через моего тестирования, я могу установить, что это либо:

    установка
  • OpenGL, который не играет хорошо на Android, но делает на все остальное
  • ошибка в открытой библиотеке Asset Import (Assimp), который я «ве составлен вручную, чтобы работать на Android
  • ошибка в Android симулятор

процесс Моя модель выглядит следующим образом:

на каждом розыгрыше:

- bind the program 
- change the uniforms 

- if (has vao support) 
    - bind vao 

- enable all vertex attribute arrays 

- for every mesh 
    - bind array buffer 
    - set the attribute pointer for each vertex array 
    - bind element buffer 
    - bind texture & set uniform of texture location 
    - glDrawElements 

- disable all vertex attribute arrays 

И это фактический код:

glUseProgram(program_); 

if (loaded_vao_) 
{ 
    #if !defined(TARGET_OS_IPHONE) && !defined(__ANDROID__) 
    glBindVertexArray(vao_); 
    #else 
    glBindVertexArrayOES(vao_); 
    #endif 
} 

glEnableVertexAttribArray(vPosition_); 
glEnableVertexAttribArray(vTexCoord_); 
glEnableVertexAttribArray(boneids_); 
glEnableVertexAttribArray(weights_); 

for (unsigned int i = 0; i < vbo_.size(); i++) 
{ 
    glBindBuffer(GL_ARRAY_BUFFER, vbo_[i]); 

    glVertexAttribPointer(vPosition_, 3, GL_FLOAT, GL_FALSE, 0, 0); 
    glVertexAttribPointer(vTexCoord_, 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<void*>(texcoord_locations_[i])); 

    #if !defined(TARGET_OS_IPHONE) && !defined(__ANDROID__) 
    glVertexAttribIPointer(boneids_, 4, GL_INT, 0, reinterpret_cast<void*>(bone_id_locations_[i])); 
    #else // APPLE OR ANDROID 
    glVertexAttribPointer(boneids_, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<void*>(bone_id_locations_[i])); 
    #endif 

    glVertexAttribPointer(weights_, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<void*>(bone_weight_locations_[i])); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_[i]); 

    // Textures 
    if (!textures_.empty()) 
    { 
     glActiveTexture(GL_TEXTURE0); 
     glBindTexture(GL_TEXTURE_2D, textures_[texture_numbers_[i]]); 
     glUniform1i(textureSample_, 0); 
    } 

    glDrawElements(GL_TRIANGLES, ind_size_[i], GL_UNSIGNED_SHORT, 0); 
} 

glDisableVertexAttribArray(vPosition_); 
glDisableVertexAttribArray(vTexCoord_); 
glDisableVertexAttribArray(boneids_); 
glDisableVertexAttribArray(weights_); 

Как хорошо, моя вершинный шейдер выглядит следующим образом:

precision mediump float; 

attribute vec3 vPosition; 
attribute vec2 vTexCoord; 
attribute vec4 boneids; 
attribute vec4 weights; 

uniform mat4 pos; 
uniform mat4 view; 
uniform mat4 scale; 
uniform mat4 rotate; 
uniform mat4 proj; 
uniform mat4 bones[50]; 
uniform int has_bones; 

varying vec4 color; 
varying vec2 texcoord; 

void main() 
{ 
    color = vec4(1.0f); 
    texcoord = vTexCoord; 

    vec4 newPos = vec4(vPosition,1.0); 

    if (has_bones == 1) 
    { 
     mat4 bone_transform = bones[int(boneids[0])]*weights[0]; 
     bone_transform += bones[int(boneids[1])]*weights[1]; 
     bone_transform += bones[int(boneids[2])]*weights[2]; 
     bone_transform += bones[int(boneids[3])]*weights[3]; 

     newPos = bone_transform * newPos; 
    } 

    gl_Position = proj * view * pos * scale * rotate * newPos; 
} 

Обратите внимание, что я пытался закомментировав bone_transform в vertex shader, и проблема все еще сохраняется.

EDIT:

Кажется, что я был в состоянии воссоздать некоторые деформации на моем Linux OpenGL версии 3.3 путем удаления assimp оптимизации почтовых процессов флаги:

scene = importer.ReadFile(file_path.c_str(), aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_LimitBoneWeights | aiProcess_ValidateDataStructure); 

Основываясь на выходе Assimp: : DefaultLogger, ошибок и вершинных предупреждений нет.

+0

Является ли ошибка согласованной, когда это происходит, или полностью случайным? Если это скорее не проблема инициализации. Это происходит со всеми сетками? Не связанный с вашим вопросом, почему вы используете VAO? Точка VAO не должна настраивать атрибуты буферов и вершин каждый раз, когда вы рисуете. – user1906

+0

Без VAO у меня были проблемы с рендерингом на новых телефонах Android. Однако, возможно, это просто скрывает большую проблему. Это абсолютно случайно. Небольшие разделы модели расширяются (иногда это лицо, шляпа и т. Д.), Но всегда кажется, что это небольшое количество, а не все, что взрывается. Проблема, похоже, только с этой моделью. Единственная реальная разница для этой модели заключается в том, что она определяется 3 «сетками» (цикл for работает 3 раза), и у нее намного больше вершин, чем у остальных. Я не видел, чтобы модель с 1 "сеткой" имела эту ошибку. – Izman

+0

Являются ли модели, которые вы получаете из библиотеки, точно так же, как и каждый запуск? Если они есть, и вы получаете разные результаты, это устранит это как источник проблем. – user1906

ответ

0

Этот вопрос, казалось, был частью экспорта COLLADA Blender или считывателя COLLADA от Assimp.

Экспортируя в FBX и используя бесплатный инструмент FBX для DAE от Autodesk, была исправлена ​​деформация.

  • Blender была версия 2,71
  • Assimp была версия 3.1.1

Assimp, даже со всеми лесозаготовительных и целостности данных флагов, не размещать какие-либо ошибки, о коррупции, так что я не знаете, какой компонент виноват. Несмотря ни на что, я счастлив, что нашел обходной путь.

Смежные вопросы