Sign in to follow this  
Mathy

[SlimDX] Rendering some objects just once?

Recommended Posts

Mathy    104
Alright, so now that I am close to finishing my first 2D game in Direct3D, with all the physics included and such, the framerate is getting very low. On my laptop (3 year old laptop that is), the framerate is 30 FPS. I know this is okay, but I want it to be higher. So I looked at surfaces, and I thought: Would it be possible to draw objects that you knew never changed size or position to a surface, that would never be cleared, so that it wouldn't have to be redrawn every frame as well?

Share this post


Link to post
Share on other sites
Evil Steve    2017
It's certainly possible, that's how impostors are usually done. However, it's only a performance gain if the object is updated very infrequently, and is relatively complex to draw.

You'd be best profiling to find out where most of your scene time is going using a GPU profiler, for NVidia cards there's NVPerfHUD, and I gather something similar exists for ATI cards.

Share this post


Link to post
Share on other sites
Mathy    104
Thanks. So I tried this:

Created a new texture.
Got the surface of the texture through <TextureName>.GetSurfaceLevel(0).
Set the render target of the device to the texture surface.
Drew the objects.

Now what? I don't know what to do from here, or if I'm even doing it correctly.

Share this post


Link to post
Share on other sites
Evil Steve    2017
That looks fine - so long as you created the texture as a render target (I don't know how you do that in SlimDX).

After you've drawn the objects, you can call EndScene() and then set the original render target back, and use the texture like any other texture - and it should have the model you drew on it.

Share this post


Link to post
Share on other sites
Mathy    104
Quote:
Original post by Evil Steve
That looks fine - so long as you created the texture as a render target (I don't know how you do that in SlimDX).

After you've drawn the objects, you can call EndScene() and then set the original render target back, and use the texture like any other texture - and it should have the model you drew on it.


Alright, that seems to work. Now, on the new surface, the edges are very sharp. I used to have Multisampling on, but how do I enable that for the new surface too?

Share this post


Link to post
Share on other sites
adt7    751
I would profile your code before doing anything else. Both on the CPU and GPU side.

If you don't want to, then there are some other things you can look at, such as:

How many draw calls are you making each frame?
Are you doing any large lock, update, unlock operations on GPU resources (buffers, textures, etc) each frame?

Plenty of other too, but they would be my first ports of call.

Share this post


Link to post
Share on other sites
adt7    751
Quote:
Original post by Mathy
Alright, that seems to work. Now, on the new surface, the edges are very sharp. I used to have Multisampling on, but how do I enable that for the new surface too?


I'm fairly sure you can do it using the Surface.CreateRenderTarget(...) method.

You then have to use Device.StretchRectangle(...) with your back buffer as the second arguement to copy the results to the screen.

The class reference in the Slim DX Docs is your friend, use it.

Share this post


Link to post
Share on other sites
Mathy    104
Quote:
Original post by adt7
Quote:
Original post by Mathy
Alright, that seems to work. Now, on the new surface, the edges are very sharp. I used to have Multisampling on, but how do I enable that for the new surface too?


I'm fairly sure you can do it using the Surface.CreateRenderTarget(...) method.

You then have to use Device.StretchRectangle(...) with your back buffer as the second arguement to copy the results to the screen.

The class reference in the Slim DX Docs is your friend, use it.


Surface.CreateRenderTarget returns an error: "Device is not capable of sharing resource. CreateRenderTarget/CreateDepthStencil fails."

Share this post


Link to post
Share on other sites
Mathy    104
I should be mentioning that I am making the device like this:

Dim Handle As IntPtr
Dim STATIC_SURFACE As Surface = Surface.CreateRenderTarget(DEVICE, DEVICE_PARAMETERS.BackBufferWidth, DEVICE_PARAMETERS.BackBufferHeight, DEVICE_PARAMETERS.BackBufferFormat, DEVICE_PARAMETERS.Multisample, DEVICE_PARAMETERS.MultisampleQuality, False, Handle)

I am also creating it before any other rendering.

Share this post


Link to post
Share on other sites
Mathy    104
Just as you said that, I noticed there was another overload.

Visual Studio 2010 RC 1 has a tendency of randomly disabling intellisense on my computer, or only allowing to show the longest overload of a procedure/function.

Share this post


Link to post
Share on other sites
adt7    751
I assume that using the other method has solved the problem? Since IIRC it doesn't specify the surface as being available for sharing if you use that one.

Share this post


Link to post
Share on other sites
Evil Steve    2017
If you create a render target, you can't set it as a texture. It doesn't make sense to have an anti-aliased texture anyway - that's what texture sampling is for.

I think the closest you'll get is making the texture twice the size you need, rendering to it, then drawing it at 50% size to let the bilinear filtering take care of the anti-aliasing.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this