下記のコードで、ピクセルシェーダーを使用して2D画像の描画を行っています。
ピクセルシェーダーは2種類使っているのですが、
どちらのピクセルシェーダーもdummyParams[0〜4]は動作確認できたのですが、
dummyParams[5]に値を入れるととたんに表示が崩れたりSetDrawScreenで指定した描画先が全て透明色にクリアされたりしてしまいます。
(ロード部分)
pixelShaderHandle_Normal = LoadPixelShader("HSBHueShiftPS.cso");
txtShaderHandle_Normal = LoadPixelShader("TextShader.cso");
constantBufferHandleTxt = CreateShaderConstantBuffer(sizeof(float) * 16);
constantBufferHandlePxl = CreateShaderConstantBuffer(sizeof(float) * 16);
実際の描画処理
// 頂点を蓄積するバッファ
std::vector<VERTEX2DSHADER> sampleVertices;
int psHandle = -1;
int cbHandle = -1;
TextureData td;
int th = -1;
// デバッグ用:FlushBatchの仕組みを模して「機体・弾・文字」を続けて一括描画する関数
void DrawBatchSampleDirectly(int screenHandle)
{
if (screenHandle == -1) return;
// 描画先スクリーンを設定
SetDrawScreen(screenHandle);
SetUseZBuffer3D(TRUE);
SetWriteZBuffer3D(TRUE);
// ----------------------------------------------------
// 1. データの準備(機体、弾、文字の頂点を1つの配列に連結して積む)
// ----------------------------------------------------
// --- (A) 機体データの追加 (6頂点) ---
{
td = Texture_Player.GetTextureData(3); // プレイヤーのSpriteID
th = td.SrcTextureHandle;
if (td.SrcTextureHandle != -1)
{
float x = 100.0f, y = 100.0f;
int idx[6] = { 0, 1, 2, 2, 1, 3 };
size_t oldSize = sampleVertices.size();
sampleVertices.resize(6);
for (int i = 0; i < 6; ++i)
{
int id = idx[i];
VERTEX2DSHADER& v = sampleVertices[i];
v.pos.x = x + td.lx[id];
v.pos.y = y + td.ly[id];
v.pos.z = 0.0f;
v.rhw = 1.0f;
v.dif = GetColorU8(255, 255, 255, 255);
v.spc = GetColorU8(0, 0, 0, 0);
v.u = td.u[id];
v.v = td.v[id];
}
}
}
psHandle = pixelShaderHandle_Normal;
cbHandle = constantBufferHandlePxl;
DrawBatchSampleDirectly2();
return;
// --- (B) 弾データの追加 (6頂点) ---
{
td = Texture_EnemyShot.GetTextureData(0);
th = td.SrcTextureHandle;
if (td.SrcTextureHandle != -1)
{
float x = 240.0f, y = 150.0f;
int idx[6] = { 0, 1, 2, 2, 1, 3 };
size_t oldSize = sampleVertices.size();
sampleVertices.resize(6);
for (int i = 0; i < 6; ++i)
{
int id = idx[i];
VERTEX2DSHADER& v = sampleVertices[i];
v.pos.x = x + td.lx[id];
v.pos.y = y + td.ly[id];
v.pos.z = 0.0f;
v.rhw = 1.0f;
v.dif = GetColorU8(255, 255, 255, 255);
v.spc = GetColorU8(0, 0, 0, 0);
v.u = td.u[id];
v.v = td.v[id];
}
}
}
psHandle = pixelShaderHandle_Normal;
cbHandle = constantBufferHandlePxl;
DrawBatchSampleDirectly2();
// --- (C) 文字列データの追加 (文字数 × 6頂点) ---
{
std::string text = "BATCH TEST";
float startX = 180.0f;
float startY = 100.0f;
float charSpacing = 12.0f;
int idx[6] = { 0, 1, 2, 2, 1, 3 };
int cnt = 0;
for (size_t i = 0; i < text.length(); ++i)
{
char c = text[i];
int patternIndex = (c < 0x20 || c > 0x5F) ? 0 : static_cast<int>(c - 0x20);
td = Texture_Font.GetTextureData(patternIndex);
th = td.SrcTextureHandle;
if (td.SrcTextureHandle != -1)
{
float charX = startX + (i * charSpacing);
float charY = startY;
size_t oldSize = sampleVertices.size();
sampleVertices.resize(60);
for (int k = 0; k < 6; ++k)
{
int id = idx[k];
VERTEX2DSHADER& v = sampleVertices[cnt];
v.pos.x = charX + td.lx[id];
v.pos.y = charY + td.ly[id];
v.pos.z = 0.0f;
v.rhw = 1.0f;
v.dif = GetColorU8(255, 255, 255, 255);
v.spc = GetColorU8(0, 0, 0, 0);
v.u = td.u[id];
v.v = td.v[id];
cnt++;
}
}
}
}
psHandle = txtShaderHandle_Normal;
cbHandle = constantBufferHandleTxt;
DrawBatchSampleDirectly2();
}
void DrawBatchSampleDirectly2()
{
if (sampleVertices.empty()) return;
//return;
SetDrawScreen(ScreenHandle);
// ----------------------------------------------------
// 2. 描画実行
// ----------------------------------------------------
// テクスチャのバインド(例としてFontテクスチャを使用)
if (th != -1) {
SetUseTextureToShader(0, th);
}
// 定数バッファの更新(memcpy を使用:64バイト / 16個のfloat)
//int cbHandle = constantBufferHandlePxl;
if (cbHandle >= 0) {
void* buffer = GetBufferShaderConstantBuffer(cbHandle);
if (buffer != nullptr) {
// ダミーのパラメータ配列(16個)を用意して一括memcpy
float dummyParams[16] = {
1.0f, 0.0f, 0.0f, 1.0f, // 0~3: 赤色
1.0f, 0.0f, 0.0f, 0.0f, // 4~7
0.0f, 0.0f, 0.0f, 0.0f, // 8~11
0.0f, 0.0f, 0.0f, 0.0f // 12~15
};
std::memcpy(buffer, dummyParams, sizeof(float) * 16);
UpdateShaderConstantBuffer(cbHandle);
}
}
// ピクセルシェーダーと定数バッファの適用
if (psHandle >= 0) {
SetUsePixelShader(psHandle);
}
if (cbHandle >= 0) {
SetShaderConstantBuffer(cbHandle, DX_SHADERTYPE_PIXEL, 1);
}
// ポリゴン数計算と描画命令
int polygonCount = static_cast<int>(sampleVertices.size()) / 3;
DrawPolygon2DToShader(sampleVertices.data(), polygonCount);
// ステータスの後始末(標準に戻す)
SetUsePixelShader(-1);
}
ピクセルシェーダ(例)
exture2D tex : register(t0);
SamplerState smp : register(s0);
cbuffer ConstantBuffer : register(b1)
{
float4 g_ColorTL; // パラメータ0〜3: 左上の色 (Top-Left)
float4 g_ColorTR; // パラメータ4〜7: 右上の色 (Top-Right)
float4 g_ColorBL; // パラメータ8〜11: 左下の色 (Bottom-Left)
float4 g_ColorBR; // パラメータ12〜15: 右下の色 (Bottom-Right)
// ※もし影や縁取りのパラメータも入れたい場合は、ここから後ろに追加できます
// 今回は4点カラーを確実に動かすため、16バイト境界(float4単位)で綺麗にスロットを割り当てています
};
struct PSInput
{
float4 Position : SV_POSITION;
float4 DiffuseColor : COLOR0;
float4 SpecularColor : COLOR1;
float2 TextureCoord0 : TEXCOORD0; // ← これが各ピクセルのUV座標 (0.0 〜 1.0)
float2 TextureCoord1 : TEXCOORD1;
};
float4 main(PSInput input) : SV_TARGET
{
float2 uv = input.TextureCoord0;
// 1. テクスチャのサンプリング
float4 texColor = tex.Sample(smp, uv);
//確認用のため一旦何も触らずにそのまま返す
return texColor;
}