🔒 Locked
implementing antialiasing
Advertisement
Original Post
I have been porting a big OpenGL tool to Direct3D. In the process i had to port some variable-width line rendering codes ( glLineWidth() ) to Direct3D. While doing that, first i used the ID3DXLine interface which had a major flaw, that i later realized. The flaw appears mainly in the Perspective Projection mode. If one vertex of a line, in eye-space , goes, beyond the near-plane, it gets projected in a wrong way (which is mathematically understood) but ID3DXLine interface doesn't clip that line inside. Hence the ID3DXLine interface was totally useless for me. So i had to implement my own variable-width line drawing modules using two-triangle method (similar to ID3DXLine ). Everything works perfectly now but i want to implement the AntiAliasing (ID3DXLine->SetAntialiasing() ). What i did was, i used a thin alpha edge in the texture that gradually goes from 1 to 0 (alpha goes from 255 to 0) and used that texture to texture the two triangles. These scheme works fine when the line width is big enough. But it never gives the same visual output as ID3DXLine when antialiasing is turned on for smaller line widths. I am just wondering how ID3DXLine achieved antialiasing?
I don't know how ID3DXLine does this 'under the hood', but maybe it's an option for you to enable antialiassing for the entire application? If so, this can be done by setting the appropriate values for MultiSampleType and MultiSampleQuality in the D3DPRESENT_PARAMETERS used to create your device.
Hope this helps :)
Hope this helps :)
To use a texture (and 2 triangles) to make a line, be sure to:
-enable bilinear filtering (this might be what you mean by antialiasing)
-disable mipmaps on the texture
-make sure the actual line graphic is interior to the texture, ie have a row of blank pixels above and below your line.
-enable bilinear filtering (this might be what you mean by antialiasing)
-disable mipmaps on the texture
-make sure the actual line graphic is interior to the texture, ie have a row of blank pixels above and below your line.
There's not much you can do, really. If your line is so thin that the rasteriser renders it as a segmented series of dots on the screen, then no texture can fix that.
The best you can do is render all your lines to a super-high-resolution (probably something like 2048x2048 or larger) rendertarget then downsample it and overlay over the backbuffer once you're done. In other words, doing "manual" supersampling.
The best you can do is render all your lines to a super-high-resolution (probably something like 2048x2048 or larger) rendertarget then downsample it and overlay over the backbuffer once you're done. In other words, doing "manual" supersampling.
Ok, i have a new idea.. since that texturing idea actually sucked ( :P ).
I will create an extra render target (having same dimension as my back buffer)
with MSAA enabled and then all my lines in that render target. Later i will use that surface as a texture on a screen-aligned quad to overlay the whole thing on the backbuffer (with Alpha Blend and Alpha test enabled). Hope that will render antialiased lines. Now the first question is...
1. How do i use IDirect3DSurface9 as texture ?
My guess is to copy the content of the IDirect3DSurface9 to a texture previously created.
I will create an extra render target (having same dimension as my back buffer)
with MSAA enabled and then all my lines in that render target. Later i will use that surface as a texture on a screen-aligned quad to overlay the whole thing on the backbuffer (with Alpha Blend and Alpha test enabled). Hope that will render antialiased lines. Now the first question is...
1. How do i use IDirect3DSurface9 as texture ?
My guess is to copy the content of the IDirect3DSurface9 to a texture previously created.
Ok, i have a new idea.. since that texturing idea actually sucked ( :P ).
I will create an extra render target (having same dimension as my back buffer)
with MSAA enabled and then all my lines in that render target. Later i will use that surface as a texture on a screen-aligned quad to overlay the whole thing on the backbuffer (with Alpha Blend and Alpha test enabled). Hope that will render antialiased lines. Now the first question is...
1. How do i use IDirect3DSurface9 as texture ?
My guess is to copy the content of the IDirect3DSurface9 to a texture previously created.
I will create an extra render target (having same dimension as my back buffer)
with MSAA enabled and then all my lines in that render target. Later i will use that surface as a texture on a screen-aligned quad to overlay the whole thing on the backbuffer (with Alpha Blend and Alpha test enabled). Hope that will render antialiased lines. Now the first question is...
1. How do i use IDirect3DSurface9 as texture ?
My guess is to copy the content of the IDirect3DSurface9 to a texture previously created.
Quote:
Original post by browny
Ok, i have a new idea.. since that texturing idea actually sucked ( :P ).
I will create an extra render target (having same dimension as my back buffer)
with MSAA enabled and then all my lines in that render target. Later i will use that surface as a texture on a screen-aligned quad to overlay the whole thing on the backbuffer (with Alpha Blend and Alpha test enabled). Hope that will render antialiased lines. Now the first question is...
1. How do i use IDirect3DSurface9 as texture ?
My guess is to copy the content of the IDirect3DSurface9 to a texture previously created.
Yup. You need to do a stretchrect (or something similar) to copy the data from the MSAA render target surface to the texture so you can overlay it over your scene.
I used a extra backbuffer (using CreateRenderTarget) with MSAA enabled and then created a texture. But when i do StretchRect from the new RenderTarget it doesn't work. Later i found from the docs that the StretchRect from RT surface to a texture only works when the texture is RT Texture ( ie. created with D3DUSAGE_RENDERTARGET ). I did that too.. and StretchRect atleast returns S_OK, but when i lay that texture on the original backbuffer, all garbage seem to appear.. as if the StretchRect dint work !
Could someone give me a small code snippet of how to get this working
Could someone give me a small code snippet of how to get this working
well.. let me show u the layout of the code..im basically doing the following
BeginScene();
CreateRenderTarget( with MSAA enabled );
SaveOldRenderTargers();
SetRenderTarget();
RenderFewLines();
CreateTexture();
StretchRect( from MSAA rendertarget to the texture )
Restore Original BackBuffer and ZBuffer
Draw a screen aligned quad with the texture
EndScene();
Present();
The the DX doc says that StretchRect doesn't work between BeginScene() and EndScene() pair.. but i have seem examples where StretchRect are put between BeginScene() and EndScene();
Could someone clear me up here
BeginScene();
CreateRenderTarget( with MSAA enabled );
SaveOldRenderTargers();
SetRenderTarget();
RenderFewLines();
CreateTexture();
StretchRect( from MSAA rendertarget to the texture )
Restore Original BackBuffer and ZBuffer
Draw a screen aligned quad with the texture
EndScene();
Present();
The the DX doc says that StretchRect doesn't work between BeginScene() and EndScene() pair.. but i have seem examples where StretchRect are put between BeginScene() and EndScene();
Could someone clear me up here
How exactly are you doing your StretchRect?
You need to create the texture, then use GetSurfaceLevel() to retrieve the top-level surface. That's the surface you need to stretchrect to.
For example:
PS: You should never create textures like that every frame. It means that every frame your program has to go through the slow process of creating textures, and the ramifications of forgetting to release the textures are massive if you're creating them each frame.
You need to create the texture, then use GetSurfaceLevel() to retrieve the top-level surface. That's the surface you need to stretchrect to.
For example:
IDirect3DTexture9* LineTexture;IDirect3DSurface9* LineSurface;D3D9DeviceInterface->CreateTexture(ScreenWidth,ScreenHeight,1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8,D3DPOOL_DEFAULT,&LineTexture, NULL);LineTexture->GetSurfaceLevel(0,&LineSurface);D3D9DeviceInterface->StretchRect(MSAALineSurface, NULL, LineSurface, NULL, D3DTEXF_NONE);// Now draw LineTexture using a screen-aligned quadPS: You should never create textures like that every frame. It means that every frame your program has to go through the slow process of creating textures, and the ramifications of forgetting to release the textures are massive if you're creating them each frame.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement