On Sun, Apr 13, 2008 at 06:22:29PM +0200, [EMAIL PROTECTED] wrote: > Hi, > Are you still working on the texture functions? > I'd need them for completing my ID3DXSprite implementation, > so if you don't mind I could complete your started patches. > > Best regards, > Tony
I have a hacky implementation of D3DXLoadSurfaceFromMemory and D3DXLoadSurfaceFromSurface, as well as a pretty good implementation of D3DXCreateTexture and D3DXCheckTextureRequirements. I'll send in the patch for the last two when I have time, and have looked it over a final time. I pretty much abandoned the first two, because there's got to be a whole lot of code somewhere in the tree already. It does work in some cases, however. Attached in case it might be helpful. -- Philip Nilsson
struct d3dformat { unsigned int id; unsigned int amask; unsigned int rmask; unsigned int gmask; unsigned int bmask; unsigned int bytespp; }; /* TODO: Use the one in dlls/wined3d/utils.c */ struct d3dformat surface_formats[] = { {D3DFMT_A8R8G8B8, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4}, {D3DFMT_X8R8G8B8, 0x00000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4}, {D3DFMT_R5G6B5, 0x00000000, 0x0000f800, 0x000007e0, 0x0000001f, 2}, {D3DFMT_A4R4G4B4, 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2}, }; static struct d3dformat* find_format(const unsigned int format) { unsigned int i = 0; for (i = 0; i < sizeof(surface_formats); ++i) { if (surface_formats[i].id == format) return &surface_formats[i]; } return NULL; } /* XXX: From dlls/wined3d/utils.c */ /* This small helper function is used to convert a bitmask into the number of masked bits */ unsigned int count_bits(unsigned int mask) { unsigned int count; for (count = 0; mask; ++count) { mask &= mask - 1; } return count; } static void do_magic_stuff(unsigned int* const dest, const unsigned int destmask, const unsigned int src, const unsigned int srcmask) { if (destmask == srcmask) { *dest = (*dest & ~destmask) | (src & srcmask); } else { unsigned int srcoff = count_bits(srcmask); unsigned int destoff = count_bits(destmask); /* Find out the maximum values the masks can hold. */ unsigned int srcmax = srcmask >> srcoff; unsigned int destmax = destmask >> destoff; /* Calculate a new scaled value. */ unsigned int newvalue = (float)((float)((src & srcmask) >> srcoff) / (float)srcmax * (float)destmax); /* Clear the field first. */ /* Shift it into position. */ /* Remove any possible stray bits. */ /* Add it to the return value. */ *dest = (*dest & ~destmask) | ((newvalue << destoff) & destmask); } } /* Translate a single pixel from one pixel format to another. * Pixels are passed in as 32-bit integers, the output pixel as a pointer. */ static void translate_pixel(unsigned int* const dest, const struct d3dformat* const destformat, const unsigned int src, const struct d3dformat* const srcformat) { /* Find the formats in the format table. */ do_magic_stuff(dest, destformat->rmask, src, srcformat->rmask); do_magic_stuff(dest, destformat->gmask, src, srcformat->gmask); do_magic_stuff(dest, destformat->bmask, src, srcformat->bmask); do_magic_stuff(dest, destformat->amask, src, srcformat->amask); } static HRESULT convert_memory( void* const dest, /* Destination buffer. */ const D3DFORMAT destfmt, /* Destination buffer format. */ const RECT* const destrect, /* Destination buffer rectangle. */ unsigned int destsurfacewidth, unsigned int destsurfaceheight, const void* const src, /* Source buffer. */ const D3DFORMAT srcfmt, /* Source buffer format. */ const RECT* const srcrect, /* Source buffer size. */ DWORD filter) { struct d3dformat* srcformat = find_format(srcfmt); struct d3dformat* destformat = find_format(destfmt); if (!srcformat || !destformat) { ERR("Unsupported format (%d or %d).\n", srcfmt, destfmt); return 0; } if (destrect == NULL || (srcrect->left == destrect->left && srcrect->right == destrect->right && srcrect->top == destrect->top && srcrect->bottom == destrect->bottom)) { unsigned int x, y; /* I assume the rects are the same size here. */ /* I further assume that srcrect->left and srcrect->top are 0. */ /* Don't access destrect as it might be NULL. */ for (y = 0; y < srcrect->bottom; ++y) { for (x = 0; x < srcrect->right; ++x) { unsigned int srcpixel = 0; unsigned int destpixel = 0; unsigned int offset = y * srcrect->right + x; /* srcw == destw */ memcpy(&srcpixel, (char*)src + offset * srcformat->bytespp, srcformat->bytespp); translate_pixel(&destpixel, destformat, srcpixel, srcformat); /* I hope endianness doesn't mess this up too bad. */ memcpy((char*)dest + offset * destformat->bytespp, &destpixel, destformat->bytespp); if (srcpixel != destpixel) TRACE("Pixel conversion problem: %08x %08x\n", srcpixel, destpixel); } } } else { unsigned int srcwidth = srcrect->right - srcrect->left; unsigned int srcheight = srcrect->bottom - srcrect->top; unsigned int destwidth = destrect->right - destrect->left; unsigned int destheight = destrect->bottom - destrect->top; float xscale = (float)srcwidth / (float)destwidth; float yscale = (float)srcheight / (float)destheight; /* Scaling is necessary. */ unsigned int x, y; for (y = 0; y < destheight; ++y) { for (x = 0; x < destwidth; ++x) { unsigned int srcpixel = 0; unsigned int destpixel = 0; unsigned int srcx = (float)x * (float)xscale; unsigned int srcy = (float)y * (float)yscale; unsigned int srcoffset = srcy * srcwidth + srcx; unsigned int destoffset = (y + destrect->top) * destsurfacewidth + x + destrect->left; memcpy(&srcpixel, (char*)src + srcoffset * srcformat->bytespp, srcformat->bytespp); translate_pixel(&destpixel, destformat, srcpixel, srcformat); memcpy((char*)dest + destoffset * destformat->bytespp, &destpixel, destformat->bytespp); if (srcpixel != destpixel) { TRACE("Pixel conversion problem: %08x -> %08x for %d -> %d\n", srcpixel, destpixel, srcfmt, destfmt); } } } } return D3D_OK; } /* TODO: * Copy palette. * Handle formats. * Handle filters. * Colorkey replacement. * Confirm that surfaces can not be upscaled. * See if OpenGL can be used. */ HRESULT WINAPI D3DXLoadSurfaceFromMemory( LPDIRECT3DSURFACE9 surface, CONST PALETTEENTRY *destpalette, CONST RECT *destrect, LPCVOID memory, D3DFORMAT memoryformat, UINT memorypitch, CONST PALETTEENTRY *memorypalette, CONST RECT *memoryrect, DWORD filter, D3DCOLOR colorkey) { D3DLOCKED_RECT lockrect; D3DSURFACE_DESC surfdesc; TRACE("(%p, %p, %p, %p, %d, %d, %p, %p, %d, %d)\n", surface, destpalette, destrect, memory, memoryformat, memorypitch, memorypalette, memoryrect, filter, colorkey); if (destpalette || memorypalette) { TRACE("destpal: %p, srcpal: %p\n", destpalette, memorypalette); } IDirect3DSurface9_GetDesc(surface, &surfdesc); TRACE("(%d..%d, %d..%d) to (%d..%d, %d..%d) of (%d, %d)\n", memoryrect->left, memoryrect->right, memoryrect->top, memoryrect->bottom, destrect->left, destrect->right, destrect->top, destrect->bottom, surfdesc.Width, surfdesc.Height); IDirect3DSurface9_LockRect(surface, &lockrect, NULL, 0); convert_memory(lockrect.pBits, surfdesc.Format, destrect, surfdesc.Width, surfdesc.Height, memory, memoryformat, memoryrect, filter); IDirect3DSurface9_UnlockRect(surface); return D3D_OK; } HRESULT WINAPI D3DXLoadSurfaceFromSurface( LPDIRECT3DSURFACE9 destsurface, CONST PALETTEENTRY* destpalette, CONST RECT* destrect, LPDIRECT3DSURFACE9 srcsurface, CONST PALETTEENTRY* srcpalette, CONST RECT* srcrect, DWORD filter, D3DCOLOR colorkey) { D3DSURFACE_DESC srcdesc; D3DSURFACE_DESC destdesc; D3DLOCKED_RECT srclock; D3DLOCKED_RECT destlock; TRACE("(%p, %p, %p, %p, %p, %p, %d, %d)\n", destsurface, destpalette, destrect, srcsurface, srcpalette, srcrect, filter, colorkey); IDirect3DSurface9_GetDesc(srcsurface, &srcdesc); IDirect3DSurface9_GetDesc(destsurface, &destdesc); IDirect3DSurface9_LockRect(destsurface, &destlock, NULL, 0); IDirect3DSurface9_LockRect(srcsurface, &srclock, NULL, 0); convert_memory(destlock.pBits, destdesc.Format, destrect, destdesc.Width, destdesc.Height, srclock.pBits, srcdesc.Format, srcrect, filter); IDirect3DSurface9_UnlockRect(srcsurface); IDirect3DSurface9_UnlockRect(destsurface); return D3D_OK; }