三角剖分后的Android OpenGL UV贴图错误

时间:2018-10-24 10:04:30

标签: android c++ opengl-es native

我正在构建一个Android应用程序来渲染3d(wavefront.obj)模型。通过使用tinyobjloader,我可以成功加载模型。

代码:

std::vector<glm::vec3> vertices;
std::vector<glm::vec2> uvs;
std::vector<glm::vec3> normals;

tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
for(size_t s =0; s < shapes.size(); s++)
    {
        size_t index_offset = 0;
        for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++)
        {
            int fv = shapes[s].mesh.num_face_vertices[f];
            for(size_t v = 0; v < fv; v++)
            {
                tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
                tinyobj::real_t vx = attrib.vertices[3*idx.vertex_index+0];
                tinyobj::real_t vy = attrib.vertices[3*idx.vertex_index+1];
                tinyobj::real_t vz = attrib.vertices[3*idx.vertex_index+2];
                tinyobj::real_t nx = attrib.normals[3*idx.normal_index+0];
                tinyobj::real_t ny = attrib.normals[3*idx.normal_index+1];
                tinyobj::real_t nz = attrib.normals[3*idx.normal_index+2];
                tinyobj::real_t ux = attrib.texcoords[2*idx.texcoord_index+0];
                tinyobj::real_t uy = attrib.texcoords[2*idx.texcoord_index+1];
                vertices.push_back(glm::vec3(vx,vy,vz));
                normals.push_back(glm::vec3(nx,ny,nz));
                uvs.push_back(glm::vec2(ux,uy));
            }
            index_offset += fv;
        }
    }

因为原始.obj文件具有多种面孔格式,即:

f 1/2/3 3/2/1 3/2/3
f 1/2/3 1/3/4 1/4/5 6/7/2

以便我将Blender Triangulate与“ Beauty”选项一起使用,以将Quad转换为三角形。但是呈现的结果很奇怪result

我已经为initOpenGL(运行一次)和render()构建了两个函数。

initOpenGL代码:

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);


glGenBuffers(1, &UVBO);
glBindBuffer(GL_ARRAY_BUFFER, UVBO);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);

//Linking Vertex Attribute
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

//bind texture
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, UVBO);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

//load texture
//texture1
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if(patternSrc1)
{

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, patWidth1, patHeight1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 patternSrc1);
    //glGenerateMipmap(GL_TEXTURE_2D);
}

render()代码:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram);

camera.ProcessOneFinger(moveStpX, moveStpY);
camera.ProcessTwoFinger(move2X, move2Y);
projection = glm::perspective(camera.GetZoom(), (GLfloat)600/(GLfloat)1024, nearPlane, farPlane);
view = camera.GetViewMatrix();
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, glm::value_ptr(view));
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
GLfloat angle = 20.0f;
model = glm::rotate(model, angle, glm::vec3( 1.0f, 0.3f, 0.5f));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr( model ) );

glDrawArrays(GL_TRIANGLES, 0, vertices.size());

模型详细信息

纹理: enter image description here

三角剖分后的Model.obj文件:

https://pastebin.com/vUjHv8Fr

谢谢!

1 个答案:

答案 0 :(得分:0)

在我看来,您的纹理是颠倒的。基本上有两个潜在的错误可能会导致这种情况的发生。纹理图像本身很可能是上下颠倒的,例如,因为传递到glTexImage2D()的图像数据顺序错误。与大多数其他API不同,OpenGL(默认情况下)期望像素数据以行顺序从底部行开始。检查加载纹理数据的方式,以确保其顺序正确。

如果这不是问题,则可能是您的纹理坐标用于左手纹理坐标系。但是,OpenGL使用右手纹理坐标,其中原点是纹理图像的左下角而不是左上角。我不是Blender家伙,但是可能有一个导出设置…