Hello. I am using Directx9.
I am trying to apply a very simple shader to my project. But even if the shader works, the objects are corrupted. I am not very good at this. So I decided to ask for help from knowledgeable people here.
There is no error log or log.
For testing purposes I only wanted to run a transparent red color.
Maybe I don't need to use vertex for this. I'm not sure. I'd appreciate it if you could help me with this.
SS:
The codes I generally use are:
constexpr std::string_view gEffectString = R"(
struct VS_OUTPUT
{
float4 PosH : POSITION;
float2 TexCoord : TEXCOORD0;
};
float2 gPixelSize;
Texture2D gTexture;
sampler2D gSampler : register(s4)
{
Texture = <gTexture>;
};
VS_OUTPUT mainVS(float4 Pos : POSITION0)
{
float2 p = float2(-gPixelSize.x, gPixelSize.y);
VS_OUTPUT output;
output.PosH = float4(Pos.xy + p, 0.0f, 1.0f);
output.TexCoord = Pos.zw;
return output;
}
float4 mainPS(VS_OUTPUT Input) : COLOR
{
float4 c = tex2D(gSampler, Input.TexCoord);
float l = dot(c.rgb, float3(0.299f, 0.587f, 0.114f));
// Şeffaf kırmızı döndür (kırmızı kanal l, diğerleri 0)
return float4(l, 0.0f, 0.0f, c.a);
}
technique RedscaleEffect
{
pass p0
{
VertexShader = compile vs_3_0 mainVS();
PixelShader = compile ps_3_0 mainPS();
}
};
)";
bool ShaderRenderTargetEffect::CreateVertexBuffer(IDirect3DDevice9* pDevice)
{
static auto vertices = std::to_array<D3DXVECTOR4>({
{-1.0f, 1.0f, 0.0f, 0.0f}, {-1.0f, -3.0f, 0.0f, 2.0f}, {3.0f, 1.0f, 2.0f, 0.0f}
});
auto hr = pDevice->CreateVertexBuffer(sizeof(vertices), D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT,
&m_pVerteBuffer, nullptr);
if (FAILED(hr)) return false;
void* data = nullptr;
hr = m_pVerteBuffer->Lock(0, 0, &data, 0);
if (FAILED(hr)) return false;
std::memcpy(data, vertices.data(), sizeof(vertices));
m_pVerteBuffer->Unlock();
return true;
}
bool ShaderRenderTargetEffect::CreateVertexDeclaration(IDirect3DDevice9* pDevice)
{
static constexpr auto elems = std::to_array<D3DVERTEXELEMENT9>({
{0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
D3DDECL_END()
});
auto hr = pDevice->CreateVertexDeclaration(elems.data(), &m_pVertexDeclaration);
if (FAILED(hr)) return false;
return true;
}
bool ShaderRenderTargetEffect::CreateEffect(IDirect3DDevice9* pDevice)
{
auto hr = D3DXCreateEffect(pDevice, gEffectString.data(), gEffectString.size(),
nullptr, nullptr, 0, nullptr, &m_pEffect, nullptr);
if (FAILED(hr)) return false;
m_Technique = m_pEffect->GetTechniqueByName("RedscaleEffect");
if (m_Technique == NULL) return false;
m_PixelSizeParam = m_pEffect->GetParameterByName(NULL, "gPixelSize");
if (m_PixelSizeParam == NULL) return false;
m_TextureParam = m_pEffect->GetParameterByName(NULL, "gTexture");
if (m_TextureParam == NULL) return false;
return true;
}
ShaderRenderTargetEffect::~ShaderRenderTargetEffect()
{
if (m_pVertexDeclaration)
{
m_pVertexDeclaration->Release();
m_pVertexDeclaration = nullptr;
}
if (m_pVerteBuffer)
{
m_pVerteBuffer->Release();
m_pVerteBuffer = nullptr;
}
if (m_pEffect)
{
m_pEffect->Release();
m_pEffect = nullptr;
}
m_TextureParam = NULL;
m_PixelSizeParam = NULL;
m_Technique = NULL;
m_pDevice = nullptr;
}
bool ShaderRenderTargetEffect::Create(IDirect3DDevice9* pDevice)
{
if (!CreateEffect(pDevice)) return false;
if (!CreateVertexDeclaration(pDevice)) return false;
if (!CreateVertexBuffer(pDevice)) return false;
m_pEffect->SetTechnique(m_Technique);
m_pDevice = pDevice;
return true;
}
bool ShaderRenderTargetEffect::Apply(IDirect3DTexture9* pTexture)
{
D3DSURFACE_DESC desc;
auto hr = pTexture->GetLevelDesc(0, &desc);
if (FAILED(hr)) return false;
D3DXVECTOR2 v(1.0f / desc.Width, 1.0f / desc.Height);
m_pEffect->SetFloatArray(m_PixelSizeParam, v, 2);
hr = m_pEffect->SetTexture(m_TextureParam, pTexture);
if (FAILED(hr))
{
TraceError("m_pEffect->SetTexture ERROR");
return false;
}
UINT passes = 0;
hr = m_pEffect->Begin(&passes, 0);
if (FAILED(hr))
{
TraceError("m_pEffect->Begin ERROR");
return false;
}
hr = m_pEffect->BeginPass(0);
if (FAILED(hr))
{
TraceError("m_pEffect->BeginPass ERROR");
return false;
}
STATEMANAGER.SetVertexDeclaration(m_pVertexDeclaration);
STATEMANAGER.SetStreamSource(0, m_pVerteBuffer, sizeof(D3DXVECTOR4));
STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);
m_pEffect->EndPass();
m_pEffect->End();
return true;
}
+++
ShaderRenderTarget::~ShaderRenderTarget()
{
if (m_pTex)
{
m_pTex->Release();
m_pTex = nullptr;
}
if (m_pTexSurface)
{
m_pTexSurface->Release();
m_pTexSurface = nullptr;
}
if (m_pOldRenderTarget)
{
m_pOldRenderTarget->Release();
m_pOldRenderTarget = nullptr;
}
if (m_pOldDepthStencil)
{
m_pOldDepthStencil->Release();
m_pOldDepthStencil = nullptr;
}
m_pDev = nullptr;
}
bool ShaderRenderTarget::Create(IDirect3DDevice9* pDevice, int Width, int Height, D3DFORMAT Format)
{
if (FAILED(pDevice->CreateTexture(Width, Height, 1, D3DUSAGE_RENDERTARGET, Format, D3DPOOL_DEFAULT,
&m_pTex, nullptr)))
{
return false;
}
if (FAILED(m_pTex->GetSurfaceLevel(0, &m_pTexSurface))) return false;
m_pDev = pDevice;
return true;
}
bool ShaderRenderTarget::Begin(D3DCOLOR Color)
{
if (m_pOldRenderTarget)
{
m_pOldRenderTarget->Release();
m_pOldRenderTarget = nullptr;
}
if (m_pOldDepthStencil)
{
m_pOldDepthStencil->Release();
m_pOldDepthStencil = nullptr;
}
auto hr = m_pDev->GetRenderTarget(0, &m_pOldRenderTarget);
if (hr != D3D_OK && hr != D3DERR_NOTFOUND)
{
TraceError("m_pDev->GetRenderTarget ERROR!");
return false;
}
hr = m_pDev->GetDepthStencilSurface(&m_pOldDepthStencil);
if (hr != D3D_OK && hr != D3DERR_NOTFOUND)
{
TraceError("m_pDev->GetDepthStencilSurface ERROR!");
return false;
}
hr = m_pDev->SetRenderTarget(0, m_pTexSurface);
if (FAILED(hr))
{
TraceError("m_pDev->SetRenderTarget ERROR!");
return false;
}
hr = m_pDev->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
if (FAILED(hr))
{
TraceError("m_pDev->Clear ERROR!");
return false;
}
return true;
}
bool ShaderRenderTarget::End()
{
auto hr = m_pDev->SetRenderTarget(0, m_pOldRenderTarget);
if (FAILED(hr)) return false;
hr = m_pDev->SetDepthStencilSurface(m_pOldDepthStencil);
if (FAILED(hr)) return false;
return true;
}