2015-11-01 8 views
1

Я пытаюсь выполнить резервное копирование некоторых версий Direct3d9 порт программного обеспечения Quake 1 by ID на Direct3d8, чтобы я мог перенести его в исходный Xbox (используется только API D3D8).Проблема с отображением IDirect3DTexture8 после backporting из IDirect3DTexture9

После внесения изменений в использование Direct3d8 он отображает на экране несколько заштрихованных пикселей, которые, как представляется, находятся в маленьких квадратах:/(см. Рисунки).

Кто-нибудь знает, что случилось не так? Он работает безупречно с D3D9, есть ли какие-то дополнительные аргументы, которые мне не нужны, для D3D8?

Данные были переданы в файл изображения Quake 1 .lmp 2d. «Он состоит из двух целых чисел (ширина и высота), за которыми следует строка ширины x высота байтов, каждый из которых является индексом в палитре Quake«

Его передали функции 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

При блокировании текстуры, вы должны наблюдать за возвращенную Pitch члена D3DLOCKED_RECT структуры. В вашем коде предполагается, что все данные смежны, но Pitch может быть больше ширины линии сканирования, чтобы обеспечить блокировку субрегиона и других макетов буфера, которые не имеют смежных пикселей в конце одной линии сканирования к началу следующего.

Посмотрите на страницу Chapter 4 моей книги "The Direct3D Graphics Pipeline", чтобы увидеть пример доступа к поверхности и правильно использовать Pitch.