//----------------------------------------------------------------------------- // Name: CreateBumpmap() // Desc: Create a bump map texture and fill its content to BUMPDUDV format //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::CreateBumpMap( UINT iWidth, UINT iHeight ) { // Create the bumpmap's surface and texture objects if( FAILED( m_pd3dDevice->CreateTexture( iWidth, iHeight, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &m_pBumpMapTexture ) ) ) { return E_FAIL; } // Fill the bumpmap texels to simulate a lens D3DLOCKED_RECT d3dlr; m_pBumpMapTexture->LockRect( 0, &d3dlr, 0, 0 ); DWORD dwDstPitch = (DWORD)d3dlr.Pitch; BYTE* pDst = (BYTE*)d3dlr.pBits; UINT mid = iWidth/2; for( DWORD y0 = 0; y0 < iHeight; y0++ ) { CHAR* pDst = (CHAR*)d3dlr.pBits + y0*d3dlr.Pitch; for( DWORD x0 = 0; x0 < iWidth; x0++ ) { DWORD x1 = ( (x0==iWidth-1) ? x0 : x0+1 ); DWORD y1 = ( (x0==iHeight-1) ? y0 : y0+1 ); FLOAT fDistSq00 = (FLOAT)( (x0-mid)*(x0-mid) + (y0-mid)*(y0-mid) ); FLOAT fDistSq01 = (FLOAT)( (x1-mid)*(x1-mid) + (y0-mid)*(y0-mid) ); FLOAT fDistSq10 = (FLOAT)( (x0-mid)*(x0-mid) + (y1-mid)*(y1-mid) ); FLOAT v00 = ( fDistSq00 > (mid*mid) ) ? 0.0f : sqrtf( (mid*mid) - fDistSq00 ); FLOAT v01 = ( fDistSq01 > (mid*mid) ) ? 0.0f : sqrtf( (mid*mid) - fDistSq01 ); FLOAT v10 = ( fDistSq10 > (mid*mid) ) ? 0.0f : sqrtf( (mid*mid) - fDistSq10 ); FLOAT iDu = (128/D3DX_PI)*atanf(v00-v01); // The delta-u bump value FLOAT iDv = (128/D3DX_PI)*atanf(v00-v10); // The delta-v bump value *pDst++ = (CHAR)(iDu); *pDst++ = (CHAR)(iDv); } } m_pBumpMapTexture->UnlockRect(0); return S_OK; }
int CGUITextureManager::Load(const CStdString& strTextureName, DWORD dwColorKey, bool checkBundleOnly /*= false */) { CStdString strPath; int bundle = -1; int size = 0; if (!HasTexture(strTextureName, &strPath, &bundle, &size)) return 0; if (size) // we found the texture return size; // See if texture is being overridden. CStdString strTextureFile = strTextureName; CStdString strTextureOverridePath1; CStdString strTextureOverridePath2; CStdString strExt = CUtil::GetExtension(strTextureFile); CUtil::RemoveExtension(strTextureFile); // Check original format and JPEG. strTextureOverridePath1.Format("%s/media/%s%s", _P("Q:"), strTextureFile.c_str(), strExt.c_str()); strTextureOverridePath2.Format("%s/media/%s.jpg", _P("Q:"), strTextureFile.c_str(), strExt.c_str()); if (checkBundleOnly && bundle == -1) return 0; if (XFILE::CFile::Exists(strTextureOverridePath1)) { strPath = strTextureOverridePath1; bundle = -1; } else if (XFILE::CFile::Exists(strTextureOverridePath2)) { strPath = strTextureOverridePath2; bundle = -1; } else if (bundle == -1) strPath = GetTexturePath(strTextureName); else strPath = strTextureName; //Lock here, we will do stuff that could break rendering CSingleLock lock(g_graphicsContext); #ifndef HAS_SDL LPDIRECT3DTEXTURE8 pTexture; LPDIRECT3DPALETTE8 pPal = 0; #else SDL_Surface* pTexture; SDL_Palette* pPal = NULL; #endif #ifdef _DEBUG LARGE_INTEGER start; QueryPerformanceCounter(&start); #endif D3DXIMAGE_INFO info; if (strPath.Right(4).ToLower() == ".gif") { CTextureMap* pMap; if (bundle >= 0) { #ifndef HAS_SDL LPDIRECT3DTEXTURE8* pTextures; #else SDL_Surface** pTextures; #endif int nLoops = 0; int* Delay; #ifndef HAS_SDL int nImages = m_TexBundle[bundle].LoadAnim(g_graphicsContext.Get3DDevice(), strTextureName, &info, &pTextures, &pPal, nLoops, &Delay); #else int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &info, &pTextures, &pPal, nLoops, &Delay); #endif if (!nImages) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); return 0; } pMap = new CTextureMap(strTextureName); for (int iImage = 0; iImage < nImages; ++iImage) { CTexture* pclsTexture = new CTexture(pTextures[iImage], info.Width, info.Height, true, 100, pPal); pclsTexture->SetDelay(Delay[iImage]); pclsTexture->SetLoops(nLoops); pMap->Add(pclsTexture); #ifndef HAS_SDL delete pTextures[iImage]; #else SDL_FreeSurface(pTextures[iImage]); #endif } delete [] pTextures; delete [] Delay; } else { CAnimatedGifSet AnimatedGifSet; int iImages = AnimatedGifSet.LoadGIF(strPath.c_str()); if (iImages == 0) { if (!strnicmp(strPath.c_str(), "q:\\skin", 7)) CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str()); return 0; } int iWidth = AnimatedGifSet.FrameWidth; int iHeight = AnimatedGifSet.FrameHeight; int iPaletteSize = (1 << AnimatedGifSet.m_vecimg[0]->BPP); pMap = new CTextureMap(strTextureName); for (int iImage = 0; iImage < iImages; iImage++) { int w = iWidth; int h = iHeight; #if defined(HAS_SDL) pTexture = SDL_CreateRGBSurface(SDL_HWSURFACE, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); if (pTexture) #else if (D3DXCreateTexture(g_graphicsContext.Get3DDevice(), w, h, 1, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_MANAGED, &pTexture) == D3D_OK) #endif { CAnimatedGif* pImage = AnimatedGifSet.m_vecimg[iImage]; #ifndef HAS_SDL D3DLOCKED_RECT lr; RECT rc = { 0, 0, pImage->Width, pImage->Height }; if ( D3D_OK == pTexture->LockRect( 0, &lr, &rc, 0 )) #else if (SDL_LockSurface(pTexture) != -1) #endif { COLOR *palette = AnimatedGifSet.m_vecimg[0]->Palette; // set the alpha values to fully opaque for (int i = 0; i < iPaletteSize; i++) palette[i].x = 0xff; // and set the transparent colour if (AnimatedGifSet.m_vecimg[0]->Transparency && AnimatedGifSet.m_vecimg[0]->Transparent >= 0) palette[AnimatedGifSet.m_vecimg[0]->Transparent].x = 0; #ifdef HAS_SDL // Allocate memory for the actual pixels in the surface and set the surface BYTE* pixels = (BYTE*) malloc(w * h * 4); pTexture->pixels = pixels; #endif for (int y = 0; y < pImage->Height; y++) { #ifndef HAS_SDL BYTE *dest = (BYTE *)lr.pBits + y * lr.Pitch; #else BYTE *dest = (BYTE *)pixels + (y * w * 4); #endif BYTE *source = (BYTE *)pImage->Raster + y * pImage->BytesPerRow; for (int x = 0; x < pImage->Width; x++) { COLOR col = palette[*source++]; *dest++ = col.b; *dest++ = col.g; *dest++ = col.r; *dest++ = col.x; } } #ifndef HAS_SDL pTexture->UnlockRect( 0 ); #else SDL_UnlockSurface(pTexture); #endif CTexture* pclsTexture = new CTexture(pTexture, iWidth, iHeight, false, 100, pPal); pclsTexture->SetDelay(pImage->Delay); pclsTexture->SetLoops(AnimatedGifSet.nLoops); #ifdef HAS_SDL free(pixels); #endif #ifdef HAS_SDL_2D SDL_FreeSurface(pTexture); #endif pMap->Add(pclsTexture); } } } // of for (int iImage=0; iImage < iImages; iImage++) } #ifdef _DEBUG LARGE_INTEGER end, freq; QueryPerformanceCounter(&end); QueryPerformanceFrequency(&freq); char temp[200]; sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end.QuadPart - start.QuadPart) / freq.QuadPart, (bundle >= 0) ? " (bundled)" : ""); OutputDebugString(temp); #endif m_vecTextures.push_back(pMap); return pMap->size(); } // of if (strPath.Right(4).ToLower()==".gif") if (bundle >= 0) { #ifndef HAS_SDL if (FAILED(m_TexBundle[bundle].LoadTexture(g_graphicsContext.Get3DDevice(), strTextureName, &info, &pTexture, &pPal))) #else if (FAILED(m_TexBundle[bundle].LoadTexture(strTextureName, &info, &pTexture, &pPal))) #endif { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); return 0; } } else { // normal picture // convert from utf8 CStdString texturePath; g_charsetConverter.utf8ToStringCharset(_P(strPath), texturePath); #ifndef HAS_SDL if ( D3DXCreateTextureFromFileEx(g_graphicsContext.Get3DDevice(), texturePath.c_str(), D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE , D3DX_FILTER_NONE, dwColorKey, &info, NULL, &pTexture) != D3D_OK) { if (!strnicmp(strPath.c_str(), "q:\\skin", 7)) CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str()); return 0; } #else SDL_Surface *original = IMG_Load(texturePath.c_str()); CPicture pic; if (!original && !(original = pic.Load(texturePath, MAX_PICTURE_WIDTH, MAX_PICTURE_HEIGHT))) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str()); return 0; } // make sure the texture format is correct SDL_PixelFormat format; format.palette = 0; format.colorkey = 0; format.alpha = 0; format.BitsPerPixel = 32; format.BytesPerPixel = 4; format.Amask = 0xff000000; format.Ashift = 24; format.Rmask = 0x00ff0000; format.Rshift = 16; format.Gmask = 0x0000ff00; format.Gshift = 8; format.Bmask = 0x000000ff; format.Bshift = 0; #ifdef HAS_SDL_OPENGL pTexture = SDL_ConvertSurface(original, &format, SDL_SWSURFACE); #else pTexture = SDL_ConvertSurface(original, &format, SDL_HWSURFACE); #endif SDL_FreeSurface(original); if (!pTexture) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str()); return 0; } info.Width = pTexture->w; info.Height = pTexture->h; #endif } CTextureMap* pMap = new CTextureMap(strTextureName); CTexture* pclsTexture = new CTexture(pTexture, info.Width, info.Height, bundle >= 0, 100, pPal); pMap->Add(pclsTexture); m_vecTextures.push_back(pMap); #ifdef HAS_SDL_OPENGL SDL_FreeSurface(pTexture); #endif #ifdef _DEBUG LARGE_INTEGER end, freq; QueryPerformanceCounter(&end); QueryPerformanceFrequency(&freq); char temp[200]; sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end.QuadPart - start.QuadPart) / freq.QuadPart, (bundle >= 0) ? " (bundled)" : ""); OutputDebugString(temp); #endif return 1; }
Filename_notice *prepare_filename_notice(LPDIRECT3DDEVICE8 pd3dDevice, char const *filename) { HRESULT result; Filename_notice *notice = NULL; HDC hDC = NULL; HFONT hFont = NULL; SIZE size; int width, height; LPDIRECT3DTEXTURE8 pTexture = NULL; LPDIRECT3DVERTEXBUFFER8 pVB = NULL; DWORD *pBitmapBits = NULL; BITMAPINFO bmi; HBITMAP hbmBitmap = NULL; D3DLOCKED_RECT d3dlr; BYTE *pDstRow; int x, y; hDC = CreateCompatibleDC(NULL); SetMapMode(hDC, MM_TEXT); hFont = CreateFont( FONT_HEIGHT, // height 0, // width (0 = closest) 0, // escapement (0 = none) 0, // orientation (0 = none) FW_NORMAL, // bold FALSE, // italic FALSE, // underline FALSE, // strikeout DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, // TrueType (OUT_TT_PRECIS) doesn't help CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, FONT_NAME); if (hFont == NULL) { goto done; } // Set text properties SelectObject(hDC, hFont); SetTextColor(hDC, RGB(255,255,255)); SetBkColor(hDC, 0x00000000); SetTextAlign(hDC, TA_TOP); GetTextExtentPoint32(hDC, filename, strlen(filename), &size); width = size.cx; height = size.cy; // Create a new texture for the font result = pd3dDevice->CreateTexture(width, height, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, &pTexture); if (FAILED(result)) { goto done; } // Prepare to create a bitmap ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = -height; // negative means top-down bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0); SelectObject(hDC, hbmBitmap); ExtTextOut(hDC, 0, 0, ETO_OPAQUE, NULL, filename, strlen(filename), NULL); // Lock the surface and write the alpha values for the set pixels pTexture->LockRect(0, &d3dlr, 0, 0); pDstRow = (BYTE*)d3dlr.pBits; for (y = 0; y < height; y++) { WORD *pDst16 = (WORD *)pDstRow; for (x = 0; x < width; x++) { BYTE bAlpha = (BYTE)((pBitmapBits[width*y + x] & 0xff) >> 4); if (bAlpha > 0) { *pDst16++ = (WORD)((bAlpha << 12) | 0x0fff); } else { *pDst16++ = (WORD)(0x0000); } } pDstRow += d3dlr.Pitch; } // Done updating texture pTexture->UnlockRect(0); // Create vertices result = pd3dDevice->CreateVertexBuffer(4*sizeof(FONT2DVERTEX), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &pVB); if (FAILED(result)) { goto done; } notice = new Filename_notice; notice->width = width; notice->height = height; notice->pd3dDevice = pd3dDevice; notice->pTexture = pTexture; pTexture = NULL; notice->pVB = pVB; pVB = NULL; pd3dDevice->BeginStateBlock(); apply_render_state(pd3dDevice); pd3dDevice->SetTexture(0, notice->pTexture); pd3dDevice->EndStateBlock(¬ice->dwSavedStateBlock); pd3dDevice->BeginStateBlock(); apply_render_state(pd3dDevice); pd3dDevice->SetTexture(0, notice->pTexture); pd3dDevice->EndStateBlock(¬ice->dwDrawTextStateBlock); done: if (pVB != NULL) { pVB->Release(); } if (pTexture != NULL) { pTexture->Release(); } if (hbmBitmap != NULL) { DeleteObject(hbmBitmap); } if (hFont != NULL) { DeleteObject(hFont); } if (hDC != NULL) { DeleteDC(hDC); } return notice; }