for all those D3D Freaks out there:
I'm currently implementing a Renderer for D3D8, as D3D8 support is officially cancelled for the 7.x series.
It's basically a straight-ahead down-port of the D3D9 Renderer, however as the ScissorRect functionality isn't implemented in D3D8, CE gave me the hint to check the Irrlicht Renderer, as the same functionality is implemented there by modifying the viewport / projection matrix.
I tried to convert the code there to D3D8 and it seems to work - except that nothing is drawn on the screen.
I'm quite sure, that I missed something important in the viewport / projection matrix modification in Direct3D8GeometryBuffer::draw(), but I just can't see, what's wrong... Anyone, who might shed some light on this?
Best regards
- Mark
Code: Select all
void Direct3D8GeometryBuffer::draw() const
{
// Set up clipping for this buffer
//
// This is done via viewport & projection manipulation because DirectX 8
// has no scissoring facilities. This has the unfortunate side effect of
// being much more expensive to set up.
D3DVIEWPORT8 target_vp;
d_device->GetViewport(&target_vp);
D3DXMATRIX proj;
d_device->GetTransform(D3DTS_PROJECTION, &proj);
const Size csz(d_clipRect.getSize());
const Size tsz(static_cast<float>(target_vp.Width),
static_cast<float>(target_vp.Height));
// set modified projection 'scissor' matix that negates scale and
// translation that would be done by setting the viewport to the clip area.
float m_00 = tsz.d_width / csz.d_width;
float m_11 = tsz.d_height / csz.d_height;
float m_30 = 1.0f * (tsz.d_width + 2.0f *
(target_vp.X -
(d_clipRect.d_left + csz.d_width * 0.5f))) / csz.d_width;
float m_31 = -(tsz.d_height + 2.0f *
(target_vp.Y -
(d_clipRect.d_top + csz.d_height * 0.5f))) / csz.d_height;
D3DXMATRIX scsr(
m_00, 0.0f, 0.0f, 0.0f,
0.0f, m_11, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
m_30, m_31, 0.0f, 1.0f);
D3DXMATRIX scproj;
d_functions.D3DXMatrixMultiply(&scproj, &scsr, &proj);
d_device->SetTransform(D3DTS_PROJECTION, &scproj);
// set new viewport for the clipping area
D3DVIEWPORT8 vp;
vp.X = static_cast<DWORD>(d_clipRect.d_left);
vp.Y = static_cast<DWORD>(d_clipRect.d_top);
vp.Width = static_cast<DWORD>(d_clipRect.getWidth());
vp.Height = static_cast<DWORD>(d_clipRect.getHeight());
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
d_device->SetViewport(&vp);
// apply the transformations we need to use.
if (!d_matrixValid)
updateMatrix();
d_device->SetTransform(D3DTS_WORLD, &d_matrix);
d_owner.setupRenderingBlendMode(d_blendMode);
const int pass_count = d_effect ? d_effect->getPassCount() : 1;
for (int pass = 0; pass < pass_count; ++pass)
{
// set up RenderEffect
if (d_effect)
d_effect->performPreRenderFunctions(pass);
// draw the batches
size_t pos = 0;
BatchList::const_iterator i = d_batches.begin();
for ( ; i != d_batches.end(); ++i)
{
d_device->SetTexture(0, (*i).first);
d_device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, (*i).second / 3,
&d_vertices[pos], sizeof(D3DVertex));
pos += (*i).second;
}
}
// clean up RenderEffect
if (d_effect)
d_effect->performPostRenderFunctions();
// restore original projection matrix and viewport.
d_device->SetTransform(D3DTS_PROJECTION, &proj);
d_device->SetViewport(&target_vp);
}