Пример #1
0
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();
}
Пример #2
0
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;
}
Пример #3
0
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);
    }
}
Пример #4
0
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);
}
Пример #5
0
 void DiTextureDrv::CopyFromMemory(const DiPixelBox& srcBox, uint32 level, uint32 surface /*= 0*/)
 {
     DiBox dest(0, 0, srcBox.GetWidth(), srcBox.GetHeight());
     CopyFromMemory(srcBox, dest, level, surface);
 }