2021SC@SDUSC 

 for (const auto &it: partUvRects) {
        const auto &partId = it.first;
        const auto &rects = it.second;
        auto findSourceColorResult = partColorMap.find(partId);
        if (findSourceColorResult != partColorMap.end()) {
            const auto &color = findSourceColorResult->second;
            QBrush brush(color);
            float fillExpandSize = 2;
            for (const auto &rect: rects) {
                QRectF translatedRect = {
                    rect.left() * TextureGenerator::m_textureSize - fillExpandSize,
                    rect.top() * TextureGenerator::m_textureSize - fillExpandSize,
                    rect.width() * TextureGenerator::m_textureSize + fillExpandSize * 2,
                    rect.height() * TextureGenerator::m_textureSize + fillExpandSize * 2
                };
                texturePainter.fillRect(translatedRect, brush);
            }
        }
    }
    
    for (const auto &it: partUvRects) {
        const auto &partId = it.first;
        const auto &rects = it.second;
        auto findMetalnessResult = partMetalnessMap.find(partId);
        if (findMetalnessResult != partMetalnessMap.end()) {
            if (qFuzzyCompare(findMetalnessResult->second, (float)0.0))
                continue;
            const auto &color = QColor(findMetalnessResult->second * 255,
                findMetalnessResult->second * 255,
                findMetalnessResult->second * 255);
            QBrush brush(color);
            float fillExpandSize = 2;
            for (const auto &rect: rects) {
                QRectF translatedRect = {
                    rect.left() * TextureGenerator::m_textureSize - fillExpandSize,
                    rect.top() * TextureGenerator::m_textureSize - fillExpandSize,
                    rect.width() * TextureGenerator::m_textureSize + fillExpandSize * 2,
                    rect.height() * TextureGenerator::m_textureSize + fillExpandSize * 2
                };
                textureMetalnessPainter.fillRect(translatedRect, brush);
                hasMetalnessMap = true;
            }
        }
    }
    
    for (const auto &it: partUvRects) {
        const auto &partId = it.first;
        const auto &rects = it.second;
        auto findRoughnessResult = partRoughnessMap.find(partId);
        if (findRoughnessResult != partRoughnessMap.end()) {
            if (qFuzzyCompare(findRoughnessResult->second, (float)1.0))
                continue;
            const auto &color = QColor(findRoughnessResult->second * 255,
                findRoughnessResult->second * 255,
                findRoughnessResult->second * 255);
            QBrush brush(color);
            float fillExpandSize = 2;
            for (const auto &rect: rects) {
                QRectF translatedRect = {
                    rect.left() * TextureGenerator::m_textureSize - fillExpandSize,
                    rect.top() * TextureGenerator::m_textureSize - fillExpandSize,
                    rect.width() * TextureGenerator::m_textureSize + fillExpandSize * 2,
                    rect.height() * TextureGenerator::m_textureSize + fillExpandSize * 2
                };
                textureRoughnessPainter.fillRect(translatedRect, brush);
                hasRoughnessMap = true;
            }
        }
    }
    
    auto drawTexture = [&](const std::map<QUuid, std::pair<QPixmap, QPixmap>> &map, QPainter &painter, bool useAlpha) {
        for (const auto &it: partUvRects) {
            const auto &partId = it.first;
            const auto &rects = it.second;
            float alpha = 1.0;
            if (useAlpha) {
                auto findSourceColorResult = partColorMap.find(partId);
                if (findSourceColorResult != partColorMap.end()) {
                    const auto &color = findSourceColorResult->second;
                    alpha = color.alphaF();
                }
            }
            auto findTextureResult = map.find(partId);
            if (findTextureResult != map.end()) {
                const auto &pixmap = findTextureResult->second.first;
                const auto &rotatedPixmap = findTextureResult->second.second;
                painter.setOpacity(alpha);
                for (const auto &rect: rects) {
                    QRectF translatedRect = {
                        rect.left() * TextureGenerator::m_textureSize,
                        rect.top() * TextureGenerator::m_textureSize,
                        rect.width() * TextureGenerator::m_textureSize,
                        rect.height() * TextureGenerator::m_textureSize
                    };
                    if (translatedRect.width() < translatedRect.height()) {
                        painter.drawTiledPixmap(translatedRect, rotatedPixmap, QPointF(rect.top(), rect.left()));
                    } else {
                        painter.drawTiledPixmap(translatedRect, pixmap, rect.topLeft());
                    }
                }
                painter.setOpacity(1.0);
            }
        }
    };
    
    auto convertTextureImageToPixmap = [&](const std::map<QUuid, std::pair<QImage, float>> &sourceMap,
            std::map<QUuid, std::pair<QPixmap, QPixmap>> &targetMap) {
        for (const auto &it: sourceMap) {
            float tileScale = it.second.second;
            const auto &image = it.second.first;
            auto newSize = image.size() * tileScale;
            QImage scaledImage = image.scaled(newSize);
            QPoint center = scaledImage.rect().center();
            QMatrix matrix;
            matrix.translate(center.x(), center.y());
            matrix.rotate(90);
            auto rotatedImage = scaledImage.transformed(matrix).mirrored(true, false);
            targetMap[it.first] = std::make_pair(QPixmap::fromImage(scaledImage),
                QPixmap::fromImage(rotatedImage));
        }
    };
    
    std::map<QUuid, std::pair<QPixmap, QPixmap>> partColorTexturePixmaps;
    std::map<QUuid, std::pair<QPixmap, QPixmap>> partNormalTexturePixmaps;
    std::map<QUuid, std::pair<QPixmap, QPixmap>> partMetalnessTexturePixmaps;
    std::map<QUuid, std::pair<QPixmap, QPixmap>> partRoughnessTexturePixmaps;
    std::map<QUuid, std::pair<QPixmap, QPixmap>> partAmbientOcclusionTexturePixmaps;
    
    convertTextureImageToPixmap(m_partColorTextureMap, partColorTexturePixmaps);
    convertTextureImageToPixmap(m_partNormalTextureMap, partNormalTexturePixmaps);
    convertTextureImageToPixmap(m_partMetalnessTextureMap, partMetalnessTexturePixmaps);
    convertTextureImageToPixmap(m_partRoughnessTextureMap, partRoughnessTexturePixmaps);
    convertTextureImageToPixmap(m_partAmbientOcclusionTextureMap, partAmbientOcclusionTexturePixmaps);
    
    drawTexture(partColorTexturePixmaps, texturePainter, true);
    drawTexture(partNormalTexturePixmaps, textureNormalPainter, false);
    drawTexture(partMetalnessTexturePixmaps, textureMetalnessPainter, false);
    drawTexture(partRoughnessTexturePixmaps, textureRoughnessPainter, false);
    drawTexture(partAmbientOcclusionTexturePixmaps, textureAmbientOcclusionPainter, false);
    
    

这一部分首先针对color、metalness、roughness贴图用QBrush进行绘制,前面三段for循环是完全并列的,分别处理color map,metalness map和roughness map。接下来将纹理图像转化为pixmap,建立QUuid到QPixmap的键值对完成纹理贴图的绘制。

drawTexture和convertTextureImageToPixmap这里使用的是C++ 11标准中的Lambda Function语法,实现了在generate()函数内部定义其他“函数”的功能,由于generate()函数本身跨度很大,这样处理提高了程序的可读性。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