Sign in to follow this  
Ixusv4

[.net] Running DirectX in a seperate thread in VB.net

Recommended Posts

I can do DirectX in an picturebox on a form in VB.net.. Only problem is when I put a slider or anything else on the form for example adjust the speed of something..the rendering halts..Is there a way to run DirectX in a seperate thread so that the rendering loop will continu when I do something else on a form?

Share this post


Link to post
Share on other sites
You don't need to run directx in a different thread to do this. How are you handling the forms events, and when is the rendering occurring?

For that matter, I'm not sure directx would even appreciate being in a different thread from the form it's being rendered to.

Share this post


Link to post
Share on other sites
The rendering is currently done in a class. In the future I would like to make a DLL with these classes. The rendering is done in loop wich fires every 40 miliseconds...

The program on this stage is an MDI with a form wich shows the actual render...Another form is a control form with several sliders on it to control the movement of the object..Once I slide a slider...the rendering is halted...

Are there any examples wich can help me with the current problem..

Share this post


Link to post
Share on other sites
I don't have any specific examples, but I've done it before.

Instead of handing event handling over to application.run, and doing the rendering on a timed basis, use application.doevents instead.

Something like the following (c#, but you get the idea):

while(someForm.Created)
{
// Render to picture box
Application.DoEvents();
}

Share this post


Link to post
Share on other sites
I'm confused. Rendering halts when you add the scrollbar/objects or when the user interects with the scrollbar/object?

If it's interaction, then yes running it on another thread will solve the problem. But before I gurantee that 100%, answer the above question ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by gharen2
I don't have any specific examples, but I've done it before.

Instead of handing event handling over to application.run, and doing the rendering on a timed basis, use application.doevents instead.

Something like the following (c#, but you get the idea):

while(someForm.Created)
{
// Render to picture box
Application.DoEvents();
}

Bad Code!

Better code! [grin]

Share this post


Link to post
Share on other sites
Yeah yeah yeah.

I didn't want to complicate things further by going into that. I figure, once he gets it working with Application.DoEvents, he can look at optimizing it. Implement first, optimize second, they always say :)

Share this post


Link to post
Share on other sites
The DOEvents was already implanted in my renderloop. If it wasn't there any interaction with other controls on any form in the same program would be impossible.

The problem arises when the user interacts with the scrollbar/object or any object or when one moves any form around..

The problem is in the fact dat VB.net is not multi-tasking. And usually one makes a directX program Fullscreen...Buth I want to make my own 3D Editor :(

Share this post


Link to post
Share on other sites
Quote:
Original post by gharen2
Yeah yeah yeah.

I didn't want to complicate things further by going into that. I figure, once he gets it working with Application.DoEvents, he can look at optimizing it. Implement first, optimize second, they always say :)


Yeah, but implement the best way you know how. :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Machaira
Quote:
Original post by gharen2
Yeah yeah yeah.

I didn't want to complicate things further by going into that. I figure, once he gets it working with Application.DoEvents, he can look at optimizing it. Implement first, optimize second, they always say :)


Yeah, but implement the best way you know how. :)


So..the Do events doesn't do what everybody thinks.. So if anybody has an idea to help me with my problem...

Share this post


Link to post
Share on other sites
Without seeing the project it's hard to offer a suggestion. The Tick event on the timer fires even when another form has focus. I threw together a sample project to test this. There might be something in your render code that's causing the problem. Without seeing anything that's the best I can do. :(

Share this post


Link to post
Share on other sites
I too can't help you without seeing code.

Quote:
Original post by Ixusv4
So..the Do events doesn't do what everybody thinks.. So if anybody has an idea to help me with my problem...


And not to belabor the issue, but don't worry about the question of the validity of DoEvents for now. It does do what it's supposed to, the issue is just that it doesn't do it as efficiently as it could. But in terms of behavior, it has no bearing on your problem. Hence why I didn't want to bring it up :)

So, how about some code?

Share this post


Link to post
Share on other sites
Quote:
Original post by Ixusv4
The DOEvents was already implanted in my renderloop. If it wasn't there any interaction with other controls on any form in the same program would be impossible.

The problem arises when the user interacts with the scrollbar/object or any object or when one moves any form around..

The problem is in the fact dat VB.net is not multi-tasking. And usually one makes a directX program Fullscreen...Buth I want to make my own 3D Editor :(


Yes, your problem makes sense. When you fire the DoEvents() function, all user mouse clicks, key strokes, etc now have time to execute. Obviously the scrolling of your form/picturebox are taking longer than anticipated. This could be bad code or just the amount of work that needs to be done.

Multithreading may not solve your problem, as others stated please post your scrollbar event code and render loop. they're may be an easier way to fix the problem.

Share this post


Link to post
Share on other sites
Well..indeed...it resolves some issues...
Buth..there are now some other issues..
First of all...the responsiness of the program is not quite like what u would expect of a windows program...second of is that the thing that does fire the actual render is not in the class anymore..

Share this post


Link to post
Share on other sites
The first thing can probably be fixed by fixing the second thing. Given that what you did was thrown together a rethinking of the design could probably solve both problems simultaneously. [wink]

Share this post


Link to post
Share on other sites
Ok..I'm open for any suggestion :D
But bringing the Winproc to the class resolves in a minor problem..
First the Overrides doesn't work in a class...
So it would me something like this...


Protected Overloads Sub WndProc(ByRef m As Message)

If m.Msg = 15 Then

frmMain.Engine.Render()

SendNotifyMessage(Me, 15, IntPtr.Zero, IntPtr.Zero)
Else
MyBase.WndProc(m)
End If

End Sub

Only how do we get an integer pointer of a class?
And what does the 15 mean?

Share this post


Link to post
Share on other sites
First off, use spacing! Your code was impossible to read. Extra lines and proper formatting go a LONG way :)

This works perfect for me. You'll notice moving the scrollbars or moving the form DOESN'T halt rendering. Update your CTRL form Button1_Click to the below code:


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

If Button1.Text = "Start Renderloop" Then
Button1.Text = "Stop Renderloop"

Dim thrStart As New Threading.Thread(AddressOf frmMain.Engine.Start)
thrStart.Start()

Else
Button1.Text = "Start Renderloop"
frmMain.Engine.Stop()
End If

End Sub

Share this post


Link to post
Share on other sites
Thanx Zach...this really did the trick!!!
Even when the form is minimized it runs smootly in my Preview Window!!

The original program consist's swapchains rendering to different forms..

Really great..thnx...and sorry for the messy test program :( had to make it in 5 minutes...

Only problem now is to get the framerate right...so...if anybody has an idea :$

Share this post


Link to post
Share on other sites
No problem - glad it worked for you. Amazing what one line of code can do, love .NET!

1.) Add this to your frmMain (under your Dim EngineDX):


Public Delegate Sub UpdateFPSDelegate(ByVal FPS As Integer)


2.) Add a new function to frmMain:


