I have an application that is receiving images from a camera. The application is written using wxWidgets and I am trying to display the image by creating a paint event. Every time I get a new image, I call Refresh on the panel.
After about a half a minute to a minute, it stops responding to the paint events. I've been looking on the wxWidgets Wiki, but I can't seem to find why it's doing that (I believe I'm allowing the GUI event loop to run).
When I change the window size, it refreshes the image as normal (so it's not blocking all paint events).
Any idea why this is happening?
I'm not sure how much this will help, but here's the paint event's code.
void ImageViewer::onPaint(wxPaintEvent &event)
{
wxBufferedPaintDC dc(this);
cv::Mat buffer;
static int count = 0;
std::cout << "drawing " << ++count << std::endl;
{
// doing stuff in a lock
}
// it doesn't ever seem to get stuck in the lock
std::cout << "finished" << std::endl;
// buffer is an object with the image data buffered
wxImage img(buffer.rows,
buffer.cols,
buffer.data, true);
wxBitmap bmp(img);
dc.DrawBitmap(bmp, 0, 0);
}
I call refresh every time I get a new image and change the buffer (changing the buffer is done inside of a lock).
Here is something to try: call Update() immediately after your call to Refresh().
Refresh invalidates the window and queues the paint request. Update forces an immediate repaint of any invalidated rectangles.
Related
I have a code to when I press "p" the game pauses. Although, I want to show some text saying like "Game is Paused. Press P to progress" how can I do that? Here´s my code:
//create event
pause=false;
pauseSurf=-1;
pauseSurfBuffer=-1;
resW=1920;
resH=1080;
//Post-Draw event
gpu_set_blendenable(false);
if(pause)
{
surface_set_target(application_surface);
if(surface_exists(pauseSurf)) draw_surface(pauseSurf,0,0);
else // restore from buffer if we lost the surface
{
pauseSurf = surface_create(resW,resH);
buffer_set_surface(pauseSurfBuffer,pauseSurf,0);
}
surface_reset_target();
}
if(keyboard_check_pressed(ord("P")))// Toggle pause(Whatever condition/trigger you like)
{
if(!pause)// pause now
{
pause=true;
// deactivate everything other than this instance
instance_deactivate_all(true);
// NOTE:
// If you need to pause anything like animating sprites,tiles,room backgrounds
// you need to do that separately,unfortunately!
// capture this game moment(won't capture draw gui contents though)
pauseSurf=surface_create(resW,resH);
surface_set_target(pauseSurf);
draw_surface(application_surface,0,0);
surface_reset_target();
// Back up this surface toabuffer in case we lose it(screen focus,etc)
if(buffer_exists(pauseSurfBuffer)) buffer_delete(pauseSurfBuffer);
pauseSurfBuffer=buffer_create(resW*resH*4,buffer_fixed,1);
buffer_get_surface(pauseSurfBuffer,pauseSurf,0);
}
else // unpause now
{
pause=false;
instance_activate_all();
if(surface_exists(pauseSurf))surface_free(pauseSurf);
if(buffer_exists(pauseSurfBuffer))buffer_delete(pauseSurfBuffer);
}
}
gpu_set_blendenable(true);
//Clean up event
if(surface_exists(pauseSurf))surface_free(pauseSurf);
if(buffer_exists(pauseSurfBuffer))buffer_delete(pauseSurfBuffer);
Code from: https://www.youtube.com/watch?v=dNiLIX8jNOM&t=95s&ab_channel=ShaunSpalding
If any of you knows how to help me I would be thankful! :)
Add a DrawGui Event to your object, and then add the following code within:
if (pause)
{
draw_text(50, 50, "Game is Paused. Press P to progress");
}
DrawGui makes it so that it renders on top of your viewport, so it's not connected with the position in the room.
The 50, 50, is the X and Y position of the text, use it as you see fit. You can use it centered if you take the width/height of the camera/viewport and divide that by 2.
The pause is already defined in the Create Event, so that shouldn't give any problems.
I have an object I want to drag around the screen with the mouse in Processing. I set acquired to true on mouse down over the object, and to false on mouse up, thus:
void mousePressed() {
if (overThing()) {
acquired = true;
}
}
void mouseReleased() {
acquired = false;
}
I then query acquired in my update(), and drag the object if it is true.
void update() {
\\ other stuff...
if (acquired) {
\\ drag thing code ...
}
}
This all works fine in Processing. mouseReleased() gets called whether I release the mouse inside or outside the active window.
However, when I move the code to Chrome, using processing.js (v1.4.8), mouseReleased() is not called if I release the mouse outside the canvas (whether the mouse is still over the web page, or outside the browser window). So when I return the (now unclicked) mouse to the canvas, the object is still getting dragged around.
I tried including a test of mousePressed in update(), but that also returns true in these circumstances.
Any help on what I need to do to make mouse state changes outside the canvas visible with processing.js?
I don't know about Processing specifically, but releasing mouse buttons outside a widget is a common issue in GUI development.
I suspect that you have no way of knowing the precise time when the mouse is released outside the widget, but you do have two options:
Set acquired = false in mouseOut(), as #Kevin suggests.
I assume there is some type of mouseEntered() method in Processing, and also some way of knowing if the mouse button is currently pressed (either a global variable, or an event object passed to mouseEntered()). You can catch the mouse entered event, check if the mouse has been released, and set acquired = false then.
Like so:
void mouseEntered() {
if (mouse button is pressed) {
acquired = false;
}
}
Edit: From your comments, #Susan, it seems like there is a bug in processing.js, where mousePressed is not set to false if the mouse button is released outside the canvas. One thing pointing to this being a bug is that the mouse movement example on the processing website also shows this behaviour.
Depending upon how much control you have over the website this is going on, and how much effort you want to go to, you could fix the bug yourself by writing some javascript (separate from your processing code):
Define a mouseUp() event on the page <body>, to catch all mouse release events on the page.
In the mouseUp() event, check if the event comes from your Processing control. (There is probably an event object passed to the mouseUp() function, and you might have to give your Processing control an ID to identify it)
If the event doesn't come from your Processing control, then fire a mouseUp event yourself, on the Processing control. This should (hopefully!) trigger a mouse event inside your Processing code.
I'm not sure what Processing will make of the mouse (x,y) position being outside its control when it handles the event you send it. You might want to set a flag on the event object (assuming you can add extra data to the event object) to say "don't use the (x,y) position of this event - it's outside the control".
Edit2: It was easier than I thought! Here is the JavaScript code to detect the mouse being released outside of the Processing canvas and send the mouseReleased event to the canvas. I've tested it on the mouse movement example from the Processing website, and it fixes the bug.
It uses jQuery (although it could be re-written to not use jQuery), and it assumes your Processing canvas has the ID "processingCanvas":
$(':not(processingCanvas)').mouseup(function(){
Processing.getInstanceById('processingCanvas').mouseReleased();
});
To use this code, include it anywhere in your page (in a JavaScript file or in <script> tags) and make sure you have the jQuery library included before this code.
The Processing object allows JavaScript to call any functions defined in your Processing code. Here I've used it to call Processing's built in mouseReleased() function, but if you wanted to call a custom function to handle the mouse-released-outside state differently, then you could.
You should use the mouseOut() function to detect when the mouse leaves the sketch:
void mouseOut() {
acquired = false;
}
More info in the reference here.
I'm trying to use NAudio's FadeInOutSampleProvider to fade in a sample and fade it out. The fade in works OK, but instead of fading out gradually I get abrupt silence from where the fade-out should begin.
What's the correct way to fade out with FadeInOutSampleProvider?
Here's how I'm trying to do it:
IWaveProvider waveSource; // initialised by reading a WAV file
// The ISampleProvider will be the underlying source for the following operations
ISampleProvider sampleSource = waveSource.ToSampleProvider();
// Create a provider which defines the samples we want to fade in
// (including the full-volume "middle" of the final output)
ISampleProvider fadeInSource = new OffsetSampleProvider(sampleSource);
fadeInSource.TakeSamples = most_of_file; // calculation omitted for brevity
// Create a provider which defines the samples we want to fade out:
// We will play these samples when fadeInSource is finished
ISampleProvider fadeOutSource = new OffsetSampleProvider(sampleSource);
fadeOutSource.SkipOverSamples = fadeInSource.TakeSamples;
// Wrap the truncated sources in FadeInOutSampleProviders
var fadeIn = new FadeInOutSampleProvider(fadeInSource);
fadeIn.BeginFadeIn(500); // half-second fade
var fadeOut = new FadeInOutSampleProvider(fadeOutSource);
fadeOut.BeginFadeOut(500);
// doc-comments suggest the fade-out will begin "after first Read"
I'm expecting fadeOut to initially read non-zero samples from 500ms before the end of the original source, but fade out to zeros by the end of the source.
However, when I play fadeIn to completion, then play fadeOut, I find that the very first Read call to fadeOut fills the buffer with zeros.
Am I doing something wrong? Or is there a bug in NAudio?
Note: I'm handling the sequential playback using a ConcatenatingSampleProvider which I implemented myself — I can't anything similar in NAudio's API. It's pretty trivial, so I've omitted the source here.
The problem is you're trying to reuse sampleSource twice in your graph. So sampleSource has already been read to the end before anything is read from fadeOutSource. Probably for your usage, it would be better for FadeInOutSampleProvider to be able to "schedule" a fade-out after a known number of samples.
An alternative approach is a FadeOutSampleProvider that caches the fade-out duration, and then when it detects the end of its source has been reached, it returns the cached portion faded out. It does mean latency is introduced.
Im working with a MediaElement object and SurfaceSlider object, I use the SurfaceSlider to control the Video position and also want the SurfaceSlider to show the current position of the video, like youtube does.
I use this code to control the position of the video, this function is called when the ValueChanged event of the SurfaceSlider object occurs...
private void SeekToMediaPosition(object sender, RoutedPropertyChangedEventArgs<double> args)
{
int SliderValue = (int)mySurfaceSlider.Value;
TimeSpan ts = new TimeSpan(0, 0, 0, 0, SliderValue);
myMediaElement.Position = ts;
}
I use this code to show the current position of the video...
DispatcherTimer ticks = new DispatcherTimer();
private void Element_MediaOpened(object sender, EventArgs e)
{
mySurfaceSlider.Maximum = myMediaElement.NaturalDuration.TimeSpan.TotalMilliseconds;
ticks.Interval = TimeSpan.FromMilliseconds(1);
ticks.Tick += ticks_Tick;
ticks.Start();
myMediaElement.Play();
}
void ticks_Tick(object sender, object e)
{
mySurfaceSlider.Value = myMediaElement.Position.TotalMilliseconds;
}
The problem is when the SurfaceSlider value is changed showing the current position of the video, the ValueChanged event is called too, and the position of the video is changed, creating a loop I guess.
Is there any other event to be used when the user changes the SurfaceSlider value, or a way to handle this issue?
Thanks
Esteban,
I think there are a few things I would try.
1... Increase your TimeSpan.FromMilliseconds(1) to TimeSpan.FromMilliseconds(100) or higher. I don't think your slider needs to be polling your video so continuously.
2... I think you could set a flag in SeekToMediaPosition (SeekInProgress=true) before you set myMediaElement.Position. Then in ticks_Tick, if SeekInProgress==true, set SeekInProgress=false and don't set mySurfaceSlider.Value for one timer cycle.
I believe the original version of the code you are using comes from here: http://msdn.microsoft.com/en-us/library/ms748248.aspx ... Perhaps there is something that code was doing to prevent your problem that has been omitted from your implementation?
If the slider is jumping around, maybe there is lag between when the user places their finger down on the slider and when they move it (causing SeekToMediaPosition to fire). What you need to do is detect if the user is currently touching mySurfaceSlider in ticks_Tick (maybe there is a collection of touch points to query for intersection with mySurfaceSlider? Or does mySurfaceSlider have touchdown and touchup events?) In any case, if the user is even TOUCHING mySurfaceSlider, you shouldn't let ticks_Tick update mySurfaceSlider.Value (or for a few milliseconds after).
I made a game for Windows 8 in monogame but running into a problem. We finally got our hands on a Surface RT but we noticed that the loading times are really long on this device. We looked at several other games and noticed that this wasn't an uncommon issue. To fight the boredom of the user during the loading of the resources I want to draw a loading bar and some random facts onto the screen. The problem is that loading the resources blocks the rest of the game and doesn't allow me to draw anything because it stays stuck at the initializing part.
I searched for creating a lose Thread but found that Windows Store didn't support that so now my question to you how can I load my resources in the background or another way to not block the complete game and be able to call handle my Draw() function to draw a loading bar onto my screen.
I did something like this:
protected volatile bool ContentLoaded = false;
protected async override void LoadContent()
{
base.LoadContent();
Enabled = false;
await ThreadPool.RunAsync(new WorkItemHandler(LoadAllContent));
}
protected void LoadAllContent(Windows.Foundation.IAsyncAction action)
{
if (action.Status == Windows.Foundation.AsyncStatus.Error)
System.Diagnostics.Debug.WriteLine(action.ErrorCode);
// load your contents
ContentLoaded = true;
Enable = true;
}
And at the beginning of your Draw method:
if (!ContentLoaded)
{
// draw your loading screen
return;
}
If you want a progress bar you need a counter to increase every resource you've loaded, then in your Draw your bar has to relate to that counter.