static void UpdateYUVTextureData(SDL_Texture * texture) { D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; SDL_Rect rect; RECT d3drect; D3DLOCKED_RECT locked; HRESULT result; d3drect.left = 0; d3drect.right = texture->w; d3drect.top = 0; d3drect.bottom = texture->h; result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0); if (FAILED(result)) { return; } rect.x = 0; rect.y = 0; rect.w = texture->w; rect.h = texture->h; SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w, texture->h, locked.pBits, locked.Pitch); IDirect3DTexture9_UnlockRect(data->texture, 0); }
static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; IDirect3DTexture9_UnlockRect(data->texture, 0); }
static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; if (data->yuv) { SDL_SW_UnlockYUVTexture(data->yuv); UpdateYUVTextureData(texture); } else { IDirect3DTexture9_UnlockRect(data->texture, 0); } }
static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; RECT d3drect; D3DLOCKED_RECT locked; const Uint8 *src; Uint8 *dst; int row, length; HRESULT result; #ifdef USE_DYNAMIC_TEXTURE if (texture->access == SDL_TEXTUREACCESS_STREAMING && rect->x == 0 && rect->y == 0 && rect->w == texture->w && rect->h == texture->h) { result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, NULL, D3DLOCK_DISCARD); } else #endif { d3drect.left = rect->x; d3drect.right = rect->x + rect->w; d3drect.top = rect->y; d3drect.bottom = rect->y + rect->h; result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0); } if (FAILED(result)) { D3D_SetError("LockRect()", result); return -1; } src = pixels; dst = locked.pBits; length = rect->w * SDL_BYTESPERPIXEL(texture->format); if (length == pitch && length == locked.Pitch) { SDL_memcpy(dst, src, length*rect->h); } else { for (row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); src += pitch; dst += locked.Pitch; } } IDirect3DTexture9_UnlockRect(data->texture, 0); return 0; }
IDirect3DTexture9* iD3DMakeTexture( IDirect3DDevice9 *Device, void *Data, ILuint DLen, ILuint Width, ILuint Height, D3DFORMAT Format, D3DPOOL Pool, ILuint Levels ) { IDirect3DTexture9 *Texture; D3DLOCKED_RECT Rect; if (FAILED(IDirect3DDevice9_CreateTexture(Device, Width, Height, Levels, 0, Format, Pool, &Texture, NULL))) return NULL; if (FAILED(IDirect3DTexture9_LockRect(Texture, 0, &Rect, NULL, 0))) return NULL; memcpy(Rect.pBits, Data, DLen); IDirect3DTexture9_UnlockRect(Texture, 0); return Texture; }
/** @brief Callback function to render the OSD to the texture */ static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { D3DLOCKED_RECT locked_rect; /**< Offscreen surface we lock in order to copy MPlayer's frame inside it.*/ if (FAILED(IDirect3DTexture9_LockRect(priv->d3d_texture_system, 0, &locked_rect, NULL, 0))) { mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>OSD texture lock failed.\n"); return; } vo_draw_alpha_l8a8(w, h, src, srca, stride, (unsigned char *)locked_rect.pBits + locked_rect.Pitch*y0 + 2*x0, locked_rect.Pitch); /* this unlock is used for both slice_draw path and D3DRenderFrame path */ if (FAILED(IDirect3DTexture9_UnlockRect(priv->d3d_texture_system, 0))) { mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>OSD texture unlock failed.\n"); return; } priv->is_osd_populated = 1; }
/** @brief libvo Callback: Draw OSD/Subtitles, */ static void draw_osd(void) { // we can not render OSD if we lost the device e.g. because it was uncooperative if (!priv->d3d_device) return; if (vo_osd_changed(0)) { D3DLOCKED_RECT locked_rect; /**< Offscreen surface we lock in order to copy MPlayer's frame inside it.*/ /* clear the OSD */ if (FAILED(IDirect3DTexture9_LockRect(priv->d3d_texture_system, 0, &locked_rect, NULL, 0))) { mp_msg(MSGT_VO,MSGL_ERR, "<vo_direct3d>OSD texture lock failed.\n"); return; } /* clear the whole texture to avoid issues due to interpolation */ memset(locked_rect.pBits, 0, locked_rect.Pitch * priv->osd_texture_height); /* this unlock is used for both slice_draw path and D3DRenderFrame path */ if (FAILED(IDirect3DTexture9_UnlockRect(priv->d3d_texture_system, 0))) { mp_msg(MSGT_VO,MSGL_ERR, "<vo_direct3d>OSD texture unlock failed.\n"); return; } priv->is_osd_populated = 0; /* required for if subs are in the boarder region */ priv->is_clear_needed = 1; vo_draw_text_ext(priv->osd_width, priv->osd_height, priv->border_x, priv->border_y, priv->border_x, priv->border_y, priv->src_width, priv->src_height, draw_alpha); if (!priv->device_texture_sys) { /* only DMA to the shadow if its required */ if (FAILED(IDirect3DDevice9_UpdateTexture(priv->d3d_device, (IDirect3DBaseTexture9 *)priv->d3d_texture_system, (IDirect3DBaseTexture9 *)priv->d3d_texture_osd))) { mp_msg(MSGT_VO,MSGL_ERR, "<vo_direct3d>OSD texture transfer failed.\n"); return; } } } /* update OSD */ if (priv->is_osd_populated) { struct_vertex osd_quad_vb[] = { {-1.0f, 1.0f, 0.0f, 0, 0 }, { 1.0f, 1.0f, 0.0f, 1, 0 }, {-1.0f,-1.0f, 0.0f, 0, 1 }, { 1.0f,-1.0f, 0.0f, 1, 1 } }; /* calculate the texture coordinates */ osd_quad_vb[1].tu = osd_quad_vb[3].tu = (float)priv->osd_width / priv->osd_texture_width; osd_quad_vb[2].tv = osd_quad_vb[3].tv = (float)priv->osd_height / priv->osd_texture_height; if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) { mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>BeginScene failed.\n"); return; } /* turn on alpha test */ IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHABLENDENABLE, TRUE); IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHATESTENABLE, TRUE); /* need to use a texture here (done here as we may be able to texture from system memory) */ IDirect3DDevice9_SetTexture(priv->d3d_device, 0, (IDirect3DBaseTexture9 *)(priv->device_texture_sys ? priv->d3d_texture_system : priv->d3d_texture_osd)); IDirect3DDevice9_SetFVF(priv->d3d_device, D3DFVF_MY_VERTEX); IDirect3DDevice9_DrawPrimitiveUP(priv->d3d_device, D3DPT_TRIANGLESTRIP, 2, osd_quad_vb, sizeof(struct_vertex)); /* turn off alpha test */ IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHATESTENABLE, FALSE); IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHABLENDENABLE, FALSE); if (FAILED(IDirect3DDevice9_EndScene(priv->d3d_device))) { mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>EndScene failed.\n"); return; } } }
static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; if (data->yuv) { if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) { return -1; } UpdateYUVTextureData(texture); return 0; } else { #ifdef SDL_MEMORY_POOL_DEFAULT IDirect3DTexture9 *temp; RECT d3drect; D3DLOCKED_RECT locked; const Uint8 *src; Uint8 *dst; int row, length; HRESULT result; result = IDirect3DDevice9_CreateTexture(renderdata->device, texture->w, texture->h, 1, 0, PixelFormatToD3DFMT(texture-> format), D3DPOOL_SYSTEMMEM, &temp, NULL); if (FAILED(result)) { D3D_SetError("CreateTexture()", result); return -1; } d3drect.left = rect->x; d3drect.right = rect->x + rect->w; d3drect.top = rect->y; d3drect.bottom = rect->y + rect->h; result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0); if (FAILED(result)) { IDirect3DTexture9_Release(temp); D3D_SetError("LockRect()", result); return -1; } src = pixels; dst = locked.pBits; length = rect->w * SDL_BYTESPERPIXEL(texture->format); for (row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); src += pitch; dst += locked.Pitch; } IDirect3DTexture9_UnlockRect(temp, 0); result = IDirect3DDevice9_UpdateTexture(renderdata->device, (IDirect3DBaseTexture9 *) temp, (IDirect3DBaseTexture9 *) data->texture); IDirect3DTexture9_Release(temp); if (FAILED(result)) { D3D_SetError("UpdateTexture()", result); return -1; } #else RECT d3drect; D3DLOCKED_RECT locked; const Uint8 *src; Uint8 *dst; int row, length; HRESULT result; d3drect.left = rect->x; d3drect.right = rect->x + rect->w; d3drect.top = rect->y; d3drect.bottom = rect->y + rect->h; result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0); if (FAILED(result)) { D3D_SetError("LockRect()", result); return -1; } src = pixels; dst = locked.pBits; length = rect->w * SDL_BYTESPERPIXEL(texture->format); for (row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); src += pitch; dst += locked.Pitch; } IDirect3DTexture9_UnlockRect(data->texture, 0); #endif // SDL_MEMORY_POOL_DEFAULT return 0; } }
static void Direct3DImportSubpicture(vout_display_t *vd, int *count_ptr, d3d_region_t **region, subpicture_t *subpicture) { vout_display_sys_t *sys = vd->sys; int count = 0; for (subpicture_region_t *r = subpicture->p_region; r; r = r->p_next) count++; *count_ptr = count; *region = calloc(count, sizeof(**region)); if (*region == NULL) { *count_ptr = 0; return; } int i = 0; for (subpicture_region_t *r = subpicture->p_region; r; r = r->p_next, i++) { d3d_region_t *d3dr = &(*region)[i]; HRESULT hr; d3dr->texture = NULL; for (int j = 0; j < sys->d3dregion_count; j++) { d3d_region_t *cache = &sys->d3dregion[j]; if (cache->texture && cache->format == sys->d3dregion_format && cache->width == r->fmt.i_visible_width && cache->height == r->fmt.i_visible_height) { #ifndef NDEBUG msg_Dbg(vd, "Reusing %dx%d texture for OSD", cache->width, cache->height); #endif *d3dr = *cache; memset(cache, 0, sizeof(*cache)); } } if (!d3dr->texture) { d3dr->format = sys->d3dregion_format; d3dr->width = r->fmt.i_visible_width; d3dr->height = r->fmt.i_visible_height; hr = IDirect3DDevice9_CreateTexture(sys->d3ddev, d3dr->width, d3dr->height, 1, D3DUSAGE_DYNAMIC, d3dr->format, D3DPOOL_DEFAULT, &d3dr->texture, NULL); if (FAILED(hr)) { d3dr->texture = NULL; msg_Err(vd, "Failed to create %dx%d texture for OSD (hr=0x%0lX)", d3dr->width, d3dr->height, hr); continue; } msg_Dbg(vd, "Created %dx%d texture for OSD", r->fmt.i_visible_width, r->fmt.i_visible_height); } D3DLOCKED_RECT lock; hr = IDirect3DTexture9_LockRect(d3dr->texture, 0, &lock, NULL, 0); if (SUCCEEDED(hr)) { uint8_t *dst_data = lock.pBits; int dst_pitch = lock.Pitch; const int src_offset = r->fmt.i_y_offset * r->p_picture->p->i_pitch + r->fmt.i_x_offset * r->p_picture->p->i_pixel_pitch; uint8_t *src_data = &r->p_picture->p->p_pixels[src_offset]; int src_pitch = r->p_picture->p->i_pitch; for (unsigned y = 0; y < r->fmt.i_visible_height; y++) { int copy_pitch = __MIN(dst_pitch, r->p_picture->p->i_visible_pitch); if (d3dr->format == D3DFMT_A8B8G8R8) { memcpy(&dst_data[y * dst_pitch], &src_data[y * src_pitch], copy_pitch); } else { for (int x = 0; x < copy_pitch; x += 4) { dst_data[y * dst_pitch + x + 0] = src_data[y * src_pitch + x + 2]; dst_data[y * dst_pitch + x + 1] = src_data[y * src_pitch + x + 1]; dst_data[y * dst_pitch + x + 2] = src_data[y * src_pitch + x + 0]; dst_data[y * dst_pitch + x + 3] = src_data[y * src_pitch + x + 3]; } } } hr = IDirect3DTexture9_UnlockRect(d3dr->texture, 0); if (FAILED(hr)) msg_Err(vd, "Failed to unlock the texture"); } else { msg_Err(vd, "Failed to lock the texture"); } /* Map the subpicture to sys->rect_dest */ RECT src; src.left = 0; src.right = src.left + r->fmt.i_visible_width; src.top = 0; src.bottom = src.top + r->fmt.i_visible_height; const RECT video = sys->rect_dest; const float scale_w = (float)(video.right - video.left) / subpicture->i_original_picture_width; const float scale_h = (float)(video.bottom - video.top) / subpicture->i_original_picture_height; RECT dst; dst.left = video.left + scale_w * r->i_x, dst.right = dst.left + scale_w * r->fmt.i_visible_width, dst.top = video.top + scale_h * r->i_y, dst.bottom = dst.top + scale_h * r->fmt.i_visible_height, Direct3DSetupVertices(d3dr->vertex, src, src, dst, subpicture->i_alpha * r->i_alpha / 255); } }
static void test_mipmap_gen(IDirect3DDevice9 *device) { HRESULT hr; IDirect3D9 *d3d9; IDirect3DTexture9 *texture = NULL; IDirect3DSurface9 *surface; DWORD levels; D3DSURFACE_DESC desc; int i; D3DLOCKED_RECT lr; hr = IDirect3DDevice9_GetDirect3D(device, &d3d9); ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D returned %#x\n", hr); hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8); if(FAILED(hr)) { skip("No mipmap generation support\n"); return; } /* testing shows that autogenmipmap and rendertarget are mutually exclusive options */ hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP), D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, 0); ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned 0x%08x, expected 0x%08x\n", hr, D3D_OK); if (texture) IDirect3DTexture9_Release(texture); texture = NULL; hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0); ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed(%08x)\n", hr); if (SUCCEEDED(hr)) { D3DTEXTUREFILTERTYPE fltt; fltt = IDirect3DTexture9_GetAutoGenFilterType(texture); ok(D3DTEXF_LINEAR == fltt /* || broken(D3DTEXF_POINT == fltt)*/, "GetAutoGenFilterType returned default %d\n", fltt); hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE); todo_wine ok(hr == D3DERR_INVALIDCALL, "SetAutoGenFilterType D3DTEXF_NONE returned %08x\n", hr); hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC); ok(hr == D3D_OK, "SetAutoGenFilterType D3DTEXF_ANISOTROPIC returned %08x\n", hr); fltt = IDirect3DTexture9_GetAutoGenFilterType(texture); ok(D3DTEXF_ANISOTROPIC == fltt, "GetAutoGenFilterType returned %d\n", fltt); hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR); ok(hr == D3D_OK, "SetAutoGenFilterType D3DTEXF_LINEAR returned %08x\n", hr); } levels = IDirect3DTexture9_GetLevelCount(texture); ok(levels == 1, "Got %d levels, expected 1\n", levels); for(i = 0; i < 6 /* 64 = 2 ^ 6 */; i++) { surface = NULL; hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface); ok(hr == (i == 0 ? D3D_OK : D3DERR_INVALIDCALL), "GetSurfaceLevel on level %d returned %#x\n", i, hr); if(surface) IDirect3DSurface9_Release(surface); hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc); ok(hr == (i == 0 ? D3D_OK : D3DERR_INVALIDCALL), "GetLevelDesc on level %d returned %#x\n", i, hr); hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0); ok(hr == (i == 0 ? D3D_OK : D3DERR_INVALIDCALL), "LockRect on level %d returned %#x\n", i, hr); if(SUCCEEDED(hr)) { hr = IDirect3DTexture9_UnlockRect(texture, i); ok(hr == D3D_OK, "Unlock returned %08x\n", hr); } } IDirect3DTexture9_Release(texture); hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2 /* levels */, D3DUSAGE_AUTOGENMIPMAP, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0); ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture(levels = 2) returned %08x\n", hr); hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6 /* levels */, D3DUSAGE_AUTOGENMIPMAP, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0); ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture(levels = 6) returned %08x\n", hr); hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1 /* levels */, D3DUSAGE_AUTOGENMIPMAP, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0); ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture(levels = 1) returned %08x\n", hr); levels = IDirect3DTexture9_GetLevelCount(texture); ok(levels == 1, "Got %d levels, expected 1\n", levels); IDirect3DTexture9_Release(texture); }
static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite, const WCHAR *string, INT count, RECT *rect, DWORD format, D3DCOLOR color) { struct d3dx_font *This = impl_from_ID3DXFont(iface); RECT calc_rect; INT height; TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x\n", iface, sprite, debugstr_w(string), count, wine_dbgstr_rect(rect), format, color); if (!string || count == 0) return 0; if (count < 0) count = lstrlenW(string); /* Strip terminating NULL characters */ while (count > 0 && !string[count-1]) count--; if (rect) calc_rect = *rect; height = DrawTextW(This->hdc, string, count, &calc_rect, format | DT_CALCRECT); if (format & DT_CALCRECT) { if (rect) *rect = calc_rect; return height; } if (format & DT_CENTER) { UINT new_width = calc_rect.right - calc_rect.left; calc_rect.left = (rect->right + rect->left - new_width) / 2; calc_rect.right = calc_rect.left + new_width; } if (height && (calc_rect.left < calc_rect.right)) { D3DLOCKED_RECT locked_rect; D3DXVECTOR3 position; UINT text_width, text_height; RECT text_rect; ID3DXSprite *target = sprite; HRESULT hr; int i, j; /* Get rect position and dimensions */ position.x = calc_rect.left; position.y = calc_rect.top; position.z = 0; text_width = calc_rect.right - calc_rect.left; text_height = calc_rect.bottom - calc_rect.top; text_rect.left = 0; text_rect.top = 0; text_rect.right = text_width; text_rect.bottom = text_height; /* We need to flush as it seems all draws in the begin/end sequence use only the latest updated texture */ if (sprite) ID3DXSprite_Flush(sprite); /* Extend texture and DIB section to contain text */ if ((text_width > This->tex_width) || (text_height > This->tex_height)) { BITMAPINFOHEADER header; if (text_width > This->tex_width) This->tex_width = make_pow2(text_width); if (text_height > This->tex_height) This->tex_height = make_pow2(text_height); if (This->texture) { IDirect3DTexture9_Release(This->texture); DeleteObject(This->bitmap); } hr = D3DXCreateTexture(This->device, This->tex_width, This->tex_height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &This->texture); if (FAILED(hr)) { This->texture = NULL; return 0; } header.biSize = sizeof(header); header.biWidth = This->tex_width; header.biHeight = -This->tex_height; header.biPlanes = 1; header.biBitCount = 32; header.biCompression = BI_RGB; header.biSizeImage = sizeof(DWORD) * This->tex_width * This->tex_height; header.biXPelsPerMeter = 0; header.biYPelsPerMeter = 0; header.biClrUsed = 0; header.biClrImportant = 0; This->bitmap = CreateDIBSection(This->hdc, (const BITMAPINFO*)&header, DIB_RGB_COLORS, (void**)&This->bits, NULL, 0); if (!This->bitmap) { IDirect3DTexture9_Release(This->texture); This->texture = NULL; return 0; } SelectObject(This->hdc, This->bitmap); } if (FAILED(IDirect3DTexture9_LockRect(This->texture, 0, &locked_rect, &text_rect, D3DLOCK_DISCARD))) return 0; /* Clear rect */ for (i = 0; i < text_height; i++) memset(This->bits + i * This->tex_width * sizeof(DWORD), 0, text_width * sizeof(DWORD)); DrawTextW(This->hdc, string, count, &text_rect, format); /* All RGB components are equal so take one as alpha and set RGB * color to white, so it can be modulated with color parameter */ for (i = 0; i < text_height; i++) { DWORD *src = (DWORD *)This->bits + i * This->tex_width; DWORD *dst = (DWORD *)((BYTE *)locked_rect.pBits + i * locked_rect.Pitch); for (j = 0; j < text_width; j++) { *dst++ = (*src++ << 24) | 0xFFFFFF; } } IDirect3DTexture9_UnlockRect(This->texture, 0); if (!sprite) { hr = D3DXCreateSprite(This->device, &target); if (FAILED(hr)) return 0; ID3DXSprite_Begin(target, 0); } hr = target->lpVtbl->Draw(target, This->texture, &text_rect, NULL, &position, color); if (!sprite) { ID3DXSprite_End(target); ID3DXSprite_Release(target); } if (FAILED(hr)) return 0; } return height; }
ILboolean iD3D9CreateMipmaps(IDirect3DTexture9 *Texture, ILimage *Image) { D3DLOCKED_RECT Rect; D3DSURFACE_DESC Desc; ILuint NumMips, Width, Height, i; ILimage *CurImage, *MipImage, *Temp; ILenum DXTCFormat; ILuint Size; ILubyte *Buffer; ILboolean useDXTC = IL_FALSE; NumMips = IDirect3DTexture9_GetLevelCount(Texture); Width = Image->Width; Height = Image->Height; if (NumMips == 1) return IL_TRUE; CurImage = ilGetCurImage(); MipImage = Image; if (MipImage->NumMips != NumMips-1) { MipImage = ilCopyImage_(Image); ilSetCurImage(MipImage); if (!iluBuildMipmaps()) { ilCloseImage(MipImage); ilSetCurImage(CurImage); return IL_FALSE; } } // ilSetCurImage(CurImage); Temp = MipImage->Mipmaps; if (ilutGetBoolean(ILUT_D3D_USE_DXTC) && FormatsDX9supported[3] && FormatsDX9supported[4] && FormatsDX9supported[5]) useDXTC = IL_TRUE; // Counts the base texture as 1. for (i = 1; i < NumMips && Temp != NULL; i++) { ilSetCurImage(Temp); if (FAILED(IDirect3DTexture9_LockRect(Texture, i, &Rect, NULL, 0))) return IL_FALSE; Width = IL_MAX(1, Width / 2); Height = IL_MAX(1, Height / 2); IDirect3DTexture9_GetLevelDesc(Texture, i, &Desc); if (Desc.Width != Width || Desc.Height != Height) { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } if (useDXTC) { if (Temp->DxtcData != NULL && Temp->DxtcSize != 0) { memcpy(Rect.pBits, Temp->DxtcData, Temp->DxtcSize); } else if (ilutGetBoolean(ILUT_D3D_GEN_DXTC)) { DXTCFormat = ilutGetInteger(ILUT_DXTC_FORMAT); Size = ilGetDXTCData(NULL, 0, DXTCFormat); if (Size != 0) { Buffer = (ILubyte*)ialloc(Size); if (Buffer == NULL) { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } Size = ilGetDXTCData(Buffer, Size, DXTCFormat); if (Size == 0) { ifree(Buffer); IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } memcpy(Rect.pBits, Buffer, Size); } else { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } } else { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } } else memcpy(Rect.pBits, Temp->Data, Temp->SizeOfData); IDirect3DTexture9_UnlockRect(Texture, i); Temp = Temp->Next; } if (MipImage != Image) ilCloseImage(MipImage); ilSetCurImage(CurImage); return IL_TRUE; }
CR_API CrBool crTextureCommit(CrTexture* self, const void* data) { CrTextureImpl* impl = (CrTextureImpl*)self; if(nullptr == self) return CrFalse; if(nullptr == impl->apiFormatMapping) return CrFalse; if(self->surfCount == 1) { HRESULT hr; size_t i; IDirect3DTexture9* stageTex; hr = IDirect3DDevice9_CreateTexture(crContextImpl()->d3ddev, self->width, self->height, self->mipCount, 0, impl->apiFormatMapping->d3dFormat, D3DPOOL_SYSTEMMEM, &stageTex, nullptr); if(FAILED(hr)) { crDbgStr("d3d9 failed to create texture %8x", hr); return CrFalse; } for(i=0; i<self->mipCount; ++i) { size_t mipW, mipH; D3DLOCKED_RECT locked; unsigned char* mipdata = crTextureGetMipLevel(self, (unsigned char*)data, 0, i, &mipW, &mipH); hr = IDirect3DTexture9_LockRect(stageTex, i, &locked, nullptr, 0); if(FAILED(hr)) continue; if(CrGpuFormat_UnormR8G8B8A8 != self->format) { memcpy(locked.pBits, mipdata, mipW * mipH * impl->apiFormatMapping->pixelSize); } else { // CrGpuFormat_UnormR8G8B8A8 need to flip the endian since we actually use the OpenGL's layout char* dst = locked.pBits; char* src = mipdata; size_t cnt = mipW * mipH; size_t i; for(i = 0; i<cnt; ++i) { dst[0] = src[2]; dst[1] = src[1]; dst[2] = src[0]; dst[3] = src[3]; dst += 4; src += 4; } } IDirect3DTexture9_UnlockRect(stageTex, i); } IDirect3DDevice9_UpdateTexture(crContextImpl()->d3ddev, (IDirect3DBaseTexture9*)stageTex, (IDirect3DBaseTexture9*)impl->d3dtex); IDirect3DTexture9_Release(stageTex); } return CrTrue; }