Private Sub UpdateFPS(ByVal FPS As Integer)

frmCNS.Text = "The Framerate is " & FPS

End Sub


3.) Change your Handles Engine.Framerate function code to:

Me.Invoke(New UpdateFPSDelegate(AddressOf UpdateFPS), FPS)


The problem was that you are throwing the FrameRate() event on the new thread you made, so you can't access the frmCNS because you made the form using the original main thread for the application. Now, when the event is fired it calls a new event using Invoke() - which forces the function to run on the original main thread. So the function UpdateFPS() will always run on the original thread, hence why the forms text is now accessible.

I can explain any questions you may have.

Zach

Share this post


Link to post
Share on other sites
Well..get ready for a whole bunch of questions :D
Thanx for the code u just gave me..I'll try to implent it tomorrow..

The major problem is that I want to render it at 50 fps.. In the example it should render at 25 fps...althoug the framecounter say's it runs at 22 fps...
Some timing with my watch shows it is 22 fps and not the desired 25 fps..

So how could I get an exact framerate I desire(50 of 60 fps)..

Share this post


Link to post
Share on other sites
Well...I get 60 :D (sorry..had to sleep sometime :p)
So 60 would be the maximum possible on my machine...
Buth if u get 57...and I get 60....it would be alot nicer when I could set the framerate...due to the fact my motion of the vertexen are timecode-based...

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