DirectX 9 点精灵不缩放
DirectX 9 point sprites not scaling
我几乎立即得到了点精灵,但我只坚持一件事,它们被渲染为可能是 2x2 像素的精灵,这并不是很容易看到,尤其是在有其他运动的情况下。现在,我已经尝试调整所有变量,下面是可能效果最好的代码:
void renderParticles()
{
for(int i = 0; i < particleCount; i ++)
{
particlePoints[i] += particleSpeeds[i];
}
void* data;
pParticleBuffer->Lock(0, particleCount*sizeof(PARTICLE_VERTEX), &data, NULL);
memcpy(data, particlePoints, sizeof(particlePoints));
pParticleBuffer->Unlock();
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_POINTSIZE, (DWORD)1.0f);
//pd3dDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD)9999.0f);
//pd3dDevice->SetRenderState(D3DRS_POINTSIZE_MIN, (DWORD)0.0f);
pd3dDevice->SetRenderState(D3DRS_POINTSCALE_A, (DWORD)0.0f);
pd3dDevice->SetRenderState(D3DRS_POINTSCALE_B, (DWORD)0.0f);
pd3dDevice->SetRenderState(D3DRS_POINTSCALE_C, (DWORD)1.0f);
pd3dDevice->SetStreamSource(0, pParticleBuffer, 0, sizeof(D3DXVECTOR3));
pd3dDevice->DrawPrimitive(D3DPT_POINTLIST, 0, particleCount);
pd3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
pd3dDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
}
好的,所以当我更改 POINTSCALE_A
和 POINTSCALE_B
时,实际上没有太大变化,C 也一样。 POINTSIZE
也没有什么区别。当我尝试将某些东西分配给 POINTSIZE_MAX
和 _MIN
时,无论我分配什么,它总是会停止精灵的渲染。我还尝试将 POINTSIZE
和 POINTSCALEENABLE
设置为 false,但也不走运。
这看起来似乎没有多少人环顾四周找到答案。 MSDN, while, yes, I did check Whosebug and found a similar question with no answer. Another source 上对该机制的解释仅建议设置最大和最小变量,正如我所说,这几乎会使我的粒子消失。
ParticlePoints
和 particleSpeeds
是 D3DXVector3 数组,我得到了我对它们的期望。我关注的一本书建议我用 XYZ 和漫反射定义一个自定义顶点,但老实说,我认为没有理由这么做,它只是为一长串声明添加了更多内容。
欢迎任何帮助,提前致谢。
编辑: 进一步的调整表明,当任何比例值高于 0.99999997f(至少在 0.99999998f 之间,我看到了效果),我得到了小版本,如果我把它们放在那里或更低,我几乎可以得到纹理的大小——尽管它仍然不是那么好,因为它可能很大,而且它几乎无法完成可控的任务。
很高兴提供帮助 :) 我的评论作为回答:
One more problem that I've seen is you float to dword cast. The official documentation suggests the following conversion *((DWORD*)&Variable
(doc) to be put into SetRenderState. I'm not very familiar with C++, but I would assume that this makes a difference, because your cast sets a real dword, but the API expects a float in the dwords memory space.
我几乎立即得到了点精灵,但我只坚持一件事,它们被渲染为可能是 2x2 像素的精灵,这并不是很容易看到,尤其是在有其他运动的情况下。现在,我已经尝试调整所有变量,下面是可能效果最好的代码:
void renderParticles()
{
for(int i = 0; i < particleCount; i ++)
{
particlePoints[i] += particleSpeeds[i];
}
void* data;
pParticleBuffer->Lock(0, particleCount*sizeof(PARTICLE_VERTEX), &data, NULL);
memcpy(data, particlePoints, sizeof(particlePoints));
pParticleBuffer->Unlock();
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_POINTSIZE, (DWORD)1.0f);
//pd3dDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD)9999.0f);
//pd3dDevice->SetRenderState(D3DRS_POINTSIZE_MIN, (DWORD)0.0f);
pd3dDevice->SetRenderState(D3DRS_POINTSCALE_A, (DWORD)0.0f);
pd3dDevice->SetRenderState(D3DRS_POINTSCALE_B, (DWORD)0.0f);
pd3dDevice->SetRenderState(D3DRS_POINTSCALE_C, (DWORD)1.0f);
pd3dDevice->SetStreamSource(0, pParticleBuffer, 0, sizeof(D3DXVECTOR3));
pd3dDevice->DrawPrimitive(D3DPT_POINTLIST, 0, particleCount);
pd3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
pd3dDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
}
好的,所以当我更改 POINTSCALE_A
和 POINTSCALE_B
时,实际上没有太大变化,C 也一样。 POINTSIZE
也没有什么区别。当我尝试将某些东西分配给 POINTSIZE_MAX
和 _MIN
时,无论我分配什么,它总是会停止精灵的渲染。我还尝试将 POINTSIZE
和 POINTSCALEENABLE
设置为 false,但也不走运。
这看起来似乎没有多少人环顾四周找到答案。 MSDN, while, yes, I did check Whosebug and found a similar question with no answer. Another source 上对该机制的解释仅建议设置最大和最小变量,正如我所说,这几乎会使我的粒子消失。
ParticlePoints
和 particleSpeeds
是 D3DXVector3 数组,我得到了我对它们的期望。我关注的一本书建议我用 XYZ 和漫反射定义一个自定义顶点,但老实说,我认为没有理由这么做,它只是为一长串声明添加了更多内容。
欢迎任何帮助,提前致谢。
编辑: 进一步的调整表明,当任何比例值高于 0.99999997f(至少在 0.99999998f 之间,我看到了效果),我得到了小版本,如果我把它们放在那里或更低,我几乎可以得到纹理的大小——尽管它仍然不是那么好,因为它可能很大,而且它几乎无法完成可控的任务。
很高兴提供帮助 :) 我的评论作为回答:
One more problem that I've seen is you float to dword cast. The official documentation suggests the following conversion
*((DWORD*)&Variable
(doc) to be put into SetRenderState. I'm not very familiar with C++, but I would assume that this makes a difference, because your cast sets a real dword, but the API expects a float in the dwords memory space.