2015-11-01 24 views
1

我试图通过ID软件将Direct3d9的Quake 1端口反向移植到Direct3d8,以便将其移植到原始Xbox(仅使用D3D8 API)。从IDirect3DTexture9反向移植后显示IDirect3DTexture8的问题

在进行更改以使用Direct3d8后,它会在屏幕上显示一些看似小方块的混合像素:/(请参见图片)。

有没有人知道这里有什么问题?它与D3D9完美地工作,是否有一些额外的论据需要我缺少D3D8的要求,直接投球也许?

传入的数据是Quake 1.lmp 2d映像文件。 “它包含两个整数(宽度和高度),后跟一串宽度x高度字节,每个字符都是震动调色板的索引”

它已传递给D3D_ResampleTexture()函数。

任何帮助将不胜感激。

Image output using D3D8

Image output using D3D9

代码:

void D3D_ResampleTexture (image_t *src, image_t *dst) 
{ 
    int y, x , srcpos, srcbase, dstpos; 

    unsigned int *dstdata, *srcdata; 

    // take an unsigned pointer to the dest data that we'll actually fill 
    dstdata = (unsigned int *) dst->data; 

    // easier access to src data for 32 bit resampling 
    srcdata = (unsigned int *) src->data; 

    // nearest neighbour for now 
    for (y = 0, dstpos = 0; y < dst->height; y++) 
    { 
     srcbase = (y * src->height/dst->height) * src->width; 

     for (x = 0; x < dst->width; x++, dstpos++) 
     { 
      srcpos = srcbase + (x * src->width/dst->width); 

      if (src->flags & IMAGE_32BIT) 
       dstdata[dstpos] = srcdata[srcpos]; 
      else if (src->palette) 
       dstdata[dstpos] = src->palette[src->data[srcpos]]; 
      else Sys_Error ("D3D_ResampleTexture: !(flags & IMAGE_32BIT) without palette set"); 
     } 
    } 
} 


void D3D_LoadTextureStage3 (LPDIRECT3DTEXTURE8/*9*/ *tex, image_t *image) 
{ 
    int i; 
    image_t scaled; 

    D3DLOCKED_RECT LockRect; 

    memset (&LockRect, 0, sizeof(D3DLOCKED_RECT)); 

    // check scaling here first 
    for (scaled.width = 1; scaled.width < image->width; scaled.width *= 2); 
    for (scaled.height = 1; scaled.height < image->height; scaled.height *= 2); 

    // clamp to max texture size 
    if (scaled.width > /*d3d_DeviceCaps.MaxTextureWidth*/640) scaled.width = /*d3d_DeviceCaps.MaxTextureWidth*/640; 
    if (scaled.height > /*d3d_DeviceCaps.MaxTextureHeight*/480) scaled.height = /*d3d_DeviceCaps.MaxTextureHeight*/480; 


    IDirect3DDevice8/*9*/_CreateTexture(d3d_Device, scaled.width, scaled.height, 
    (image->flags & IMAGE_MIPMAP) ? 0 : 1, 
    /*(image->flags & IMAGE_MIPMAP) ? D3DUSAGE_AUTOGENMIPMAP :*/ 0, 
    (image->flags & IMAGE_ALPHA) ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8, 
    D3DPOOL_MANAGED, 
    tex 
    ); 

    // lock the texture rectangle 
    //(*tex)->LockRect (0, &LockRect, NULL, 0); 
    IDirect3DTexture8/*9*/_LockRect(*tex, 0, &LockRect, NULL, 0); 

    // fill it in - how we do it depends on the scaling 
    if (scaled.width == image->width && scaled.height == image->height) 
    { 
     // no scaling 
     for (i = 0; i < (scaled.width * scaled.height); i++) 
     { 
      unsigned int p; 

      // retrieve the correct texel - this will either be direct or a palette lookup 
      if (image->flags & IMAGE_32BIT) 
       p = ((unsigned *) image->data)[i]; 
      else if (image->palette) 
       p = image->palette[image->data[i]]; 
      else Sys_Error ("D3D_LoadTexture: !(flags & IMAGE_32BIT) without palette set"); 
      // store it back 
      ((unsigned *) LockRect.pBits)[i] = p; 
     } 
    } 
    else 
    { 
     // save out lockbits in scaled data pointer 
     scaled.data = (byte *) LockRect.pBits; 

     // resample data into the texture 
     D3D_ResampleTexture (image, &scaled); 
    } 

    // unlock it 
    //(*tex)->UnlockRect (0); 
    IDirect3DTexture8/*9*/_UnlockRect(*tex, 0); 

    // tell Direct 3D that we're going to be needing to use this managed resource shortly 
    //FIXME 
    //(*tex)->PreLoad(); 
} 


LPDIRECT3DTEXTURE8/*9*/ D3D_LoadTextureStage2 (image_t *image) 
{ 
    d3d_texture_t *tex; 

    // look for a match 

    // create a new one 
    tex = (d3d_texture_t *) malloc (sizeof (d3d_texture_t)); 

    // link it in 
    tex->next = d3d_Textures; 
    d3d_Textures = tex; 

    // fill in the struct 
    tex->LastUsage = 0; 
    tex->d3d_Texture = NULL; 

    // copy the image 
    memcpy (&tex->TexImage, image, sizeof (image_t)); 

    // upload through direct 3d 
    D3D_LoadTextureStage3 (&tex->d3d_Texture, image); 

    // return the texture we got 
    return tex->d3d_Texture; 
} 


LPDIRECT3DTEXTURE8/*9*/ D3D_LoadTexture (char *identifier, int width, int height, byte *data, /*bool*/qboolean mipmap, /*bool*/qboolean alpha) 
{ 
    image_t image; 

    image.data = data; 
    image.flags = 0; 
    image.height = height; 
    image.width = width; 
    image.palette = d_8to24table; 

    strcpy (image.identifier, identifier); 

    if (mipmap) image.flags |= IMAGE_MIPMAP; 
    if (alpha) image.flags |= IMAGE_ALPHA; 

    return D3D_LoadTextureStage2 (&image); 
} 

回答

0

对于遇到此问题的其他人,这是由于图像被加载到Xbox内存中的方式,因此需要调整它。

+0

您可以将自己的答案标记为已接受的答案。 –

1

当你锁定的纹理,你必须观察D3DLOCKED_RECT结构的返回Pitch成员。您的代码假定所有数据都是连续的,但Pitch可能大于扫描线的宽度,以便允许锁定一个子区域和缓冲区的其他布局,这些布局在一条扫描线的末端没有连续的像素到下一个开始。

查看我的书"The Direct3D Graphics Pipeline"Chapter 4,查看访问表面并正确使用Pitch的示例。