bool CPicture::CreateTiledThumb(const std::vector<std::string> &files, const std::string &thumb) { if (!files.size()) return false; unsigned int num_across = (unsigned int)ceil(sqrt((float)files.size())); unsigned int num_down = (files.size() + num_across - 1) / num_across; unsigned int tile_width = g_advancedSettings.m_thumbSize / num_across; unsigned int tile_height = g_advancedSettings.m_thumbSize / num_down; unsigned int tile_gap = std::max(1,g_advancedSettings.m_thumbSize / 512); // create a buffer for the resulting thumb uint32_t *buffer = (uint32_t *)calloc(g_advancedSettings.m_thumbSize * g_advancedSettings.m_thumbSize, 4); for (unsigned int i = 0; i < files.size(); ++i) { int x = i % num_across; int y = i / num_across; // load in the image CTexture texture; unsigned int width = tile_width - 2*tile_gap, height = tile_height - 2*tile_gap; if (texture.LoadFromFile(files[i], width, height, g_guiSettings.GetBool("pictures.useexifrotation")) && texture.GetWidth() && texture.GetHeight()) { GetScale(texture.GetWidth(), texture.GetHeight(), width, height); // scale appropriately uint32_t *scaled = new uint32_t[width * height]; if (ScaleImage(texture.GetPixels(), texture.GetWidth(), texture.GetHeight(), texture.GetPitch(), (uint8_t *)scaled, width, height, width * 4)) { if (!texture.GetOrientation() || OrientateImage(scaled, width, height, texture.GetOrientation())) { // drop into the texture unsigned int posX = x*tile_width + (tile_width - width)/2; unsigned int posY = y*tile_height + (tile_height - height)/2; uint32_t *dest = buffer + posX + posY*g_advancedSettings.m_thumbSize; uint32_t *src = scaled; for (unsigned int y = 0; y < height; ++y) { memcpy(dest, src, width*4); dest += g_advancedSettings.m_thumbSize; src += width; } } } delete[] scaled; } } // now save to a file bool ret = CreateThumbnailFromSurface((uint8_t *)buffer, g_advancedSettings.m_thumbSize, g_advancedSettings.m_thumbSize, g_advancedSettings.m_thumbSize * 4, thumb); free(buffer); return ret; }
const CTextureArray& CGUITextureManager::Load(const std::string& strTextureName, bool checkBundleOnly /*= false */) { std::string strPath; static CTextureArray emptyTexture; int bundle = -1; int size = 0; if (!HasTexture(strTextureName, &strPath, &bundle, &size)) return emptyTexture; if (size) // we found the texture { for (int i = 0; i < (int)m_vecTextures.size(); ++i) { CTextureMap *pMap = m_vecTextures[i]; if (pMap->GetName() == strTextureName) { //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage()); return pMap->GetTexture(); } } // Whoops, not there. return emptyTexture; } for (ilistUnused i = m_unusedTextures.begin(); i != m_unusedTextures.end(); ++i) { CTextureMap* pMap = i->first; if (pMap->GetName() == strTextureName && i->second > 0) { m_vecTextures.push_back(pMap); m_unusedTextures.erase(i); return pMap->GetTexture(); } } if (checkBundleOnly && bundle == -1) return emptyTexture; //Lock here, we will do stuff that could break rendering CSingleLock lock(g_graphicsContext); #ifdef _DEBUG_TEXTURES int64_t start; start = CurrentHostCounter(); #endif if (bundle >= 0 && StringUtils::EndsWithNoCase(strPath, ".gif")) { CTextureMap* pMap = nullptr; CBaseTexture **pTextures = nullptr; int nLoops = 0, width = 0, height = 0; int* Delay = nullptr; int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &pTextures, width, height, nLoops, &Delay); if (!nImages) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); delete[] pTextures; delete[] Delay; return emptyTexture; } unsigned int maxWidth = 0; unsigned int maxHeight = 0; pMap = new CTextureMap(strTextureName, width, height, nLoops); for (int iImage = 0; iImage < nImages; ++iImage) { pMap->Add(pTextures[iImage], Delay[iImage]); maxWidth = std::max(maxWidth, pTextures[iImage]->GetWidth()); maxHeight = std::max(maxHeight, pTextures[iImage]->GetHeight()); } pMap->SetWidth((int)maxWidth); pMap->SetHeight((int)maxHeight); delete[] pTextures; delete[] Delay; if (pMap) { m_vecTextures.push_back(pMap); return pMap->GetTexture(); } } else if (StringUtils::EndsWithNoCase(strPath, ".gif") || StringUtils::EndsWithNoCase(strPath, ".apng")) { CTextureMap* pMap = nullptr; std::string mimeType; if (StringUtils::EndsWithNoCase(strPath, ".gif")) mimeType = "image/gif"; else if (StringUtils::EndsWithNoCase(strPath, ".apng")) mimeType = "image/apng"; XFILE::CFile file; XFILE::auto_buffer buf; CFFmpegImage anim(mimeType); pMap = new CTextureMap(strTextureName, 0, 0, 0); if (file.LoadFile(strPath, buf) <= 0 || !anim.Initialize((uint8_t*)buf.get(), buf.size()) || !pMap) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", CURL::GetRedacted(strPath).c_str()); file.Close(); return emptyTexture; } unsigned int maxWidth = 0; unsigned int maxHeight = 0; uint64_t maxMemoryUsage = 91238400;// 1920*1080*4*11 bytes, i.e, a total of approx. 12 full hd frames auto frame = anim.ReadFrame(); while (frame) { CTexture *glTexture = new CTexture(); if (glTexture) { glTexture->LoadFromMemory(anim.Width(), anim.Height(), frame->GetPitch(), XB_FMT_A8R8G8B8, true, frame->m_pImage); pMap->Add(glTexture, frame->m_delay); maxWidth = std::max(maxWidth, glTexture->GetWidth()); maxHeight = std::max(maxHeight, glTexture->GetHeight()); } if (pMap->GetMemoryUsage() <= maxMemoryUsage) { frame = anim.ReadFrame(); } else { CLog::Log(LOGDEBUG, "Memory limit (%" PRIu64 " bytes) exceeded, %i frames extracted from file : %s", (maxMemoryUsage/11)*12,pMap->GetTexture().size(), CURL::GetRedacted(strPath).c_str()); break; } } pMap->SetWidth((int)maxWidth); pMap->SetHeight((int)maxHeight); file.Close(); if (pMap) { m_vecTextures.push_back(pMap); return pMap->GetTexture(); } } CBaseTexture *pTexture = NULL; int width = 0, height = 0; if (bundle >= 0) { if (!m_TexBundle[bundle].LoadTexture(strTextureName, &pTexture, width, height)) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); return emptyTexture; } } else { pTexture = CBaseTexture::LoadFromFile(strPath); if (!pTexture) return emptyTexture; width = pTexture->GetWidth(); height = pTexture->GetHeight(); } if (!pTexture) return emptyTexture; CTextureMap* pMap = new CTextureMap(strTextureName, width, height, 0); pMap->Add(pTexture, 100); m_vecTextures.push_back(pMap); #ifdef _DEBUG_TEXTURES int64_t end, freq; end = CurrentHostCounter(); freq = CurrentHostFrequency(); char temp[200]; sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : ""); OutputDebugString(temp); #endif return pMap->GetTexture(); }
bool CWinSystemEGL::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction) { if(!SetFullScreen(fullScreen, res, false)) return false; CTexture iconTexture; iconTexture.LoadFromFile("special://xbmc/media/icon.png"); SDL_WM_SetIcon(SDL_CreateRGBSurfaceFrom(iconTexture.GetPixels(), iconTexture.GetWidth(), iconTexture.GetHeight(), BPP, iconTexture.GetPitch(), 0xff0000, 0x00ff00, 0x0000ff, 0xff000000L), NULL); SDL_WM_SetCaption("XBMC Media Center", NULL); m_bWindowCreated = true; m_eglext = " "; m_eglext += eglQueryString(m_eglDisplay, EGL_EXTENSIONS); m_eglext += " "; CLog::Log(LOGDEBUG, "EGL_EXTENSIONS:%s", m_eglext.c_str()); return true; }
bool CTextureDDSJob::DoWork() { CTexture texture; if (URIUtils::GetExtension(m_original).Equals(".dds")) return false; if (texture.LoadFromFile(m_original)) { // convert to DDS CDDSImage dds; CLog::Log(LOGDEBUG, "Creating DDS version of: %s", m_original.c_str()); return dds.Create(URIUtils::ReplaceExtension(m_original, ".dds"), texture.GetWidth(), texture.GetHeight(), texture.GetPitch(), texture.GetPixels(), 40); } return false; }
//******************************************** // BuildList //******************************************** int CSceneGraph3d::glBuildList() { // Meshes //*********************************** unsigned int i,size = m_ArrayObject3d.GetSize(); for(i=0; i<size; i++) { CObject3d *pObject3d = m_ArrayObject3d.GetAt(i); if(pObject3d != NULL) { pObject3d->glBuildList(); } } // Textures //*********************************** unsigned int NbTexture = m_ArrayTexture.GetSize(); if(NbTexture) { TRACE("SceneGraph : texture binding...(%d texture(s))\n",NbTexture); // Cleanup if(m_pIndexTextureBinding != NULL) { ::glDeleteTextures(NbTexture,m_pIndexTextureBinding); delete [] m_pIndexTextureBinding; } m_pIndexTextureBinding = new unsigned int[NbTexture]; ::glGenTextures(NbTexture,m_pIndexTextureBinding); int error = glGetError(); ASSERT(error != GL_INVALID_VALUE); ASSERT(error != GL_INVALID_OPERATION); TRACE("Bind texture...\n"); for(i=0;i<NbTexture;i++) { while (GL_NO_ERROR != glGetError() ) {} // Bind texture glBindTexture(GL_TEXTURE_2D,m_pIndexTextureBinding[i]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); int error = glGetError(); ASSERT(error != GL_INVALID_ENUM); ASSERT(error != GL_INVALID_OPERATION); // Read datas CTexture *pTexture = m_ArrayTexture[i]; ASSERT(pTexture->GetData() != NULL); ::glTexImage2D(GL_TEXTURE_2D,0,3, pTexture->GetWidth(),pTexture->GetHeight(),0, GL_RGB,GL_UNSIGNED_BYTE,pTexture->GetData()); error = glGetError(); ASSERT(error != GL_INVALID_ENUM); ASSERT(error != GL_INVALID_OPERATION); ASSERT(error != GL_INVALID_VALUE); } } m_ListDone = 1; return 1; }
bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction) { RESOLUTION_INFO& desktop = g_settings.m_ResInfo[RES_DESKTOP]; if (fullScreen && (res.iWidth != desktop.iWidth || res.iHeight != desktop.iHeight || res.fRefreshRate != desktop.fRefreshRate || res.iScreen != desktop.iScreen)) { //on the first call to SDL_SetVideoMode, SDL stores the current displaymode //SDL restores the displaymode on SDL_QUIT(), if we change the displaymode //before the first call to SDL_SetVideoMode, SDL changes the displaymode back //to the wrong mode on exit CLog::Log(LOGINFO, "CWinSystemX11::CreateNewWindow initializing to desktop resolution first"); if (!SetFullScreen(true, desktop, false)) return false; } if(!SetFullScreen(fullScreen, res, false)) return false; CTexture iconTexture; iconTexture.LoadFromFile("special://xbmc/media/icon.png"); SDL_WM_SetIcon(SDL_CreateRGBSurfaceFrom(iconTexture.GetPixels(), iconTexture.GetWidth(), iconTexture.GetHeight(), 32, iconTexture.GetPitch(), 0xff0000, 0x00ff00, 0x0000ff, 0xff000000L), NULL); SDL_WM_SetCaption("XBMC Media Center", NULL); m_bWindowCreated = true; return true; }
void _UpdateVertexes() { if(!m_Font || !m_TextLines.Size()) return; m_Vertexes.SetUsed(m_GlyphCount << 2); m_Positions.SetUsed(m_GlyphCount << 2); f32 nXCoord = 0.0f; f32 nYCoord = 0.0f; CTexture* texture = m_Font->GetTexture(); u32 glyphCounter = 0; CList<STextLine>::CIterator it = m_TextLines.Begin(); while(it != m_TextLines.End()) { STextLine& line = *it; ++it; for(u32 j = 0; j < line.Text.Size(); j++) { CFont2D::SGlyph* glyph = m_Font->GetGlyph(line.Text[j]); if(glyph) { f32 tx = f32(glyph->X)/f32(texture->GetWidth()); f32 ty = f32(glyph->Y)/f32(texture->GetHeight()); f32 tw = f32(glyph->W)/f32(texture->GetWidth()); f32 th = f32(glyph->H)/f32(texture->GetHeight()); f32 fXOffset = f32(glyph->Xo); f32 fYOffset = f32(glyph->Yo); f32 ox = 0.0f; f32 oy = 0.0f; if(m_HAlignment == EHA_CENTER) { ox = (m_TextSize.X - line.Width)/2.0f; } else if(m_HAlignment == EHA_RIGHT) { ox = m_TextSize.X - line.Width; } if(m_VAlignment == EVA_CENTER) { oy = (m_TextSize.Y - m_TextLines.Size()*m_Font->GetSize())/2.0f; } else if(m_VAlignment == EVA_BOTTOM) { oy = m_TextSize.Y - m_TextLines.Size()*m_Font->GetSize(); } u32 idx = glyphCounter << 2; m_Positions[idx + 0].X = nXCoord + fXOffset + ox; m_Positions[idx + 0].Y = nYCoord + fYOffset + oy; m_Positions[idx + 0].Z = 0.0f; m_Vertexes[idx + 0].U = tx; m_Vertexes[idx + 0].V = ty; m_Vertexes[idx + 0].Color = m_Color; m_Positions[idx + 1].X = nXCoord + fXOffset + ox; m_Positions[idx + 1].Y = nYCoord + f32(glyph->H) + fYOffset + oy; m_Positions[idx + 1].Z = 0.0f; m_Vertexes[idx + 1].U = tx; m_Vertexes[idx + 1].V = ty + th; m_Vertexes[idx + 1].Color = m_Color; m_Positions[idx + 2].X = nXCoord + f32(glyph->W) + fXOffset + ox; m_Positions[idx + 2].Y = nYCoord + f32(glyph->H) + fYOffset + oy; m_Positions[idx + 2].Z = 0.0f; m_Vertexes[idx + 2].U = tx + tw; m_Vertexes[idx + 2].V = ty + th; m_Vertexes[idx + 2].Color = m_Color; m_Positions[idx + 3].X = nXCoord + f32(glyph->W) + fXOffset + ox; m_Positions[idx + 3].Y = nYCoord + fYOffset + oy; m_Positions[idx + 3].Z = 0.0f; m_Vertexes[idx + 3].U = tx + tw; m_Vertexes[idx + 3].V = ty; m_Vertexes[idx + 3].Color = m_Color; glyphCounter++; nXCoord += glyph->Xa; } else nXCoord += m_Font->GetSize(); } nXCoord = 0.0; nYCoord += m_Font->GetSize(); } }