void DiD3D9TextureDrv::BlitToMemory(const DiBox &srcBox, const DiPixelBox &dst) { if (mParent->GetTextureType() == TEXTURE_CUBE) { DI_WARNING("Cannot blit cube texture to memory."); return; } DI_ASSERT(mSurface); D3DLOCKED_RECT lrect; HRESULT res = mSurface->LockRect(&lrect, NULL, D3DLOCK_READONLY); DX9_CHKERR(res); DiPixelBox locked(dst.GetWidth(), dst.GetHeight(), mParent->GetFormat()); FromD3DLock(locked, lrect); DiPixelBox::BulkPixelConversion(locked, dst); mSurface->UnlockRect(); }
static void FromD3DLock(DiPixelBox &rval, const D3DLOCKED_RECT &lrect) { size_t bpp = DiPixelBox::GetNumElemBytes(rval.format); if (bpp != 0) { rval.rowPitch = lrect.Pitch / bpp; rval.slicePitch = rval.rowPitch * rval.GetHeight(); DI_ASSERT((lrect.Pitch % bpp) == 0); } else if (DiPixelBox::IsCompressedFormat(rval.format)) { rval.rowPitch = rval.GetWidth(); rval.slicePitch = rval.GetWidth() * rval.GetHeight(); } else { DI_WARNING("Unsupported FromD3DLock() calling."); } rval.data = lrect.pBits; }
void DiGLTextureDrv::Download(const DiPixelBox &data, uint32 level, uint32 surface) { if (data.GetWidth() != mParent->GetWidth() || data.GetHeight() != mParent->GetHeight()) { DI_WARNING("Only download of entire buffer of the texture is supported."); return; } glBindTexture(mGLTextureType, mTextureID); DiPixelFormat fmt = mParent->GetFormat(); bool isCompressed = DiPixelBox::IsCompressedFormat(fmt); GLenum faceType = GL_TEXTURE_2D; if (mGLTextureType == GL_TEXTURE_CUBE_MAP) faceType = GL_TEXTURE_CUBE_MAP_POSITIVE_X + surface; GLenum glfmt = DiGLTypeMappings::GLFormatMapping[fmt]; GLenum glType = DiGLTypeMappings::GetDataType(fmt); if (isCompressed) { glGetCompressedTexImageARB(faceType, level, data.data); } else { if (data.GetWidth() != data.rowPitch) glPixelStorei(GL_PACK_ROW_LENGTH, data.rowPitch); if (data.GetHeight()*data.GetWidth() != data.slicePitch) glPixelStorei(GL_PACK_IMAGE_HEIGHT, (data.slicePitch / data.GetWidth())); if (data.left > 0 || data.top > 0) glPixelStorei(GL_PACK_SKIP_PIXELS, data.left + data.rowPitch * data.top); if ((data.GetWidth()*DiPixelBox::GetNumElemBytes(data.format)) & 3) { // Standard alignment of 4 is not right glPixelStorei(GL_PACK_ALIGNMENT, 1); } // We can only get the entire texture glGetTexImage(faceType, level, glfmt, glType, data.data); // Restore defaults glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_ALIGNMENT, 4); } }
void DiGLTextureDrv::Upload(const DiPixelBox &src, const DiBox &dst, uint32 level, uint32 surface) { glBindTexture(mGLTextureType, mTextureID); DiPixelFormat fmt = mParent->GetFormat(); bool isCompressed = DiPixelBox::IsCompressedFormat(fmt); unsigned dataType = DiGLTypeMappings::GetDataType(mGLFormat); GLenum faceType = GL_TEXTURE_2D; if (mGLTextureType == GL_TEXTURE_CUBE_MAP) faceType = GL_TEXTURE_CUBE_MAP_POSITIVE_X + surface; if (isCompressed) { if (!src.IsConsecutive()) { DI_WARNING("Compressed images should be consective."); return; } size_t size = src.GetConsecutiveSize(); switch (mGLTextureType) { case GL_TEXTURE_2D: case GL_TEXTURE_CUBE_MAP: if (dst.left == 0 && dst.top == 0) { glCompressedTexImage2DARB(faceType, level, mGLFormat, dst.GetWidth(), dst.GetHeight(), 0, size, src.data); } else { glCompressedTexSubImage2DARB(faceType, level, dst.left, dst.top, dst.GetWidth(), dst.GetHeight(), mGLFormat, size, src.data); } break; } } else { if (src.GetWidth() != src.rowPitch) glPixelStorei(GL_UNPACK_ROW_LENGTH, src.rowPitch); if (src.GetWidth() > 0 && src.GetHeight()*src.GetWidth() != src.slicePitch) glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (src.slicePitch / src.GetWidth())); if (src.left > 0 || src.top > 0) glPixelStorei(GL_UNPACK_SKIP_PIXELS, src.left + src.rowPitch * src.top); if ((src.GetWidth() * DiPixelBox::GetNumElemBytes(src.format)) & 3) { // Standard alignment of 4 is not right glPixelStorei(GL_UNPACK_ALIGNMENT, 1); } glGetError(); switch (mGLTextureType) { case GL_TEXTURE_2D: case GL_TEXTURE_CUBE_MAP: if (dst.left == 0 && dst.top == 0) { glTexImage2D(faceType, level, mGLFormat, dst.GetWidth(), dst.GetHeight(), 0, mGLOriginFormat, dataType, src.data); } else { glTexSubImage2D(faceType, level, dst.left, dst.top, dst.GetWidth(), dst.GetHeight(), mGLOriginFormat, dataType, src.data); } break; } GLenum glErr = glGetError(); if (glErr != GL_NO_ERROR) DI_WARNING("Uploading texture (surface %d, level %d): %s", surface, level, (const char*)gluErrorString(glErr)); } // restore glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); if (GLEW_VERSION_1_2) glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); }
void DiTextureDrv::CopyFromMemory(const DiPixelBox& srcBox, uint32 level, uint32 surface /*= 0*/) { DiBox dest(0, 0, srcBox.GetWidth(), srcBox.GetHeight()); CopyFromMemory(srcBox, dest, level, surface); }