std::shared_ptr<Texture> Pass::GetTexture(const std::string &name, bool input) const { unsigned int index = GetTextureIndex(name, input); if (index == -1) return nullptr; return input ? m_InputTextures[index] : m_OutputTextures[index]; }
std::vector<Texture> Model::LoadMaterialTextures(aiMaterial* pMaterial, aiTextureType textureType, aiScene const* pScene) { std::vector<Texture> materialTextures; TextureStorageType storeType = TextureStorageType::Invalid; unsigned int textureCount = pMaterial->GetTextureCount(textureType); if (textureCount == 0) // If there are no textures. { storeType = TextureStorageType::None; aiColor3D aiColor(0.0f, 0.0f, 0.0f); switch (textureType) { case aiTextureType::aiTextureType_DIFFUSE: { pMaterial->Get(AI_MATKEY_COLOR_DIFFUSE, aiColor); if (aiColor.IsBlack()) { materialTextures.push_back(Texture(device, Colors::UnloadedTextureColor, textureType)); return materialTextures; } materialTextures.push_back(Texture(device, Color(static_cast<uint8>(aiColor.r * 255), static_cast<uint8>(aiColor.g * 255), static_cast<uint8>(aiColor.b * 255)), textureType)); return materialTextures; } } } else { for (UINT i = 0; i < textureCount; ++i) { aiString path; pMaterial->GetTexture(textureType, i, &path); storeType = DetermineTextureStorageType(pScene, pMaterial, i, textureType); switch (storeType) { case TextureStorageType::EmbeddedIndexCompressed: { int index = GetTextureIndex(&path); Texture embeddedIndexedTexture(device, reinterpret_cast<uint8*>(pScene->mTextures[index]->pcData), pScene->mTextures[index]->mWidth, textureType); materialTextures.push_back(embeddedIndexedTexture); break; } case TextureStorageType::EmbeddedCompressed: { aiTexture const* pTexture = pScene->GetEmbeddedTexture(path.C_Str()); Texture embeddedTexture(device, reinterpret_cast<uint8*>(pTexture->pcData), pTexture->mWidth, textureType); materialTextures.push_back(embeddedTexture); break; } case TextureStorageType::Disk: { std::string fileName = directory + '\\' + path.C_Str(); Texture diskTexture(device, fileName, textureType); materialTextures.push_back(diskTexture); break; } } } } if (materialTextures.size() == 0) { materialTextures.push_back(Texture(device, Colors::UnhandledTextureColor, textureType)); } return materialTextures; }
bool KG3DFontTexture::InitGlyphBorder(UINT charCode, void* ftGlyph, KG3DTextureGlyph* fontGlyph) { BOOL bRetCode = FALSE; FT_GlyphSlot pGlyphSlot = (FT_GlyphSlot)ftGlyph; FT_Error nError = 0; FT_Bitmap bitmap; FT_UInt nGlyph = 0; FT_F26Dot6 FontSize = 0; KG3DTextureGlyph* pGlyphFont = (KG3DTextureGlyph*)fontGlyph; ASSERT(pGlyphSlot); ASSERT(pGlyphFont); KGLOG_PROCESS_ERROR(pGlyphSlot); nGlyph = FT_Get_Char_Index(m_pFontFace, charCode); KGLOG_PROCESS_ERROR(nGlyph != 0); FontSize = FontFixMul(m_InitParams.fPixel); nError = FT_Set_Char_Size(m_pFontFace, FontSize, 0, 0, 0); KGLOG_PROCESS_ERROR(nError == 0); nError = FT_Load_Glyph(m_pFontFace, nGlyph, m_InitParams.dwLoadFlag); KGLOG_PROCESS_ERROR(nError == 0); nError = FT_Render_Glyph(pGlyphSlot, (FT_Render_Mode)m_InitParams.dwRenderMode); KGLOG_PROCESS_ERROR(nError == 0); KGLOG_PROCESS_ERROR(pGlyphSlot->format == FT_GLYPH_FORMAT_BITMAP); // request glyph texture pGlyphFont->nBoderTextureID = GetTextureIndex(); KGLOG_PROCESS_ERROR(pGlyphFont->nBoderTextureID != KG3DFontRenderer::INVALID_TEXTURE_INDEX); // upload sub texture bitmap = pGlyphSlot->bitmap; pGlyphFont->vBorderU.x = (float)(m_uEmptyTextureX - 1) / (float)m_uTextureWidth; pGlyphFont->vBorderU.y = (float)(m_uEmptyTextureY - 1) / (float)m_uTextureHeight; pGlyphFont->vBorderV.x = (float)(m_uEmptyTextureX + bitmap.width + 1) / (float)m_uTextureWidth; pGlyphFont->vBorderV.y = (float)(m_uEmptyTextureY + bitmap.rows + 1) / (float)m_uTextureHeight; // empty glyph? // 如果轮廓线没有被上载,FreeType 使用的位图渲染模式为 1bit/pixel if (0 == pGlyphSlot->outline.n_contours && 0 == pGlyphSlot->outline.n_points || FT_PIXEL_MODE_MONO == bitmap.pixel_mode) { bRetCode = m_pRenderer->UploadMonoBoderTexture(pGlyphFont->nBoderTextureID, 0, m_uEmptyTextureX, m_uEmptyTextureY, (UINT)pGlyphFont->cx, (UINT)pGlyphFont->cy, (UINT)bitmap.pitch, bitmap.buffer); KGLOG_PROCESS_ERROR(bRetCode); } else { bRetCode = m_pRenderer->UploadBoderTexture(pGlyphFont->nBoderTextureID, 0, m_uEmptyTextureX, m_uEmptyTextureY, (UINT)pGlyphFont->cx, (UINT)pGlyphFont->cy, bitmap.buffer, m_uchAdjustBuffer); KGLOG_PROCESS_ERROR(bRetCode); } m_uEmptyTextureX += static_cast<INT>( pGlyphFont->cx ); m_uEmptyTextureX += KG3DFONT_DEFAULT_PADDING; return true; Exit0: return false; }
bool KG3DFontTexture::InitGlyph(UINT charCode, void* ftGlyph, KG3DTextureGlyph* fontGlyph, BOOL bBorder) { BOOL bRetCode = FALSE; FT_GlyphSlot pGlyphSlot = (FT_GlyphSlot)ftGlyph; FT_Error nError = 0; KG3DTextureGlyph* pGlyphFont = (KG3DTextureGlyph*)fontGlyph; FT_UInt nGlyph = 0; BOOL bBit = FALSE; UINT uX = 0; UINT uY = 0; int nDivisor = 1; FT_F26Dot6 FontSize = 0; ASSERT(pGlyphSlot); ASSERT(pGlyphFont); KGLOG_PROCESS_ERROR(pGlyphSlot); nGlyph = FT_Get_Char_Index(m_pFontFace, charCode); KG_PROCESS_ERROR(nGlyph != 0); // request glyph texture pGlyphFont->nTextureID = GetTextureIndex(); KGLOG_PROCESS_ERROR(pGlyphFont->nTextureID != KG3DFontRenderer::INVALID_TEXTURE_INDEX); uX = m_uEmptyTextureX; uY = m_uEmptyTextureY; for (UINT uMipmapLevel = 0; uMipmapLevel < m_uMipmapLevel; ++uMipmapLevel) { FontSize = FontFixMul(m_InitParams.fPixel); nError = FT_Set_Char_Size(m_pFontFace, FontSize, 0, 0, 0); KGLOG_PROCESS_ERROR(nError == 0); nError = FT_Load_Glyph(m_pFontFace, nGlyph, m_InitParams.dwLoadFlag); KGLOG_PROCESS_ERROR(nError == 0); nError = FT_Render_Glyph(m_pFontFace->glyph, (FT_Render_Mode)m_InitParams.dwRenderMode); KGLOG_PROCESS_ERROR(nError == 0); KGLOG_PROCESS_ERROR(m_pFontFace->glyph->format == FT_GLYPH_FORMAT_BITMAP); // empty glyph? // 如果轮廓线没有被上载,FreeType 使用的位图渲染模式为 1bit/pixel bBit = pGlyphSlot->outline.n_contours == 0 && pGlyphSlot->outline.n_points == 0 || FT_PIXEL_MODE_MONO == m_pFontFace->glyph->bitmap.pixel_mode; if (bBit) { bRetCode = m_pRenderer->UploadMonoTexture(pGlyphFont->nTextureID, uMipmapLevel, uX / nDivisor, uY / nDivisor, m_pFontFace->glyph->bitmap.width, m_pFontFace->glyph->bitmap.rows, m_pFontFace->glyph->bitmap.pitch, m_pFontFace->glyph->bitmap.buffer); KGLOG_PROCESS_ERROR(bRetCode); } else { bRetCode = m_pRenderer->UploadTexture(pGlyphFont->nTextureID, uMipmapLevel, uX / nDivisor, uY / nDivisor, m_pFontFace->glyph->bitmap.width, m_pFontFace->glyph->bitmap.rows, m_pFontFace->glyph->bitmap.buffer, m_uchAdjustBuffer); KGLOG_PROCESS_ERROR(bRetCode); } nDivisor *= 2; if (uMipmapLevel == 0) { pGlyphFont->xOffset = (FLOAT)m_pFontFace->glyph->bitmap_left; pGlyphFont->yOffset = (FLOAT)m_fontAscender - m_pFontFace->glyph->bitmap_top; pGlyphFont->cx = (FLOAT)m_pFontFace->glyph->bitmap.width; pGlyphFont->cy = (FLOAT)m_pFontFace->glyph->bitmap.rows; pGlyphFont->vFontU.x = (float)m_uEmptyTextureX / (float)m_uTextureWidth; pGlyphFont->vFontU.y = (float)m_uEmptyTextureY / (float)m_uTextureHeight; pGlyphFont->vFontV.x = (float)(m_uEmptyTextureX + m_pFontFace->glyph->bitmap.width) / (float)m_uTextureWidth; pGlyphFont->vFontV.y = (float)(m_uEmptyTextureY + m_pFontFace->glyph->bitmap.rows) / (float)m_uTextureHeight; m_uEmptyTextureX += static_cast<INT>(pGlyphFont->cx); m_uEmptyTextureX += KG3DFONT_DEFAULT_PADDING; } } FontSize = FontFixMul(m_InitParams.fPixel); nError = FT_Set_Char_Size(m_pFontFace, FontSize, 0, 0, 0); KGLOG_PROCESS_ERROR(nError == 0); if (bBorder && m_uMipmapLevel == 1) { pGlyphFont->nBoderTextureID = GetTextureIndex(); KGLOG_PROCESS_ERROR(pGlyphFont->nBoderTextureID != KG3DFontRenderer::INVALID_TEXTURE_INDEX); pGlyphFont->vBorderU.x = (float)(m_uEmptyTextureX - 1) / (float)m_uTextureWidth; pGlyphFont->vBorderU.y = (float)(m_uEmptyTextureY - 1) / (float)m_uTextureHeight; pGlyphFont->vBorderV.x = (float)(m_uEmptyTextureX + m_pFontFace->glyph->bitmap.width + 1) / (float)m_uTextureWidth; pGlyphFont->vBorderV.y = (float)(m_uEmptyTextureY + m_pFontFace->glyph->bitmap.rows + 1) / (float)m_uTextureHeight; if (bBit) { bRetCode = m_pRenderer->UploadMonoBoderTexture(pGlyphFont->nBoderTextureID, 0, m_uEmptyTextureX, m_uEmptyTextureY, (UINT)pGlyphFont->cx, (UINT)pGlyphFont->cy, (UINT)m_pFontFace->glyph->bitmap.pitch, m_pFontFace->glyph->bitmap.buffer); KGLOG_PROCESS_ERROR(bRetCode); } else { bRetCode = m_pRenderer->UploadBoderTexture(pGlyphFont->nBoderTextureID, 0, m_uEmptyTextureX, m_uEmptyTextureY, (UINT)pGlyphFont->cx, (UINT)pGlyphFont->cy, m_pFontFace->glyph->bitmap.buffer, m_uchAdjustBuffer); KGLOG_PROCESS_ERROR(bRetCode); } m_uEmptyTextureX += static_cast<INT>( pGlyphFont->cx ); m_uEmptyTextureX += KG3DFONT_DEFAULT_PADDING; } return true; Exit0: return false; }
inline float BlockRenderer::GetTextureFloatIndex() { return (float) GetTextureIndex() / numBlocks + 1.0f / (numBlocks * 2); }