bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data) { URHO3D_PROFILE(SetTextureData); if (!object_ || !graphics_) { URHO3D_LOGERROR("No texture created, can not set data"); return false; } if (!data) { URHO3D_LOGERROR("Null source for setting data"); return false; } if (level >= levels_) { URHO3D_LOGERROR("Illegal mip level for setting data"); return false; } if (graphics_->IsDeviceLost()) { URHO3D_LOGWARNING("Texture data assignment while device is lost"); dataPending_ = true; return true; } if (IsCompressed()) { x &= ~3; y &= ~3; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); int levelDepth = GetLevelDepth(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || z < 0 || z + depth > levelDepth || width <= 0 || height <= 0 || depth <= 0) { URHO3D_LOGERROR("Illegal dimensions for setting data"); return false; } graphics_->SetTextureForUpdate(this); #ifndef GL_ES_VERSION_2_0 bool wholeLevel = x == 0 && y == 0 && z == 0 && width == levelWidth && height == levelHeight && depth == levelDepth; unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_; if (!IsCompressed()) { if (wholeLevel) glTexImage3D(target_, level, format, width, height, depth, 0, GetExternalFormat(format_), GetDataType(format_), data); else glTexSubImage3D(target_, level, x, y, z, width, height, depth, GetExternalFormat(format_), GetDataType(format_), data); } else { if (wholeLevel) glCompressedTexImage3D(target_, level, format, width, height, depth, 0, GetDataSize(width, height, depth), data); else glCompressedTexSubImage3D(target_, level, x, y, z, width, height, depth, format, GetDataSize(width, height, depth), data); } #endif graphics_->SetTexture(0, 0); return true; }
bool Texture3D::GetData(unsigned level, void* dest) const { if (!object_) { LOGERROR("No texture created, can not get data"); return false; } if (!dest) { LOGERROR("Null destination for getting data"); return false; } if (level >= levels_) { LOGERROR("Illegal mip level for getting data"); return false; } if (graphics_->IsDeviceLost()) { LOGWARNING("Getting texture data while device is lost"); return false; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); int levelDepth = GetLevelDepth(level); D3DLOCKED_BOX d3dLockedBox; D3DBOX d3dBox; d3dBox.Left = 0; d3dBox.Top = 0; d3dBox.Front = 0; d3dBox.Right = levelWidth; d3dBox.Bottom = levelHeight; d3dBox.Back = levelDepth; if (FAILED(((IDirect3DVolumeTexture9*)object_)->LockBox(level, &d3dLockedBox, &d3dBox, D3DLOCK_READONLY))) { LOGERROR("Could not lock texture"); return false; } int height = levelHeight; if (IsCompressed()) height = (height + 3) >> 2; unsigned char* destPtr = (unsigned char*)dest; unsigned rowSize = GetRowDataSize(levelWidth); // GetRowDataSize() returns CPU-side (destination) data size, so need to convert for X8R8G8B8 if (format_ == D3DFMT_X8R8G8B8) rowSize = rowSize / 3 * 4; // Perform conversion to RGB / RGBA as necessary switch (format_) { default: for (int k = 0; k < levelDepth; ++k) { for (int i = 0; i < height; ++i) { unsigned char* src = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch; memcpy(destPtr, src, rowSize); destPtr += rowSize; } } break; case D3DFMT_X8R8G8B8: for (int k = 0; k < levelDepth; ++k) { for (int i = 0; i < height; ++i) { unsigned char* src = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch; for (int j = 0; j < levelWidth; ++j) { destPtr[2] = *src++; destPtr[1] = *src++; destPtr[0] = *src++; ++src; destPtr += 3; } } } break; case D3DFMT_A8R8G8B8: for (int k = 0; k < levelDepth; ++k) { for (int i = 0; i < height; ++i) { unsigned char* src = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch; for (int j = 0; j < levelWidth; ++j) { destPtr[2] = *src++; destPtr[1] = *src++; destPtr[0] = *src++; destPtr[3] = *src++; destPtr += 4; } } } break; } ((IDirect3DVolumeTexture9*)object_)->UnlockBox(level); return true; }
bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data) { PROFILE(SetTextureData); if (!object_) { LOGERROR("No texture created, can not set data"); return false; } if (!data) { LOGERROR("Null source for setting data"); return false; } if (level >= levels_) { LOGERROR("Illegal mip level for setting data"); return false; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); int levelDepth = GetLevelDepth(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || z < 0 || z + depth > levelDepth || width <= 0 || height <= 0 || depth <= 0) { LOGERROR("Illegal dimensions for setting data"); return false; } // If compressed, align the update region on a block if (IsCompressed()) { x &= ~3; y &= ~3; width += 3; width &= 0xfffffffc; height += 3; height &= 0xfffffffc; } unsigned char* src = (unsigned char*)data; unsigned rowSize = GetRowDataSize(width); unsigned rowStart = GetRowDataSize(x); unsigned subResource = D3D11CalcSubresource(level, 0, levels_); if (usage_ == TEXTURE_DYNAMIC) { if (IsCompressed()) { height = (height + 3) >> 2; y >>= 2; } D3D11_MAPPED_SUBRESOURCE mappedData; mappedData.pData = 0; graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0, &mappedData); if (mappedData.pData) { for (int page = 0; page < depth; ++page) { for (int row = 0; row < height; ++row) { memcpy((unsigned char*)mappedData.pData + (page + z) * mappedData.DepthPitch + (row + y) * mappedData.RowPitch + rowStart, src + row * rowSize, rowSize); } } graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource); } else { LOGERROR("Failed to map texture for update"); return false; } } else { if (IsCompressed())
bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data) { if (!object_) { LOGERROR("No texture created, can not set data"); return false; } if (!data) { LOGERROR("Null source for setting data"); return false; } if (level >= levels_) { LOGERROR("Illegal mip level for setting data"); return false; } if (graphics_->IsDeviceLost()) { LOGWARNING("Texture data assignment while device is lost"); dataPending_ = true; return true; } if (IsCompressed()) { x &= ~3; y &= ~3; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); int levelDepth = GetLevelDepth(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || z < 0 || z + depth > levelDepth || width <= 0 || height <= 0 || depth <= 0) { LOGERROR("Illegal dimensions for setting data"); return false; } D3DLOCKED_BOX d3dLockedBox; D3DBOX d3dBox; d3dBox.Left = x; d3dBox.Top = y; d3dBox.Front = z; d3dBox.Right = x + width; d3dBox.Bottom = y + height; d3dBox.Back = z + depth; DWORD flags = 0; if (level == 0 && x == 0 && y == 0 && z == 0 && width == levelWidth && height == levelHeight && depth == levelDepth && pool_ == D3DPOOL_DEFAULT) flags |= D3DLOCK_DISCARD; if (FAILED(((IDirect3DVolumeTexture9*)object_)->LockBox(level, &d3dLockedBox, (flags & D3DLOCK_DISCARD) ? 0 : &d3dBox, flags))) { LOGERROR("Could not lock texture"); return false; } if (IsCompressed()) { height = (height + 3) >> 2; y >>= 2; } unsigned char* src = (unsigned char*)data; unsigned rowSize = GetRowDataSize(width); // GetRowDataSize() returns CPU-side (source) data size, so need to convert for X8R8G8B8 if (format_ == D3DFMT_X8R8G8B8) rowSize = rowSize / 3 * 4; // Perform conversion from RGB / RGBA as necessary switch (format_) { default: for (int k = 0; k < levelDepth; ++k) { for (int i = 0; i < height; ++i) { unsigned char* dest = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch; memcpy(dest, src, rowSize); src += rowSize; } } break; case D3DFMT_X8R8G8B8: for (int k = 0; k < levelDepth; ++k) { for (int i = 0; i < height; ++i) { unsigned char* dest = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch; for (int j = 0; j < width; ++j) { *dest++ = src[2]; *dest++ = src[1]; *dest++ = src[0]; *dest++ = 255; src += 3; } } } break; case D3DFMT_A8R8G8B8: for (int k = 0; k < levelDepth; ++k) { for (int i = 0; i < height; ++i) { unsigned char* dest = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch; for (int j = 0; j < width; ++j) { *dest++ = src[2]; *dest++ = src[1]; *dest++ = src[0]; *dest++ = src[3]; src += 4; } } } break; } ((IDirect3DVolumeTexture9*)object_)->UnlockBox(level); return true; }