2015-04-13 83 views
0

我已經將桌面OpenGL應用程序移植到Android NDK(在OpenGL ES 2下),並且似乎有一個隨機變形我的網格。在大多數應用程序運行時,它看起來100%的完美,但有時它看起來如下:Android OpenGL ES 2隨機模型變形

enter image description here

問題的矛盾是關於對我來說最。我不知道是因爲我的Android模擬器,還是其他東西。經過我的測試,我可以證明它要麼:

  • 一個OpenGL設置,不玩Android上不錯,但確實對一切
  • 開放資產導入庫(Assimp)中的錯誤,我「VE手工編制,以供Android
  • 在Android模擬器的bug

我的模型過程看起來如下工作:

在每一個抽獎:

- 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頂點着色器,問題仍然存在。

編輯:

看來,我是能夠通過移除任何assimp後優化進程標誌重新在我的Linux的OpenGL 3.3版本的一些變形:

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

這個問題似乎是Blender的COLLADA輸出或Assimp的COLLADA閱讀器的一部分。

通過導出到FBX並使用Autodesk的免費FBX到DAE工具,變形得到了修復。

  • 混合機版本2.71
  • Assimp是3.1.1版

Assimp,即使在所有的日誌和數據完整性標誌,也沒有發佈關於腐敗的任何錯誤,所以不知道應該責怪哪個組件。無論如何,我很高興我找到了解決方法。