DirectX: Render to a screen buffer without using a render target
- by knight666
Hello,
I'm writing an open source 2D game engine, and I want to support as many devices and platforms as possible. I currently only have Windows Mobile though. I'm rendering using DirectX Mobile, with DirectDraw as a fallback path. However, I've run into a bit of trouble.
It seems that while the reference driver supports createRenderTarget, many many many physical devices do not. I need some way to render to the screen without using a render target, because I render sprites using textured quads, but I also need to be able to draw individual pixels.
This is how I do it right now:
// save old values
if (Error::Failed(m_D3DDevice->GetRenderTarget(&m_D3DOldTarget)))
{
ERROR_EXPLAIN("Could not retrieve backbuffer.");
return false;
}
// clear render surface
if (Error::Failed(m_D3DDevice->SetRenderTarget(m_D3DRenderSurface, NULL)))
{
ERROR_EXPLAIN("Could not set render target to render texture.");
return false;
}
if (Error::Failed (m_D3DDevice->Clear(
0,
NULL, // target rectangle
D3DMCLEAR_TARGET,
D3DMCOLOR_XRGB(0, 0, 0), // clear color
1.0f,
0
)
)
)
{
ERROR_EXPLAIN("Failed to clear render texture.");
return false;
}
D3DMLOCKED_RECT render_rect;
if (Error::Failed(m_D3DRenderSurface->LockRect(&render_rect, NULL, NULL)))
{
ERROR_EXPLAIN("Failed to lock render surface pixels.");
}
else
{
m_D3DBackSurf->SetBuffer((Pixel*)render_rect.pBits);
m_D3DRenderSurface->UnlockRect();
}
// begin scene
if (Error::Failed(m_D3DDevice->BeginScene()))
{
ERROR_EXPLAIN("Failed to start rendering.");
return false;
}
// =====================
// example rendering
// =====================
// some other stuff, but the most important part of rendering a sprite:
device->SetTexture(0, m_Texture));
device->SetStreamSource(0, m_VertexBuffer, sizeof(Vertex));
device->DrawPrimitive(D3DMPT_TRIANGLELIST, 0, 2);
// plotting a pixel
Surface* target = (Surface*)Device::GetRenderMethod()->GetRenderTarget();
buffer = target->GetBuffer();
buffer[somepixel] = MAKECOLOR(255, 0, 0);
// end scene
if (Error::Failed(device->EndScene()))
{
ERROR_EXPLAIN("Failed to end scene.");
return false;
}
// clear screen
if (Error::Failed(device->SetRenderTarget(m_D3DOldTarget, NULL)))
{
ERROR_EXPLAIN("Couldn't set render target to backbuffer.");
return false;
}
if (Error::Failed(device->GetBackBuffer (
0,
D3DMBACKBUFFER_TYPE_MONO,
&m_D3DBack
)
)
)
{
ERROR_EXPLAIN("Couldn't retrieve backbuffer.");
return false;
}
RECT dest = {
0,
0,
Device::GetWidth(),
Device::GetHeight()
};
if (Error::Failed( device->StretchRect (
m_D3DRenderSurface,
NULL,
m_D3DBack,
&dest,
D3DMTEXF_NONE
)
)
)
{
ERROR_EXPLAIN("Failed to stretch render texture to backbuffer.");
return false;
}
if (Error::Failed(device->Present(NULL, NULL, NULL, NULL)))
{
ERROR_EXPLAIN("Failed to present device.");
return false;
}
I'm looking for a way to do the same thing (render sprites using hardware acceleration and plot pixels on a buffer) without using a render target.
Thanks in advance.