2021SC@SDUSC
纹理生成函数generate(),函数相对复杂,主要负责纹理的生成功能。因为代码跨度较大,这里会分成几篇文章进行分析。
void TextureGenerator::generate()
{
m_resultMesh = new Model(*m_object);
if (nullptr == m_object->triangleVertexUvs())
return;
if (nullptr == m_object->triangleSourceNodes())
return;
if (nullptr == m_object->partUvRects())
return;
QElapsedTimer countTimeConsumed;
countTimeConsumed.start();
prepare();
bool hasNormalMap = false;
bool hasMetalnessMap = false;
bool hasRoughnessMap = false;
bool hasAmbientOcclusionMap = false;
const auto &triangleVertexUvs = *m_object->triangleVertexUvs();
const auto &triangleSourceNodes = *m_object->triangleSourceNodes();
const auto &partUvRects = *m_object->partUvRects();
const auto &triangleNormals = m_object->triangleNormals;
std::map<QUuid, QColor> partColorMap;
std::map<std::pair<QUuid, QUuid>, const ObjectNode *> nodeMap;
std::map<QUuid, float> partColorSolubilityMap;
std::map<QUuid, float> partMetalnessMap;
std::map<QUuid, float> partRoughnessMap;
for (const auto &item: m_object->nodes) {
if (!m_hasTransparencySettings) {
if (!qFuzzyCompare(1.0, item.color.alphaF()))
m_hasTransparencySettings = true;
}
nodeMap.insert({{item.partId, item.nodeId}, &item});
partColorMap.insert({item.partId, item.color});
partColorSolubilityMap.insert({item.partId, item.colorSolubility});
partMetalnessMap.insert({item.partId, item.metalness});
partRoughnessMap.insert({item.partId, item.roughness});
}
auto createImageBeginTime = countTimeConsumed.elapsed();
m_resultTextureColorImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureColorImage->fill(m_hasTransparencySettings ? m_defaultTextureColor : Qt::white);
m_resultTextureNormalImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureNormalImage->fill(QColor(128, 128, 255));
m_resultTextureMetalnessImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureMetalnessImage->fill(Qt::black);
m_resultTextureRoughnessImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureRoughnessImage->fill(Qt::white);
m_resultTextureAmbientOcclusionImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureAmbientOcclusionImage->fill(Qt::white);
auto createImageEndTime = countTimeConsumed.elapsed();
QColor borderColor = Qt::darkGray;
QPen pen(borderColor);
QPainter texturePainter;
texturePainter.begin(m_resultTextureColorImage);
texturePainter.setRenderHint(QPainter::Antialiasing);
texturePainter.setRenderHint(QPainter::HighQualityAntialiasing);
QPainter textureNormalPainter;
textureNormalPainter.begin(m_resultTextureNormalImage);
textureNormalPainter.setRenderHint(QPainter::Antialiasing);
textureNormalPainter.setRenderHint(QPainter::HighQualityAntialiasing);
QPainter textureMetalnessPainter;
textureMetalnessPainter.begin(m_resultTextureMetalnessImage);
textureMetalnessPainter.setRenderHint(QPainter::Antialiasing);
textureMetalnessPainter.setRenderHint(QPainter::HighQualityAntialiasing);
QPainter textureRoughnessPainter;
textureRoughnessPainter.begin(m_resultTextureRoughnessImage);
textureRoughnessPainter.setRenderHint(QPainter::Antialiasing);
textureRoughnessPainter.setRenderHint(QPainter::HighQualityAntialiasing);
QPainter textureAmbientOcclusionPainter;
textureAmbientOcclusionPainter.begin(m_resultTextureAmbientOcclusionImage);
textureAmbientOcclusionPainter.setRenderHint(QPainter::Antialiasing);
textureAmbientOcclusionPainter.setRenderHint(QPainter::HighQualityAntialiasing);
auto paintTextureBeginTime = countTimeConsumed.elapsed();
texturePainter.setPen(Qt::NoPen);
首先检测一些必要数据是否为空(顶点UV、源节点等),如果为空则无法生成纹理,直接return。如果可以生成,执行prepare(),然后从m_object指向的对象中提取三角形顶点UV、三角形来源节点、局部UV数据和三角面法线的信息。之后遍历m_object的nodes,依次将检测到的nodeMap、colorMap、colorSolubilityMap、metalnessMap和roughnessMap键值对添加到类的对应数据成员中,并且用QImage构建新的color、normal、metalness、roughness和AO贴图并初始化。