Exemple #1
0
bool SegmentImage(LPDIRECT3DTEXTURE9 texture,
                  int subimage_width,
                  int subimage_height,
                  int rows,
                  int columns,
                  int selected_index,
                  LPDIRECT3DTEXTURE9* segment) {

  D3DSURFACE_DESC desc;
  HRESULT hr = texture->GetLevelDesc(0, &desc);
  CONFIRM(SUCCEEDED(hr)) else return false;


  // Locate the source rectangle
  UINT sii = selected_index; // The sub-image index (sii)
  UINT sixc = sii % columns; // sub-image x-coordinate
  UINT siyc = sii / columns; // sub-image y-coordinate
  RECT sourceRect = { (sixc+0) * subimage_width, (siyc+0) * subimage_height,
                      (sixc+1) * subimage_width, (siyc+1) * subimage_height };


  // Create a texture for the sub-image
  LPDIRECT3DTEXTURE9 subimageTexture = NULL;
  {
    LPDIRECT3DDEVICE9 d3d_device;
    texture->GetDevice(&d3d_device);
    hr = D3DXCreateTexture(d3d_device,
                           subimage_width,
                           subimage_height,
                          -1,
                           0,
                           desc.Format,
                           desc.Pool,
                          &subimageTexture);
    SAFE_RELEASE(d3d_device);

    // If we can't make this texture, something is wrong, but we can't do much about it
    if (APP_WARNING(FAILED(hr))("Unable to create sub-image texture")) {
      return false;
    }

    //D3DSURFACE_DESC desc;
    //subimageTexture->GetLevelDesc(0, &desc);
    //DEBUG_INFO("creating image:  %lu, %lu; actual size:  %lu, %lu",
    //           subimage_width,
    //           subimage_height,
    //           desc.Width,
    //           desc.Height);
  }

  DWORD format_byte_size = 4;
  switch (desc.Format) {
    default: DEBUG_ERROR("Unknown image format"); return false;
    case D3DFMT_A8R8G8B8:
    case D3DFMT_X8R8G8B8: format_byte_size = sizeof(D3DCOLOR); break;
    case D3DFMT_A8P8:
    case D3DFMT_R5G6B5:
    case D3DFMT_X1R5G5B5: 
    case D3DFMT_X4R4G4B4: format_byte_size = sizeof(WORD); break;
  }

  // Copy the texture
  D3DLOCKED_RECT sourceLR, destLR;
  texture->LockRect(0, &sourceLR, &sourceRect, D3DLOCK_READONLY);
  subimageTexture->LockRect(0, &destLR, NULL, 0);
  BYTE* sourceBits = (BYTE*)sourceLR.pBits;
  BYTE* destBits = (BYTE*)destLR.pBits;

  // Copy each row
  for (long y = 0; y < subimage_height; ++y) {
      memcpy(&destBits[destLR.Pitch*y],
             &sourceBits[sourceLR.Pitch*y],
             subimage_width*format_byte_size);
  }

  // Unlock the source and destination
  texture->UnlockRect(0);
  subimageTexture->UnlockRect(0);

  // Generate mipmaps, if necessary
  // TODO: this generates an error...why?!
  //if (mipmap)
  //    subimageTexture->GenerateMipSubLevels();

  // Save the sub-image as the output texture
  *segment = subimageTexture;
  return true;
}