need help with a tearing like graphics glitch

Member
Posts: 208
Joined: 2005.04
Post: #1
I'm having trouble with a little graphics glitch. I think it's either refresh rate related, or pixel format related.

Here's my app:

http://www.cs.camosun.bc.ca/~c0262447/so...e_cube.dmg

It requires a gamepad or joystick (see the included ReadMe).

And here's my pixel format:

Code:
NSOpenGLPixelFormatAttribute attributes [] = {
NSOpenGLPFAWindow,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFADepthSize, 16,
NSOpenGLPFASampleBuffers, 1,
NSOpenGLPFASamples, 2,
NSOpenGLPFANoRecovery,
(NSOpenGLPixelFormatAttribute)nil
};


Thanks,

Andrew Garber
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #2
It doesn't pick up either my Saitek joystick or Macally iShock game pad. Without motion I didn't see any tearing. You remembered to synch to VBL right?
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #3
AnotherJake Wrote:It doesn't pick up either my Saitek joystick or Macally iShock game pad. Without motion I didn't see any tearing. You remembered to synch to VBL right?

Hmm... I guess your devices are reporting themselves properly. They should be matching to kHIDUsage_GD_Joystick. I'll post an auto-animated version (non joystick controlled), tonight so you can check out the tearing.

I'm using an NSTimer set to repeat at your display's refresh rate. I get the refresh rate by using CGDisplayCurrentMode(CGMainDisplayID()). The method which the timer invokes calls the view's setNeedsDisplay, passing YES.

Will that sync to VBL, or is there something else I have to do?
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #4
Hey AnotherJake, could you run the little command line app to find out what the device usage pairs are for your 2 controllers? Here's the app:

hid-info.dmg

It'll create files name HID_X.plist on your Desktop, one for each HID class device. Your mouse and keyboard should show up as HID_0.plist and HID_1.plist (and possibly HID_2.plist as well), then will follow your gamepad and joystick (assuming no other controllers are plugged in). Look for "DeviceUsagePairs" in the files. Inside "DeviceUsagePairs", you should see a few pairs of "DeviceUsage" and "DeviceUsagePage". It's the values those I'm looking for.

Alternatively, maybe you just post or email me the files?

It would really help me figure out why your controllers aren't showing up as joysticks. Wink


Thanks,

Andrew
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #5
Andrew Wrote:Will that sync to VBL, or is there something else I have to do?
We had a discussion about this a while back. Maybe arekkusu has some updated info on this now, but the best way is to set your timer to like 0.001f and turn on vbl synch with something like:
Code:
const long    vblSynch = 1;
CGLSetParameter( CGLGetCurrentContext(), kCGLCPSwapInterval, &vblSynch );

I'll get you some HID info in just a bit...

... for the macally DeviceUsagePairs it's 5,1 and 1,1 and for the saitek it's 4,1 and 1,1 for DeviceUsage and DeviceUsagePage respectively. You want the plists?
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #6
Andrew Wrote:The method which the timer invokes calls the view's setNeedsDisplay, passing YES.
You don't need to use setNeedsDisplay, just draw the frame in the timer callback and be done with it. Here's a more elaborate illustration of how to do it:

Code:
- (id)initWithFrame:(NSRect)frameRect
{
    NSOpenGLPixelFormat    *nsglFormat;
    const long            vblSynch = 1;
    
    nsglFormat = [self createPixelFormat:frameRect];
    if (!nsglFormat)
    {
        return nil;
    }
    self = [super initWithFrame:frameRect pixelFormat:nsglFormat];
    [nsglFormat release];
    if (!self)
    {
        return nil;
    }
    [[self openGLContext] makeCurrentContext];
    timer = [[NSTimer scheduledTimerWithTimeInterval:0.001f
        target:self
        selector:@selector(drawFrame)
        userInfo:nil
        repeats:YES]
        retain];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSModalPanelRunLoopMode];
    CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &vblSynch);

    return self;
}

- (void)drawFrame
{
    // opengl drawing code here
}

BTW, the application thread that does the graphics flushing gets automatically blocked when it doesn't need to draw a frame when vbl synch is on so there's no need to throttle the frame rate.
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #7
It would be rad if you could send me the plist files. The Saitek, with a pair of (4,1), SHOULD be matching.

I tried to sync the VBL with both your code, and the following:

Code:
long newVBLState = 1;
[glContext setValues:&newVBLState
forParameter:NSOpenGLCPSwapInterval];

It gets rid of the graphic glitch, but slows down my app BIG TIME. I'm talking 1/2 second lags between when you move the joystick and see a reaction on the screen. I've also tried setting my NSTimer's interval to setting to something other than reciprocal of the detected refresh rate (like 0.001 as you suggested).

Any ideas?

