You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在DirectX 11中实现2D纹理绕自身中心旋转?

Fixing 2D Texture Rotation Around Its Center in DirectX 11

Hey there, let's tackle your rotation issue—this is a super common gotcha with 2D transformations in DirectX, so you're not alone here!

The core problem is that when you apply a rotation directly to your texture's position, the rotation happens around the world origin (0,0) (usually the top-left corner of the screen) instead of the texture's own center. To fix this, you need to adjust the order of your transformations:

The Correct Transformation Sequence

You need three steps to rotate around the texture center:

  • Translate the texture to the world origin: Shift the texture so its center lines up with (0,0). This means subtracting half the texture's width and height from its position.
  • Apply the Z-axis rotation: Rotate the texture around the origin using your rotation value.
  • Translate the texture back to its original position: Shift it back to where it started, but now centered around its original position.

How to Implement This in Your Code

Let's adjust your existing functions to handle this:

1. Update GraphicsClass::Render to Calculate the Transformation Matrix

First, you'll need to compute the combined world matrix that handles the translate-rotate-translate sequence. Use DirectX's math library (like DirectXMath) for clean matrix operations:

bool GraphicsClass::Render(float rotation)
{
    // Add GetWidth()/GetHeight() methods to BitmapClass if you don't have them already
    int texWidth = m_bitmap->GetWidth();
    int texHeight = m_bitmap->GetHeight();
    int positionX = /* Your existing X position value */;
    int positionY = /* Your existing Y position value */;

    // Step 1: Shift texture so its center aligns with world origin
    XMMATRIX translateToOrigin = XMMatrixTranslation(-(texWidth / 2.0f), -(texHeight / 2.0f), 0.0f);
    // Step 2: Apply Z-axis rotation
    XMMATRIX rotateMat = XMMatrixRotationZ(rotation);
    // Step 3: Shift texture back to its original centered position
    XMMATRIX translateBack = XMMatrixTranslation(positionX + (texWidth / 2.0f), positionY + (texHeight / 2.0f), 0.0f);

    // Combine matrices (order matters: right-to-left for multiplication in DirectX)
    XMMATRIX worldMatrix = translateToOrigin * rotateMat * translateBack;

    // Pass the precomputed world matrix to BitmapClass instead of raw position values
    m_bitmap->Render(m_deviceContext, worldMatrix);

    // Rest of your existing rendering logic...
    return true;
}

2. Modify BitmapClass to Use the World Matrix

Your current BitmapClass functions probably set vertex positions directly using positionX/positionY. Instead, shift the transformation work to the GPU (more efficient for dynamic rotations) by passing the world matrix to your vertex shader:

bool BitmapClass::Render(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix)
{
    // Update your shader's constant buffer with the world matrix
    m_shader->SetWorldMatrix(deviceContext, worldMatrix);

    // Skip manual position updates in UpdateBuffers—let the shader handle transformation
    RenderBuffers(deviceContext);
    m_shader->Render(deviceContext, m_indexCount);

    return true;
}

Key Notes

  • Matrix Order: DirectX uses row-major matrices, so the multiplication order translateToOrigin * rotateMat * translateBack correctly applies the transforms in the sequence we want (translate to origin → rotate → translate back).
  • Texture Dimensions: Use the actual pixel dimensions of your texture (not scaled values) when calculating the center offset—this ensures the rotation point is truly the texture's center.
  • Vertex Shader Adjustment: Your vertex shader needs to accept the world matrix and apply it to vertex positions. Here's a quick example:
    struct VS_INPUT
    {
        float4 position : POSITION;
        float2 texCoord : TEXCOORD0;
    };
    
    struct PS_INPUT
    {
        float4 position : SV_POSITION;
        float2 texCoord : TEXCOORD0;
    };
    
    cbuffer MatrixBuffer
    {
        matrix world;
        matrix view;
        matrix projection;
    };
    
    PS_INPUT VS(VS_INPUT input)
    {
        PS_INPUT output;
        input.position.w = 1.0f;
        // Apply world → view → projection transforms
        output.position = mul(input.position, world);
        output.position = mul(output.position, view);
        output.position = mul(output.position, projection);
        output.texCoord = input.texCoord;
        return output;
    }
    

That should get your texture rotating smoothly around its own center instead of an off-screen origin. If you need help tweaking any specific parts of your existing code, feel free to dig into the details!

内容的提问来源于stack exchange,提问作者adrotter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:16:32