D3D11:如何绘制简单的像素对齐线
D3D11: How to draw a simple pixel aligned line?
我尝试用D3D11在两个顶点之间画一条线。我在D3D9和D3D11中有一些经验,但在D3D11中画一条线似乎是一个问题,它从一个给定像素开始,以另一个像素结束。
我做了什么:
-
我在每个顶点的像素坐标上添加了0.5f,以适应texel- pixel坐标系(我阅读了Microsoft页面以了解D3D9和D3D11坐标系之间的差异):
f32 fOff = 0.5f;ColoredVertex newVertices[2] ={{D3DXVECTOR3(fStartX + fOff, fStartY + fOff,0), vecColorRGB},{D3DXVECTOR3(fEndX + fOff, fEndY + fOff,0), vecColorRGB}};
-
生成一个适合渲染目标的正射影矩阵:
D3DXMatrixOrthoOffCenterLH(及MatrixOrthoProj, 0.0 f (f32) uRTWidth 0.0 f (f32) uRTHeight 0.0 f, 1.0度);D3DXMatrixTranspose(及cbConstant.m_matOrthoProjection, MatrixOrthoProj);
-
设置RasterizerState, BlendState, Viewport,…
- 将顶点绘制为D3D11_PRIMITIVE_TOPOLOGY_LINELIST
问题:这条线似乎短了一个像素。它从给定的像素坐标开始,并完美地匹配它。线的方向看起来是正确的,但是我想要线结束的像素仍然没有上色。看起来这行只短了一个像素…
有教程解释这个问题吗?或者有人有同样的问题吗?我记得这在D3D9中并不难。
如果您需要进一步的信息,请询问。
Stefan谢谢,
编辑:发现d3d10的栅格化规则(d3d11应该相同):http://msdn.microsoft.com/en-us/library/cc627092%28v=vs.85%29.aspx Line_1
根据光栅化规则(上面问题中的链接),我可能已经找到了一个应该工作的解决方案:
- 排序顶点StartX
<恩迪>恩迪> - 添加(0.5/0.5)到开始顶点(就像我之前做的那样),将顶点移动到像素的中心
- 添加(1.0/1.0)到结束顶点,将顶点移动到右下角
这是用来告诉光栅化器应该绘制线条的最后一个像素。
f32 fXStartOff = 0.5f;
f32 fYStartOff = 0.5f;
f32 fXEndOff = 1.0f;
f32 fYEndOff = 1.0f;
ColoredVertex newVertices[2] =
{
{ D3DXVECTOR3((f32)fStartX + fXStartOff, (f32)fStartY + fYStartOff,0), vecColorRGB },
{ D3DXVECTOR3((f32)fEndX + fXEndOff , (f32)fEndY + fYEndOff,0), vecColorRGB }
};
如果你知道更好的解决办法,请告诉我。
我不知道D3D11,但你的问题听起来很像D3D9的D3DRS_LASTPIXEL渲染状态-也许D3D11有一个相等的,你需要看看
我遇到了完全相同的问题,我修复了感谢这个讨论。
我的顶点存储在D3D11_PRIMITIVE_TOPOLOGY_LINELIST顶点缓冲区。
谢谢这个有用的帖子,你让我今天修复了这个bug。这真的比我一开始想象的要棘手。这是我的几行代码。
// projection matrix code
float width = 1024.0f;
float height = 768.0f;
DirectX::XMMATRIX offsetedProj = DirectX::XMMatrixOrthographicRH(width, height, 0.0f, 10.0f);
DirectX::XMMATRIX proj = DirectX::XMMatrixMultiply(DirectX::XMMatrixTranslation(- width / 2, height / 2, 0), offsetedProj);
// view matrix code
// screen top left pixel is 0,0 and bottom right is 1023,767
DirectX::XMMATRIX viewMirrored = DirectX::XMMatrixLookAtRH(eye, at, up);
DirectX::XMMATRIX mirrorYZ = DirectX::XMMatrixScaling(1.0f, -1.0f, -1.0f);
DirectX::XMMATRIX view = DirectX::XMMatrixMultiply(mirrorYZ, viewMirrored);
// draw line code in my visual debug tool.
void TVisualDebug::DrawLine2D(int2 const& parStart,
int2 const& parEnd,
TColor parColorStart,
TColor parColorEnd,
float parDepth)
{
FLine2DsDirty = true;
// D3D11_PRIMITIVE_TOPOLOGY_LINELIST
float2 const startFloat(parStart.x() + 0.5f, parStart.y() + 0.5f);
float2 const endFloat(parEnd.x() + 0.5f, parEnd.y() + 0.5f);
float2 const diff = endFloat - startFloat;
// return normalized difference or float2(1.0f, 1.0f) if distance between the points is null. Then multiplies the result by something a little bigger than 0.5f, 0.5f is not enough.
float2 const diffNormalized = diff.normalized_replace_if_null(float2(1.0f, 1.0f)) * 0.501f;
size_t const currentIndex = FLine2Ds.size();
FLine2Ds.resize(currentIndex + 2);
render::vertex::TVertexColor* baseAddress = FLine2Ds.data() + currentIndex;
render::vertex::TVertexColor& v0 = baseAddress[0];
render::vertex::TVertexColor& v1 = baseAddress[1];
v0.FPosition = float3(startFloat.x(), startFloat.y(), parDepth);
v0.FColor = parColorStart;
v1.FPosition = float3(endFloat.x() + diffNormalized.x(), endFloat.y() + diffNormalized.y(), parDepth);
v1.FColor = parColorEnd;
}
我测试了几个DrawLine2D调用,它似乎工作得很好。
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何在24位SDL_Surface上设置像素的颜色
- 如何从SDL_Surface获取特定像素的颜色
- 如何将CMSampleBufferRef/CIImage/UIImage转换为像素,例如uint8_t[]
- 在C++中查找像素 RGB 数据的最快方法是什么?
- 是否可以从 OpenGL 缓冲区获取原始大小的像素?
- 选择基于另一个垫子的非零像素的cv::Mat的一部分?
- 如何使用 sdl2 快速绘制像素网格?
- 如何在C++中进行像素操作? - Linux
- 他们如何将红外锁定像素转换为镜头前方 1m 的正常平面上的位置
- 访问随机图像像素的快速方法,最多一次
- OpenCV 像素访问点与 at() - 不同的值
- 如何使用 freetype2 访问单色位图中的像素状态
- 尝试渲染像素坐标时,简单线条渲染失败
- 计算另一个图像像素满足条件的像素值的平均值
- 如何返回定义良好的内存部分?例如来自图像数据的像素的颜色值
- 在Qt-cpp中通过像素获取QString的子字符串
- 有效地计算像素到其对应核线的距离
- D3D11:如何绘制简单的像素对齐线