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;
}
Ejemplo n.º 2
0
static int
D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                const SDL_Rect * rect, int markDirty, void **pixels,
                int *pitch)
{
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;

    if (data->yuv) {
        return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels,
                                     pitch);
    } else {
        RECT d3drect;
        D3DLOCKED_RECT locked;
        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,
                                       markDirty ? 0 :
                                       D3DLOCK_NO_DIRTY_UPDATE);
        if (FAILED(result)) {
            D3D_SetError("LockRect()", result);
            return -1;
        }
        *pixels = locked.pBits;
        *pitch = locked.Pitch;
        return 0;
    }
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
static int
D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                const SDL_Rect * rect, void **pixels, int *pitch)
{
    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
    RECT d3drect;
    D3DLOCKED_RECT locked;
    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)) {
        return D3D_SetError("LockRect()", result);
    }
    *pixels = locked.pBits;
    *pitch = locked.Pitch;
    return 0;
}
Ejemplo n.º 6
0
/** @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;
}
Ejemplo n.º 7
0
/** @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;
        }
    }
}
Ejemplo n.º 8
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;

    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;
    }
}
Ejemplo n.º 9
0
Archivo: direct3d.c Proyecto: BtbN/vlc
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);
    }
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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;
}