Constant Buffer¶
マウス座標と ViewPort サイズを ConstantBuffer 経由で送り込んでカーソル位置に三角形を描画する。
void vsMain() {}
struct DummyInput {};
struct GS_OUTPUT {
float4 position : SV_POSITION;
float4 color : COLOR0;
};
float4 xywh;
float pixel_to_screen_x(float x) { return (x / xywh.z) * 2 - 1; }
float pixel_to_screen_y(float y) { return (y / xywh.w) * 2 - 1; }
[maxvertexcount(3)] void gsMain(point DummyInput input[1]
: POSITION,
inout TriangleStream<GS_OUTPUT> output) {
GS_OUTPUT element;
// rect
const float size = 10;
float l = pixel_to_screen_x(xywh.x - size);
float r = pixel_to_screen_x(xywh.x + size);
float b = -pixel_to_screen_y(xywh.y + size);
float t = -pixel_to_screen_y(xywh.y - size);
// d3d default. clock wise
// 0
element.position = float4(l, b, 0, 1);
element.color = float4(1, 0, 0, 1);
output.Append(element);
// 1
element.position = float4(l, t, 0, 1);
element.color = float4(0, 1, 0, 1);
output.Append(element);
// 2
element.position = float4(r, t, 0, 1);
element.color = float4(0, 0, 1, 1);
output.Append(element);
output.RestartStrip();
}
float4 psMain(GS_OUTPUT V)
: SV_Target {
return V.color;
}
#include "constant_buffer.h"
#include <assert.h>
namespace gorilla {
bool ConstantBuffer::create(const ComPtr<ID3D11Device> &device, UINT size) {
desc.ByteWidth = size;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
auto hr = device->CreateBuffer(&desc, nullptr, &buffer);
if (FAILED(hr)) {
return false;
}
return true;
}
void ConstantBuffer::update(const ComPtr<ID3D11DeviceContext> &context,
const void *p, size_t size) {
assert(desc.ByteWidth == size);
context->UpdateSubresource(buffer.Get(), 0, nullptr, p, 0, 0);
}
} // namespace gorilla
CPU側のメモリレイアウト¶
16バイトアライメント。
例えば、hlsl の float3x3
は,
struct Mat3 {
float _11, _12, _13, padding,
_21, _22, _23, padding,
_31, _32, _33, padding,
};
になることに注意する。 DirectX::FLOAT3X3 ではなく DirectX::FLOAT3X4 に格納する必要がある。