c++ - 如何在父 RECT 中有效地执行图像剪辑?

标签 c++ visual-c++ directx clipping rect

所以,
我正在使用 C++ 中的 DIRECTX API 并设计一个 Sprite 界面,该界面在父 RECT 中进行裁剪,例如 UI 窗口或其他 Sprite 或您拥有的东西。

这是因为,稍后,我将为 UI 窗口制作一个滚动功能。

我认为一张图片很适合展示我想要实现的目标。
Clipping

为了进行裁剪计算,至少需要四个变量/结构(据我所知):

  • RECT:“裁剪”边界
  • D3DXIMAGE_INFO:包含图片的宽高等信息
  • Sprite 位置
  • 绘制 RECT:用于 LPD3DXSPRITE->Draw() 函数。基本上,应该绘制图像的哪一部分。这是完成“剪裁”的地方。

现在,如果我向您展示我的整个界面及其内部工作原理以及它如何处理变量,我认为您会感到困惑。

所以,相反,
这段代码演示了我目前如何计算裁剪。

void ClippingCalculation(){
    RECT parent_bounds, draw_rect;
    D3DXVECTOR2 sprite_position; //Relative to parent rect
    D3DXIMAGE_INFO img_info;

    //Fill image info
    D3DXGetImageInfoFromFile("image.png", &img_info); //Image is 100x100px

    //Define the rects
    SetRect(&parent_bounds, 0, 0, 200, 200);
    SetRect(&draw_rect, 0, 0, img_info.Width, img_info.Height); //Draw the entire image by default

    //Give it a position that makes a portion go out of parent bounds
    sprite_position = D3DXVECTOR2(150, 150); // 3/4 of the entire image is out of bounds

    //Check if completely within bounds
    bool min_x = (sprite_position.x > parent_bounds.left),
         min_y = (sprite_position.y > parent_bounds.top),
         max_x = (sprite_position.x+img_info.Width < parent_bounds.right),
         max_y = (sprite_position.y+img_info.Height < parent_bounds.bottom);

    if(min_x && min_y && max_x && max_y) 
         return; //No clipping needs to be done

    float delta_top = parent_bounds.top - sprite_position.y,
          delta_left = parent_bounds.left - sprite_position.x,    
          delta_bottom = parent_bounds.bottom - sprite_position.y,
          delta_right = parent_bounds.right - sprite_position.x;

    //Check if completely outside bounds
    bool out_left = (delta_left >= img_info.Width),
         out_top = (delta_top >= img_info.Height),
         out_bottom = (delta_bottom >= img_info.Height),
         out_right = (delta_right >= img_info.Width);

    if(out_left || out_top || out_bottom || out_right){ 
         //No drawing needs to be done, it's not even visible
         return; //No clipping
    }

    if(!min_x) draw_rect.left = delta_left;

    if(!min_x) draw_rect.top = delta_top;

    if(!max_x) draw_rect.right = delta_right;

    if(!max_y) draw_rect.bottom = delta_bottom;

    return;
}

我的问题是:

  1. 您是否立即发现代码有任何错误?
  2. 它是高效还是低效?
    每次重新定位、加载 Sprite 或添加父级 Sprite 时都会进行剪裁。
  3. 数学扎实吗?我应该采用不同的方法吗?
  4. 能否以更好的方式完成,您能否提供示例?

最佳答案

剪辑 RECT 比这容易得多:

clipped_rect.left= MAX(rect_a.left, rect_b.left);
clipped_rect.right= MIN(rect_a.right, rect_b.right);
clipped_rect.top= MIN(rect_a.top, rect_b.top);
clipped_rect.bottom= MAX(rect_a.bottom, rect_b.bottom);

bool completely_clipped= 
    clipped_rect.left>=clipped_rect.right || 
    clipped_rect.bottom>=clipped_rect.top

这假设 Y 随着您的上升而增加。应该很容易找到特定于平台的 MINMAX 的高性能版本。

关于c++ - 如何在父 RECT 中有效地执行图像剪辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9552003/

相关文章:

c++ - 为什么这些 header 只能在预编译 header 之外工作?

c++ - 空基类优化

c++ - 是什么在窗口的上角创建了三个关闭/最小化/最大化图标? (C++)

c++ - 这是 DirectX9 Effect Compiler 中的错误吗? "Invalid input semantics - POSITIONT0"

c++ - 如何确保我已经对 std::set 中的每一对元素进行了插入循环操作?

c++ - 如何使这个运算符(operator)调用明确?

c++ - 如何在另一台计算机上运行调试文件?

C++:在 Visual Studio 中处理每个可变参数

c++ - 检索要通过网络发送的 ID3D11Texture2D 数据

c++ - Windows 更新后不需要的 C++ 项目重建