Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt3D: Problem with UV texture mapping.



  • Hello everyone!

    In my application I want to use PMX/PMD models. For this I've implemented parser for both model formats and this parser works perfect.
    The models are renders by Qt3D module from Qt and this works fine.
    I have the problem with UV texture. The results which I'm getting looke likt this:
    qt3d_render_result_mini.png

    Texture is here:
    body.png

    // Create geometry render
    m_geometryRender = new Qt3DRender::QGeometryRenderer(this);
    m_geometryRender->setInstanceCount(1);
    auto geometry = new ShavMmdPmxGeometry(m_model, m_geometryRender);
    m_geometryRender->setGeometry(geometry);
    
    // Load UV texture
    auto url = QUrl::fromLocalFile("<path to body texture>");
    auto image = new Qt3DRender::QTextureImage(m_geometryRender);
    image->setSource(url);
    
    // Create material
    auto diffuseMapMaterial = new Qt3DExtras::QDiffuseMapMaterial(m_geometryRender);
    diffuseMapMaterial->diffuse()->addTextureImage(image);
    diffuseMapMaterial->diffuse()->setMaximumAnisotropy(16.0f);
    
    // Add components
    addComponent(m_geometryRender);
    addComponent(diffuseMapMaterial);
    

    The code for create geometry:

    // Initialise
    m_positionAttribute = new Qt3DRender::QAttribute(this);
    m_textureCoordinateAttribute = new Qt3DRender::QAttribute(this);
    m_normalAttribute = new Qt3DRender::QAttribute(this);
    m_indexAttribute = new Qt3DRender::QAttribute(this);
    
    m_vertexBuffer = new Qt3DRender::QBuffer(this);
    m_vertexBuffer->setUsage(Qt3DRender::QBuffer::StreamDraw);
    m_indexBuffer = new Qt3DRender::QBuffer(this);
    m_indexBuffer->setUsage(Qt3DRender::QBuffer::StreamDraw);
    
    m_positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
    m_positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
    m_positionAttribute->setVertexSize(3);
    m_positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
    m_positionAttribute->setBuffer(m_vertexBuffer);
    
    m_normalAttribute->setName(Qt3DRender::QAttribute::defaultNormalAttributeName());
    m_normalAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
    m_normalAttribute->setVertexSize(3);
    m_normalAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
    m_normalAttribute->setBuffer(m_vertexBuffer);
    
    m_textureCoordinateAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
    m_textureCoordinateAttribute->setBuffer(m_vertexBuffer);
    m_textureCoordinateAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
    m_textureCoordinateAttribute->setVertexSize(2);
    m_textureCoordinateAttribute->setName(Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName());
    
    m_indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
    m_indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedShort);
    m_indexAttribute->setBuffer(m_indexBuffer);
    
    //Apply geometry
    auto vertices = m_pmx->getVertices();
    auto verticesCount = m_pmx->getVertexCount();
    auto indicesCount = m_pmx->getIndices().count();
    if(!vertices || verticesCount == 0 || indicesCount == 0) { return; }
    
    const quint32 elementSize = 3 + 3 + 2;
    const quint32 stride = elementSize * sizeof(float);
    
    // Generate vertex data.
    auto verticesData = m_pmx->toVertexByteArray();
    m_vertexBuffer->setData(verticesData);
    m_positionAttribute->setByteOffset(0);
    m_positionAttribute->setByteStride(stride);
    m_positionAttribute->setCount(verticesCount);
    
    // Normal Attribytes
    m_normalAttribute->setByteOffset(3 * sizeof(float));
    m_normalAttribute->setByteStride(stride);
    m_normalAttribute->setCount(verticesCount);
    
    // Texture coordinate
    m_textureCoordinateAttribute->setByteOffset(2 * sizeof(float));
    m_textureCoordinateAttribute->setCount(verticesCount);
    
    // Generate Indices
    auto indicesData = m_pmx->toIndicesByteArray();
    m_indexBuffer->setData(indicesData);
    m_indexAttribute->setCount(indicesCount);
    
    // Apply geometry
    addAttribute(m_positionAttribute);
    addAttribute(m_normalAttribute);
    addAttribute(m_indexAttribute);
    addAttribute(m_textureCoordinateAttribute);
    

    My question is what I do wrong with texture render?