Anti Aliasing in Textures

I am trying to use DirectX9 to draw into one texture and then use that texture in another scene. My problem is that any antialiasing that is done when drawing into the texture is lost when I draw the texture in the new scene. Here is some code that demonstrates the problem:

void RenderScene(HWND hwnd)
{
	RECT		clientRect;
	GetClientRect(hwnd, &clientRect);

	if (s_pD3D == NULL)
		return;

	IDirect3DDevice9*		pDevice = NULL;
	IDirect3DTexture9*		pBitmap = NULL;
	ID3DXRenderToSurface*	pRenderer = NULL;

	D3DPRESENT_PARAMETERS	d3dpp; 
	HRESULT					hResult;
	ZeroMemory( &d3dpp, sizeof(d3dpp) );
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
	d3dpp.BackBufferHeight = clientRect.bottom;
	d3dpp.BackBufferWidth = clientRect.right;
	d3dpp.hDeviceWindow = hWnd;

	DWORD	qualityStops;
	for (int type = D3DMULTISAMPLE_16_SAMPLES; type > D3DMULTISAMPLE_NONE; type--)
	{
		hResult = s_pD3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, (D3DMULTISAMPLE_TYPE)type, &qualityStops);
		if (hResult == S_OK)
		{
			d3dpp.MultiSampleQuality = qualityStops - 1;
			d3dpp.MultiSampleType = (D3DMULTISAMPLE_TYPE)type;
			break;
		}
	}

	hResult = s_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
	if (hResult != S_OK)
		return;

	pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
	pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

	RECT	client;
	GetClientRect(hWnd, &client);
	hResult = D3DXCreateTexture(pDevice, clientRect.right, clientRect.bottom, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pBitmap);
	if (hResult != S_OK)
		return;

	hResult = D3DXCreateRenderToSurface(pDevice, clientRect.right, clientRect.bottom, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN, &pRenderer); 

	IDirect3DSurface9*		pSurface;
	hResult = pBitmap->GetSurfaceLevel(0, &pSurface);
	hResult = pRenderer->BeginScene(pSurface, NULL);
	pSurface->Release();

	hResult = pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255, 255), 1.0f, 0 );

	IDirect3DVertexBuffer9*		pBuffer = NULL;
	hResult = pDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &pBuffer, NULL);
	if (pBuffer != NULL)
	{
		CUSTOMVERTEX*	pVerts;
		hResult = pBuffer->Lock(0, 3*sizeof(CUSTOMVERTEX), (void**)&pVerts, 0);

		pVerts[0].x = .9;
		pVerts[0].y = -.3;
		pVerts[0].z = 0;
		pVerts[0].color = D3DCOLOR_XRGB(0, 0, 255);
		pVerts[1].x = -.1;
		pVerts[1].y = -.6;
		pVerts[1].z = 0;
		pVerts[1].color = D3DCOLOR_XRGB(0, 0, 255);;
		pVerts[2].x = .7;
		pVerts[2].y = .8;
		pVerts[2].z = 0;
		pVerts[2].color = D3DCOLOR_XRGB(0, 0, 255);;
		pBuffer->Unlock();
		hResult = pDevice->SetStreamSource(0, pBuffer, 0, sizeof(CUSTOMVERTEX));
		hResult = pDevice->SetFVF(D3DFVF_CUSTOMVERTEX);

		hResult = pDevice->DrawPrimitive(D3DPT_TRIANGLELIST , 0, 1);

		pBuffer->Release();
	}

	hResult = pRenderer->EndScene(D3DX_FILTER_NONE);

	hResult = pDevice->BeginScene();
	hResult = pDevice->CreateVertexBuffer(4*sizeof(TEXTUREVERTEX), D3DUSAGE_WRITEONLY, D3DFVF_TEXTUREVERTEX, D3DPOOL_DEFAULT, &pBuffer, NULL);
	if (pBuffer != NULL)
	{
		TEXTUREVERTEX*	pVerts;
		hResult = pBuffer->Lock(0, 4*sizeof(TEXTUREVERTEX), (void**)&pVerts, 0);

			pVerts[0].x = -1.0f;
			pVerts[0].y = -1.0f;
			pVerts[0].z = 0.0f;
			pVerts[0].tu = 0.0f;
			pVerts[0].tv = 1.0f;

			pVerts[1].x = 1.0f;
			pVerts[1].y = -1.0f;
			pVerts[1].z = 0.0f;
			pVerts[1].tu = 1.0f;
			pVerts[1].tv = 1.0f;

			pVerts[2].x = -1.0f;
			pVerts[2].y = 1.0f;
			pVerts[2].z = 0.0f;
			pVerts[2].tu = 0.0f;
			pVerts[2].tv = 0.0f;

			pVerts[3].x = 1.0f;
			pVerts[3].y = 1.0f;
			pVerts[3].z = 0.0f;
			pVerts[3].tu = 1.0f;
			pVerts[3].tv = 0.0f;

			hResult = pBuffer->Unlock();

			hResult = pDevice->SetTexture(0, pBitmap);
			hResult = pDevice->SetStreamSource(0, pBuffer, 0, sizeof(TEXTUREVERTEX));
			hResult = pDevice->SetFVF(D3DFVF_TEXTUREVERTEX);
			hResult = pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
	}				

	pDevice->EndScene();

	hResult = pDevice->Present(NULL, NULL, NULL, NULL);

	if (pRenderer)
		pRenderer->Release();

	if (pBitmap)
		pBitmap->Release();

	if (pDevice)
		pDevice->Release();
}
If I remove the code that draws into the texture and instead draw the triangle directly to the device it antialiases fine.
Does anybody have any idea why I would loose the anti-aliasing 
Thanks


Answer this question

Anti Aliasing in Textures

  • James L VanDusen

    Your Texture has no multisampling buffer because you can’t create a render target texture that supports this. The multisampling flags in the present parameters are only for the back buffer.

    Depending on the effect you want to build there are multiple solutions to get AA even if you need your rendered image again as texture. Do you want to build a post filter or more something like a mirror effect



  • ha ha

    In this case you should try the following:

    1. Create your texture as before.

    2. Create a render target with the same size and format but with AA enabled. (CreateRenderTarget)

    3. Render to your new render target

    4. Copy the content of your render target to the surface of your texture with StretchRect. The downs sampling will happens during this operation.

    5. Use your texture.

    Instead of creating a new render target you can reuse the back buffer if it is large enough and not already used for your current frame.



  • NormLane

    I am actually just trying to composite the texture on top of another scene.
  • Anti Aliasing in Textures