DirectX 11 Sprite 2D Camera
DirectX 11 Sprite 2D Camera
长期阅读。第一次海报。我的问题已经破坏脑细胞好几个小时了,但进展缓慢。所以我想我应该把它放在这里,让一双新的眼睛看到它…
基本上我正在尝试使用c++和DirectX 11创建一个2D游戏。我以前用过c#和XNA,我也在DirectX中做过一些3D的东西,但没有这么大的。
我试着用基本的相机和基本的精灵批处理在屏幕的中心画一个精灵,但是没有东西显示出来,我也不知道为什么。我将发布一些代码来给出一个想法。
这是我在相机类中设置所有矩阵的地方,它们保持这种方式(现在,以后会改变为移动等):
XMStoreFloat4x4(&m_world, XMMatrixIdentity());
XMStoreFloat4x4(&m_proj, XMMatrixOrthographicOffCenterLH(0.0f, width, height, 0.0f, 0.0f, 1.0f));
m_position = XMFLOAT3(width / 2, height / 2, 0);
m_look = XMFLOAT3(0, 0, 1);
m_up = XMFLOAT3(0, 1, 0);
XMVECTOR p = XMLoadFloat3(&m_position);
XMVECTOR l = XMLoadFloat3(&m_look);
XMVECTOR u = XMLoadFloat3(&m_up);
XMStoreFloat4x4(&m_view, XMMatrixLookToLH(p, l, u));
这将被传递到sprite batch begin方法中,该方法将信息传递给着色器:
D3D11_MAPPED_SUBRESOURCE data;
ZeroMemory(&data, sizeof(data));
m_deviceContext->Map(m_cBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &data);
ConstantBuffer* cb = (ConstantBuffer*)data.pData;
XMMATRIX w = XMLoadFloat4x4(&world);
XMMATRIX v = XMLoadFloat4x4(&view);
XMMATRIX p = XMLoadFloat4x4(&proj);
w = XMMatrixTranspose(w);
v = XMMatrixTranspose(v);
p = XMMatrixTranspose(p);
XMStoreFloat4x4(&world, w);
XMStoreFloat4x4(&view, v);
XMStoreFloat4x4(&proj, p);
cb->World = world;
cb->View = view;
cb->Proj = proj;
m_deviceContext->Unmap(m_cBuffer, 0);
最后是着色器本身:
cbuffer ConstantBuffer : register(b0)
{
float4x4 World;
float4x4 View;
float4x4 Proj;
};
SamplerState sam : register(s0);
Texture2D tex : register(t0);
struct VertexIn
{
float3 Position : POSITION;
float2 Texture : TEXCOORD;
float4 Color : COLOR;
};
struct PixelIn
{
float4 Position : SV_POSITION;
float2 Texture : TEXCOORD;
float4 Color : COLOR;
};
PixelIn VS(VertexIn vin)
{
float4 position = float4(vin.Position, 1.0f);
position = mul(position, World);
position = mul(position, View);
position = mul(position, Proj);
PixelIn vout;
vout.Position = position;
vout.Texture = vin.Texture;
vout.Color = vin.Color;
return vout;
}
float4 PS(PixelIn pin) : SV_Target
{
float4 textureColor = tex.Sample(sam, pin.Texture);
return pin.Color * textureColor;
}
如你所见,非常简单的东西。但是没有任何东西被绘制到屏幕上。我试着不去打扰矩阵,离开世界矩阵,使用透视投影矩阵,使用看而不是看矩阵,使用(0,0,0)作为中心,通过XMMatrixOrthographicLH和转换精灵位置到屏幕空间。
我甚至大大简化了精灵批处理,限制它一次只能绘制一个精灵!
我使用一个不可变的索引缓冲区(0,1,2,0,2,3)和一个动态顶点缓冲区,更新如下:
D3D11_MAPPED_SUBRESOURCE data;
ZeroMemory(&data, sizeof(data));
m_deviceContext->Map(m_vBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &data);
Vertex* vertex = (Vertex*)data.pData;
for(UINT i = 0; i < sprite->Vertices.size(); ++i)
{
vertex[i] = sprite->Vertices[i];
}
m_deviceContext->Unmap(m_vBuffer, 0);
m_deviceContext->DrawIndexed(6, 0, 0);
我使用类似的方法来渲染3D模型。事实上,这更困难,因为我有一个动态索引缓冲区和更多的常量缓冲区数据,着色器更复杂。
我认为这可能是一个数据丢失的问题,但这一切似乎都通过正确地传递到DrawIndexed方法调用。我已经仔细检查了缓冲区的创建和状态,目前将其设置为CULL_NONE,以确保它没有被剔除。
我将发布缓冲区创建和精灵创建的清晰度:
HRESULT result = S_OK;
device->GetImmediateContext(&m_deviceContext);
D3D11_BUFFER_DESC cbd;
ZeroMemory(&cbd, sizeof(cbd));
cbd.ByteWidth = sizeof(ConstantBuffer);
cbd.Usage = D3D11_USAGE_DYNAMIC;
cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbd.MiscFlags = 0;
cbd.StructureByteStride = 0;
result = device->CreateBuffer(&cbd, 0, &m_cBuffer);
if (FAILED(result))
{
return 0;
}
vector<short> indices;
indices.push_back(0);
indices.push_back(1);
indices.push_back(2);
indices.push_back(0);
indices.push_back(2);
indices.push_back(3);
D3D11_SUBRESOURCE_DATA indexData;
ZeroMemory(&indexData, sizeof(indexData));
indexData.pSysMem = &indices;
D3D11_BUFFER_DESC ibd;
ZeroMemory(&ibd, sizeof(ibd));
ibd.ByteWidth = 6 * sizeof(short);
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;
result = device->CreateBuffer(&ibd, &indexData, &m_iBuffer);
if (FAILED(result))
{
return 0;
}
D3D11_BUFFER_DESC vbd;
ZeroMemory(&vbd, sizeof(vbd));
vbd.ByteWidth = 4 * sizeof(Vertex);
vbd.Usage = D3D11_USAGE_DYNAMIC;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;
result = device->CreateBuffer(&vbd, 0, &m_vBuffer);
if (FAILED(result))
{
return 0;
}
return 1;
雪碧:
ID3D11Resource* resource;
ZeroMemory(&resource, sizeof(resource));
texture->GetResource(&resource);
ID3D11Texture2D* tex = (ID3D11Texture2D*)resource;
D3D11_TEXTURE2D_DESC t;
ZeroMemory(&t, sizeof(t));
tex->GetDesc(&t);
Vertex v[4];
ZeroMemory(&v, sizeof(v));
v[0].Position = XMFLOAT3((float)destinationRectangle.value.left, (float)destinationRectangle.value.top, z);
v[1].Position = XMFLOAT3((float)destinationRectangle.value.right, (float)destinationRectangle.value.top, z);
v[2].Position = XMFLOAT3((float)destinationRectangle.value.right, (float)destinationRectangle.value.bottom, z);
v[3].Position = XMFLOAT3((float)destinationRectangle.value.left, (float)destinationRectangle.value.bottom, z);
v[0].Texture = XMFLOAT2((float)(sourceRectangle.value.left / t.Width), (float)(sourceRectangle.value.top / t.Height));
v[1].Texture = XMFLOAT2((float)(sourceRectangle.value.right / t.Width), (float)(sourceRectangle.value.top / t.Height));
v[2].Texture = XMFLOAT2((float)(sourceRectangle.value.right / t.Width), (float)(sourceRectangle.value.bottom / t.Height));
v[3].Texture = XMFLOAT2((float)(sourceRectangle.value.left / t.Width), (float)(sourceRectangle.value.bottom / t.Height));
v[0].Color = color;
v[1].Color = color;
v[2].Color = color;
v[3].Color = color;
Sprite* sprite = new Sprite();
sprite->Vertices.push_back(v[0]);
sprite->Vertices.push_back(v[1]);
sprite->Vertices.push_back(v[2]);
sprite->Vertices.push_back(v[3]);
sprite->Texture = texture;
m_sprites.push_back(sprite);
我疯了吗?我是不是太蠢了?或者有更简单的方法来做到这一点?谢谢。任何帮助都是感激的!
还要指出的是,我正在绘制的精灵在800x600的屏幕上有一个全白色的矩形(左= 300,右= 500,顶= 350,底= 450)。纹理正在正确加载,我甚至尝试只是输出颜色在着色器只是为了确保没有运气。
哦,我尝试绘制的精灵的Z值设置为0.5f,尽管我已经尝试将其设置为不同的值,但这是我期望使用的值
我在另一个网站上找到了答案。问题出在这一行:
indexData.pSysMem = &indices;
应该是这样的:
indexData.pSysMem = &indices[0];
显然,我发送了一个指向整个向量的指针,而不是第一个实例,所以索引缓冲区不知道我在说什么!
就像我说的,我只是刚刚开始从XNA编程DirectX编程。;)
我希望这能帮助到有类似处境的人。
您是否将DepthStencil配置为使用2D?也可以尝试负Z轴到相机位置,你把它设为0
- 2D数组来自文本输入,中间有空格
- 将值指定给向量(2D)的向量中的某个位置
- 如何使用用户输入在C++中正确填充2D数组
- 如何在C++中检查2D数组中负值的输入验证
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- 在 2D 向量中使用第三个 [ ] 有什么意义?
- 四边形的 2D 旋转
- 打印第二列时的2d字符矢量打印空间
- 如何在 MFCaptureEngine 中获取"Camera removed"事件
- 如何将以逗号和空格分隔的整数读取到 2D 数组中?
- 如何在C++函数中声明静态 2D 数组?
- 我是 C++ 的初学者,我想知道如何在 2D 矢量中获取重复值
- 如何声明一个可以在整个程序中使用的全局 2d 3d 4d .. 数组(堆版本)变量?
- opengl glBegin(GL_LINES) 和 glBegin(GL_POINT) 在 2D 中不可视化点矢量
- 在C++中迭代 2D 容器的最干净方法
- 如何引用 2D 指针?
- 如何在 C++ 中使用它的构造函数初始化 unique_ptrs 的 2D 向量?
- C++动态安全 2D 交错阵列
- 如何在C++或OpenCV子矩阵中的2D子向量上使用OpenACC?
- DirectX 11 Sprite 2D Camera