AnotherJake Wrote:We had a discussion about this a while back. Maybe arekkusu has some updated info on this now, but the best way is to set your timer to like 0.001f and turn on vbl synch with something like:
Code:
const long    vblSynch = 1;
CGLSetParameter( CGLGetCurrentContext(), kCGLCPSwapInterval, &vblSynch );

I'll get you some HID info in just a bit...

... for the macally DeviceUsagePairs it's 5,1 and 1,1 and for the saitek it's 4,1 and 1,1 for DeviceUsage and DeviceUsagePage respectively. You want the plists?
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #8
AnotherJake Wrote:You don't need to use setNeedsDisplay, just draw the frame in the timer callback and be done with it.

But in this document, Apple suggests using -setNeedsDisplay

I'll give your way a shot to see how it goes though
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #9
Andrew Wrote:Any ideas?
Hmm... Yeah, that should work for the graphics problem. I don't understand why there would be a control lag except that maybe your timing issues changed with the vbl synch. Did you put in an fps counter to see if it's indeed doing the screen refresh rate for fps? Also, you might try doing something like keyboard control temporarily to do some testing outside of your hid code for a bit. It's really hard to say without a peek at the code.

Andrew Wrote:It would be rad if you could send me the plist files.
No problemo, I just sent the plists to the address on your website. Your user prefs here apparently do not allow users to email you from the forums. These two controllers are notoriously difficult to deal with in the hid manager.

Andrew Wrote:But in this document, Apple suggests using -setNeedsDisplay
Yeah, hard to say. What they're talking about is the same thing we were discussing in that discussion I linked to above. There was a q&a that Arekkusu linked to in there that says not to overdrive the graphics, similar to the document you're referring to. We think that is actually incorrect for games.
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #10
I figured out the control lag. My HID code (which runs, for the most part, in a separate thread) does the following call whether a new event comes in from a device:

Code:
[delegate performSelectorOnMainThread: @selector(didReceiveHIDEvent:)
                           withObject: event
                        waitUntilDone: YES];

Setting waitUntilDone to YES worked great for debugging, but now it's unnecessary. Changing it to NO (thus prevent the call from blocking) fixed the lag issue I had when VBL sync'ing was enabled in my OpenGL context. Everything now runs smoothly!

I got your email with the plist files, but I still can't figure out why the Saitek gamepad isn't working. According to the plist, it should match without a hitch. I also checked whether it actually has the elements my app looks for (X, Y, Z, and Rz). It does. Have you tried unplugging it and plugging it back in (while the app is running)?

Thanks for all your help Jake! Grin
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #11
Andrew Wrote:I figured out the control lag... Everything now runs smoothly!
Aha! Excellent! Grin

I wish I could say that I tried the joystick again and it worked, but alas I tried it again and the result is still nada. I tried unplugging several times with app on/off/slowly/fast/praying/etc. but to no avail. Sad

I wish I could offer suggestions on the HID coding but I travelled down that path myself a couple years ago and decided that Apple screwed it up so badly that I wasn't going to bother again until I had heard of improvements from other developers. I still haven't heard any good news yet. Every time I think of approaching the HID manager again I see a vision... It's an entrance to a dark cave at the base of a stoney outcrop... Just above the entrance is a chiseled inscription which says, "Abandon all hope, ye who enter here..."

But good luck!
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #12
Here's the new version (VBL sync'ed):

floating_blue_cube.dmg

I also set it to match both the generic desktop page and the joystick usage. That, shouldn't make any difference to the Saitek controller problem, but you might as well give it a shot.

I was looking through the SDL source code earlier, and it turns out that they try to match only on the primary usage key (which is contrary to what Apple recommends). Does your controller work with apps built around SDL?
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #13
The Saitek picked up but the macally is still a no-show. I don't know about any SDL-specific behavior.
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #14
Sweet! The macally shouldn't show up because its device usage pairs are 1,1 and 1,5. In other words, it's claiming to be a pointer device and a gamepad device. My app is only looking for devices which report themselves as joysticks. I'll update it so that it will match both joysticks and gamepads (but not right now... I have to get to the bank before it closes).
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #15
k, it should work with both of your controllers now:

floating_blue_cube.dmg

please let me know if it does Smile
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  iPhone/iPad Audio Glitch - Double Hiss/Static reapz 2 4,926 Dec 8, 2010 06:22 PM
Last Post: reapz
  Visual Tearing Arjan B 11 5,829 Nov 9, 2007 08:47 AM
Last Post: Arjan B
  Weird Windowed Mode GFX Tearing nabobnick 2 2,758 Jul 25, 2005 06:45 PM
Last Post: nabobnick
  nasty tearing when I scroll in openGL Joseph Duchesne 3 3,108 Aug 15, 2004 10:30 PM
Last Post: arekkusu